added dgemm-, dtrmm-, zgemm- and ztrmm-kernel for power8
[platform/upstream/openblas.git] / kernel / power / zgemv_t.S
1 /*********************************************************************/
2 /* Copyright 2009, 2010 The University of Texas at Austin.           */
3 /* All rights reserved.                                              */
4 /*                                                                   */
5 /* Redistribution and use in source and binary forms, with or        */
6 /* without modification, are permitted provided that the following   */
7 /* conditions are met:                                               */
8 /*                                                                   */
9 /*   1. Redistributions of source code must retain the above         */
10 /*      copyright notice, this list of conditions and the following  */
11 /*      disclaimer.                                                  */
12 /*                                                                   */
13 /*   2. Redistributions in binary form must reproduce the above      */
14 /*      copyright notice, this list of conditions and the following  */
15 /*      disclaimer in the documentation and/or other materials       */
16 /*      provided with the distribution.                              */
17 /*                                                                   */
18 /*    THIS  SOFTWARE IS PROVIDED  BY THE  UNIVERSITY OF  TEXAS AT    */
19 /*    AUSTIN  ``AS IS''  AND ANY  EXPRESS OR  IMPLIED WARRANTIES,    */
20 /*    INCLUDING, BUT  NOT LIMITED  TO, THE IMPLIED  WARRANTIES OF    */
21 /*    MERCHANTABILITY  AND FITNESS FOR  A PARTICULAR  PURPOSE ARE    */
22 /*    DISCLAIMED.  IN  NO EVENT SHALL THE UNIVERSITY  OF TEXAS AT    */
23 /*    AUSTIN OR CONTRIBUTORS BE  LIABLE FOR ANY DIRECT, INDIRECT,    */
24 /*    INCIDENTAL,  SPECIAL, EXEMPLARY,  OR  CONSEQUENTIAL DAMAGES    */
25 /*    (INCLUDING, BUT  NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE    */
26 /*    GOODS  OR  SERVICES; LOSS  OF  USE,  DATA,  OR PROFITS;  OR    */
27 /*    BUSINESS INTERRUPTION) HOWEVER CAUSED  AND ON ANY THEORY OF    */
28 /*    LIABILITY, WHETHER  IN CONTRACT, STRICT  LIABILITY, OR TORT    */
29 /*    (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT    */
30 /*    OF  THE  USE OF  THIS  SOFTWARE,  EVEN  IF ADVISED  OF  THE    */
31 /*    POSSIBILITY OF SUCH DAMAGE.                                    */
32 /*                                                                   */
33 /* The views and conclusions contained in the software and           */
34 /* documentation are those of the authors and should not be          */
35 /* interpreted as representing official policies, either expressed   */
36 /* or implied, of The University of Texas at Austin.                 */
37 /*********************************************************************/
38
39 #define ASSEMBLER
40 #include "common.h"
41
42 #define P 2048
43
44 #ifndef __64BIT__
45 #define STACKSIZE 224
46 #else
47 #define STACKSIZE 304
48 #endif
49
50 #ifdef linux
51 #ifndef __64BIT__
52 #define M       r3
53 #define N       r4
54 #define A       r6
55 #define LDA     r7
56 #define X       r8
57 #define INCX    r9
58 #define Y       r10
59 #define INCY    r5
60 #else
61 #define M       r3
62 #define N       r4
63 #define A       r8
64 #define LDA     r9
65 #define X       r10
66 #define INCX    r5
67 #define Y       r6
68 #define INCY    r7
69 #endif
70 #endif
71
72 #if defined(_AIX) || defined(__APPLE__)
73 #if !defined(__64BIT__) && defined(DOUBLE)
74 #define M       r3
75 #define N       r4
76 #define A       r10
77 #define LDA     r5
78 #define X       r6
79 #define INCX    r7
80 #define Y       r8
81 #define INCY    r9
82 #else
83 #define M       r3
84 #define N       r4
85 #define A       r8
86 #define LDA     r9
87 #define X       r10
88 #define INCX    r5
89 #define Y       r6
90 #define INCY    r7
91 #endif
92 #endif
93
94 #define BUFFER  r11
95 #define XP      r12
96 #define MIN_N   r14
97 #define J       r15
98 #define CO      r16
99 #define BO      r17
100 #define PLDA_M  r18
101 #define AO1     r19
102 #define AO2     r20
103 #define AO3     r21
104 #define AO4     r22
105 #define IS      r23
106 #define PREA    r24
107 #define PREC    r25
108
109 #define Y1      r23   /* dummy; should be same as gemv_n.S */
110 #define Y2      r24   /* dummy; should be same as gemv_n.S */
111
112 #if defined(PPCG4)
113 #define PREFETCHSIZE_A  34
114 #define PREFETCHSIZE_C  16
115 #endif
116
117 #if defined(PPC440) || defined(PPC440FP2)
118 #define PREFETCHSIZE_A  34
119 #define PREFETCHSIZE_C  16
120 #endif
121
122 #ifdef PPC970
123 #define PREFETCHSIZE_A  56
124 #define PREFETCHSIZE_C  16
125 #endif
126
127 #ifdef CELL
128 #define PREFETCHSIZE_A  56
129 #define PREFETCHSIZE_C  16
130 #endif
131
132 #ifdef POWER4
133 #define PREFETCHSIZE_A  34
134 #define PREFETCHSIZE_C  16
135 #endif
136
137 #ifdef POWER5
138 #define PREFETCHSIZE_A  40
139 #define PREFETCHSIZE_C   8
140 #endif
141
142 #ifdef POWER6
143 #define PREFETCHSIZE_A  24
144 #define PREFETCHSIZE_C   8
145 #endif
146
147 #if !(defined(CONJ) && defined(XCONJ))
148 #define FMADDR FMADD
149 #define FMSUBR FNMSUB
150 #else
151 #define FMADDR FNMSUB
152 #define FMSUBR FMADD
153 #endif
154
155 #ifndef NEEDPARAM
156
157 #ifndef __64BIT__
158 #define FZERO   200(SP)
159 #define ALPHA_R 208(SP)
160 #define ALPHA_I 216(SP)
161 #else
162 #define FZERO   256(SP)
163 #define ALPHA_R 264(SP)
164 #define ALPHA_I 272(SP)
165 #endif
166
167         PROLOGUE
168         PROFCODE
169
170         addi    SP, SP,  -STACKSIZE
171         li      r0,   0
172
173         stfd    f14,     0(SP)
174         stfd    f15,     8(SP)
175         stfd    f16,    16(SP)
176         stfd    f17,    24(SP)
177         stfd    f18,    32(SP)
178         stfd    f19,    40(SP)
179         stfd    f20,    48(SP)
180         stfd    f21,    56(SP)
181         stfd    f22,    64(SP)
182         stfd    f23,    72(SP)
183         stfd    f24,    80(SP)
184         stfd    f25,    88(SP)
185         stfd    f26,    96(SP)
186         stfd    f27,   104(SP)
187         stfd    f28,   112(SP)
188         stfd    f29,   120(SP)
189         stfd    f30,   128(SP)
190         stfd    f31,   136(SP)
191
192 #ifdef __64BIT__
193         std     r14,   144(SP)
194         std     r15,   152(SP)
195         std     r16,   160(SP)
196         std     r17,   168(SP)
197         std     r18,   176(SP)
198         std     r19,   184(SP)
199         std     r20,   192(SP)
200         std     r21,   200(SP)
201         std     r22,   208(SP)
202         std     r23,   216(SP)
203         std     r24,   224(SP)
204         std     r25,   232(SP)
205         std     r0,    FZERO
206 #else
207         stw     r14,   144(SP)
208         stw     r15,   148(SP)
209         stw     r16,   152(SP)
210         stw     r17,   156(SP)
211         stw     r18,   160(SP)
212         stw     r19,   164(SP)
213         stw     r20,   168(SP)
214         stw     r21,   172(SP)
215         stw     r22,   176(SP)
216         stw     r23,   180(SP)
217         stw     r24,   184(SP)
218         stw     r25,   188(SP)
219         stw     r0,    FZERO
220         stw     r0,    4 + FZERO
221 #endif
222
223 #ifdef linux
224 #ifndef __64BIT__
225         lwz     INCY,    FRAMESLOT(0) + STACKSIZE(SP)
226         lwz     BUFFER,  FRAMESLOT(1) + STACKSIZE(SP)
227 #else
228         ld      INCX,    FRAMESLOT(0) + STACKSIZE(SP)
229         ld      Y,       FRAMESLOT(1) + STACKSIZE(SP)
230         ld      INCY,    FRAMESLOT(2) + STACKSIZE(SP)
231         ld      BUFFER,  FRAMESLOT(3) + STACKSIZE(SP)
232 #endif
233 #endif
234
235 #if defined(_AIX) || defined(__APPLE__)
236 #ifndef __64BIT__
237 #ifdef DOUBLE
238         lwz     LDA,     FRAMESLOT(0) + STACKSIZE(SP)
239         lwz     X,       FRAMESLOT(1) + STACKSIZE(SP)
240         lwz     INCX,    FRAMESLOT(2) + STACKSIZE(SP)
241         lwz     Y,       FRAMESLOT(3) + STACKSIZE(SP)
242         lwz     INCY,    FRAMESLOT(4) + STACKSIZE(SP)
243         lwz     BUFFER,  FRAMESLOT(5) + STACKSIZE(SP)
244 #else
245         lwz     INCX,    FRAMESLOT(0) + STACKSIZE(SP)
246         lwz     Y,       FRAMESLOT(1) + STACKSIZE(SP)
247         lwz     INCY,    FRAMESLOT(2) + STACKSIZE(SP)
248         lwz     BUFFER,  FRAMESLOT(3) + STACKSIZE(SP)
249 #endif
250 #else
251         ld      INCX,    FRAMESLOT(0) + STACKSIZE(SP)
252         ld      Y,       FRAMESLOT(1) + STACKSIZE(SP)
253         ld      INCY,    FRAMESLOT(2) + STACKSIZE(SP)
254         ld      BUFFER,  FRAMESLOT(3) + STACKSIZE(SP)
255 #endif
256 #endif
257
258         stfd    f1, ALPHA_R
259         stfd    f2, ALPHA_I
260
261         mullw   PLDA_M, LDA, N
262         li      XP,  P
263         subf    PLDA_M, XP, PLDA_M
264         slwi    PLDA_M, PLDA_M, ZBASE_SHIFT
265
266         slwi    LDA,  LDA,  ZBASE_SHIFT
267         slwi    INCX, INCX, ZBASE_SHIFT
268         slwi    INCY, INCY, ZBASE_SHIFT
269
270         li      IS,  0
271
272         li      PREA, PREFETCHSIZE_A * SIZE
273         li      PREC, PREFETCHSIZE_C * SIZE
274
275         cmpwi   cr0, M, 0
276         ble     LL(End)
277         cmpwi   cr0, N, 0
278         ble     LL(End)
279         .align 4
280
281 LL(ISLoop):
282         subf    MIN_N, IS, M
283         slwi    r0, IS, ZBASE_SHIFT
284         cmpi    cr0, 0, MIN_N, P
285         ble+    LL(min_nP)
286         li      MIN_N, P
287 LL(min_nP):
288         add     XP, X,  r0
289         cmpwi   cr0, INCX, 2 * SIZE
290         beq     LL(Main)
291
292         mr      XP, BUFFER
293         addi    CO, BUFFER, -SIZE
294
295         srawi.  r0, MIN_N, 2
296         mtspr   CTR, r0
297         ble     LL(CopyRemain)
298         .align 4
299
300 LL(CopyKernel):
301         LFD     f0, 0 * SIZE(X)
302         LFD     f1, 1 * SIZE(X)
303         add     X, X, INCX
304         LFD     f2, 0 * SIZE(X)
305         LFD     f3, 1 * SIZE(X)
306         add     X, X, INCX
307         LFD     f4, 0 * SIZE(X)
308         LFD     f5, 1 * SIZE(X)
309         add     X, X, INCX
310         LFD     f6, 0 * SIZE(X)
311         LFD     f7, 1 * SIZE(X)
312         add     X, X, INCX
313
314         STFD    f0,  1 * SIZE(CO)
315         STFD    f1,  2 * SIZE(CO)
316         STFD    f2,  3 * SIZE(CO)
317         STFD    f3,  4 * SIZE(CO)
318         STFD    f4,  5 * SIZE(CO)
319         STFD    f5,  6 * SIZE(CO)
320         STFD    f6,  7 * SIZE(CO)
321         STFDU   f7,  8 * SIZE(CO)
322         bdnz    LL(CopyKernel)
323         .align 4
324
325 LL(CopyRemain):
326         andi.   r0, MIN_N, 3
327         mtspr   CTR, r0
328         ble     LL(Main)
329         .align 4
330
331 LL(CopySub):
332         LFD     f0, 0 * SIZE(X)
333         LFD     f1, 1 * SIZE(X)
334         add     X, X, INCX
335         STFD    f0,  1 * SIZE(CO)
336         STFDU   f1,  2 * SIZE(CO)
337         bdnz    LL(CopySub)
338         .align 4
339
340 LL(Main):
341         mr      CO, Y
342         addi    XP, XP, -SIZE
343         srawi.  J, N, 2
344         ble     LL(Remain)
345         .align 4
346
347 LL(MainHead):
348         mr     AO1, A
349         add    AO2, A,   LDA
350         add    AO3, AO2, LDA
351         add    AO4, AO3, LDA
352         add    A,   AO4, LDA
353
354         mr     BO, XP
355
356         lfd      f0,  FZERO
357         fmr      f1,  f0
358         fmr      f2,  f0
359         fmr      f3,  f0
360         fmr      f4,  f0
361         fmr      f5,  f0
362         fmr      f6,  f0
363         fmr      f7,  f0
364         fmr      f8,  f0
365         fmr      f9,  f0
366         fmr      f10, f0
367         fmr      f11, f0
368         fmr      f12, f0
369         fmr      f13, f0
370         fmr      f14, f0
371         fmr      f15, f0
372
373         dcbtst   PREC, CO
374         srawi.  r0,  MIN_N, 3
375         mtspr   CTR, r0
376         ble     LL(MainN3)
377
378         LFD     f16, 0 * SIZE(AO1)
379         LFD     f17, 1 * SIZE(AO1)
380         LFD     f18, 0 * SIZE(AO2)
381         LFD     f19, 1 * SIZE(AO2)
382         LFD     f20, 0 * SIZE(AO3)
383         LFD     f21, 1 * SIZE(AO3)
384         LFD     f22, 0 * SIZE(AO4)
385         LFD     f23, 1 * SIZE(AO4)
386
387         LFD     f24, 1 * SIZE(BO)
388         LFD     f25, 2 * SIZE(BO)
389         LFD     f26, 3 * SIZE(BO)
390         LFD     f27, 4 * SIZE(BO)
391         LFD     f28, 5 * SIZE(BO)
392         LFD     f29, 6 * SIZE(BO)
393         LFD     f30, 7 * SIZE(BO)
394         LFD     f31, 8 * SIZE(BO)
395
396         bdz     LL(MainKernelSkip)
397         .align 5
398
399 LL(MainKernel):
400         FMADD   f0,  f16,  f24, f0
401         FMADD   f1,  f16,  f25, f1
402         FMADD   f2,  f17,  f24, f2
403         FMADD   f3,  f17,  f25, f3
404
405         FMADD   f4,  f18,  f24, f4
406         FMADD   f5,  f18,  f25, f5
407         FMADD   f6,  f19,  f24, f6
408         FMADD   f7,  f19,  f25, f7
409
410         LFD     f16, 2 * SIZE(AO1)
411         LFD     f17, 3 * SIZE(AO1)
412         LFD     f18, 2 * SIZE(AO2)
413         LFD     f19, 3 * SIZE(AO2)
414
415         FMADD   f8,  f20,  f24, f8
416         FMADD   f9,  f20,  f25, f9
417         FMADD   f10, f21,  f24, f10
418         FMADD   f11, f21,  f25, f11
419
420         FMADD   f12, f22,  f24, f12
421         FMADD   f13, f22,  f25, f13
422         FMADD   f14, f23,  f24, f14
423         FMADD   f15, f23,  f25, f15
424
425         LFD     f20, 2 * SIZE(AO3)
426         LFD     f21, 3 * SIZE(AO3)
427         LFD     f22, 2 * SIZE(AO4)
428         LFD     f23, 3 * SIZE(AO4)
429
430         FMADD   f0,  f16,  f26, f0
431         FMADD   f1,  f16,  f27, f1
432         FMADD   f2,  f17,  f26, f2
433         FMADD   f3,  f17,  f27, f3
434
435         FMADD   f4,  f18,  f26, f4
436         FMADD   f5,  f18,  f27, f5
437         FMADD   f6,  f19,  f26, f6
438         FMADD   f7,  f19,  f27, f7
439
440         LFD     f16, 4 * SIZE(AO1)
441         LFD     f17, 5 * SIZE(AO1)
442         LFD     f18, 4 * SIZE(AO2)
443         LFD     f19, 5 * SIZE(AO2)
444
445         FMADD   f8,  f20,  f26, f8
446         FMADD   f9,  f20,  f27, f9
447         FMADD   f10, f21,  f26, f10
448         FMADD   f11, f21,  f27, f11
449
450         FMADD   f12, f22,  f26, f12
451         FMADD   f13, f22,  f27, f13
452         FMADD   f14, f23,  f26, f14
453         FMADD   f15, f23,  f27, f15
454
455         LFD     f20, 4 * SIZE(AO3)
456         LFD     f21, 5 * SIZE(AO3)
457         LFD     f22, 4 * SIZE(AO4)
458         LFD     f23, 5 * SIZE(AO4)
459
460         LFD     f24,  9 * SIZE(BO)
461         LFD     f25, 10 * SIZE(BO)
462         LFD     f26, 11 * SIZE(BO)
463         LFD     f27, 12 * SIZE(BO)
464
465         FMADD   f0,  f16,  f28, f0
466         FMADD   f1,  f16,  f29, f1
467         FMADD   f2,  f17,  f28, f2
468         FMADD   f3,  f17,  f29, f3
469
470         FMADD   f4,  f18,  f28, f4
471         FMADD   f5,  f18,  f29, f5
472         FMADD   f6,  f19,  f28, f6
473         FMADD   f7,  f19,  f29, f7
474
475         LFD     f16, 6 * SIZE(AO1)
476         LFD     f17, 7 * SIZE(AO1)
477         LFD     f18, 6 * SIZE(AO2)
478         LFD     f19, 7 * SIZE(AO2)
479
480         FMADD   f8,  f20,  f28, f8
481         FMADD   f9,  f20,  f29, f9
482         FMADD   f10, f21,  f28, f10
483         FMADD   f11, f21,  f29, f11
484
485         FMADD   f12, f22,  f28, f12
486         FMADD   f13, f22,  f29, f13
487         FMADD   f14, f23,  f28, f14
488         FMADD   f15, f23,  f29, f15
489
490         LFD     f20, 6 * SIZE(AO3)
491         LFD     f21, 7 * SIZE(AO3)
492         LFD     f22, 6 * SIZE(AO4)
493         LFD     f23, 7 * SIZE(AO4)
494
495         FMADD   f0,  f16,  f30, f0
496         FMADD   f1,  f16,  f31, f1
497         FMADD   f2,  f17,  f30, f2
498         FMADD   f3,  f17,  f31, f3
499
500         FMADD   f4,  f18,  f30, f4
501         FMADD   f5,  f18,  f31, f5
502         FMADD   f6,  f19,  f30, f6
503         FMADD   f7,  f19,  f31, f7
504
505         LFD     f16, 8 * SIZE(AO1)
506         LFD     f17, 9 * SIZE(AO1)
507         LFD     f18, 8 * SIZE(AO2)
508         LFD     f19, 9 * SIZE(AO2)
509
510         FMADD   f8,  f20,  f30, f8
511         FMADD   f9,  f20,  f31, f9
512         FMADD   f10, f21,  f30, f10
513         FMADD   f11, f21,  f31, f11
514
515         FMADD   f12, f22,  f30, f12
516         FMADD   f13, f22,  f31, f13
517         FMADD   f14, f23,  f30, f14
518         FMADD   f15, f23,  f31, f15
519
520         LFD     f20, 8 * SIZE(AO3)
521         LFD     f21, 9 * SIZE(AO3)
522         LFD     f22, 8 * SIZE(AO4)
523         LFD     f23, 9 * SIZE(AO4)
524
525         LFD     f28, 13 * SIZE(BO)
526         LFD     f29, 14 * SIZE(BO)
527         LFD     f30, 15 * SIZE(BO)
528         LFD     f31, 16 * SIZE(BO)
529
530         FMADD   f0,  f16,  f24, f0
531         FMADD   f1,  f16,  f25, f1
532         FMADD   f2,  f17,  f24, f2
533         FMADD   f3,  f17,  f25, f3
534
535         FMADD   f4,  f18,  f24, f4
536         FMADD   f5,  f18,  f25, f5
537         FMADD   f6,  f19,  f24, f6
538         FMADD   f7,  f19,  f25, f7
539
540         LFD     f16, 10 * SIZE(AO1)
541         LFD     f17, 11 * SIZE(AO1)
542         LFD     f18, 10 * SIZE(AO2)
543         LFD     f19, 11 * SIZE(AO2)
544
545         FMADD   f8,  f20,  f24, f8
546         FMADD   f9,  f20,  f25, f9
547         FMADD   f10, f21,  f24, f10
548         FMADD   f11, f21,  f25, f11
549
550         FMADD   f12, f22,  f24, f12
551         FMADD   f13, f22,  f25, f13
552         FMADD   f14, f23,  f24, f14
553         FMADD   f15, f23,  f25, f15
554
555         LFD     f20, 10 * SIZE(AO3)
556         LFD     f21, 11 * SIZE(AO3)
557         LFD     f22, 10 * SIZE(AO4)
558         LFD     f23, 11 * SIZE(AO4)
559
560         FMADD   f0,  f16,  f26, f0
561         FMADD   f1,  f16,  f27, f1
562         FMADD   f2,  f17,  f26, f2
563         FMADD   f3,  f17,  f27, f3
564
565         FMADD   f4,  f18,  f26, f4
566         FMADD   f5,  f18,  f27, f5
567         FMADD   f6,  f19,  f26, f6
568         FMADD   f7,  f19,  f27, f7
569
570         LFD     f16, 12 * SIZE(AO1)
571         LFD     f17, 13 * SIZE(AO1)
572         LFD     f18, 12 * SIZE(AO2)
573         LFD     f19, 13 * SIZE(AO2)
574
575         FMADD   f8,  f20,  f26, f8
576         FMADD   f9,  f20,  f27, f9
577         FMADD   f10, f21,  f26, f10
578         FMADD   f11, f21,  f27, f11
579
580         FMADD   f12, f22,  f26, f12
581         FMADD   f13, f22,  f27, f13
582         FMADD   f14, f23,  f26, f14
583         FMADD   f15, f23,  f27, f15
584
585         LFD     f20, 12 * SIZE(AO3)
586         LFD     f21, 13 * SIZE(AO3)
587         LFD     f22, 12 * SIZE(AO4)
588         LFD     f23, 13 * SIZE(AO4)
589
590         LFD     f24, 17 * SIZE(BO)
591         LFD     f25, 18 * SIZE(BO)
592         LFD     f26, 19 * SIZE(BO)
593         LFD     f27, 20 * SIZE(BO)
594
595         FMADD   f0,  f16,  f28, f0
596         FMADD   f1,  f16,  f29, f1
597         FMADD   f2,  f17,  f28, f2
598         FMADD   f3,  f17,  f29, f3
599
600         FMADD   f4,  f18,  f28, f4
601         FMADD   f5,  f18,  f29, f5
602         FMADD   f6,  f19,  f28, f6
603         FMADD   f7,  f19,  f29, f7
604
605         LFD     f16, 14 * SIZE(AO1)
606         LFD     f17, 15 * SIZE(AO1)
607         LFD     f18, 14 * SIZE(AO2)
608         LFD     f19, 15 * SIZE(AO2)
609
610         FMADD   f8,  f20,  f28, f8
611         FMADD   f9,  f20,  f29, f9
612         FMADD   f10, f21,  f28, f10
613         FMADD   f11, f21,  f29, f11
614
615         FMADD   f12, f22,  f28, f12
616         FMADD   f13, f22,  f29, f13
617         FMADD   f14, f23,  f28, f14
618         FMADD   f15, f23,  f29, f15
619
620         LFD     f20, 14 * SIZE(AO3)
621         LFD     f21, 15 * SIZE(AO3)
622         LFD     f22, 14 * SIZE(AO4)
623         LFD     f23, 15 * SIZE(AO4)
624
625         FMADD   f0,  f16,  f30, f0
626         FMADD   f1,  f16,  f31, f1
627         FMADD   f2,  f17,  f30, f2
628         FMADD   f3,  f17,  f31, f3
629
630         FMADD   f4,  f18,  f30, f4
631         FMADD   f5,  f18,  f31, f5
632         FMADD   f6,  f19,  f30, f6
633         FMADD   f7,  f19,  f31, f7
634
635         LFD     f16, 16 * SIZE(AO1)
636         LFD     f17, 17 * SIZE(AO1)
637         LFD     f18, 16 * SIZE(AO2)
638         LFD     f19, 17 * SIZE(AO2)
639
640         addi    AO1, AO1, 16 * SIZE
641         addi    AO2, AO2, 16 * SIZE
642         DCBT(AO1, PREA)
643         DCBT(AO2, PREA)
644
645         FMADD   f8,  f20,  f30, f8
646         FMADD   f9,  f20,  f31, f9
647         FMADD   f10, f21,  f30, f10
648         FMADD   f11, f21,  f31, f11
649
650         FMADD   f12, f22,  f30, f12
651         FMADD   f13, f22,  f31, f13
652         FMADD   f14, f23,  f30, f14
653         FMADD   f15, f23,  f31, f15
654
655         LFD     f20, 16 * SIZE(AO3)
656         LFD     f21, 17 * SIZE(AO3)
657         LFD     f22, 16 * SIZE(AO4)
658         LFD     f23, 17 * SIZE(AO4)
659
660         LFD     f28, 21 * SIZE(BO)
661         LFD     f29, 22 * SIZE(BO)
662         LFD     f30, 23 * SIZE(BO)
663         LFD     f31, 24 * SIZE(BO)
664
665         addi    AO3, AO3, 16 * SIZE
666         addi    AO4, AO4, 16 * SIZE
667         DCBT(AO3, PREA)
668         DCBT(AO4, PREA)
669
670         addi    BO, BO, 16 * SIZE
671         bdnz    LL(MainKernel)
672         .align 4
673
674 LL(MainKernelSkip):
675         FMADD   f0,  f16,  f24, f0
676         FMADD   f1,  f16,  f25, f1
677         FMADD   f2,  f17,  f24, f2
678         FMADD   f3,  f17,  f25, f3
679
680         FMADD   f4,  f18,  f24, f4
681         FMADD   f5,  f18,  f25, f5
682         FMADD   f6,  f19,  f24, f6
683         FMADD   f7,  f19,  f25, f7
684
685         LFD     f16, 2 * SIZE(AO1)
686         LFD     f17, 3 * SIZE(AO1)
687         LFD     f18, 2 * SIZE(AO2)
688         LFD     f19, 3 * SIZE(AO2)
689
690         FMADD   f8,  f20,  f24, f8
691         FMADD   f9,  f20,  f25, f9
692         FMADD   f10, f21,  f24, f10
693         FMADD   f11, f21,  f25, f11
694
695         FMADD   f12, f22,  f24, f12
696         FMADD   f13, f22,  f25, f13
697         FMADD   f14, f23,  f24, f14
698         FMADD   f15, f23,  f25, f15
699
700         LFD     f20, 2 * SIZE(AO3)
701         LFD     f21, 3 * SIZE(AO3)
702         LFD     f22, 2 * SIZE(AO4)
703         LFD     f23, 3 * SIZE(AO4)
704
705         FMADD   f0,  f16,  f26, f0
706         FMADD   f1,  f16,  f27, f1
707         FMADD   f2,  f17,  f26, f2
708         FMADD   f3,  f17,  f27, f3
709
710         FMADD   f4,  f18,  f26, f4
711         FMADD   f5,  f18,  f27, f5
712         FMADD   f6,  f19,  f26, f6
713         FMADD   f7,  f19,  f27, f7
714
715         LFD     f16, 4 * SIZE(AO1)
716         LFD     f17, 5 * SIZE(AO1)
717         LFD     f18, 4 * SIZE(AO2)
718         LFD     f19, 5 * SIZE(AO2)
719
720         FMADD   f8,  f20,  f26, f8
721         FMADD   f9,  f20,  f27, f9
722         FMADD   f10, f21,  f26, f10
723         FMADD   f11, f21,  f27, f11
724
725         FMADD   f12, f22,  f26, f12
726         FMADD   f13, f22,  f27, f13
727         FMADD   f14, f23,  f26, f14
728         FMADD   f15, f23,  f27, f15
729
730         LFD     f20, 4 * SIZE(AO3)
731         LFD     f21, 5 * SIZE(AO3)
732         LFD     f22, 4 * SIZE(AO4)
733         LFD     f23, 5 * SIZE(AO4)
734
735         FMADD   f0,  f16,  f28, f0
736         FMADD   f1,  f16,  f29, f1
737         FMADD   f2,  f17,  f28, f2
738         FMADD   f3,  f17,  f29, f3
739
740         FMADD   f4,  f18,  f28, f4
741         FMADD   f5,  f18,  f29, f5
742         FMADD   f6,  f19,  f28, f6
743         FMADD   f7,  f19,  f29, f7
744
745         LFD     f16, 6 * SIZE(AO1)
746         LFD     f17, 7 * SIZE(AO1)
747         LFD     f18, 6 * SIZE(AO2)
748         LFD     f19, 7 * SIZE(AO2)
749
750         FMADD   f8,  f20,  f28, f8
751         FMADD   f9,  f20,  f29, f9
752         FMADD   f10, f21,  f28, f10
753         FMADD   f11, f21,  f29, f11
754
755         FMADD   f12, f22,  f28, f12
756         FMADD   f13, f22,  f29, f13
757         FMADD   f14, f23,  f28, f14
758         FMADD   f15, f23,  f29, f15
759
760         LFD     f20, 6 * SIZE(AO3)
761         LFD     f21, 7 * SIZE(AO3)
762         LFD     f22, 6 * SIZE(AO4)
763         LFD     f23, 7 * SIZE(AO4)
764
765         FMADD   f0,  f16,  f30, f0
766         FMADD   f1,  f16,  f31, f1
767         FMADD   f2,  f17,  f30, f2
768         FMADD   f3,  f17,  f31, f3
769
770         FMADD   f4,  f18,  f30, f4
771         FMADD   f5,  f18,  f31, f5
772         FMADD   f6,  f19,  f30, f6
773         FMADD   f7,  f19,  f31, f7
774
775         LFD     f16, 8 * SIZE(AO1)
776         LFD     f17, 9 * SIZE(AO1)
777         LFD     f18, 8 * SIZE(AO2)
778         LFD     f19, 9 * SIZE(AO2)
779
780         FMADD   f8,  f20,  f30, f8
781         FMADD   f9,  f20,  f31, f9
782         FMADD   f10, f21,  f30, f10
783         FMADD   f11, f21,  f31, f11
784
785         FMADD   f12, f22,  f30, f12
786         FMADD   f13, f22,  f31, f13
787         FMADD   f14, f23,  f30, f14
788         FMADD   f15, f23,  f31, f15
789
790         LFD     f20, 8 * SIZE(AO3)
791         LFD     f21, 9 * SIZE(AO3)
792         LFD     f22, 8 * SIZE(AO4)
793         LFD     f23, 9 * SIZE(AO4)
794
795         LFD     f24,  9 * SIZE(BO)
796         LFD     f25, 10 * SIZE(BO)
797         LFD     f26, 11 * SIZE(BO)
798         LFD     f27, 12 * SIZE(BO)
799
800         LFD     f28, 13 * SIZE(BO)
801         LFD     f29, 14 * SIZE(BO)
802         LFD     f30, 15 * SIZE(BO)
803         LFDU    f31, 16 * SIZE(BO)
804
805         FMADD   f0,  f16,  f24, f0
806         FMADD   f1,  f16,  f25, f1
807         FMADD   f2,  f17,  f24, f2
808         FMADD   f3,  f17,  f25, f3
809
810         FMADD   f4,  f18,  f24, f4
811         FMADD   f5,  f18,  f25, f5
812         FMADD   f6,  f19,  f24, f6
813         FMADD   f7,  f19,  f25, f7
814
815         LFD     f16, 10 * SIZE(AO1)
816         LFD     f17, 11 * SIZE(AO1)
817         LFD     f18, 10 * SIZE(AO2)
818         LFD     f19, 11 * SIZE(AO2)
819
820         FMADD   f8,  f20,  f24, f8
821         FMADD   f9,  f20,  f25, f9
822         FMADD   f10, f21,  f24, f10
823         FMADD   f11, f21,  f25, f11
824
825         FMADD   f12, f22,  f24, f12
826         FMADD   f13, f22,  f25, f13
827         FMADD   f14, f23,  f24, f14
828         FMADD   f15, f23,  f25, f15
829
830         LFD     f20, 10 * SIZE(AO3)
831         LFD     f21, 11 * SIZE(AO3)
832         LFD     f22, 10 * SIZE(AO4)
833         LFD     f23, 11 * SIZE(AO4)
834
835         FMADD   f0,  f16,  f26, f0
836         FMADD   f1,  f16,  f27, f1
837         FMADD   f2,  f17,  f26, f2
838         FMADD   f3,  f17,  f27, f3
839
840         FMADD   f4,  f18,  f26, f4
841         FMADD   f5,  f18,  f27, f5
842         FMADD   f6,  f19,  f26, f6
843         FMADD   f7,  f19,  f27, f7
844
845         LFD     f16, 12 * SIZE(AO1)
846         LFD     f17, 13 * SIZE(AO1)
847         LFD     f18, 12 * SIZE(AO2)
848         LFD     f19, 13 * SIZE(AO2)
849
850         FMADD   f8,  f20,  f26, f8
851         FMADD   f9,  f20,  f27, f9
852         FMADD   f10, f21,  f26, f10
853         FMADD   f11, f21,  f27, f11
854
855         FMADD   f12, f22,  f26, f12
856         FMADD   f13, f22,  f27, f13
857         FMADD   f14, f23,  f26, f14
858         FMADD   f15, f23,  f27, f15
859
860         LFD     f20, 12 * SIZE(AO3)
861         LFD     f21, 13 * SIZE(AO3)
862         LFD     f22, 12 * SIZE(AO4)
863         LFD     f23, 13 * SIZE(AO4)
864
865         FMADD   f0,  f16,  f28, f0
866         FMADD   f1,  f16,  f29, f1
867         FMADD   f2,  f17,  f28, f2
868         FMADD   f3,  f17,  f29, f3
869
870         FMADD   f4,  f18,  f28, f4
871         FMADD   f5,  f18,  f29, f5
872         FMADD   f6,  f19,  f28, f6
873         FMADD   f7,  f19,  f29, f7
874
875         LFD     f16, 14 * SIZE(AO1)
876         LFD     f17, 15 * SIZE(AO1)
877         LFD     f18, 14 * SIZE(AO2)
878         LFD     f19, 15 * SIZE(AO2)
879
880         FMADD   f8,  f20,  f28, f8
881         FMADD   f9,  f20,  f29, f9
882         FMADD   f10, f21,  f28, f10
883         FMADD   f11, f21,  f29, f11
884
885         FMADD   f12, f22,  f28, f12
886         FMADD   f13, f22,  f29, f13
887         FMADD   f14, f23,  f28, f14
888         FMADD   f15, f23,  f29, f15
889
890         LFD     f20, 14 * SIZE(AO3)
891         LFD     f21, 15 * SIZE(AO3)
892         LFD     f22, 14 * SIZE(AO4)
893         LFD     f23, 15 * SIZE(AO4)
894
895         addi    AO1, AO1, 16 * SIZE
896         addi    AO2, AO2, 16 * SIZE
897         addi    AO3, AO3, 16 * SIZE
898         addi    AO4, AO4, 16 * SIZE
899
900         FMADD   f0,  f16,  f30, f0
901         FMADD   f1,  f16,  f31, f1
902         FMADD   f2,  f17,  f30, f2
903         FMADD   f3,  f17,  f31, f3
904
905         FMADD   f4,  f18,  f30, f4
906         FMADD   f5,  f18,  f31, f5
907         FMADD   f6,  f19,  f30, f6
908         FMADD   f7,  f19,  f31, f7
909
910         FMADD   f8,  f20,  f30, f8
911         FMADD   f9,  f20,  f31, f9
912         FMADD   f10, f21,  f30, f10
913         FMADD   f11, f21,  f31, f11
914
915         FMADD   f12, f22,  f30, f12
916         FMADD   f13, f22,  f31, f13
917         FMADD   f14, f23,  f30, f14
918         FMADD   f15, f23,  f31, f15
919         .align 4
920
921 LL(MainN3):
922         andi.   r0, MIN_N, 7
923         mtspr   CTR, r0
924         ble     LL(MainFinish)
925         .align 4
926
927         LFD     f16, 0 * SIZE(AO1)
928         LFD     f17, 1 * SIZE(AO1)
929         LFD     f18, 0 * SIZE(AO2)
930         LFD     f19, 1 * SIZE(AO2)
931         LFD     f20, 0 * SIZE(AO3)
932         LFD     f21, 1 * SIZE(AO3)
933         LFD     f22, 0 * SIZE(AO4)
934         LFD     f23, 1 * SIZE(AO4)
935
936         LFD     f24, 1 * SIZE(BO)
937         LFDU    f25, 2 * SIZE(BO)
938
939         addi    AO1, AO1, 2 * SIZE
940         addi    AO2, AO2, 2 * SIZE
941         addi    AO3, AO3, 2 * SIZE
942         addi    AO4, AO4, 2 * SIZE
943
944         bdz     LL(MainN3KernelSkip)
945         .align 4
946
947 LL(MainN3Kernel):
948         FMADD   f0,  f16,  f24, f0
949         FMADD   f1,  f16,  f25, f1
950         FMADD   f2,  f17,  f24, f2
951         FMADD   f3,  f17,  f25, f3
952
953         FMADD   f4,  f18,  f24, f4
954         FMADD   f5,  f18,  f25, f5
955         FMADD   f6,  f19,  f24, f6
956         FMADD   f7,  f19,  f25, f7
957
958         LFD     f16, 0 * SIZE(AO1)
959         LFD     f17, 1 * SIZE(AO1)
960         LFD     f18, 0 * SIZE(AO2)
961         LFD     f19, 1 * SIZE(AO2)
962
963         FMADD   f8,  f20,  f24, f8
964         FMADD   f9,  f20,  f25, f9
965         FMADD   f10, f21,  f24, f10
966         FMADD   f11, f21,  f25, f11
967
968         FMADD   f12, f22,  f24, f12
969         FMADD   f13, f22,  f25, f13
970         FMADD   f14, f23,  f24, f14
971         FMADD   f15, f23,  f25, f15
972
973         LFD     f20, 0 * SIZE(AO3)
974         LFD     f21, 1 * SIZE(AO3)
975         LFD     f22, 0 * SIZE(AO4)
976         LFD     f23, 1 * SIZE(AO4)
977
978         LFD     f24, 1 * SIZE(BO)
979         LFDU    f25, 2 * SIZE(BO)
980
981         addi    AO1, AO1, 2 * SIZE
982         addi    AO2, AO2, 2 * SIZE
983         addi    AO3, AO3, 2 * SIZE
984         addi    AO4, AO4, 2 * SIZE
985
986         bdnz    LL(MainN3Kernel)
987         .align 4
988
989 LL(MainN3KernelSkip):
990         FMADD   f0,  f16,  f24, f0
991         FMADD   f1,  f16,  f25, f1
992         FMADD   f2,  f17,  f24, f2
993         FMADD   f3,  f17,  f25, f3
994
995         FMADD   f4,  f18,  f24, f4
996         FMADD   f5,  f18,  f25, f5
997         FMADD   f6,  f19,  f24, f6
998         FMADD   f7,  f19,  f25, f7
999
1000         FMADD   f8,  f20,  f24, f8
1001         FMADD   f9,  f20,  f25, f9
1002         FMADD   f10, f21,  f24, f10
1003         FMADD   f11, f21,  f25, f11
1004
1005         FMADD   f12, f22,  f24, f12
1006         FMADD   f13, f22,  f25, f13
1007         FMADD   f14, f23,  f24, f14
1008         FMADD   f15, f23,  f25, f15
1009         .align 4
1010
1011 LL(MainFinish):
1012         lfd     f30, ALPHA_R
1013         lfd     f31, ALPHA_I
1014
1015 #ifndef XCONJ
1016 #ifndef CONJ
1017         FSUB    f0,  f0,  f3
1018         FADD    f1,  f1,  f2
1019         FSUB    f4,  f4,  f7
1020         FADD    f5,  f5,  f6
1021         FSUB    f8,  f8,  f11
1022         FADD    f9,  f9,  f10
1023         FSUB    f12, f12, f15
1024         FADD    f13, f13, f14
1025 #else
1026         FADD    f0,  f0,  f3
1027         FSUB    f1,  f1,  f2
1028         FADD    f4,  f4,  f7
1029         FSUB    f5,  f5,  f6
1030         FADD    f8,  f8,  f11
1031         FSUB    f9,  f9,  f10
1032         FADD    f12, f12, f15
1033         FSUB    f13, f13, f14
1034 #endif
1035 #else
1036 #ifndef CONJ
1037         FADD    f0,  f0,  f3
1038         FSUB    f1,  f2,  f1
1039         FADD    f4,  f4,  f7
1040         FSUB    f5,  f6,  f5
1041         FADD    f8,  f8,  f11
1042         FSUB    f9,  f10, f9
1043         FADD    f12, f12, f15
1044         FSUB    f13, f14, f13
1045 #else
1046         FSUB    f0,  f0,  f3
1047         FADD    f1,  f1,  f2
1048         FSUB    f4,  f4,  f7
1049         FADD    f5,  f5,  f6
1050         FSUB    f8,  f8,  f11
1051         FADD    f9,  f9,  f10
1052         FSUB    f12, f12, f15
1053         FADD    f13, f13, f14
1054 #endif
1055 #endif
1056
1057         mr      BO, CO
1058         cmpwi   cr0, INCY, 2 * SIZE
1059         bne     LL(FinishN1)
1060
1061         LFD     f16,  0 * SIZE(CO)
1062         LFD     f17,  1 * SIZE(CO)
1063         LFD     f18,  2 * SIZE(CO)
1064         LFD     f19,  3 * SIZE(CO)
1065         LFD     f20,  4 * SIZE(CO)
1066         LFD     f21,  5 * SIZE(CO)
1067         LFD     f22,  6 * SIZE(CO)
1068         LFD     f23,  7 * SIZE(CO)
1069
1070         FMADD   f16, f30, f0,  f16
1071         FMADDR  f17, f30, f1,  f17
1072         FMADD   f18, f30, f4,  f18
1073         FMADDR  f19, f30, f5,  f19
1074
1075         FMADD   f20, f30, f8,  f20
1076         FMADDR  f21, f30, f9,  f21
1077         FMADD   f22, f30, f12, f22
1078         FMADDR  f23, f30, f13, f23
1079
1080         FMSUBR  f16, f31, f1,  f16
1081         FMADD   f17, f31, f0,  f17
1082         FMSUBR  f18, f31, f5,  f18
1083         FMADD   f19, f31, f4,  f19
1084
1085         FMSUBR  f20, f31, f9,  f20
1086         FMADD   f21, f31, f8,  f21
1087         FMSUBR  f22, f31, f13, f22
1088         FMADD   f23, f31, f12, f23
1089
1090         STFD    f16,  0 * SIZE(CO)
1091         STFD    f17,  1 * SIZE(CO)
1092         STFD    f18,  2 * SIZE(CO)
1093         STFD    f19,  3 * SIZE(CO)
1094
1095         STFD    f20,  4 * SIZE(CO)
1096         STFD    f21,  5 * SIZE(CO)
1097         STFD    f22,  6 * SIZE(CO)
1098         STFD    f23,  7 * SIZE(CO)
1099
1100         addi    CO, CO, 8 * SIZE
1101
1102         addi    J, J, -1
1103         cmpwi   cr0, J, 0
1104         bgt     LL(MainHead)
1105         b       LL(Remain)
1106         .align 4
1107
1108 LL(FinishN1):
1109         LFD     f16,  0 * SIZE(CO)
1110         LFD     f17,  1 * SIZE(CO)
1111         add     CO, CO, INCY
1112
1113         LFD     f18,  0 * SIZE(CO)
1114         LFD     f19,  1 * SIZE(CO)
1115         add     CO, CO, INCY
1116
1117         LFD     f20,  0 * SIZE(CO)
1118         LFD     f21,  1 * SIZE(CO)
1119         add     CO, CO, INCY
1120
1121         LFD     f22,  0 * SIZE(CO)
1122         LFD     f23,  1 * SIZE(CO)
1123         add     CO, CO, INCY
1124
1125         FMADD   f16, f30, f0,  f16
1126         FMADDR  f17, f30, f1,  f17
1127         FMADD   f18, f30, f4,  f18
1128         FMADDR  f19, f30, f5,  f19
1129
1130         FMADD   f20, f30, f8,  f20
1131         FMADDR  f21, f30, f9,  f21
1132         FMADD   f22, f30, f12, f22
1133         FMADDR  f23, f30, f13, f23
1134
1135         FMSUBR  f16, f31, f1,  f16
1136         FMADD   f17, f31, f0,  f17
1137         FMSUBR  f18, f31, f5,  f18
1138         FMADD   f19, f31, f4,  f19
1139
1140         FMSUBR  f20, f31, f9,  f20
1141         FMADD   f21, f31, f8,  f21
1142         FMSUBR  f22, f31, f13, f22
1143         FMADD   f23, f31, f12, f23
1144
1145         STFD    f16,  0 * SIZE(BO)
1146         STFD    f17,  1 * SIZE(BO)
1147         add     BO, BO, INCY
1148         STFD    f18,  0 * SIZE(BO)
1149         STFD    f19,  1 * SIZE(BO)
1150         add     BO, BO, INCY
1151
1152         STFD    f20,  0 * SIZE(BO)
1153         STFD    f21,  1 * SIZE(BO)
1154         add     BO, BO, INCY
1155         STFD    f22,  0 * SIZE(BO)
1156         STFD    f23,  1 * SIZE(BO)
1157
1158         addi    J, J, -1
1159         cmpwi   cr0, J, 0
1160         bgt     LL(MainHead)
1161         .align 4
1162
1163 LL(Remain):
1164         andi.   J, N, 3
1165         ble     LL(ISEnd)
1166         .align 4
1167
1168 LL(RemainHead):
1169         mr      AO1, A
1170         add     A,   A,  LDA
1171         mr      BO,  XP
1172         lfd     f0, FZERO
1173
1174         fmr      f1,  f0
1175         fmr      f2,  f0
1176         fmr      f3,  f0
1177         fmr      f4,  f0
1178         fmr      f5,  f0
1179         fmr      f6,  f0
1180         fmr      f7,  f0
1181         fmr      f8,  f0
1182         fmr      f9,  f0
1183         fmr      f10, f0
1184         fmr      f11, f0
1185         fmr      f12, f0
1186         fmr      f13, f0
1187         fmr      f14, f0
1188         fmr      f15, f0
1189
1190         srawi.  r0 , MIN_N, 3
1191         mtspr   CTR, r0
1192         ble     LL(RemainN3)
1193
1194         LFD     f16, 0 * SIZE(AO1)
1195         LFD     f17, 1 * SIZE(AO1)
1196         LFD     f18, 2 * SIZE(AO1)
1197         LFD     f19, 3 * SIZE(AO1)
1198
1199         LFD     f20, 4 * SIZE(AO1)
1200         LFD     f21, 5 * SIZE(AO1)
1201         LFD     f22, 6 * SIZE(AO1)
1202         LFD     f23, 7 * SIZE(AO1)
1203
1204         LFD     f24, 1 * SIZE(BO)
1205         LFD     f25, 2 * SIZE(BO)
1206         LFD     f26, 3 * SIZE(BO)
1207         LFD     f27, 4 * SIZE(BO)
1208
1209         LFD     f28, 5 * SIZE(BO)
1210         LFD     f29, 6 * SIZE(BO)
1211         LFD     f30, 7 * SIZE(BO)
1212         LFD     f31, 8 * SIZE(BO)
1213
1214         bdz     LL(RemainKernelSkip)
1215         .align 4
1216
1217 LL(RemainKernel):
1218         FMADD   f0,  f16,  f24, f0
1219         FMADD   f1,  f16,  f25, f1
1220         FMADD   f2,  f17,  f24, f2
1221         FMADD   f3,  f17,  f25, f3
1222
1223         FMADD   f4,  f18,  f26, f4
1224         FMADD   f5,  f18,  f27, f5
1225         FMADD   f6,  f19,  f26, f6
1226         FMADD   f7,  f19,  f27, f7
1227
1228         LFD     f16,  8 * SIZE(AO1)
1229         LFD     f17,  9 * SIZE(AO1)
1230         LFD     f18, 10 * SIZE(AO1)
1231         LFD     f19, 11 * SIZE(AO1)
1232
1233         LFD     f24,  9 * SIZE(BO)
1234         LFD     f25, 10 * SIZE(BO)
1235         LFD     f26, 11 * SIZE(BO)
1236         LFD     f27, 12 * SIZE(BO)
1237
1238         FMADD   f8,  f20,  f28, f8
1239         FMADD   f9,  f20,  f29, f9
1240         FMADD   f10, f21,  f28, f10
1241         FMADD   f11, f21,  f29, f11
1242
1243         FMADD   f12, f22,  f30, f12
1244         FMADD   f13, f22,  f31, f13
1245         FMADD   f14, f23,  f30, f14
1246         FMADD   f15, f23,  f31, f15
1247
1248         LFD     f20, 12 * SIZE(AO1)
1249         LFD     f21, 13 * SIZE(AO1)
1250         LFD     f22, 14 * SIZE(AO1)
1251         LFD     f23, 15 * SIZE(AO1)
1252
1253         LFD     f28, 13 * SIZE(BO)
1254         LFD     f29, 14 * SIZE(BO)
1255         LFD     f30, 15 * SIZE(BO)
1256         LFD     f31, 16 * SIZE(BO)
1257
1258         FMADD   f0,  f16,  f24, f0
1259         FMADD   f1,  f16,  f25, f1
1260         FMADD   f2,  f17,  f24, f2
1261         FMADD   f3,  f17,  f25, f3
1262
1263         FMADD   f4,  f18,  f26, f4
1264         FMADD   f5,  f18,  f27, f5
1265         FMADD   f6,  f19,  f26, f6
1266         FMADD   f7,  f19,  f27, f7
1267
1268         LFD     f16, 16 * SIZE(AO1)
1269         LFD     f17, 17 * SIZE(AO1)
1270         LFD     f18, 18 * SIZE(AO1)
1271         LFD     f19, 19 * SIZE(AO1)
1272
1273         LFD     f24, 17 * SIZE(BO)
1274         LFD     f25, 18 * SIZE(BO)
1275         LFD     f26, 19 * SIZE(BO)
1276         LFD     f27, 20 * SIZE(BO)
1277
1278         FMADD   f8,  f20,  f28, f8
1279         FMADD   f9,  f20,  f29, f9
1280         FMADD   f10, f21,  f28, f10
1281         FMADD   f11, f21,  f29, f11
1282
1283         FMADD   f12, f22,  f30, f12
1284         FMADD   f13, f22,  f31, f13
1285         FMADD   f14, f23,  f30, f14
1286         FMADD   f15, f23,  f31, f15
1287
1288         LFD     f20, 20 * SIZE(AO1)
1289         LFD     f21, 21 * SIZE(AO1)
1290         LFD     f22, 22 * SIZE(AO1)
1291         LFD     f23, 23 * SIZE(AO1)
1292
1293         LFD     f28, 21 * SIZE(BO)
1294         LFD     f29, 22 * SIZE(BO)
1295         LFD     f30, 23 * SIZE(BO)
1296         LFD     f31, 24 * SIZE(BO)
1297
1298         addi    AO1, AO1, 16 * SIZE
1299         addi    BO,  BO,  16 * SIZE
1300
1301         DCBT(AO1, PREA)
1302
1303         bdnz    LL(RemainKernel)
1304         .align 4
1305
1306 LL(RemainKernelSkip):
1307         FMADD   f0,  f16,  f24, f0
1308         FMADD   f1,  f16,  f25, f1
1309         FMADD   f2,  f17,  f24, f2
1310         FMADD   f3,  f17,  f25, f3
1311
1312         FMADD   f4,  f18,  f26, f4
1313         FMADD   f5,  f18,  f27, f5
1314         FMADD   f6,  f19,  f26, f6
1315         FMADD   f7,  f19,  f27, f7
1316
1317         LFD     f16,  8 * SIZE(AO1)
1318         LFD     f17,  9 * SIZE(AO1)
1319         LFD     f18, 10 * SIZE(AO1)
1320         LFD     f19, 11 * SIZE(AO1)
1321
1322         LFD     f24,  9 * SIZE(BO)
1323         LFD     f25, 10 * SIZE(BO)
1324         LFD     f26, 11 * SIZE(BO)
1325         LFD     f27, 12 * SIZE(BO)
1326
1327         FMADD   f8,  f20,  f28, f8
1328         FMADD   f9,  f20,  f29, f9
1329         FMADD   f10, f21,  f28, f10
1330         FMADD   f11, f21,  f29, f11
1331
1332         FMADD   f12, f22,  f30, f12
1333         FMADD   f13, f22,  f31, f13
1334         FMADD   f14, f23,  f30, f14
1335         FMADD   f15, f23,  f31, f15
1336
1337         LFD     f20, 12 * SIZE(AO1)
1338         LFD     f21, 13 * SIZE(AO1)
1339         LFD     f22, 14 * SIZE(AO1)
1340         LFD     f23, 15 * SIZE(AO1)
1341
1342         LFD     f28, 13 * SIZE(BO)
1343         LFD     f29, 14 * SIZE(BO)
1344         LFD     f30, 15 * SIZE(BO)
1345         LFDU    f31, 16 * SIZE(BO)
1346
1347         FMADD   f0,  f16,  f24, f0
1348         FMADD   f1,  f16,  f25, f1
1349         FMADD   f2,  f17,  f24, f2
1350         FMADD   f3,  f17,  f25, f3
1351
1352         FMADD   f4,  f18,  f26, f4
1353         FMADD   f5,  f18,  f27, f5
1354         FMADD   f6,  f19,  f26, f6
1355         FMADD   f7,  f19,  f27, f7
1356
1357         FMADD   f8,  f20,  f28, f8
1358         FMADD   f9,  f20,  f29, f9
1359         FMADD   f10, f21,  f28, f10
1360         FMADD   f11, f21,  f29, f11
1361
1362         FMADD   f12, f22,  f30, f12
1363         FMADD   f13, f22,  f31, f13
1364         FMADD   f14, f23,  f30, f14
1365         FMADD   f15, f23,  f31, f15
1366
1367         addi    AO1, AO1, 16 * SIZE
1368         .align 4
1369
1370 LL(RemainN3):
1371         andi.   r0,  MIN_N, 7
1372         mtspr   CTR, r0
1373         ble     LL(RemainFinish)
1374         .align 4
1375
1376         LFD     f16, 0 * SIZE(AO1)
1377         LFD     f17, 1 * SIZE(AO1)
1378         LFD     f24, 1 * SIZE(BO)
1379         LFDU    f25, 2 * SIZE(BO)
1380         addi    AO1, AO1, 2 * SIZE
1381         bdz     LL(RemainN3KernelSkip)
1382         .align 4
1383
1384 LL(RemainN3Kernel):
1385         FMADD   f0,  f16,  f24, f0
1386         FMADD   f1,  f16,  f25, f1
1387         FMADD   f2,  f17,  f24, f2
1388         FMADD   f3,  f17,  f25, f3
1389
1390         LFD     f16, 0 * SIZE(AO1)
1391         LFD     f17, 1 * SIZE(AO1)
1392         LFD     f24, 1 * SIZE(BO)
1393         LFDU    f25, 2 * SIZE(BO)
1394         addi    AO1, AO1, 2 * SIZE
1395         bdnz    LL(RemainN3Kernel)
1396         .align 4
1397
1398 LL(RemainN3KernelSkip):
1399         FMADD   f0,  f16,  f24, f0
1400         FMADD   f1,  f16,  f25, f1
1401         FMADD   f2,  f17,  f24, f2
1402         FMADD   f3,  f17,  f25, f3
1403         .align 4
1404
1405 LL(RemainFinish):
1406         lfd     f30, ALPHA_R
1407         lfd     f31, ALPHA_I
1408         LFD     f16,  0 * SIZE(CO)
1409         LFD     f17,  1 * SIZE(CO)
1410
1411         FADD    f0, f0, f4
1412         FADD    f1, f1, f5
1413         FADD    f2, f2, f6
1414         FADD    f3, f3, f7
1415
1416         FADD    f8,  f8,  f12
1417         FADD    f9,  f9,  f13
1418         FADD    f10, f10, f14
1419         FADD    f11, f11, f15
1420
1421         FADD    f0, f0, f8
1422         FADD    f1, f1, f9
1423         FADD    f2, f2, f10
1424         FADD    f3, f3, f11
1425
1426 #ifndef XCONJ
1427 #ifndef CONJ
1428         FSUB    f0,  f0,  f3
1429         FADD    f1,  f1,  f2
1430 #else
1431         FADD    f0,  f0,  f3
1432         FSUB    f1,  f1,  f2
1433 #endif
1434 #else
1435 #ifndef CONJ
1436         FADD    f0,  f0,  f3
1437         FSUB    f1,  f2,  f1
1438 #else
1439         FSUB    f0,  f0,  f3
1440         FADD    f1,  f1,  f2
1441 #endif
1442 #endif
1443
1444         FMADD   f16, f30, f0,  f16
1445         FMADDR  f17, f30, f1,  f17
1446         FMSUBR  f16, f31, f1,  f16
1447         FMADD   f17, f31, f0,  f17
1448
1449         STFD    f16,  0 * SIZE(CO)
1450         STFD    f17,  1 * SIZE(CO)
1451         add     CO, CO, INCY
1452
1453         addi    J, J, -1
1454         cmpi    cr0, 0, J, 0
1455         bgt     LL(RemainHead)
1456         .align 4
1457
1458 LL(ISEnd):
1459         subf    A, PLDA_M, A
1460         addi    IS, IS, P
1461
1462         cmp     cr0, 0, IS, M
1463         blt     LL(ISLoop)
1464         .align 4
1465
1466 LL(End):
1467         li      r3, 0
1468
1469         lfd     f14,     0(SP)
1470         lfd     f15,     8(SP)
1471         lfd     f16,    16(SP)
1472         lfd     f17,    24(SP)
1473         lfd     f18,    32(SP)
1474         lfd     f19,    40(SP)
1475         lfd     f20,    48(SP)
1476         lfd     f21,    56(SP)
1477         lfd     f22,    64(SP)
1478         lfd     f23,    72(SP)
1479         lfd     f24,    80(SP)
1480         lfd     f25,    88(SP)
1481         lfd     f26,    96(SP)
1482         lfd     f27,   104(SP)
1483         lfd     f28,   112(SP)
1484         lfd     f29,   120(SP)
1485         lfd     f30,   128(SP)
1486         lfd     f31,   136(SP)
1487
1488 #ifdef __64BIT__
1489         ld      r14,   144(SP)
1490         ld      r15,   152(SP)
1491         ld      r16,   160(SP)
1492         ld      r17,   168(SP)
1493         ld      r18,   176(SP)
1494         ld      r19,   184(SP)
1495         ld      r20,   192(SP)
1496         ld      r21,   200(SP)
1497         ld      r22,   208(SP)
1498         ld      r23,   216(SP)
1499         ld      r24,   224(SP)
1500         ld      r25,   232(SP)
1501 #else
1502         lwz     r14,   144(SP)
1503         lwz     r15,   148(SP)
1504         lwz     r16,   152(SP)
1505         lwz     r17,   156(SP)
1506         lwz     r18,   160(SP)
1507         lwz     r19,   164(SP)
1508         lwz     r20,   168(SP)
1509         lwz     r21,   172(SP)
1510         lwz     r22,   176(SP)
1511         lwz     r23,   180(SP)
1512         lwz     r24,   184(SP)
1513         lwz     r25,   188(SP)
1514 #endif
1515
1516         addi    SP, SP, STACKSIZE
1517
1518         blr
1519
1520         EPILOGUE
1521
1522 #endif