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#include "l2param.h"
42
43#ifdef ATOM
44#define PREFETCH	prefetchnta
45#define PREFETCHW	prefetcht0
46#define PREFETCHSIZE	(8 * 6)
47#endif
48
49#ifndef WINDOWS_ABI
50
51#define STACKSIZE	64
52
53#define OLD_INCX	 8 + STACKSIZE(%rsp)
54#define OLD_Y		16 + STACKSIZE(%rsp)
55#define OLD_INCY	24 + STACKSIZE(%rsp)
56#define OLD_BUFFER	32 + STACKSIZE(%rsp)
57
58#define M	  %rdi
59#define N	  %rsi
60#define A	  %rcx
61#define LDA	  %r8
62#define X	  %r9
63#define INCX	  %rdx
64#define Y	  %rbp
65#define INCY	  %r10
66
67#else
68
69#define STACKSIZE	256
70
71#define OLD_ALPHA_I	 40 + STACKSIZE(%rsp)
72#define OLD_A		 48 + STACKSIZE(%rsp)
73#define OLD_LDA		 56 + STACKSIZE(%rsp)
74#define OLD_X		 64 + STACKSIZE(%rsp)
75#define OLD_INCX	 72 + STACKSIZE(%rsp)
76#define OLD_Y		 80 + STACKSIZE(%rsp)
77#define OLD_INCY	 88 + STACKSIZE(%rsp)
78#define OLD_BUFFER	 96 + STACKSIZE(%rsp)
79
80#define M	  %rcx
81#define N	  %rdx
82#define A	  %r8
83#define LDA	  %r9
84#define X	  %rdi
85#define INCX	  %rsi
86#define Y	  %rbp
87#define INCY	  %r10
88
89#endif
90
91#define I	%rax
92#define J	%rbx
93#define A1	%r11
94#define A2	%r12
95
96#define X1	%r13
97#define Y1	%r14
98#define BUFFER	%r15
99
100#define ALPHA_R		%xmm14
101#define ALPHA_I		%xmm15
102
103#if !defined(CONJ) && !defined(XCONJ)
104#define ADD1	   addsd
105#define ADD2	   addsd
106#define ADD3	   subsd
107#define ADD4	   addsd
108#endif
109
110#if  defined(CONJ) && !defined(XCONJ)
111#define ADD1	   addsd
112#define ADD2	   addsd
113#define ADD3	   addsd
114#define ADD4	   subsd
115#endif
116
117#if !defined(CONJ) &&  defined(XCONJ)
118#define ADD1	   addsd
119#define ADD2	   subsd
120#define ADD3	   addsd
121#define ADD4	   addsd
122#endif
123
124#if  defined(CONJ) &&  defined(XCONJ)
125#define ADD1	   addsd
126#define ADD2	   subsd
127#define ADD3	   subsd
128#define ADD4	   subsd
129#endif
130
131	PROLOGUE
132	PROFCODE
133
134	subq	$STACKSIZE, %rsp
135	movq	%rbx,  0(%rsp)
136	movq	%rbp,  8(%rsp)
137	movq	%r12, 16(%rsp)
138	movq	%r13, 24(%rsp)
139	movq	%r14, 32(%rsp)
140	movq	%r15, 40(%rsp)
141
142#ifdef WINDOWS_ABI
143	movq	%rdi,    48(%rsp)
144	movq	%rsi,    56(%rsp)
145	movups	%xmm6,   64(%rsp)
146	movups	%xmm7,   80(%rsp)
147	movups	%xmm8,   96(%rsp)
148	movups	%xmm9,  112(%rsp)
149	movups	%xmm10, 128(%rsp)
150	movups	%xmm11, 144(%rsp)
151	movups	%xmm12, 160(%rsp)
152	movups	%xmm13, 176(%rsp)
153	movups	%xmm14, 192(%rsp)
154	movups	%xmm15, 208(%rsp)
155
156	movq	OLD_A,     A
157	movq	OLD_LDA,   LDA
158	movq	OLD_X,     X
159
160	movaps	%xmm3,       %xmm0
161	movss	OLD_ALPHA_I, %xmm1
162#endif
163
164	movq	OLD_INCX,  INCX
165	movq	OLD_Y,     Y
166	movq	OLD_INCY,  INCY
167	movq	OLD_BUFFER, BUFFER
168
169	salq	$ZBASE_SHIFT,   LDA
170	salq	$ZBASE_SHIFT,   INCX
171	salq	$ZBASE_SHIFT,   INCY
172
173	movaps	%xmm0, ALPHA_R
174	movaps	%xmm1, ALPHA_I
175
176	subq	$-16 * SIZE, A
177
178	testq	M, M
179	jle	.L999
180	testq	N, N
181	jle	.L999
182	ALIGN_3
183
184	movq	BUFFER, X1
185
186	movq	Y, Y1
187
188	movq	M,  I
189	sarq	$2, I
190	jle	.L05
191	ALIGN_4
192
193.L02:
194	movsd	 0 * SIZE(X), %xmm0
195	movhpd	 1 * SIZE(X), %xmm0
196	addq	INCX, X
197
198	movsd	 0 * SIZE(X), %xmm1
199	movhpd	 1 * SIZE(X), %xmm1
200	addq	INCX, X
201
202	movsd	 0 * SIZE(X), %xmm2
203	movhpd	 1 * SIZE(X), %xmm2
204	addq	INCX, X
205
206	movsd	 0 * SIZE(X), %xmm3
207	movhpd	 1 * SIZE(X), %xmm3
208	addq	INCX, X
209
210	movapd	%xmm0,  0 * SIZE(X1)
211	movapd	%xmm1,  2 * SIZE(X1)
212	movapd	%xmm2,  4 * SIZE(X1)
213	movapd	%xmm3,  6 * SIZE(X1)
214
215	addq	$8 * SIZE, X1
216	decq	I
217	jg	.L02
218	ALIGN_4
219
220.L05:
221	movq	M,  I
222	andq	$3, I
223	jle	.L10
224	ALIGN_2
225
226.L06:
227	movsd	 0 * SIZE(X), %xmm0
228	movhpd	 1 * SIZE(X), %xmm0
229	addq	INCX, X
230	movapd	%xmm0, 0 * SIZE(X1)
231	addq	$2 * SIZE, X1
232	decq	I
233	jg	.L06
234	ALIGN_4
235
236.L10:
237	movq	N,  J
238	sarq	$1, J
239	jle	.L20
240	ALIGN_3
241
242.L11:
243	leaq	16 * SIZE(BUFFER), X1
244
245	movq	A, A1
246	leaq	(A1, LDA), A2
247	leaq	(A1, LDA, 2), A
248
249	xorpd	%xmm0, %xmm0
250	xorpd	%xmm1, %xmm1
251	xorpd	%xmm2, %xmm2
252	xorpd	%xmm3, %xmm3
253
254	movsd	-16 * SIZE(X1), %xmm4
255	movsd	-15 * SIZE(X1), %xmm5
256	movsd	-14 * SIZE(X1), %xmm6
257	movsd	-13 * SIZE(X1), %xmm7
258
259#ifdef PREFETCHW
260	PREFETCHW	3 * SIZE(Y1)
261#endif
262
263	movq	M,   I
264	sarq	$2,  I
265	jle	.L15
266
267	movsd	-16 * SIZE(A1), %xmm8
268	movsd	-15 * SIZE(A1), %xmm9
269	movsd	-16 * SIZE(A2), %xmm10
270	movsd	-15 * SIZE(A2), %xmm11
271
272	movapd	%xmm8,  %xmm12
273	mulsd	%xmm4,  %xmm8
274	mulsd	%xmm5,  %xmm12
275
276	decq	 I
277	jle	 .L14
278	ALIGN_3
279
280.L13:
281#ifdef PREFETCH
282	PREFETCH	(PREFETCHSIZE + 0) * SIZE(A1)
283#endif
284
285	movapd	%xmm9,  %xmm13
286	mulsd	%xmm5,  %xmm9
287	ADD1	%xmm8,  %xmm0
288	movsd	-14 * SIZE(A1), %xmm8
289	mulsd	%xmm4,  %xmm13
290	ADD2	%xmm12, %xmm1
291
292	movapd	%xmm10, %xmm12
293	mulsd	%xmm4,  %xmm10
294	ADD3	%xmm9,  %xmm0
295	movsd	-13 * SIZE(A1), %xmm9
296	mulsd	%xmm5,  %xmm12
297	ADD4	%xmm13, %xmm1
298
299	movapd	%xmm11, %xmm13
300	mulsd	%xmm5,  %xmm11
301	movsd	-11 * SIZE(X1), %xmm5
302	ADD1	%xmm10, %xmm2
303	movsd	-14 * SIZE(A2), %xmm10
304	mulsd	%xmm4,  %xmm13
305	movsd	-12 * SIZE(X1), %xmm4
306	ADD2	%xmm12, %xmm3
307
308	movapd	%xmm8,  %xmm12
309	mulsd	%xmm6,  %xmm8
310	ADD3	%xmm11, %xmm2
311	movsd	-13 * SIZE(A2), %xmm11
312
313	mulsd	%xmm7,  %xmm12
314	ADD4	%xmm13, %xmm3
315
316	movapd	%xmm9,  %xmm13
317	mulsd	%xmm7,  %xmm9
318	ADD1	%xmm8,  %xmm0
319	movsd	-12 * SIZE(A1), %xmm8
320	mulsd	%xmm6,  %xmm13
321	ADD2	%xmm12, %xmm1
322
323	movapd	%xmm10, %xmm12
324	mulsd	%xmm6,  %xmm10
325	ADD3	%xmm9,  %xmm0
326	movsd	-11 * SIZE(A1), %xmm9
327	mulsd	%xmm7,  %xmm12
328	ADD4	%xmm13, %xmm1
329
330	movapd	%xmm11, %xmm13
331	mulsd	%xmm7,  %xmm11
332	movsd	 -9 * SIZE(X1), %xmm7
333	ADD1	%xmm10, %xmm2
334	movsd	-12 * SIZE(A2), %xmm10
335	mulsd	%xmm6,  %xmm13
336	movsd	-10 * SIZE(X1), %xmm6
337	ADD2	%xmm12, %xmm3
338
339	movapd	%xmm8,  %xmm12
340	mulsd	%xmm4,  %xmm8
341	ADD3	%xmm11, %xmm2
342	movsd	-11 * SIZE(A2), %xmm11
343	mulsd	%xmm5,  %xmm12
344	ADD4	%xmm13, %xmm3
345
346#ifdef PREFETCH
347	PREFETCH	(PREFETCHSIZE + 0) * SIZE(A2)
348#endif
349
350	movapd	%xmm9,  %xmm13
351	mulsd	%xmm5,  %xmm9
352	ADD1	%xmm8,  %xmm0
353	movsd	-10 * SIZE(A1), %xmm8
354	mulsd	%xmm4,  %xmm13
355	ADD2	%xmm12, %xmm1
356
357	movapd	%xmm10, %xmm12
358	mulsd	%xmm4,  %xmm10
359	ADD3	%xmm9,  %xmm0
360	movsd	 -9 * SIZE(A1), %xmm9
361	mulsd	%xmm5,  %xmm12
362	ADD4	%xmm13, %xmm1
363
364	movapd	%xmm11, %xmm13
365	mulsd	%xmm5,  %xmm11
366	movsd	 -7 * SIZE(X1), %xmm5
367	ADD1	%xmm10, %xmm2
368	movsd	-10 * SIZE(A2), %xmm10
369	mulsd	%xmm4,  %xmm13
370	movsd	 -8 * SIZE(X1), %xmm4
371	ADD2	%xmm12, %xmm3
372
373	movapd	%xmm8,  %xmm12
374	mulsd	%xmm6,  %xmm8
375	ADD3	%xmm11, %xmm2
376	movsd	 -9 * SIZE(A2), %xmm11
377
378	mulsd	%xmm7,  %xmm12
379	ADD4	%xmm13, %xmm3
380
381	movapd	%xmm9,  %xmm13
382	mulsd	%xmm7,  %xmm9
383	ADD1	%xmm8,  %xmm0
384	movsd	 -8 * SIZE(A1), %xmm8
385	mulsd	%xmm6,  %xmm13
386	ADD2	%xmm12, %xmm1
387
388	movapd	%xmm10, %xmm12
389	mulsd	%xmm6,  %xmm10
390	ADD3	%xmm9,  %xmm0
391	movsd	 -7 * SIZE(A1), %xmm9
392	mulsd	%xmm7,  %xmm12
393	ADD4	%xmm13, %xmm1
394
395	movapd	%xmm11, %xmm13
396	mulsd	%xmm7,  %xmm11
397	movsd	 -5 * SIZE(X1), %xmm7
398	ADD1	%xmm10, %xmm2
399	movsd	 -8 * SIZE(A2), %xmm10
400	mulsd	%xmm6,  %xmm13
401	movsd	 -6 * SIZE(X1), %xmm6
402	ADD2	%xmm12, %xmm3
403
404	movapd	%xmm8,  %xmm12
405	subq	 $-8 * SIZE, A1
406	mulsd	%xmm4,  %xmm8
407	subq	 $-8 * SIZE, X1
408	ADD3	%xmm11, %xmm2
409	movsd	 -7 * SIZE(A2), %xmm11
410	mulsd	%xmm5,  %xmm12
411	subq	 $-8 * SIZE, A2
412	ADD4	%xmm13, %xmm3
413
414	subq	 $1, I
415	BRANCH
416	jg	.L13
417	ALIGN_3
418
419.L14:
420	movapd	%xmm9,  %xmm13
421	mulsd	%xmm5,  %xmm9
422	ADD1	%xmm8,  %xmm0
423	movsd	-14 * SIZE(A1), %xmm8
424	mulsd	%xmm4,  %xmm13
425	ADD2	%xmm12, %xmm1
426
427	movapd	%xmm10, %xmm12
428	mulsd	%xmm4,  %xmm10
429	ADD3	%xmm9,  %xmm0
430	movsd	-13 * SIZE(A1), %xmm9
431	mulsd	%xmm5,  %xmm12
432	ADD4	%xmm13, %xmm1
433
434	movapd	%xmm11, %xmm13
435	mulsd	%xmm5,  %xmm11
436	movsd	-11 * SIZE(X1), %xmm5
437	ADD1	%xmm10, %xmm2
438	movsd	-14 * SIZE(A2), %xmm10
439	mulsd	%xmm4,  %xmm13
440	movsd	-12 * SIZE(X1), %xmm4
441	ADD2	%xmm12, %xmm3
442
443	movapd	%xmm8,  %xmm12
444	mulsd	%xmm6,  %xmm8
445	ADD3	%xmm11, %xmm2
446	movsd	-13 * SIZE(A2), %xmm11
447
448	mulsd	%xmm7,  %xmm12
449	ADD4	%xmm13, %xmm3
450
451	movapd	%xmm9,  %xmm13
452	mulsd	%xmm7,  %xmm9
453	ADD1	%xmm8,  %xmm0
454	movsd	-12 * SIZE(A1), %xmm8
455	mulsd	%xmm6,  %xmm13
456	ADD2	%xmm12, %xmm1
457
458	movapd	%xmm10, %xmm12
459	mulsd	%xmm6,  %xmm10
460	ADD3	%xmm9,  %xmm0
461	movsd	-11 * SIZE(A1), %xmm9
462	mulsd	%xmm7,  %xmm12
463	ADD4	%xmm13, %xmm1
464
465	movapd	%xmm11, %xmm13
466	mulsd	%xmm7,  %xmm11
467	movsd	 -9 * SIZE(X1), %xmm7
468	ADD1	%xmm10, %xmm2
469	movsd	-12 * SIZE(A2), %xmm10
470	mulsd	%xmm6,  %xmm13
471	movsd	-10 * SIZE(X1), %xmm6
472	ADD2	%xmm12, %xmm3
473
474	movapd	%xmm8,  %xmm12
475	mulsd	%xmm4,  %xmm8
476	ADD3	%xmm11, %xmm2
477	movsd	-11 * SIZE(A2), %xmm11
478	mulsd	%xmm5,  %xmm12
479	ADD4	%xmm13, %xmm3
480
481	movapd	%xmm9,  %xmm13
482	mulsd	%xmm5,  %xmm9
483	ADD1	%xmm8,  %xmm0
484	movsd	-10 * SIZE(A1), %xmm8
485	mulsd	%xmm4,  %xmm13
486	ADD2	%xmm12, %xmm1
487
488	movapd	%xmm10, %xmm12
489	mulsd	%xmm4,  %xmm10
490	ADD3	%xmm9,  %xmm0
491	movsd	 -9 * SIZE(A1), %xmm9
492	mulsd	%xmm5,  %xmm12
493	ADD4	%xmm13, %xmm1
494
495	movapd	%xmm11, %xmm13
496	mulsd	%xmm5,  %xmm11
497	movsd	 -7 * SIZE(X1), %xmm5
498	ADD1	%xmm10, %xmm2
499	movsd	-10 * SIZE(A2), %xmm10
500	mulsd	%xmm4,  %xmm13
501	movsd	 -8 * SIZE(X1), %xmm4
502	ADD2	%xmm12, %xmm3
503
504	movapd	%xmm8,  %xmm12
505	mulsd	%xmm6,  %xmm8
506	ADD3	%xmm11, %xmm2
507	movsd	 -9 * SIZE(A2), %xmm11
508
509	mulsd	%xmm7,  %xmm12
510	ADD4	%xmm13, %xmm3
511
512	movapd	%xmm9,  %xmm13
513	mulsd	%xmm7,  %xmm9
514	ADD1	%xmm8,  %xmm0
515	mulsd	%xmm6,  %xmm13
516	ADD2	%xmm12, %xmm1
517
518	movapd	%xmm10, %xmm12
519	mulsd	%xmm6,  %xmm10
520	ADD3	%xmm9,  %xmm0
521	mulsd	%xmm7,  %xmm12
522	ADD4	%xmm13, %xmm1
523
524	movapd	%xmm11, %xmm13
525	mulsd	%xmm7,  %xmm11
526	movsd	 -5 * SIZE(X1), %xmm7
527	ADD1	%xmm10, %xmm2
528	mulsd	%xmm6,  %xmm13
529	movsd	 -6 * SIZE(X1), %xmm6
530	ADD2	%xmm12, %xmm3
531
532	ADD3	%xmm11, %xmm2
533	ADD4	%xmm13, %xmm3
534
535	subq	 $-8 * SIZE, A1
536	subq	 $-8 * SIZE, A2
537	subq	 $-8 * SIZE, X1
538	ALIGN_3
539
540.L15:
541	testq	$2, M
542	je	.L17
543
544	movsd	-16 * SIZE(A1), %xmm8
545	movsd	-15 * SIZE(A1), %xmm9
546	movsd	-16 * SIZE(A2), %xmm10
547	movsd	-15 * SIZE(A2), %xmm11
548
549	movapd	%xmm8,  %xmm12
550	mulsd	%xmm4,  %xmm8
551	mulsd	%xmm5,  %xmm12
552
553	movapd	%xmm9,  %xmm13
554	mulsd	%xmm5,  %xmm9
555	ADD1	%xmm8,  %xmm0
556	movsd	-14 * SIZE(A1), %xmm8
557	mulsd	%xmm4,  %xmm13
558	ADD2	%xmm12, %xmm1
559
560	movapd	%xmm10, %xmm12
561	mulsd	%xmm4,  %xmm10
562	ADD3	%xmm9,  %xmm0
563	movsd	-13 * SIZE(A1), %xmm9
564	mulsd	%xmm5,  %xmm12
565	ADD4	%xmm13, %xmm1
566
567	movapd	%xmm11, %xmm13
568	mulsd	%xmm5,  %xmm11
569	movsd	-11 * SIZE(X1), %xmm5
570	ADD1	%xmm10, %xmm2
571	movsd	-14 * SIZE(A2), %xmm10
572	mulsd	%xmm4,  %xmm13
573	movsd	-12 * SIZE(X1), %xmm4
574	ADD2	%xmm12, %xmm3
575
576	movapd	%xmm8,  %xmm12
577	mulsd	%xmm6,  %xmm8
578	ADD3	%xmm11, %xmm2
579	movsd	-13 * SIZE(A2), %xmm11
580
581	mulsd	%xmm7,  %xmm12
582	ADD4	%xmm13, %xmm3
583
584	movapd	%xmm9,  %xmm13
585	mulsd	%xmm7,  %xmm9
586	ADD1	%xmm8,  %xmm0
587	mulsd	%xmm6,  %xmm13
588	ADD2	%xmm12, %xmm1
589
590	movapd	%xmm10, %xmm12
591	mulsd	%xmm6,  %xmm10
592	ADD3	%xmm9,  %xmm0
593	mulsd	%xmm7,  %xmm12
594	ADD4	%xmm13, %xmm1
595
596	movapd	%xmm11, %xmm13
597	mulsd	%xmm7,  %xmm11
598	ADD1	%xmm10, %xmm2
599	mulsd	%xmm6,  %xmm13
600	ADD2	%xmm12, %xmm3
601
602	ADD3	%xmm11, %xmm2
603	ADD4	%xmm13, %xmm3
604
605	addq	 $4 * SIZE, A1
606	addq	 $4 * SIZE, A2
607	ALIGN_3
608
609.L17:
610	testq	$1, M
611	je	.L19
612
613	movsd	-16 * SIZE(A1), %xmm8
614	movsd	-15 * SIZE(A1), %xmm9
615	movsd	-16 * SIZE(A2), %xmm10
616	movsd	-15 * SIZE(A2), %xmm11
617
618	movapd	%xmm8,  %xmm12
619	mulsd	%xmm4,  %xmm8
620	mulsd	%xmm5,  %xmm12
621
622	movapd	%xmm9,  %xmm13
623	mulsd	%xmm5,  %xmm9
624	ADD1	%xmm8,  %xmm0
625	mulsd	%xmm4,  %xmm13
626	ADD2	%xmm12,  %xmm1
627
628	movapd	%xmm10, %xmm12
629	mulsd	%xmm4,  %xmm10
630	ADD3	%xmm9,  %xmm0
631	mulsd	%xmm5,  %xmm12
632	ADD4	%xmm13,  %xmm1
633
634	movapd	%xmm11, %xmm13
635	mulsd	%xmm5,  %xmm11
636	ADD1	%xmm10, %xmm2
637	mulsd	%xmm4,  %xmm13
638	ADD2	%xmm12,  %xmm3
639
640	ADD3	%xmm11, %xmm2
641	ADD4	%xmm13,  %xmm3
642	ALIGN_3
643
644.L19:
645	movsd	 0 * SIZE(Y), %xmm4
646	movapd	%xmm0, %xmm10
647	mulsd	ALPHA_R, %xmm0
648	movsd	 1 * SIZE(Y), %xmm5
649	movapd	%xmm1, %xmm11
650	mulsd	ALPHA_R, %xmm1
651	addq	INCY, Y
652
653	movsd	 0 * SIZE(Y), %xmm6
654	movapd	%xmm2, %xmm12
655	mulsd	ALPHA_R, %xmm2
656	movsd	 1 * SIZE(Y), %xmm7
657	movapd	%xmm3, %xmm13
658	mulsd	ALPHA_R, %xmm3
659	addq	INCY, Y
660
661	mulsd	ALPHA_I, %xmm10
662	mulsd	ALPHA_I, %xmm11
663	mulsd	ALPHA_I, %xmm12
664	mulsd	ALPHA_I, %xmm13
665
666	addsd	%xmm10, %xmm1
667	subsd	%xmm11, %xmm0
668	addsd	%xmm12, %xmm3
669	subsd	%xmm13, %xmm2
670
671	addsd	%xmm4, %xmm0
672	addsd	%xmm5, %xmm1
673	addsd	%xmm6, %xmm2
674	addsd	%xmm7, %xmm3
675
676	movlpd	%xmm0,  0 * SIZE(Y1)
677	movlpd	%xmm1,  1 * SIZE(Y1)
678	addq	INCY, Y1
679	movlpd	%xmm2,  0 * SIZE(Y1)
680	movlpd	%xmm3,  1 * SIZE(Y1)
681	addq	INCY, Y1
682
683	decq	J
684	jg	.L11
685	ALIGN_3
686
687.L20:
688	testq	$1, N
689	jle	.L999
690
691	leaq	16 * SIZE(BUFFER), X1
692
693	movq	A, A1
694
695	xorpd	%xmm0, %xmm0
696	xorpd	%xmm1, %xmm1
697
698	movsd	-16 * SIZE(X1), %xmm4
699	movsd	-15 * SIZE(X1), %xmm5
700	movsd	-14 * SIZE(X1), %xmm6
701	movsd	-13 * SIZE(X1), %xmm7
702
703	movq	M,   I
704	sarq	$2,  I
705	jle	.L25
706
707	movsd	-16 * SIZE(A1), %xmm8
708	movsd	-15 * SIZE(A1), %xmm9
709
710	movapd	%xmm8,  %xmm12
711	mulsd	%xmm4,  %xmm8
712	mulsd	%xmm5,  %xmm12
713
714	decq	 I
715	jle	 .L24
716	ALIGN_3
717
718.L23:
719#ifdef PREFETCH
720	PREFETCH	(PREFETCHSIZE + 0) * SIZE(A1)
721#endif
722
723	movapd	%xmm9,  %xmm13
724	mulsd	%xmm5,  %xmm9
725	movsd	-11 * SIZE(X1), %xmm5
726	ADD1	%xmm8,  %xmm0
727	movsd	-14 * SIZE(A1), %xmm8
728	mulsd	%xmm4,  %xmm13
729	movsd	-12 * SIZE(X1), %xmm4
730	ADD2	%xmm12, %xmm1
731
732	movapd	%xmm8,  %xmm12
733	mulsd	%xmm6,  %xmm8
734	ADD3	%xmm9,  %xmm0
735 	movsd	-13 * SIZE(A1), %xmm9
736	mulsd	%xmm7,  %xmm12
737	ADD4	%xmm13, %xmm1
738
739	movapd	%xmm9,  %xmm13
740	mulsd	%xmm7,  %xmm9
741	movsd	 -9 * SIZE(X1), %xmm7
742	ADD1	%xmm8,  %xmm0
743	movsd	-12 * SIZE(A1), %xmm8
744	mulsd	%xmm6,  %xmm13
745	movsd	-10 * SIZE(X1), %xmm6
746	ADD2	%xmm12, %xmm1
747
748	movapd	%xmm8,  %xmm12
749	mulsd	%xmm4,  %xmm8
750	ADD3	%xmm9,  %xmm0
751	movsd	-11 * SIZE(A1), %xmm9
752	mulsd	%xmm5,  %xmm12
753	ADD4	%xmm13, %xmm1
754
755	movapd	%xmm9,  %xmm13
756	mulsd	%xmm5,  %xmm9
757	movsd	 -7 * SIZE(X1), %xmm5
758	ADD1	%xmm8,  %xmm0
759	movsd	-10 * SIZE(A1), %xmm8
760	mulsd	%xmm4,  %xmm13
761	movsd	 -8 * SIZE(X1), %xmm4
762	ADD2	%xmm12, %xmm1
763
764	movapd	%xmm8,  %xmm12
765	mulsd	%xmm6,  %xmm8
766	ADD3	%xmm9,  %xmm0
767 	movsd	 -9 * SIZE(A1), %xmm9
768	mulsd	%xmm7,  %xmm12
769	ADD4	%xmm13, %xmm1
770
771	movapd	%xmm9,  %xmm13
772	mulsd	%xmm7,  %xmm9
773	movsd	 -5 * SIZE(X1), %xmm7
774	ADD1	%xmm8,  %xmm0
775	movsd	 -8 * SIZE(A1), %xmm8
776	mulsd	%xmm6,  %xmm13
777	movsd	 -6 * SIZE(X1), %xmm6
778	ADD2	%xmm12, %xmm1
779
780	movapd	%xmm8,  %xmm12
781	mulsd	%xmm4,  %xmm8
782	ADD3	%xmm9,  %xmm0
783	mulsd	%xmm5,  %xmm12
784	movsd	 -7 * SIZE(A1), %xmm9
785	ADD4	%xmm13, %xmm1
786
787	subq	 $-8 * SIZE, A1
788	subq	 $-8 * SIZE, X1
789	subq	 $-8 * SIZE, A2
790
791	subq	 $1, I
792	BRANCH
793	jg	.L23
794	ALIGN_3
795
796.L24:
797	movapd	%xmm9,  %xmm13
798	mulsd	%xmm5,  %xmm9
799	movsd	-11 * SIZE(X1), %xmm5
800	ADD1	%xmm8,  %xmm0
801	movsd	-14 * SIZE(A1), %xmm8
802	mulsd	%xmm4,  %xmm13
803	movsd	-12 * SIZE(X1), %xmm4
804	ADD2	%xmm12, %xmm1
805
806	movapd	%xmm8,  %xmm12
807	mulsd	%xmm6,  %xmm8
808	ADD3	%xmm9,  %xmm0
809 	movsd	-13 * SIZE(A1), %xmm9
810	mulsd	%xmm7,  %xmm12
811	ADD4	%xmm13, %xmm1
812
813	movapd	%xmm9,  %xmm13
814	mulsd	%xmm7,  %xmm9
815	movsd	 -9 * SIZE(X1), %xmm7
816	ADD1	%xmm8,  %xmm0
817	movsd	-12 * SIZE(A1), %xmm8
818	mulsd	%xmm6,  %xmm13
819	movsd	-10 * SIZE(X1), %xmm6
820	ADD2	%xmm12, %xmm1
821
822	movapd	%xmm8,  %xmm12
823	mulsd	%xmm4,  %xmm8
824	ADD3	%xmm9,  %xmm0
825	movsd	-11 * SIZE(A1), %xmm9
826	mulsd	%xmm5,  %xmm12
827	ADD4	%xmm13, %xmm1
828
829	movapd	%xmm9,  %xmm13
830	mulsd	%xmm5,  %xmm9
831	movsd	 -7 * SIZE(X1), %xmm5
832	ADD1	%xmm8,  %xmm0
833	movsd	-10 * SIZE(A1), %xmm8
834	mulsd	%xmm4,  %xmm13
835	movsd	 -8 * SIZE(X1), %xmm4
836	ADD2	%xmm12, %xmm1
837
838	movapd	%xmm8,  %xmm12
839	mulsd	%xmm6,  %xmm8
840	ADD3	%xmm9,  %xmm0
841 	movsd	 -9 * SIZE(A1), %xmm9
842	mulsd	%xmm7,  %xmm12
843	ADD4	%xmm13, %xmm1
844
845	movapd	%xmm9,  %xmm13
846	mulsd	%xmm7,  %xmm9
847	movsd	 -5 * SIZE(X1), %xmm7
848	ADD1	%xmm8,  %xmm0
849	mulsd	%xmm6,  %xmm13
850	movsd	 -6 * SIZE(X1), %xmm6
851	ADD2	%xmm12, %xmm1
852
853	ADD3	%xmm9,  %xmm0
854	ADD4	%xmm13, %xmm1
855
856	subq	 $-8 * SIZE, A1
857	subq	 $-8 * SIZE, A2
858	subq	 $-8 * SIZE, X1
859	ALIGN_3
860
861.L25:
862	testq	$2, M
863	je	.L27
864
865	movsd	-16 * SIZE(A1), %xmm8
866	movsd	-15 * SIZE(A1), %xmm9
867
868	movapd	%xmm8,  %xmm12
869	mulsd	%xmm4,  %xmm8
870	mulsd	%xmm5,  %xmm12
871
872	movapd	%xmm9,  %xmm13
873	mulsd	%xmm5,  %xmm9
874	movsd	-11 * SIZE(X1), %xmm5
875	ADD1	%xmm8,  %xmm0
876	movsd	-14 * SIZE(A1), %xmm8
877	mulsd	%xmm4,  %xmm13
878	movsd	-12 * SIZE(X1), %xmm4
879	ADD2	%xmm12, %xmm1
880
881	movapd	%xmm8,  %xmm12
882	mulsd	%xmm6,  %xmm8
883	ADD3	%xmm9,  %xmm0
884 	movsd	-13 * SIZE(A1), %xmm9
885	mulsd	%xmm7,  %xmm12
886	ADD4	%xmm13, %xmm1
887
888	movapd	%xmm9,  %xmm13
889	mulsd	%xmm7,  %xmm9
890	ADD1	%xmm8,  %xmm0
891	mulsd	%xmm6,  %xmm13
892	ADD2	%xmm12, %xmm1
893
894	ADD3	%xmm9,  %xmm0
895	ADD4	%xmm13, %xmm1
896
897	addq	 $4 * SIZE, A1
898	addq	 $4 * SIZE, A2
899	ALIGN_3
900
901.L27:
902	testq	$1, M
903	je	.L29
904
905	movsd	-16 * SIZE(A1), %xmm8
906	movsd	-15 * SIZE(A1), %xmm9
907
908	movapd	%xmm8,  %xmm12
909	mulsd	%xmm4,  %xmm8
910	mulsd	%xmm5,  %xmm12
911
912	movapd	%xmm9,  %xmm13
913	mulsd	%xmm5,  %xmm9
914	ADD1	%xmm8,  %xmm0
915	mulsd	%xmm4,  %xmm13
916	ADD2	%xmm12,  %xmm1
917
918	ADD3	%xmm9,  %xmm0
919	ADD4	%xmm13, %xmm1
920	ALIGN_3
921
922.L29:
923	movsd	 0 * SIZE(Y), %xmm4
924	movapd	%xmm0, %xmm10
925	mulsd	ALPHA_R, %xmm0
926	movsd	 1 * SIZE(Y), %xmm5
927	movapd	%xmm1, %xmm11
928	mulsd	ALPHA_R, %xmm1
929
930	mulsd	ALPHA_I, %xmm10
931	mulsd	ALPHA_I, %xmm11
932
933	addsd	%xmm10, %xmm1
934	subsd	%xmm11, %xmm0
935	addsd	%xmm4,  %xmm0
936	addsd	%xmm5,  %xmm1
937
938	movlpd	%xmm0,  0 * SIZE(Y1)
939	movlpd	%xmm1,  1 * SIZE(Y1)
940	ALIGN_3
941
942.L999:
943	movq	  0(%rsp), %rbx
944	movq	  8(%rsp), %rbp
945	movq	 16(%rsp), %r12
946	movq	 24(%rsp), %r13
947	movq	 32(%rsp), %r14
948	movq	 40(%rsp), %r15
949
950#ifdef WINDOWS_ABI
951	movq	 48(%rsp), %rdi
952	movq	 56(%rsp), %rsi
953	movups	 64(%rsp), %xmm6
954	movups	 80(%rsp), %xmm7
955	movups	 96(%rsp), %xmm8
956	movups	112(%rsp), %xmm9
957	movups	128(%rsp), %xmm10
958	movups	144(%rsp), %xmm11
959	movups	160(%rsp), %xmm12
960	movups	176(%rsp), %xmm13
961	movups	192(%rsp), %xmm14
962	movups	208(%rsp), %xmm15
963#endif
964
965	addq	$STACKSIZE, %rsp
966	ret
967
968	EPILOGUE
969