~ubuntu-branches/ubuntu/vivid/atlas/vivid

« back to all changes in this revision

Viewing changes to tune/blas/gemv/MVTCASES/ATL_cgemvT_8x4_sse3.c

  • Committer: Package Import Robot
  • Author(s): Sébastien Villemot, Sylvestre Ledru, Sébastien Villemot
  • Date: 2013-06-11 15:58:16 UTC
  • mfrom: (1.1.4) (25 sid)
  • mto: This revision was merged to the branch mainline in revision 26.
  • Revision ID: package-import@ubuntu.com-20130611155816-8xeeiziu1iml040c
Tags: 3.10.1-1
[ Sylvestre Ledru ]
* New upstream release (Closes: #609287)

[ Sébastien Villemot ]
* Provide architectural defaults (i.e. precomputed timings) for all
  release archs (except armel and mips for the time being, due to slow
  porterboxes). This will make the package build much faster and should
  eliminate transient build failures due to excessive variance in the
  timings.
* Move symlinks for lib{cblas,f77blas,atlas,lapack_atlas} out of the
  libblas.so.3 alternative and make them always present, so that
  software relying on these libs do not break when another alternative
  is selected for BLAS
* ATLAS now has improved ARM support with native asm constructs. This required
  the following tunes:
  + armel-is-v4t.diff: new patch, prevents FTBFS on armel; otherwise,
    ATLAS uses asm constructs too recent for the platform (armel is only v4t)
  + debian/rules: on armhf, define the ATL_ARM_HARDFP flag; otherwise the asm
    constructs use the soft-float ABI for passing floating points
  + on armhf, ensure that -mfloat-abi=softfp and -mcpu=vfpv3 flags are never
    used; this is implemented via a patch (armhf.diff) and by the use of fixed
    archdefs
* The generic package is now built without multi-threading, because otherwise
  the package fails to build on some single-processor machines (this required
  the introduction of a patch: fix-non-threaded-build.diff). As a side effect,
  the build of the custom package gracefully handles non-threaded
  builds. (Closes: #602524)
* Add libblas.a as slave in the libblas.so alternative (Closes: #701921)
* Add symlinks for lib{f77blas,atlas}.a in /usr/lib (Closes: #666203)
* Modify shlibs file of libatlas3-base, such that packages using
  libblas/liblapack depend on any BLAS/LAPACK alternative, while packages
  depending on ATLAS-specific libraries (e.g. libatlas.so) depend specifically
  on libatlas3-base.
* corei1.diff: remove patch, applied upstream
* Use my @debian.org email address
* Remove obsolete DM-Upload-Allowed flag
* Switch VCS to git
* Remove Conflicts/Replaces against pre-squeeze packages
* libatlas-base-dev now provides libblas.so, as libblas-dev
* No longer use -Wa,--noexecstack in CFLAGS, it makes the package FTBFS
* Do not use POWER3 arch for powerpcspe port (Closes: #701068)
* Bump to debhelper compat level 9
* README.Debian: mention that devscripts is needed to compile the custom
  package (Closes: #697431)
* Bump Standards-Version to 3.9.4. As a consequence, add Built-Using
  fields because the package embeds stuff from liblapack-pic

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *             Automatically Tuned Linear Algebra Software v3.10.1
 
3
 * Copyright (C) 2012, 2010 R. Clint Whaley
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 *   1. Redistributions of source code must retain the above copyright
 
9
 *      notice, this list of conditions and the following disclaimer.
 
10
 *   2. Redistributions in binary form must reproduce the above copyright
 
11
 *      notice, this list of conditions, and the following disclaimer in the
 
12
 *      documentation and/or other materials provided with the distribution.
 
13
 *   3. The name of the ATLAS group or the names of its contributers may
 
14
 *      not be used to endorse or promote products derived from this
 
15
 *      software without specific written permission.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
18
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 
19
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
20
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ATLAS GROUP OR ITS CONTRIBUTORS
 
21
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
22
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
23
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
24
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
25
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
26
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
27
 * POSSIBILITY OF SUCH DAMAGE.
 
28
 *
 
29
 */
 
30
#ifndef ATL_SSE3
 
31
   #error "This routine requires SSE3!"
 
32
#endif
 
33
 
 
34
#include "atlas_asm.h"
 
35
/*
 
36
 * This file does a 1x4 unrolled mvt_sse with these params:
 
37
 *    CL=8, ORDER=clmajor
 
38
 */
 
39
#ifndef ATL_GAS_x8664
 
40
   #error "This kernel requires x86-64 assembly!"
 
41
#endif
 
42
/*
 
43
 * Integer register assignment
 
44
 */
 
45
#define M       %rdi
 
46
#define N       %rsi
 
47
#define pA0     %rdx
 
48
#define lda     %rax
 
49
#define pX      %r8
 
50
#define pY      %r9
 
51
#define II      %rbx
 
52
#define pX0     %r11
 
53
#define Mr      %rcx
 
54
#define incAXm  %r10
 
55
#define incII   %r15
 
56
#define incAn   %r14
 
57
#define lda3    %r12
 
58
#define Ma      %r13
 
59
/*
 
60
 * SSE register assignment
 
61
 */
 
62
#define rA0     %xmm0
 
63
#define rX0     %xmm1
 
64
#define rx0     %xmm2
 
65
#define rt0     %xmm3
 
66
#define rY0r    %xmm4
 
67
#define rY0i    %xmm5
 
68
#define rY1r    %xmm6
 
69
#define rY1i    %xmm7
 
70
#define rY2r    %xmm8
 
71
#define rY2i    %xmm9
 
72
#define rY3r    %xmm10
 
73
#define rY3i    %xmm11
 
74
#define NONEPONEOFF -72
 
75
#define NONEPONE %xmm15
 
76
/*
 
77
 * macros
 
78
 */
 
79
#ifndef MOVA
 
80
   #define MOVA movaps
 
81
#endif
 
82
#define movapd movaps
 
83
#define movupd movups
 
84
#define xorpd xorps
 
85
#define addpd addps
 
86
#define mulpd mulps
 
87
#define addsd addss
 
88
#define mulsd mulss
 
89
#define movsd movss
 
90
#define haddpd haddps
 
91
/*
 
92
 * Define macros controlling prefetch
 
93
 */
 
94
#ifndef PFDIST
 
95
   #define PFDIST 256
 
96
#endif
 
97
#ifndef PFADIST
 
98
   #define PFADIST PFDIST
 
99
#endif
 
100
#ifndef PFYDIST
 
101
   #define PFYDIST 64
 
102
#endif
 
103
#ifndef PFXDIST
 
104
   #define PFXDIST 64
 
105
#endif
 
106
#ifndef PFIY
 
107
   #ifdef ATL_3DNow
 
108
      #define PFIY prefetchw
 
109
   #else
 
110
      #define PFIY prefetchnta
 
111
   #endif
 
112
#endif
 
113
#ifndef PFIX
 
114
   #define PFIX prefetcht0
 
115
#endif
 
116
#ifndef PFIA
 
117
   #define PFIA prefetchnta
 
118
#endif
 
119
#if PFADIST == 0                /* flag for no prefetch */
 
120
   #define prefA(mem)
 
121
#else
 
122
   #define prefA(mem) PFIA mem
 
123
#endif
 
124
#if PFYDIST == 0                /* flag for no prefetch */
 
125
   #define prefY(mem)
 
126
#else
 
127
   #define prefY(mem) PFIY mem
 
128
#endif
 
129
#if PFXDIST == 0                /* flag for no prefetch */
 
130
   #define prefX(mem)
 
131
#else
 
132
   #define prefX(mem) PFIX mem
 
133
#endif
 
134
/*
 
135
 *                      %rdi        %rsi           %rdx          %rcx
 
136
 * void ATL_UGEMV(ATL_CINT M, ATL_CINT N, const TYPE *A, ATL_CINT lda,
 
137
 *                          %r8      %r9
 
138
 *                const TYPE *X, TYPE *Y)
 
139
 */
 
140
.text
 
141
.global ATL_asmdecor(ATL_UGEMV)
 
142
ALIGN64
 
143
ATL_asmdecor(ATL_UGEMV):
 
144
 
 
145
/*
 
146
 * Save callee-saved iregs
 
147
 */
 
148
   movq %rbp, -8(%rsp)
 
149
   movq %rbx, -16(%rsp)
 
150
   movq %r12, -24(%rsp)
 
151
   movq %r13, -32(%rsp)
 
152
   movq %r14, -40(%rsp)
 
153
   movq %r15, -48(%rsp)
 
154
/*
 
155
 * Compute M = (M/MU)*MU, Mr = M - (M/MU)*MU
 
156
 * NOTE: Mr is %rcx reg, so we can use jcx to go to cleanup loop
 
157
 */
 
158
   mov  %rcx, lda       /* move lda to assigned register, rax */
 
159
   mov  $1, Mr          /* setup assignment to peel */
 
160
   xor  Ma, Ma          /* default to no peel */
 
161
   test $0xF, pA0       /* 0 if 16-byte aligned */
 
162
   cmovnz Mr, Ma        /* if nonzero, say need 1 iteration peel */
 
163
   sub  Ma, M
 
164
   mov  M, Mr           /* Mr = M */
 
165
   shr $3, M            /* M = M / MU */
 
166
   shl $3, M            /* M = (M/MU)*MU */
 
167
   sub M, Mr            /* Mr = M - (M/MU)*MU */
 
168
/*
 
169
 * Construct ponenone = {-1.0,1.0,-1.0,1.0}
 
170
 */
 
171
   finit
 
172
   fld1                                 /* ST =  1.0 */
 
173
   fldz                                 /* ST =  0.0 1.0 */
 
174
   fsub %st(1), %st                     /* ST = -1.0 1.0 */
 
175
   fsts NONEPONEOFF+4(%rsp)
 
176
   fstps NONEPONEOFF+12(%rsp)           /* ST = 1.0 */
 
177
   fsts NONEPONEOFF(%rsp)
 
178
   fstps NONEPONEOFF+8(%rsp)            /* ST=NULL, mem=-1,1,-1,1*/
 
179
   movapd NONEPONEOFF(%rsp), NONEPONE
 
180
/*
 
181
 * Setup constants
 
182
 */
 
183
   mov lda, incAn       /* incAn = lda */
 
184
   sub M, incAn         /* incAn = lda - (M/MU)*MU */
 
185
   sub Ma, incAn
 
186
   sub Mr, incAn        /* incAn = lda - M */
 
187
   shl $3, incAn        /* incAn = (lda-M)*sizeof */
 
188
   shl $3, lda          /* lda *= sizeof */
 
189
   sub $-128, pA0       /* code compaction by using signed 1-byte offsets */
 
190
   sub $-128, pX        /* code compaction by using signed 1-byte offsets */
 
191
   mov pX, pX0          /* save for restore after M loops */
 
192
   mov $-64, incAXm     /* code comp: use reg rather than constant */
 
193
   lea (lda, lda,2), lda3       /* lda3 = 3*lda */
 
194
   lea (incAn, lda3), incAn     /* incAn = (4*lda-M)*sizeof */
 
195
   mov $8*1, incII      /* code comp: use reg rather than constant */
 
196
   mov M, II
 
197
   ALIGN32
 
198
   LOOPN:
 
199
      xorpd rY0r, rY0r
 
200
      xorpd rY0i, rY0i
 
201
      xorpd rY1r, rY1r
 
202
      xorpd rY1i, rY1i
 
203
      xorpd rY2r, rY2r
 
204
      xorpd rY2i, rY2i
 
205
      xorpd rY3r, rY3r
 
206
      xorpd rY3i, rY3i
 
207
/*
 
208
 *    If no peeled iteration, start M-loop, else do peeled iteration
 
209
 */
 
210
      bt $0, Ma
 
211
      jnc LOOPM
 
212
         xorps rA0, rA0
 
213
         xorps rX0, rX0
 
214
         xorps rx0, rx0
 
215
         movlps -128(pX), rX0           /* rX0 = {0, 0, Xi, Xr} */
 
216
         pshufd $0xB1, rX0, rx0     /* rx0 = {0, 0, Xr, Xi} */
 
217
         movlps -128(pA0), rA0          /* rA0 = {0, 0, Ai, Ar} */
 
218
         movaps rA0, rt0                /* rt0 = {0, 0, Ai, Ar} */
 
219
         mulps rx0, rA0                 /* rA0 = {0, 0, Xr*Ai, Xi*Ar} */
 
220
         addps rA0, rY0i
 
221
         mulps rX0, rt0                 /* rt0 = {0, 0, Xi*Ai, Xr*Ar} */
 
222
         addps rt0, rY0r
 
223
         movlps -128(pA0,lda), rA0        /* rA0 = {0, 0, Ai, Ar} */
 
224
         movaps rA0, rt0                /* rt0 = {0, 0, Ai, Ar} */
 
225
         mulps rx0, rA0                 /* rA0 = {0, 0, Xr*Ai, Xi*Ar} */
 
226
         addps rA0, rY1i
 
227
         mulps rX0, rt0                 /* rt0 = {0, 0, Xi*Ai, Xr*Ar} */
 
228
         addps rt0, rY1r
 
229
         movlps -128(pA0,lda,2), rA0        /* rA0 = {0, 0, Ai, Ar} */
 
230
         movaps rA0, rt0                /* rt0 = {0, 0, Ai, Ar} */
 
231
         mulps rx0, rA0                 /* rA0 = {0, 0, Xr*Ai, Xi*Ar} */
 
232
         addps rA0, rY2i
 
233
         mulps rX0, rt0                 /* rt0 = {0, 0, Xi*Ai, Xr*Ar} */
 
234
         addps rt0, rY2r
 
235
         movlps -128(pA0,lda3), rA0        /* rA0 = {0, 0, Ai, Ar} */
 
236
         movaps rA0, rt0                /* rt0 = {0, 0, Ai, Ar} */
 
237
         mulps rx0, rA0                 /* rA0 = {0, 0, Xr*Ai, Xi*Ar} */
 
238
         addps rA0, rY3i
 
239
         mulps rX0, rt0                 /* rt0 = {0, 0, Xi*Ai, Xr*Ar} */
 
240
         addps rt0, rY3r
 
241
         add $8, pX
 
242
         add $8, pA0
 
243
 
 
244
      LOOPM:
 
245
         movapd 0-128(pX), rX0              /* rX0 = Xi,    Xr */
 
246
         pshufd $0xB1, rX0, rx0                 /* rx0 = Xr,    Xi */
 
247
         MOVA   0-128(pA0), rA0             /* rA0 = Ai,    Ar */
 
248
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
249
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
250
         addpd rA0, rY0i
 
251
         prefA(PFADIST+0(pA0))
 
252
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
253
         addpd rt0, rY0r
 
254
 
 
255
         MOVA   0-128(pA0,lda), rA0           /* rA0 = Ai,    Ar */
 
256
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
257
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
258
         addpd rA0, rY1i
 
259
         prefA(PFADIST+0(pA0,lda))
 
260
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
261
         addpd rt0, rY1r
 
262
         MOVA   0-128(pA0,lda,2), rA0           /* rA0 = Ai,    Ar */
 
263
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
264
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
265
         addpd rA0, rY2i
 
266
         prefA(PFADIST+0(pA0,lda,2))
 
267
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
268
         addpd rt0, rY2r
 
269
         MOVA   0-128(pA0,lda3), rA0           /* rA0 = Ai,    Ar */
 
270
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
271
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
272
         addpd rA0, rY3i
 
273
         prefA(PFADIST+0(pA0,lda3))
 
274
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
275
         addpd rt0, rY3r
 
276
 
 
277
         movapd 16-128(pX), rX0              /* rX0 = Xi,    Xr */
 
278
         pshufd $0xB1, rX0, rx0                 /* rx0 = Xr,    Xi */
 
279
         MOVA   16-128(pA0), rA0             /* rA0 = Ai,    Ar */
 
280
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
281
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
282
         addpd rA0, rY0i
 
283
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
284
         addpd rt0, rY0r
 
285
 
 
286
         MOVA   16-128(pA0,lda), rA0           /* rA0 = Ai,    Ar */
 
287
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
288
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
289
         addpd rA0, rY1i
 
290
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
291
         addpd rt0, rY1r
 
292
         MOVA   16-128(pA0,lda,2), rA0           /* rA0 = Ai,    Ar */
 
293
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
294
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
295
         addpd rA0, rY2i
 
296
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
297
         addpd rt0, rY2r
 
298
         MOVA   16-128(pA0,lda3), rA0           /* rA0 = Ai,    Ar */
 
299
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
300
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
301
         addpd rA0, rY3i
 
302
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
303
         addpd rt0, rY3r
 
304
 
 
305
         movapd 32-128(pX), rX0              /* rX0 = Xi,    Xr */
 
306
         pshufd $0xB1, rX0, rx0                 /* rx0 = Xr,    Xi */
 
307
         MOVA   32-128(pA0), rA0             /* rA0 = Ai,    Ar */
 
308
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
309
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
310
         addpd rA0, rY0i
 
311
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
312
         addpd rt0, rY0r
 
313
 
 
314
         MOVA   32-128(pA0,lda), rA0           /* rA0 = Ai,    Ar */
 
315
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
316
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
317
         addpd rA0, rY1i
 
318
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
319
         addpd rt0, rY1r
 
320
         MOVA   32-128(pA0,lda,2), rA0           /* rA0 = Ai,    Ar */
 
321
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
322
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
323
         addpd rA0, rY2i
 
324
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
325
         addpd rt0, rY2r
 
326
         MOVA   32-128(pA0,lda3), rA0           /* rA0 = Ai,    Ar */
 
327
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
328
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
329
         addpd rA0, rY3i
 
330
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
331
         addpd rt0, rY3r
 
332
 
 
333
         movapd 48-128(pX), rX0              /* rX0 = Xi,    Xr */
 
334
         pshufd $0xB1, rX0, rx0                 /* rx0 = Xr,    Xi */
 
335
         MOVA   48-128(pA0), rA0             /* rA0 = Ai,    Ar */
 
336
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
337
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
338
         addpd rA0, rY0i
 
339
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
340
         addpd rt0, rY0r
 
341
 
 
342
         MOVA   48-128(pA0,lda), rA0           /* rA0 = Ai,    Ar */
 
343
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
344
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
345
         addpd rA0, rY1i
 
346
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
347
         addpd rt0, rY1r
 
348
         MOVA   48-128(pA0,lda,2), rA0           /* rA0 = Ai,    Ar */
 
349
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
350
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
351
         addpd rA0, rY2i
 
352
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
353
         addpd rt0, rY2r
 
354
         MOVA   48-128(pA0,lda3), rA0           /* rA0 = Ai,    Ar */
 
355
         movapd rA0, rt0                        /* rt0 = Ai,    Ar */
 
356
         mulpd rx0, rA0                         /* rA0 = Ai*Xr, Ar*Xi */
 
357
         addpd rA0, rY3i
 
358
         mulpd rX0, rt0                         /* rt0 = Ai*Xi, Ar*Xr */
 
359
         addpd rt0, rY3r
 
360
 
 
361
         sub incAXm, pX
 
362
         sub incAXm, pA0
 
363
      sub incII, II
 
364
      jnz LOOPM
 
365
 
 
366
      cmp $0, Mr
 
367
      jz  MCLEANED
 
368
 
 
369
      mov Mr, II
 
370
      xorps rA0, rA0
 
371
      xorps rX0, rX0
 
372
      xorps rx0, rx0
 
373
      LOOPMCU:
 
374
         movlps -128(pX), rX0           /* rX0 = {0, 0, Xi, Xr} */
 
375
         pshufd $0xB1, rX0, rx0     /* rx0 = {0, 0, Xr, Xi} */
 
376
         movlps -128(pA0), rA0          /* rA0 = {0, 0, Ai, Ar} */
 
377
         movaps rA0, rt0                /* rt0 = {0, 0, Ai, Ar} */
 
378
         mulps rx0, rA0                 /* rA0 = {0, 0, Xr*Ai, Xi*Ar} */
 
379
         addps rA0, rY0i
 
380
         mulps rX0, rt0                 /* rt0 = {0, 0, Xi*Ai, Xr*Ar} */
 
381
         addps rt0, rY0r
 
382
         movlps -128(pA0,lda), rA0        /* rA0 = {0, 0, Ai, Ar} */
 
383
         movaps rA0, rt0                /* rt0 = {0, 0, Ai, Ar} */
 
384
         mulps rx0, rA0                 /* rA0 = {0, 0, Xr*Ai, Xi*Ar} */
 
385
         addps rA0, rY1i
 
386
         mulps rX0, rt0                 /* rt0 = {0, 0, Xi*Ai, Xr*Ar} */
 
387
         addps rt0, rY1r
 
388
         movlps -128(pA0,lda,2), rA0        /* rA0 = {0, 0, Ai, Ar} */
 
389
         movaps rA0, rt0                /* rt0 = {0, 0, Ai, Ar} */
 
390
         mulps rx0, rA0                 /* rA0 = {0, 0, Xr*Ai, Xi*Ar} */
 
391
         addps rA0, rY2i
 
392
         mulps rX0, rt0                 /* rt0 = {0, 0, Xi*Ai, Xr*Ar} */
 
393
         addps rt0, rY2r
 
394
         movlps -128(pA0,lda3), rA0        /* rA0 = {0, 0, Ai, Ar} */
 
395
         movaps rA0, rt0                /* rt0 = {0, 0, Ai, Ar} */
 
396
         mulps rx0, rA0                 /* rA0 = {0, 0, Xr*Ai, Xi*Ar} */
 
397
         addps rA0, rY3i
 
398
         mulps rX0, rt0                 /* rt0 = {0, 0, Xi*Ai, Xr*Ar} */
 
399
         addps rt0, rY3r
 
400
         add $8, pX
 
401
         add $8, pA0
 
402
      dec II
 
403
      jnz LOOPMCU
 
404
 
 
405
MCLEANED:
 
406
                                /* rYr0 = {-rY0d, rY0c, -rY0b, rY0a} */
 
407
                                /* rYi0 = { iY0d, iY0c,  iY0b, iY0a} */
 
408
      mulps NONEPONE, rY0r   /* rYr = {rY0d,  rY0c,    rY0b,   rY0a} */
 
409
      mulps NONEPONE, rY1r   /* rYr = {rY1d,  rY1c,    rY1b,   rY1a} */
 
410
      haddps rY0i, rY0r   /* rYr = {iY0cd  ,iY0ab,  rY0cd,  rY0ab} */
 
411
      haddps rY1i, rY1r   /* rYr = {iY1cd  ,iY1ab,  rY1cd,  rY1ab} */
 
412
      haddps rY1r, rY0r   /* rYr = {iY1abcd,rY1abcd,iY0abcd,rY0abcd} */
 
413
      #ifndef BETA0
 
414
         addpd 0(pY), rY0r
 
415
      #endif
 
416
      movaps rY0r, 0(pY)
 
417
      mulps NONEPONE, rY2r   /* rYr = {rY0d,  rY0c,    rY0b,   rY0a} */
 
418
      mulps NONEPONE, rY3r   /* rYr = {rY1d,  rY1c,    rY1b,   rY1a} */
 
419
      haddps rY2i, rY2r   /* rYr = {iY0cd  ,iY0ab,  rY0cd,  rY0ab} */
 
420
      haddps rY3i, rY3r   /* rYr = {iY1cd  ,iY1ab,  rY1cd,  rY1ab} */
 
421
      haddps rY3r, rY2r   /* rYr = {iY1abcd,rY1abcd,iY0abcd,rY0abcd} */
 
422
      #ifndef BETA0
 
423
         addpd 16(pY), rY2r
 
424
      #endif
 
425
      movaps rY2r, 16(pY)
 
426
      prefY(4*8+PFYDIST(pY))
 
427
      add $4*8, pY
 
428
      add incAn, pA0
 
429
      mov pX0, pX
 
430
      mov M, II
 
431
   sub $4, N
 
432
   jnz LOOPN
 
433
/*
 
434
 * EPILOGUE: restore registers and return
 
435
 */
 
436
   movq -8(%rsp), %rbp
 
437
   movq -16(%rsp), %rbx
 
438
   movq -24(%rsp), %r12
 
439
   movq -32(%rsp), %r13
 
440
   movq -40(%rsp), %r14
 
441
   movq -48(%rsp), %r15
 
442
   ret