dcfe831894f76557c1de25f074d2645d0fabb8b4
[platform/upstream/openblas.git] / kernel / x86_64 / zsymv_L_sse.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 #ifdef ATOM
43 #define PREFETCH        prefetcht0
44 #define PREFETCHW       prefetcht0
45 #define PREFETCHSIZE    (16 * 24)
46 #endif
47
48 #ifdef CORE2
49 #define PREFETCH        prefetcht0
50 #define PREFETCHW       prefetcht0
51 #define PREFETCHSIZE    (16 * 24)
52 #endif
53
54 #if defined(PENRYN) || defined(DUNNINGTON)
55 #define PREFETCH        prefetcht0
56 #define PREFETCHW       prefetcht0
57 #define PREFETCHSIZE    (16 * 24)
58 #endif
59
60 #if defined(NEHALEM) || defined(SANDYBRIDGE)
61 #define PREFETCH        prefetcht0
62 #define PREFETCHW       prefetcht0
63 #define PREFETCHSIZE    (16 * 24)
64 #endif
65
66 #ifdef PENTIUM4
67 #define PREFETCH        prefetcht0
68 #define PREFETCHW       prefetcht0
69 #define PREFETCHSIZE    (16 * 28)
70 #endif
71
72 #ifdef OPTERON
73 #define PREFETCH        prefetch
74 #define PREFETCHW       prefetchw
75 #define PREFETCHSIZE    (16 * 12)
76 #define movsd           movlpd
77 #endif
78
79 #ifdef NANO
80 #define PREFETCH        prefetcht0
81 #define PREFETCHW       prefetcht0
82 #define PREFETCHSIZE    (16 * 24)
83 #endif
84
85 #ifdef GENERIC
86 #define PREFETCH        prefetcht0
87 #define PREFETCHW       prefetcht0
88 #define PREFETCHSIZE    (16 * 12)
89 #endif
90
91 #ifndef WINDOWS_ABI
92
93 #define STACKSIZE       80
94         
95 #define OLD_Y            8 + STACKSIZE(%rsp)
96 #define OLD_INCY        16 + STACKSIZE(%rsp)
97 #define OLD_BUFFER      24 + STACKSIZE(%rsp)
98
99 #define M         ARG1
100 #define N         ARG2
101 #define A         ARG3
102 #define LDA       ARG4  
103 #define X         ARG5
104 #define INCX      ARG6  
105
106 #else
107
108 #define STACKSIZE       256
109         
110 #define OLD_A            40 + STACKSIZE(%rsp)
111 #define OLD_LDA          48 + STACKSIZE(%rsp)
112 #define OLD_X            56 + STACKSIZE(%rsp)
113 #define OLD_INCX         64 + STACKSIZE(%rsp)
114 #define OLD_Y            72 + STACKSIZE(%rsp)
115 #define OLD_INCY         80 + STACKSIZE(%rsp)
116 #define OLD_BUFFER       88 + STACKSIZE(%rsp)
117
118 #define M         ARG1
119 #define N         ARG2
120 #define A         ARG4
121 #define LDA       ARG3
122 #define X         %rdi
123 #define INCX      %rsi
124 #endif
125
126 #define Y       %r10
127 #define INCY    %r11
128 #define BUFFER  %r12
129
130 #define TEMP    %rax
131 #define I       %rax
132 #define A1      %rbx
133 #define A2      %rbp
134 #define XX      %r13
135 #define YY      %r14
136 #define IS      %r15
137 #define NEW_X   BUFFER
138 #define NEW_Y   X
139
140 #define ALPHA_R  %xmm0
141 #define ALPHA_I  %xmm1
142
143 #define xtemp1 %xmm0
144 #define xtemp2 %xmm1
145 #define xtemp3 %xmm2
146 #define xtemp4 %xmm3
147
148 #define atemp1 %xmm4
149 #define atemp2 %xmm5
150 #define atemp3 %xmm6
151 #define atemp4 %xmm7
152
153 #define xsum1  %xmm8
154 #define xsum2  %xmm9
155 #define yy1    %xmm10
156 #define yy2    %xmm11
157
158 #define a1     %xmm12
159 #define a2     %xmm13
160 #define a3     %xmm14
161 #define xt1    %xmm15
162
163 #if (defined(HAVE_SSE3) && !defined(CORE_OPTERON)) || defined(BARCELONA) || defined(SHANGHAI) || defined(BOBCAT) || defined(BULLDOZER)
164 #define MOVDDUP(a, b, c)        movddup a(b), c
165 #define MOVDDUP2(a, b, c)       movddup a##b, c
166 #else
167 #define MOVDDUP(a, b, c)        movlpd  a(b), c;movhpd  a(b), c
168 #define MOVDDUP2(a, b, c)       movlpd  a##b, c;movhpd  a##b, c
169 #endif
170
171         PROLOGUE
172         PROFCODE
173
174         subq    $STACKSIZE, %rsp
175         movq    %rbx,  0(%rsp)
176         movq    %rbp,  8(%rsp)
177         movq    %r12, 16(%rsp)
178         movq    %r13, 24(%rsp)
179         movq    %r14, 32(%rsp)
180         movq    %r15, 40(%rsp)
181
182         movq    OLD_Y,     Y
183         movq    OLD_INCY,   INCY
184         movq    OLD_BUFFER, BUFFER
185
186         salq    $ZBASE_SHIFT, INCX
187         salq    $ZBASE_SHIFT, INCY
188         salq    $ZBASE_SHIFT, LDA
189
190         testq   M, M
191         jle     .L999
192
193         pcmpeqb %xmm2,  %xmm2
194         xorpd   %xmm3,  %xmm3
195         psllq   $63,    %xmm2
196         unpcklpd %xmm3, %xmm2
197
198         unpcklpd ALPHA_I, ALPHA_R
199         unpcklpd ALPHA_R, ALPHA_I
200         xorpd    %xmm2,   ALPHA_I
201
202         movq    BUFFER, XX
203
204         movq    M,  %rax
205         sarq    $2, %rax
206         jle     .L02
207         ALIGN_3
208
209 .L01:
210         MOVDDUP(0 * SIZE, X, %xmm3)
211         MOVDDUP(1 * SIZE, X, %xmm4)
212         addq    INCX, X
213         MOVDDUP(0 * SIZE, X, %xmm5)
214         MOVDDUP(1 * SIZE, X, %xmm6)
215         addq    INCX, X
216
217         mulpd   ALPHA_R, %xmm3
218         mulpd   ALPHA_I, %xmm4
219         mulpd   ALPHA_R, %xmm5
220         mulpd   ALPHA_I, %xmm6
221
222         addpd   %xmm4, %xmm3
223         addpd   %xmm6, %xmm5
224
225         movapd  %xmm3, 0 * SIZE(XX)
226         SHUFPD_1 %xmm3, %xmm3
227         pxor    %xmm2, %xmm3
228         movapd  %xmm3, 2 * SIZE(XX)
229
230         movapd  %xmm5, 4 * SIZE(XX)
231         SHUFPD_1 %xmm5, %xmm5
232         pxor    %xmm2, %xmm5
233         movapd  %xmm5, 6 * SIZE(XX)
234
235         MOVDDUP(0 * SIZE, X, %xmm3)
236         MOVDDUP(1 * SIZE, X, %xmm4)
237         addq    INCX, X
238         MOVDDUP(0 * SIZE, X, %xmm5)
239         MOVDDUP(1 * SIZE, X, %xmm6)
240         addq    INCX, X
241
242         mulpd   ALPHA_R, %xmm3
243         mulpd   ALPHA_I, %xmm4
244         mulpd   ALPHA_R, %xmm5
245         mulpd   ALPHA_I, %xmm6
246
247         addpd   %xmm4, %xmm3
248         addpd   %xmm6, %xmm5
249
250         movapd  %xmm3,  8 * SIZE(XX)
251         SHUFPD_1 %xmm3, %xmm3
252         pxor    %xmm2, %xmm3
253         movapd  %xmm3, 10 * SIZE(XX)
254
255         movapd  %xmm5, 12 * SIZE(XX)
256         SHUFPD_1 %xmm5, %xmm5
257         pxor    %xmm2, %xmm5
258         movapd  %xmm5, 14 * SIZE(XX)
259
260         subq    $-16 * SIZE, XX
261         decq    %rax
262         jg      .L01
263         ALIGN_3
264
265 .L02:
266         movq    M, %rax
267         andq    $3, %rax
268         jle     .L05
269         ALIGN_3
270
271 .L03:
272         MOVDDUP(0 * SIZE, X, %xmm3)
273         MOVDDUP(1 * SIZE, X, %xmm4)
274         addq    INCX, X
275
276         mulpd   ALPHA_R, %xmm3
277         mulpd   ALPHA_I, %xmm4
278
279         addpd   %xmm4, %xmm3
280
281         movapd  %xmm3, 0 * SIZE(XX)
282         SHUFPD_1 %xmm3, %xmm3
283         pxor    %xmm2, %xmm3
284         movapd  %xmm3, 2 * SIZE(XX)
285
286         addq    $4 * SIZE, XX
287         decq    %rax
288         jg      .L03
289         ALIGN_3
290
291 .L05:
292         /* now we don't need original X */
293         movq   Y, NEW_Y
294
295         addq   $512, XX
296         andq   $-512, XX
297
298         cmpq   $2 * SIZE, INCY
299         je    .L10
300
301         movq   Y,  YY
302         movq   XX, NEW_Y
303
304         movq    M,  %rax
305         sarq    $2, %rax
306         jle     .L07
307         ALIGN_3
308
309 .L06:
310         movsd   0 * SIZE(YY), %xmm0
311         movhpd  1 * SIZE(YY), %xmm0
312         addq    INCY, YY
313         movsd   0 * SIZE(YY), %xmm1
314         movhpd  1 * SIZE(YY), %xmm1
315         addq    INCY, YY
316         movsd   0 * SIZE(YY), %xmm2
317         movhpd  1 * SIZE(YY), %xmm2
318         addq    INCY, YY
319         movsd   0 * SIZE(YY), %xmm3
320         movhpd  1 * SIZE(YY), %xmm3
321         addq    INCY, YY
322
323         movapd  %xmm0, 0 * SIZE(XX)
324         movapd  %xmm1, 2 * SIZE(XX)
325         movapd  %xmm2, 4 * SIZE(XX)
326         movapd  %xmm3, 6 * SIZE(XX)
327
328         addq    $8 * SIZE, XX
329         decq    %rax
330         jg      .L06
331         ALIGN_3
332
333 .L07:
334         movq    M, %rax
335         andq    $3, %rax
336         jle     .L10
337         ALIGN_3
338
339 .L08:
340         movsd   0 * SIZE(YY), %xmm0
341         movhpd  1 * SIZE(YY), %xmm0
342         addq    INCY, YY
343
344         movapd  %xmm0, 0 * SIZE(XX)
345
346         addq    $2 * SIZE, XX
347         decq    %rax
348         jg      .L08
349         ALIGN_3
350
351 .L10:
352         xorq    IS, IS          # is = 0
353
354         cmpq    $2, N
355         jl      .L20
356         ALIGN_3
357
358 .L11:
359         movq    A,  A1
360         leaq    (A, LDA, 1), A2
361         leaq    4 * SIZE(A, LDA, 2), A
362
363         leaq    (, IS, SIZE), I
364
365         leaq    0 * SIZE(NEW_X, I, 4), XX
366         leaq    4 * SIZE(NEW_Y, I, 2), YY
367
368         movapd          0 * SIZE(XX), atemp1
369         movapd          2 * SIZE(XX), atemp2
370         movapd          4 * SIZE(XX), atemp3
371         movapd          6 * SIZE(XX), atemp4
372
373         MOVDDUP(0 * SIZE, A1, xsum1)
374         MOVDDUP(2 * SIZE, A1, xsum2)
375
376         mulpd     atemp1, xsum1
377         mulpd     atemp1, xsum2
378
379         MOVDDUP(1 * SIZE, A1, a1)
380         MOVDDUP(3 * SIZE, A1, a2)
381
382         mulpd     atemp2, a1
383         mulpd     atemp2, a2
384         addpd     a1,     xsum1
385         addpd     a2,     xsum2
386
387         MOVDDUP(2 * SIZE, A1, a1)
388         MOVDDUP(2 * SIZE, A2, a2)
389
390         mulpd     atemp3, a1
391         mulpd     atemp3, a2
392         addpd     a1,     xsum1
393         addpd     a2,     xsum2
394
395         MOVDDUP(3 * SIZE, A1, a1)
396         MOVDDUP(3 * SIZE, A2, a2)
397
398         mulpd     atemp4, a1
399         mulpd     atemp4, a2
400         addpd     a1,     xsum1
401         addpd     a2,     xsum2
402
403         MOVDDUP(4 * SIZE, A1, a1)
404         MOVDDUP(6 * SIZE, A2, a2)
405
406         movsd    0 * SIZE(YY), yy1
407         movhpd   1 * SIZE(YY), yy1
408         movsd    2 * SIZE(YY), yy2
409         movhpd   3 * SIZE(YY), yy2
410
411         movapd   8 * SIZE(XX), xtemp1
412         movapd  10 * SIZE(XX), xtemp2
413         movapd  12 * SIZE(XX), xtemp3
414         movapd  14 * SIZE(XX), xtemp4
415
416         addq      $8 * SIZE, XX
417         addq      $4 * SIZE, A1
418         addq      $4 * SIZE, A2
419
420         movq     M, I
421         subq    IS, I
422         subq    $2, I
423         sarq    $2, I
424         jle     .L15
425         ALIGN_3
426
427 .L12:
428         movapd    xtemp1, xt1
429         mulpd     a1,     xt1
430         mulpd     atemp1, a1
431         addpd     xt1,    xsum1
432         addpd     a1,     yy1
433         MOVDDUP(1 * SIZE, A1, a1)
434
435         PREFETCH        PREFETCHSIZE(A1)
436
437         movapd    xtemp3, xt1
438         mulpd     a2,     xt1
439         mulpd     atemp3, a2
440         addpd     xt1,    xsum2
441         addpd     a2,     yy2
442         MOVDDUP(3 * SIZE, A2, a2)
443
444         movapd    xtemp2, xt1
445         mulpd     a1,     xt1
446         mulpd     atemp2, a1
447         addpd     xt1,    xsum1
448         addpd     a1,     yy1
449         MOVDDUP(2 * SIZE, A1, a1)
450
451         movapd    xtemp4, xt1
452         mulpd     a2,     xt1
453         mulpd     atemp4, a2
454         addpd     xt1,    xsum2
455         addpd     a2,     yy2
456         MOVDDUP(0 * SIZE, A2, a2)
457
458         PREFETCH        PREFETCHSIZE(XX)
459
460         movapd    xtemp3, xt1
461         movapd  12 * SIZE(XX), xtemp3
462         mulpd     a1,     xt1
463         mulpd     atemp1, a1
464         addpd     xt1,    xsum1
465         addpd     a1,     yy2
466         MOVDDUP(3 * SIZE, A1, a1)
467
468         movapd    xtemp1, xt1
469         movapd   8 * SIZE(XX), xtemp1
470         mulpd     a2,     xt1
471         mulpd     atemp3, a2
472         addpd     xt1,    xsum2
473         addpd     a2,     yy1
474         MOVDDUP(1 * SIZE, A2, a2)
475
476         movapd    xtemp4, xt1
477         movapd  14 * SIZE(XX), xtemp4
478         mulpd     a1,     xt1
479         mulpd     atemp2, a1
480         addpd     xt1,    xsum1
481         addpd     a1,     yy2
482         MOVDDUP(4 * SIZE, A1, a1)
483
484         movlpd   yy2, 2 * SIZE(YY)
485         movhpd   yy2, 3 * SIZE(YY)
486         movsd    6 * SIZE(YY), yy2
487         movhpd   7 * SIZE(YY), yy2
488
489         movapd    xtemp2, xt1
490         movapd  10 * SIZE(XX), xtemp2
491         mulpd     a2,     xt1
492         mulpd     atemp4, a2
493         addpd     xt1,    xsum2
494         addpd     a2,     yy1
495         MOVDDUP(6 * SIZE, A2, a2)
496
497         PREFETCH        PREFETCHSIZE(A2)
498
499         movlpd   yy1, 0 * SIZE(YY)
500         movhpd   yy1, 1 * SIZE(YY)
501         movsd    4 * SIZE(YY), yy1
502         movhpd   5 * SIZE(YY), yy1
503
504         movapd    xtemp1, xt1
505         mulpd     a1,     xt1
506         mulpd     atemp1, a1
507         addpd     xt1,    xsum1
508         addpd     a1,     yy1
509         MOVDDUP(5 * SIZE, A1, a1)
510
511         movapd    xtemp3, xt1
512         mulpd     a2,     xt1
513         mulpd     atemp3, a2
514         addpd     xt1,    xsum2
515         addpd     a2,     yy2
516         MOVDDUP(7 * SIZE, A2, a2)
517
518         movapd    xtemp2, xt1
519         mulpd     a1,     xt1
520         mulpd     atemp2, a1
521         addpd     xt1,    xsum1
522         addpd     a1,     yy1
523         MOVDDUP(6 * SIZE, A1, a1)
524
525         PREFETCHW       PREFETCHSIZE(YY)
526
527         movapd    xtemp4, xt1
528         mulpd     a2,     xt1
529         mulpd     atemp4, a2
530         addpd     xt1,    xsum2
531         addpd     a2,     yy2
532         MOVDDUP(4 * SIZE, A2, a2)
533
534         movapd    xtemp3, xt1
535         movapd  20 * SIZE(XX), xtemp3
536         mulpd     a1,     xt1
537         mulpd     atemp1, a1
538         addpd     xt1,    xsum1
539         addpd     a1,     yy2
540         MOVDDUP(7 * SIZE, A1, a1)
541
542         movapd    xtemp1, xt1
543         movapd  16 * SIZE(XX), xtemp1
544         mulpd     a2,     xt1
545         mulpd     atemp3, a2
546         addpd     xt1,    xsum2
547         addpd     a2,     yy1
548         MOVDDUP(5 * SIZE, A2, a2)
549
550         movapd    xtemp4, xt1
551         movapd  22 * SIZE(XX), xtemp4
552         mulpd     a1,     xt1
553         mulpd     atemp2, a1
554         addpd     xt1,    xsum1
555         addpd     a1,     yy2
556         MOVDDUP( 8 * SIZE, A1, a1)
557
558         movlpd   yy2, 6 * SIZE(YY)
559         movhpd   yy2, 7 * SIZE(YY)
560         movsd   10 * SIZE(YY), yy2
561         movhpd  11 * SIZE(YY), yy2
562
563         movapd    xtemp2, xt1
564         movapd  18 * SIZE(XX), xtemp2
565         mulpd     a2,     xt1
566         mulpd     atemp4, a2
567         addpd     xt1,    xsum2
568         addpd     a2,     yy1
569         MOVDDUP(10 * SIZE, A2, a2)
570
571         movlpd   yy1, 4 * SIZE(YY)
572         movhpd   yy1, 5 * SIZE(YY)
573         movsd    8 * SIZE(YY), yy1
574         movhpd   9 * SIZE(YY), yy1
575
576         subq     $-16 * SIZE, XX
577         addq     $  8 * SIZE, YY
578         addq     $  8 * SIZE, A1
579         addq     $  8 * SIZE, A2
580
581         decq     I
582         jg       .L12
583         ALIGN_3
584
585 .L15:
586         movq     M, I
587         subq    IS, I
588         subq    $2, I
589         testq   $2, I
590         jle     .L16
591
592         movapd    xtemp1, xt1
593         mulpd     a1,     xt1
594         mulpd     atemp1, a1
595         addpd     xt1,    xsum1
596         addpd     a1,     yy1
597         MOVDDUP(1 * SIZE, A1, a1)
598
599         movapd    xtemp3, xt1
600         mulpd     a2,     xt1
601         mulpd     atemp3, a2
602         addpd     xt1,    xsum2
603         addpd     a2,     yy2
604         MOVDDUP(3 * SIZE, A2, a2)
605
606         movapd    xtemp2, xt1
607         mulpd     a1,     xt1
608         mulpd     atemp2, a1
609         addpd     xt1,    xsum1
610         addpd     a1,     yy1
611         MOVDDUP(2 * SIZE, A1, a1)
612
613         movapd    xtemp4, xt1
614         mulpd     a2,     xt1
615         mulpd     atemp4, a2
616         addpd     xt1,    xsum2
617         addpd     a2,     yy2
618         MOVDDUP(0 * SIZE, A2, a2)
619
620         movapd    xtemp3, xt1
621         movapd  12 * SIZE(XX), xtemp3
622         mulpd     a1,     xt1
623         mulpd     atemp1, a1
624         addpd     xt1,    xsum1
625         addpd     a1,     yy2
626         MOVDDUP(3 * SIZE, A1, a1)
627
628         movapd    xtemp1, xt1
629         movapd   8 * SIZE(XX), xtemp1
630         mulpd     a2,     xt1
631         mulpd     atemp3, a2
632         addpd     xt1,    xsum2
633         addpd     a2,     yy1
634         MOVDDUP(1 * SIZE, A2, a2)
635
636         movapd    xtemp4, xt1
637         movapd  14 * SIZE(XX), xtemp4
638         mulpd     a1,     xt1
639         mulpd     atemp2, a1
640         addpd     xt1,    xsum1
641         addpd     a1,     yy2
642         MOVDDUP(4 * SIZE, A1, a1)
643
644         movlpd   yy2, 2 * SIZE(YY)
645         movhpd   yy2, 3 * SIZE(YY)
646         movsd    6 * SIZE(YY), yy2
647         movhpd   7 * SIZE(YY), yy2
648
649         movapd    xtemp2, xt1
650         movapd  10 * SIZE(XX), xtemp2
651         mulpd     a2,     xt1
652         mulpd     atemp4, a2
653         addpd     xt1,    xsum2
654         addpd     a2,     yy1
655
656         movlpd   yy1, 0 * SIZE(YY)
657         movhpd   yy1, 1 * SIZE(YY)
658         movsd    4 * SIZE(YY), yy1
659         movhpd   5 * SIZE(YY), yy1
660
661         addq     $4 * SIZE, YY
662         addq     $4 * SIZE, A1
663         addq     $4 * SIZE, A2
664         ALIGN_3
665
666 .L16:
667         testq   $1, M
668         jle     .L18
669
670         MOVDDUP(1 * SIZE, A1, a2)
671
672         movapd    xtemp1, xt1
673         mulpd     a1,     xt1
674         mulpd     atemp1, a1
675         addpd     xt1,    xsum1
676         addpd     a1,     yy1
677
678         MOVDDUP(0 * SIZE, A2, a1)
679
680         movapd    xtemp2, xt1
681         mulpd     a2,     xt1
682         mulpd     atemp2, a2
683         addpd     xt1,    xsum1
684         addpd     a2,     yy1
685
686         MOVDDUP(1 * SIZE, A2, a2)
687
688         movapd    xtemp1, xt1
689         mulpd     a1,     xt1
690         mulpd     atemp3, a1
691         addpd     xt1,    xsum2
692         addpd     a1,     yy1
693
694         movapd    xtemp2, xt1
695         mulpd     a2,     xt1
696         mulpd     atemp4, a2
697         addpd     xt1,    xsum2
698         addpd     a2,     yy1
699
700         movlpd   yy1, 0 * SIZE(YY)
701         movhpd   yy1, 1 * SIZE(YY)
702         ALIGN_3
703
704 .L18:
705         leaq    (, IS, SIZE), I
706
707         movsd    0 * SIZE(NEW_Y, I, 2), yy1
708         movhpd   1 * SIZE(NEW_Y, I, 2), yy1
709         movsd    2 * SIZE(NEW_Y, I, 2), yy2
710         movhpd   3 * SIZE(NEW_Y, I, 2), yy2
711
712         addpd    xsum1, yy1
713         addpd    xsum2, yy2
714
715         movlpd   yy1, 0 * SIZE(NEW_Y, I, 2)
716         movhpd   yy1, 1 * SIZE(NEW_Y, I, 2)
717         movlpd   yy2, 2 * SIZE(NEW_Y, I, 2)
718         movhpd   yy2, 3 * SIZE(NEW_Y, I, 2)
719
720         addq     $2, IS
721
722         movq     IS, I
723         addq     $2, I
724         cmpq     M, I
725         jle      .L11
726         ALIGN_3
727
728 .L20:
729         HALT
730                 testq   $1, N
731         jle     .L990
732
733         leaq    (, IS, SIZE), I
734
735         movapd   0 * SIZE(NEW_X, I, 4), atemp1
736         movapd   2 * SIZE(NEW_X, I, 4), atemp2
737
738         movsd    0 * SIZE(NEW_Y, I, 2), yy1
739         movhpd   1 * SIZE(NEW_Y, I, 2), yy1
740
741         MOVDDUP(0 * SIZE, A, a1)
742         MOVDDUP(1 * SIZE, A, a2)
743
744         mulpd     atemp1, a1
745         mulpd     atemp2, a2
746         addpd     a1,     yy1
747         addpd     a2,     yy1
748
749         movlpd   yy1, 0 * SIZE(NEW_Y, I, 2)
750         movhpd   yy1, 1 * SIZE(NEW_Y, I, 2)
751         ALIGN_3
752
753 .L990:
754         cmpq   $2 * SIZE, INCY
755         je    .L999
756
757         movq    M,  %rax
758         sarq    $2, %rax
759         jle     .L997
760         ALIGN_3
761
762 .L996:
763         movapd   0 * SIZE(NEW_Y), %xmm0
764         movapd   2 * SIZE(NEW_Y), %xmm1
765         movapd   4 * SIZE(NEW_Y), %xmm2
766         movapd   6 * SIZE(NEW_Y), %xmm3
767
768         movsd   %xmm0,  0 * SIZE(Y)
769         movhpd  %xmm0,  1 * SIZE(Y)
770         addq    INCY, Y
771         movsd   %xmm1,  0 * SIZE(Y)
772         movhpd  %xmm1,  1 * SIZE(Y)
773         addq    INCY, Y
774         movsd   %xmm2,  0 * SIZE(Y)
775         movhpd  %xmm2,  1 * SIZE(Y)
776         addq    INCY, Y
777         movsd   %xmm3,  0 * SIZE(Y)
778         movhpd  %xmm3,  1 * SIZE(Y)
779         addq    INCY, Y
780
781         addq    $8 * SIZE, NEW_Y
782         decq    %rax
783         jg      .L996
784         ALIGN_3
785
786 .L997:
787         movq    M, %rax
788         andq    $3, %rax
789         jle     .L999
790         ALIGN_3
791
792 .L998:
793         movapd  0 * SIZE(NEW_Y), %xmm0
794
795         movsd   %xmm0,  0 * SIZE(Y)
796         movhpd  %xmm0,  1 * SIZE(Y)
797         addq    INCY, Y
798
799         addq    $2 * SIZE, NEW_Y
800
801         decq    %rax
802         jg      .L998
803         ALIGN_3
804
805 .L999:
806         movq      0(%rsp), %rbx
807         movq      8(%rsp), %rbp
808         movq     16(%rsp), %r12
809         movq     24(%rsp), %r13
810         movq     32(%rsp), %r14
811         movq     40(%rsp), %r15
812         addq    $STACKSIZE, %rsp
813         ret
814         EPILOGUE