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