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

« back to all changes in this revision

Viewing changes to tune/blas/gemm/CASES/ATL_dmm2x2x2_sse2.c

  • Committer: Bazaar Package Importer
  • Author(s): Sylvestre Ledru
  • Date: 2009-09-17 23:31:54 UTC
  • mto: (2.2.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: james.westby@ubuntu.com-20090917233154-9esw88ub02twbuab
Tags: upstream-3.8.3
ImportĀ upstreamĀ versionĀ 3.8.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *             Automatically Tuned Linear Algebra Software v3.8.3
 
3
 *                    (C) Copyright 2008 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
#include "atlas_asm.h"
 
31
#include "atlas_asm.h"
 
32
#if !defined(ATL_GAS_x8664) && !defined(ATL_GAS_x8632)
 
33
   #error "This kernel requires x86 assembly!"
 
34
#endif
 
35
 
 
36
#ifdef DCPLX
 
37
   #define CMUL(arg_) 2*arg_
 
38
   #define CSH 4
 
39
#else
 
40
   #define CMUL(arg_) arg_
 
41
   #define CSH 3
 
42
#endif
 
43
#ifdef ATL_GAS_x8632
 
44
   #define movq movl
 
45
   #define addq addl
 
46
   #define subq subl
 
47
   #define shrq shrl
 
48
   #define testq testl
 
49
   #define rsp  esp
 
50
   #ifdef BETAX
 
51
      #define BETAOFF 0
 
52
      #define BETASZ 16
 
53
   #else
 
54
      #define BETASZ 0
 
55
   #endif
 
56
   #define FSIZE 16*4+BETASZ
 
57
   #define KOFF    FSIZE-4
 
58
   #define ldcOFF  KOFF-4
 
59
   #define iAmOFF  ldcOFF-4
 
60
   #define PFAOFF  iAmOFF-4
 
61
   #define PFBOFF  PFAOFF-4
 
62
   #define IOFF    PFBOFF-4
 
63
   #define MOFF    IOFF-4
 
64
   #define iAnOFF  MOFF-4
 
65
   #define iBnOFF  iAnOFF-4
 
66
   #define iCnOFF  iBnOFF-4
 
67
   #define JOFF    iCnOFF-4
 
68
#endif
 
69
/*
 
70
 *Integer register usage shown by these defines
 
71
 */
 
72
#ifdef ATL_GAS_x8632
 
73
   #define pA0     %ecx
 
74
   #define pA1     %eax
 
75
   #define pB0     %ebx
 
76
   #define pB1     %edi
 
77
   #define pC0     %esi
 
78
   #define itmp    %edx
 
79
   #define KK      %ebp
 
80
 
 
81
   #define incAm   iAmOFF(%esp)
 
82
   #define incAn   iAnOFF(%esp)
 
83
   #define incBn   iBnOFF(%esp)
 
84
   #define incCn   iCnOFF(%esp)
 
85
   #define MM      IOFF(%esp)
 
86
   #define NN      JOFF(%esp)
 
87
   #define MM0     MOFF(%esp)
 
88
   #define PFA     PFAOFF(%esp)
 
89
   #define PFB     PFBOFF(%esp)
 
90
   #define ldc     ldcOFF(%esp)
 
91
   #define KK0     KOFF(%esp)
 
92
#else
 
93
   #define pA0     %rcx
 
94
   #define pA1     %rbx
 
95
   #define pB0     %rbp
 
96
   #define pB1     %rax
 
97
   #define pC0     %rdi
 
98
   #define KK      %rdx
 
99
   #define PFB     %rsi
 
100
   #define PFA     %r8
 
101
   #define ldc     %r9
 
102
   #define KK0     %r10
 
103
   #define incAm   %r11
 
104
   #define incAn   %r12
 
105
   #define incBn   %r13
 
106
   #define MM      %r14
 
107
   #define NN      %r15
 
108
   #define incCn   iCOFF(%rsp)
 
109
   #define MM0     iIOFF(%rsp)
 
110
   #define itmp    ldc
 
111
#endif
 
112
#define rA0     %xmm0
 
113
#define rA1     %xmm1
 
114
#define ra0     %xmm2
 
115
#define rB0     %xmm3
 
116
#define rC00    %xmm4
 
117
#define rC10    %xmm5
 
118
#define rC01    %xmm6
 
119
#define rC11    %xmm7
 
120
#ifdef ATL_GAS_x8664
 
121
   #define BETA %xmm8
 
122
   #define rC0  %xmm9
 
123
   #define rC1 %xmm10
 
124
#endif
 
125
/*
 
126
 * Define some macros for instruction selection
 
127
 *    VZERO: xorpd, xorps, pxor
 
128
 *    MOVAB: movapd,movaps or movupd/movups
 
129
 */
 
130
#define VZERO(reg_) xorps reg_, reg_
 
131
#define MOVAB  movaps
 
132
#define MOVAPD movaps
 
133
#define MOVUPD movups
 
134
#define PFAINC -64
 
135
#define PFBINC 32
 
136
#if 1
 
137
   #define pref2(mem) prefetcht1        mem
 
138
   #define prefB(mem) prefetcht0        mem
 
139
   #define prefC(mem) prefetcht0        mem
 
140
#else
 
141
   #define pref2(mem)
 
142
   #define prefB(mem)
 
143
   #define prefC(mem)
 
144
#endif
 
145
/*
 
146
                      %rdi/4       %rsi/8       %rdx/12          %xmm0/16
 
147
 void ATL_USERMM(const int M, const int N, const int K, const TYPE alpha,
 
148
                       %rcx/24         %r8/28         %r9/32           8/36
 
149
                 const TYPE *A, const int lda, const TYPE *B, const int ldb,
 
150
                        %xmm1/40    16/48          24/52
 
151
                 const TYPE beta, TYPE *C, const int ldc)
 
152
*/
 
153
        .text
 
154
.global ATL_asmdecor(ATL_USERMM)
 
155
ALIGN16
 
156
ATL_asmdecor(ATL_USERMM):
 
157
/*
 
158
 *      Save callee-saved iregs
 
159
 */
 
160
#ifdef ATL_GAS_x8632
 
161
        movl    %esp, %eax              /* save original stack ptr */
 
162
        sub     $FSIZE, %esp            /* allocate stack space */
 
163
        andw    $0xFFF0, %sp            /* SP now 16-byte aligned */
 
164
        movl    %ebp, BETASZ(%esp)
 
165
        movl    %ebx, BETASZ+4(%esp)
 
166
        movl    %esi, BETASZ+8(%esp)
 
167
        movl    %edi, BETASZ+12(%esp)
 
168
        movl    %eax, BETASZ+16(%esp)   /* original SP saved to new stack */
 
169
#else
 
170
        movq    %rbp, -8(%rsp)
 
171
        movq    %rbx, -16(%rsp)
 
172
        movq    %r12, -24(%rsp)
 
173
        movq    %r13, -32(%rsp)
 
174
        movq    %r14, -40(%rsp)
 
175
        movq    %r15, -48(%rsp)
 
176
   #define iCOFF -56
 
177
   #define iIOFF -64
 
178
#endif
 
179
 
 
180
/*
 
181
 *      Setup input parameters
 
182
 *      For x8632 %eax has old stack ptr; eax is pA1, so set this up late
 
183
 */
 
184
#ifdef ATL_GAS_x8632
 
185
        movl    4(%eax), itmp
 
186
        movl    itmp, MM0
 
187
        movl    8(%eax), itmp
 
188
        movl    itmp, NN
 
189
        movl    12(%eax), KK            /* load K */
 
190
        movl    24(%eax), pA0
 
191
        movl    32(%eax), pB0
 
192
        movl    36(%eax), itmp          /* itmp = ldb */
 
193
        lea     (pB0, itmp, 8), pB1      /* pB1 = pB0 + ldb*sizeof */
 
194
        shl     $4, itmp                /* itmp = 2*sizeof*ldb */
 
195
        movl    itmp, incBn             /* incBn = 2*sizeof*ldb */
 
196
        add     pB0, itmp
 
197
        movl    itmp, PFB
 
198
#ifdef BETAX
 
199
        movsd   40(%eax), rB0           /* load beta */
 
200
        unpcklpd rB0, rB0               /* rB0 = {beta, beta} */
 
201
        MOVAPD  rB0, BETAOFF(%esp)      /* store BETA to BETAOFF */
 
202
#endif
 
203
        movl    48(%eax), pC0
 
204
        movl    52(%eax), itmp          /* itmp = ldc */
 
205
        shl     $CSH, itmp              /* itmp = ldc*sizeof */
 
206
        movl    itmp, ldcOFF(%esp)      /* ldc = ldc*sizeof */
 
207
        shr     $CSH-1, itmp            /* itmp = 2*ldc */
 
208
        sub     MM0, itmp               /* itmp = 2*ldc - M */
 
209
        shl     $CSH, itmp              /* itmp = (2*ldc-M)*sizeof */
 
210
        movl    itmp, incCn             /* incCn = (2*ldc-M)*sizeof */
 
211
        movl    28(%eax), itmp          /* itmp = lda */
 
212
        lea     (pA0, itmp,8), pA1      /* just overwrote old SP in EAX */
 
213
        shl     $4, itmp                /* itmp = 2*sizeof*lda */
 
214
        movl    itmp, incAm             /* incAm = 2*sizeof*lda */
 
215
 
 
216
/*
 
217
 *      pfA = A + 2*lda*M; incAn = lda*M
 
218
 */
 
219
        movl    MM0, itmp       /* itmp = M */
 
220
        imull   incAm, itmp     /* itmp = 2*lda*M */
 
221
        lea     PFAINC(pA0, itmp), itmp /* pfA = pA0 + 2*lda*M - PFAINC */
 
222
        movl    itmp, PFA       /* pfA = 2*lda*M + pA0 - PFAINC */
 
223
        sub     pA0, itmp       /* itmp = 2*lda*M - PFAINC*/
 
224
        sub     $PFAINC, itmp   /* itmp = 2*lda*M */
 
225
        shr     $1, itmp        /* itmp = lda*M */
 
226
        movl    itmp, incAn     /* incAn = lda*M */
 
227
#else
 
228
/*
 
229
 *      Get parameters moves to correct registers
 
230
 */
 
231
        movq    %rdi, MM
 
232
        movq    %rsi, NN
 
233
        movq    %r8, pA1                /* pA1 = lda */
 
234
        movq    %r9, pB0                /* pB0 = B */
 
235
        movslq  8(%rsp), pB1            /* pB1 = ldb */
 
236
        unpcklpd        %xmm1, %xmm1    /* xmm1 = {beta, beta} */
 
237
        MOVAPD  %xmm1, BETA
 
238
        movq    16(%rsp), pC0           /* pC0 = C */
 
239
        movslq  24(%rsp), ldc           /* ldc = ldc */
 
240
/*
 
241
 *      ===================================================
 
242
 *      Compute rest of needed variables using these inputs
 
243
 *      ===================================================
 
244
 */
 
245
        shl     $3, pB1                 /* pB1 = ldb*sizeof */
 
246
        lea     (pB1, pB1), incBn       /* incBn = 2*ldb*sizeof */
 
247
        add     pB0, pB1                /* pB1 = pB0 + ldb*sizeof */
 
248
        lea     (ldc,ldc), PFA          /* PFA = 2*ldc */
 
249
        sub     MM, PFA                 /* PFA = 2*ldc - M */
 
250
        shl     $CSH, PFA               /* PFA = (2*ldc-M)*sizeof */
 
251
        movq    PFA, incCn              /* incCn = (2*ldc-M)*sizeof */
 
252
        shl     $CSH, ldc                 /* ldc *= sizeof */
 
253
        shl     $3, pA1                 /* pA1 = lda * sizeof */
 
254
        lea     (pA1, pA1), incAm       /* incAm = 2*lda*sizeof */
 
255
        mov     MM, PFA                 /* PFA = M */
 
256
        imulq   pA1, PFA                /* PFA = M * lda*sizeof */
 
257
        movq    PFA, incAn              /* incAn = M*lda*sizeof */
 
258
        lea     PFAINC(pA0,PFA,2),PFA   /* PFA = pA0+2*M*lda*sizeof - PFAINC */
 
259
        add     pA0, pA1                /* pA1 = pA0 + lda*sizeof */
 
260
        mov     pB0, PFB                /* PBF = pB0 */
 
261
        add     incBn, PFB              /* PFB = pB0 + 2*ldb*sizeof */
 
262
        movq    MM, MM0                 /* MM0 = MM */
 
263
#endif
 
264
        sub     $2, KK          /* must stop K it early to drain advance load */
 
265
        jz      K_IS_2
 
266
/*
 
267
 *      Have pA/B point to end of column, so we can run loop backwards
 
268
 */
 
269
        lea     (pA0, KK, 8), pA0       /* pA0 += K */
 
270
        lea     (pB0, KK, 8), pB0       /* pB0 += K */
 
271
        lea     (pA1, KK, 8), pA1       /* pA1 += K */
 
272
        lea     (pB1, KK, 8), pB1       /* pB1 += K */
 
273
        neg     KK                      /* KK = -K */
 
274
        add     $2, KK
 
275
        jz      K_IS_4
 
276
        movq    KK, KK0
 
277
#ifdef ATL_GAS_x8632
 
278
        movl    MM0, itmp
 
279
        movl    itmp, MM
 
280
#else
 
281
        movq    MM, MM0
 
282
#endif
 
283
#ifndef DCPLX
 
284
        test    $15, pC0
 
285
        jnz     UNALIGNED_C
 
286
        testq   $15, ldc
 
287
        jnz     UNALIGNED_C
 
288
 
 
289
ALIGN16
 
290
MNLOOP:
 
291
/*
 
292
 *      Peel 1st iteration of K to avoid need to zero rCxx
 
293
 */
 
294
        MOVAB   -16(pB0,KK,8), rA0
 
295
        MOVAB   -16(pA0,KK,8), rC00
 
296
        MOVAPD  rC00, rC01
 
297
        mulpd   rA0, rC00
 
298
        #ifdef ATL_GAS_x8632
 
299
           movq    PFB, itmp
 
300
        #else
 
301
           #ifndef BETA0
 
302
              #ifdef DCPLX
 
303
                 movsd (pC0), rC0
 
304
                 movhpd 16(pC0), rC0
 
305
              #else
 
306
                 MOVAPD  (pC0), rC0
 
307
              #endif
 
308
           #else
 
309
               prefB((PFB))
 
310
           #endif
 
311
        #endif
 
312
        MOVAB   -16(pA1,KK,8), rC10
 
313
        MOVAPD  rC10, rC11
 
314
        mulpd   rA0, rC10
 
315
        #ifdef ATL_GAS_x8632
 
316
           prefB((itmp))
 
317
        #else
 
318
           #ifndef BETA0
 
319
              #ifdef DCPLX
 
320
                 movsd (pC0,ldc), rC1
 
321
                 movhpd 16(pC0,ldc), rC1
 
322
              #else
 
323
                 MOVAPD  (pC0,ldc), rC1
 
324
              #endif
 
325
           #else
 
326
               add      $PFBINC, PFB
 
327
           #endif
 
328
        #endif
 
329
        MOVAB   -16(pB1,KK,8), rA0
 
330
        mulpd   rA0, rC01
 
331
           MOVAB   (pB0,KK,8), rB0
 
332
        mulpd   rA0, rC11
 
333
        #if !defined(ATL_GAS_x8632) && !defined(BETA0)
 
334
               prefB((PFB))
 
335
        #endif
 
336
ALIGN16
 
337
KLOOP:
 
338
        MOVAB   (pA0,KK,8), rA0
 
339
        MOVAPD  rA0, ra0
 
340
        mulpd   rB0, rA0
 
341
        addpd   rA0, rC00
 
342
        MOVAB   (pA1,KK,8), rA1
 
343
        mulpd   rA1, rB0
 
344
        addpd   rB0, rC10
 
345
        MOVAB   (pB1,KK,8), rB0
 
346
        mulpd   rB0, ra0
 
347
        mulpd   rB0, rA1
 
348
           MOVAB   16(pB0,KK,8), rB0
 
349
           add  $2, KK
 
350
        addpd   ra0, rC01
 
351
        addpd   rA1, rC11
 
352
        jnz     KLOOP
 
353
/*
 
354
 *      Peel last iteration to stop forward fetch of B
 
355
 */
 
356
        MOVAB   (pA0), rA0
 
357
        #ifdef ATL_GAS_x8632
 
358
           add     $PFBINC, itmp
 
359
        #elif defined(BETAX)
 
360
           mulpd BETA, rC0
 
361
        #endif
 
362
        MOVAPD  rA0, ra0
 
363
        mulpd   rB0, rA0
 
364
        #ifdef ATL_GAS_x8632
 
365
           movl    itmp, PFB
 
366
        #else
 
367
           pref2((PFA))
 
368
        #endif
 
369
        addpd   rA0, rC00
 
370
        MOVAB   (pA1), rA1
 
371
        mulpd   rA1, rB0
 
372
        #ifdef ATL_GAS_x8632
 
373
           movq    PFA, itmp
 
374
        #elif defined(BETAX)
 
375
           mulpd  BETA, rC1
 
376
        #endif
 
377
        addpd   rB0, rC10
 
378
        MOVAB   (pB1), rB0
 
379
        mulpd   rB0, ra0
 
380
        #ifdef ATL_GAS_x8632
 
381
           prefetcht1      (itmp)
 
382
        #elif !defined(BETA0)
 
383
           add  $PFBINC, PFB
 
384
        #endif
 
385
        mulpd   rB0, rA1
 
386
        #ifdef ATL_GAS_x8632
 
387
           add     $PFAINC, itmp
 
388
        #else
 
389
           add     $PFAINC, PFA
 
390
        #endif
 
391
        addpd   ra0, rC01
 
392
        #ifdef ATL_GAS_x8632
 
393
           movl    itmp, PFA
 
394
        #endif
 
395
        addpd   rA1, rC11
 
396
 
 
397
#ifndef ATL_SSE3
 
398
        MOVAPD          rC00, rA0       /* rA0  = c00a c00b */
 
399
        MOVAPD          rC01, rB0       /* rB0  = c01a c01b */
 
400
        unpcklpd        rC10, rC00      /* rC00 = c00a c10a */
 
401
        unpcklpd        rC11, rC01      /* rC01 = c01a c11a */
 
402
        unpckhpd        rC10, rA0       /* rA0  = c00b c10b */
 
403
        unpckhpd        rC11, rB0       /* rB0  = c01b c11b */
 
404
        addpd           rA0, rC00       /* rC00 = c00ab c10ab */
 
405
        addpd           rB0, rC01       /* rC01 = c01ab c11ab */
 
406
#endif
 
407
#ifdef ATL_GAS_x8632
 
408
        movl    ldcOFF(%esp), itmp
 
409
        #ifdef ATL_SSE3
 
410
           haddpd  rC10, rC00
 
411
        #endif
 
412
        #ifdef BETAX
 
413
           MOVAPD BETAOFF(%esp), rB0
 
414
           MOVAPD (pC0), rA0
 
415
           mulpd  rB0, rA0
 
416
           addpd  rA0, rC00
 
417
        #endif
 
418
        #ifdef BETA1
 
419
           addpd  (pC0), rC00
 
420
        #endif
 
421
        #ifdef ATL_SSE3
 
422
           haddpd  rC11, rC01
 
423
        #endif
 
424
        #ifdef BETAX
 
425
           MOVAPD (pC0,itmp), rA1
 
426
           mulpd  rB0, rA1
 
427
           addpd  rA1, rC01
 
428
        #endif
 
429
        #ifdef BETA1
 
430
           addpd  (pC0,itmp), rC01
 
431
        #endif
 
432
#else
 
433
        #ifdef ATL_SSE3
 
434
           haddpd  rC10, rC00
 
435
        #endif
 
436
        #ifndef BETA0
 
437
           addpd  rC0, rC00
 
438
        #endif
 
439
        #ifdef ATL_SSE3
 
440
           haddpd  rC11, rC01
 
441
        #endif
 
442
        #ifndef BETA0
 
443
           addpd  rC1, rC01
 
444
        #endif
 
445
#endif
 
446
        add     $2*CMUL(8), pC0
 
447
        addq    incAm, pA0    /* pA0 += lda*sizeof*2 */
 
448
        addq    incAm, pA1    /* pA1 += lda*sizeof*2 */
 
449
        subq    $2, MM
 
450
        movq    KK0, KK
 
451
   #ifdef DCPLX
 
452
        movlpd  rC00, -32(pC0)
 
453
        movhpd  rC00, -16(pC0)
 
454
        movlpd  rC01, -32(pC0,itmp)
 
455
        movhpd  rC01, -16(pC0,itmp)
 
456
   #else
 
457
        MOVAPD  rC00, -2*CMUL(8)(pC0)
 
458
        MOVAPD  rC01, -2*CMUL(8)(pC0,itmp)
 
459
   #endif
 
460
        jnz     MNLOOP
 
461
 
 
462
#ifdef ATL_GAS_x8632
 
463
        movl    MM0, itmp
 
464
        movl    itmp, MM
 
465
#else
 
466
        movq    MM0, MM
 
467
#endif
 
468
        movq    KK0, KK
 
469
        subq    incAn, pA0
 
470
        subq    incAn, pA1
 
471
        addq    incCn, pC0
 
472
        addq    incBn, pB0
 
473
        addq    incBn, pB1
 
474
        subq    $2, NN
 
475
        jnz     MNLOOP
 
476
#ifdef ATL_GAS_x8632
 
477
        movl    BETASZ(%esp), %ebp
 
478
        movl    BETASZ+4(%esp), %ebx
 
479
        movl    BETASZ+8(%esp), %esi
 
480
        movl    BETASZ+12(%esp), %edi
 
481
        movl    BETASZ+16(%esp), %esp    /* restore saved original SP */
 
482
#else
 
483
        movq    -8(%rsp), %rbp
 
484
        movq    -16(%rsp), %rbx
 
485
        movq    -24(%rsp), %r12
 
486
        movq    -32(%rsp), %r13
 
487
        movq    -40(%rsp), %r14
 
488
        movq    -48(%rsp), %r15
 
489
#endif
 
490
        ret
 
491
#endif  /* end of ifndef DCPLX -- CPLX must use unaligned loads to C */
 
492
ALIGN16
 
493
/*
 
494
 * Code specialized for when C or ldc is not aligned to 16-byte boundary, so
 
495
 * we must use unaligned loads.  This is a big cost on Core2 systems
 
496
 */
 
497
UNALIGNED_C:
 
498
/*
 
499
 *      Peel 1st iteration of K to avoid need to zero rCxx
 
500
 */
 
501
        MOVAB   -16(pB0,KK,8), rA0
 
502
        MOVAB   -16(pA0,KK,8), rC00
 
503
        MOVAPD  rC00, rC01
 
504
        mulpd   rA0, rC00
 
505
        #ifdef ATL_GAS_x8632
 
506
           movq    PFB, itmp
 
507
        #else
 
508
           #ifndef BETA0
 
509
              #ifdef DCPLX
 
510
                 movsd (pC0), rC0
 
511
                 movhpd 16(pC0), rC0
 
512
              #else
 
513
                 MOVUPD  (pC0), rC0
 
514
              #endif
 
515
           #else
 
516
               prefB((PFB))
 
517
           #endif
 
518
        #endif
 
519
        MOVAB   -16(pA1,KK,8), rC10
 
520
        MOVAPD  rC10, rC11
 
521
        mulpd   rA0, rC10
 
522
        #ifdef ATL_GAS_x8632
 
523
           prefB((itmp))
 
524
        #else
 
525
           #ifndef BETA0
 
526
              #ifdef DCPLX
 
527
                 movsd (pC0,ldc), rC1
 
528
                 movhpd 16(pC0,ldc), rC1
 
529
              #else
 
530
                 MOVUPD  (pC0,ldc), rC1
 
531
              #endif
 
532
           #else
 
533
               add      $PFBINC, PFB
 
534
           #endif
 
535
        #endif
 
536
        MOVAB   -16(pB1,KK,8), rA0
 
537
        mulpd   rA0, rC01
 
538
           MOVAB   (pB0,KK,8), rB0
 
539
        mulpd   rA0, rC11
 
540
        #if !defined(ATL_GAS_x8632) && !defined(BETA0)
 
541
               prefB((PFB))
 
542
        #endif
 
543
ALIGN16
 
544
UKLOOP:
 
545
        MOVAB   (pA0,KK,8), rA0
 
546
        MOVAPD  rA0, ra0
 
547
        mulpd   rB0, rA0
 
548
        addpd   rA0, rC00
 
549
        MOVAB   (pA1,KK,8), rA1
 
550
        mulpd   rA1, rB0
 
551
        addpd   rB0, rC10
 
552
        MOVAB   (pB1,KK,8), rB0
 
553
        mulpd   rB0, ra0
 
554
        mulpd   rB0, rA1
 
555
           MOVAB   16(pB0,KK,8), rB0
 
556
           add  $2, KK
 
557
        addpd   ra0, rC01
 
558
        addpd   rA1, rC11
 
559
        jnz     UKLOOP
 
560
/*
 
561
 *      Peel last iteration to stop forward fetch of B
 
562
 */
 
563
        MOVAB   (pA0), rA0
 
564
        #ifdef ATL_GAS_x8632
 
565
           add     $PFBINC, itmp
 
566
        #elif defined(BETAX)
 
567
           mulpd BETA, rC0
 
568
        #endif
 
569
        MOVAPD  rA0, ra0
 
570
        mulpd   rB0, rA0
 
571
        #ifdef ATL_GAS_x8632
 
572
           movl    itmp, PFB
 
573
        #else
 
574
           pref2((PFA))
 
575
        #endif
 
576
        addpd   rA0, rC00
 
577
        MOVAB   (pA1), rA1
 
578
        mulpd   rA1, rB0
 
579
        #ifdef ATL_GAS_x8632
 
580
           movq    PFA, itmp
 
581
        #elif defined(BETAX)
 
582
           mulpd  BETA, rC1
 
583
        #endif
 
584
        addpd   rB0, rC10
 
585
        MOVAB   (pB1), rB0
 
586
        mulpd   rB0, ra0
 
587
        #ifdef ATL_GAS_x8632
 
588
           prefetcht1      (itmp)
 
589
        #elif !defined(BETA0)
 
590
           add  $PFBINC, PFB
 
591
        #endif
 
592
        mulpd   rB0, rA1
 
593
        #ifdef ATL_GAS_x8632
 
594
           add     $PFAINC, itmp
 
595
        #else
 
596
           add     $PFAINC, PFA
 
597
        #endif
 
598
        addpd   ra0, rC01
 
599
        #ifdef ATL_GAS_x8632
 
600
           movl    itmp, PFA
 
601
        #endif
 
602
        addpd   rA1, rC11
 
603
 
 
604
#ifndef ATL_SSE3
 
605
        MOVAPD          rC00, rA0       /* rA0  = c00a c00b */
 
606
        MOVAPD          rC01, rB0       /* rB0  = c01a c01b */
 
607
        unpcklpd        rC10, rC00      /* rC00 = c00a c10a */
 
608
        unpcklpd        rC11, rC01      /* rC01 = c01a c11a */
 
609
        unpckhpd        rC10, rA0       /* rA0  = c00b c10b */
 
610
        unpckhpd        rC11, rB0       /* rB0  = c01b c11b */
 
611
        addpd           rA0, rC00       /* rC00 = c00ab c10ab */
 
612
        addpd           rB0, rC01       /* rC01 = c01ab c11ab */
 
613
#endif
 
614
#ifdef ATL_GAS_x8632
 
615
        movl    ldcOFF(%esp), itmp
 
616
   #ifdef DCPLX
 
617
        #ifdef ATL_SSE3
 
618
           haddpd  rC10, rC00
 
619
        #endif
 
620
        #ifndef BETA0
 
621
           #ifdef BETAX
 
622
              movapd BETAOFF(%esp), rB0
 
623
           #endif
 
624
           movsd (pC0), rA0
 
625
           movhpd 16(pC0), rA0
 
626
           #ifdef BETAX
 
627
              mulpd  rB0, rA0
 
628
           #endif
 
629
           addpd  rA0, rC00
 
630
        #endif
 
631
        #ifdef ATL_SSE3
 
632
           haddpd  rC11, rC01
 
633
        #endif
 
634
        #ifndef BETA0
 
635
           movsd (pC0,itmp), rA1
 
636
           movhpd 16(pC0,itmp), rA1
 
637
           #ifdef BETAX
 
638
              mulpd  rB0, rA1
 
639
           #endif
 
640
           addpd  rA1, rC01
 
641
        #endif
 
642
   #else
 
643
        #ifdef ATL_SSE3
 
644
           haddpd  rC10, rC00
 
645
        #endif
 
646
        #ifdef BETAX
 
647
           MOVAPD BETAOFF(%esp), rB0
 
648
           MOVUPD (pC0), rA0
 
649
           mulpd  rB0, rA0
 
650
           addpd  rA0, rC00
 
651
        #endif
 
652
        #ifdef BETA1
 
653
           MOVUPD (pC0), rA0
 
654
           addpd   rA0, rC00
 
655
        #endif
 
656
        #ifdef ATL_SSE3
 
657
           haddpd  rC11, rC01
 
658
        #endif
 
659
        #ifdef BETAX
 
660
           MOVUPD (pC0,itmp), rA1
 
661
           mulpd  rB0, rA1
 
662
           addpd  rA1, rC01
 
663
        #endif
 
664
        #ifdef BETA1
 
665
           MOVUPD (pC0, itmp), rA1
 
666
           addpd  rA1, rC01
 
667
        #endif
 
668
   #endif
 
669
#else
 
670
        #ifdef ATL_SSE3
 
671
           haddpd  rC10, rC00
 
672
        #endif
 
673
        #ifndef BETA0
 
674
           addpd  rC0, rC00
 
675
        #endif
 
676
        #ifdef ATL_SSE3
 
677
           haddpd  rC11, rC01
 
678
        #endif
 
679
        #ifndef BETA0
 
680
           addpd  rC1, rC01
 
681
        #endif
 
682
#endif
 
683
        add     $2*CMUL(8), pC0
 
684
        addq    incAm, pA0    /* pA0 += lda*sizeof*2 */
 
685
        addq    incAm, pA1    /* pA1 += lda*sizeof*2 */
 
686
        subq    $2, MM
 
687
        movq    KK0, KK
 
688
   #ifdef DCPLX
 
689
        movlpd  rC00, -32(pC0)
 
690
        movhpd  rC00, -16(pC0)
 
691
        movlpd  rC01, -32(pC0,itmp)
 
692
        movhpd  rC01, -16(pC0,itmp)
 
693
   #else
 
694
        MOVUPD  rC00, -2*CMUL(8)(pC0)
 
695
        MOVUPD  rC01, -2*CMUL(8)(pC0,itmp)
 
696
   #endif
 
697
        jnz     UNALIGNED_C
 
698
 
 
699
#ifdef ATL_GAS_x8632
 
700
        movl    MM0, itmp
 
701
        movl    itmp, MM
 
702
#else
 
703
        movq    MM0, MM
 
704
#endif
 
705
        movq    KK0, KK
 
706
        subq    incAn, pA0
 
707
        subq    incAn, pA1
 
708
        addq    incCn, pC0
 
709
        addq    incBn, pB0
 
710
        addq    incBn, pB1
 
711
        subq    $2, NN
 
712
        jnz     UNALIGNED_C
 
713
#ifdef ATL_GAS_x8632
 
714
        movl    BETASZ(%esp), %ebp
 
715
        movl    BETASZ+4(%esp), %ebx
 
716
        movl    BETASZ+8(%esp), %esi
 
717
        movl    BETASZ+12(%esp), %edi
 
718
        movl    BETASZ+16(%esp), %esp    /* restore saved original SP */
 
719
#else
 
720
        movq    -8(%rsp), %rbp
 
721
        movq    -16(%rsp), %rbx
 
722
        movq    -24(%rsp), %r12
 
723
        movq    -32(%rsp), %r13
 
724
        movq    -40(%rsp), %r14
 
725
        movq    -48(%rsp), %r15
 
726
#endif
 
727
        ret
 
728
/*
 
729
 * Code specialized for K == 2; pA0 & pAB pt to start of arrays
 
730
 * Assume C unaligned so we don't have to write this cleanup case twice.
 
731
 * This assumption costs you major perf. if you care about this case
 
732
 * (since load/store of C dominant cost when K=2).  This code is more for
 
733
 * correctness than perf. as presently written.
 
734
 */
 
735
K_IS_2:
 
736
#ifdef ATL_GAS_x8632
 
737
        movq    ldc, itmp
 
738
#endif
 
739
        movq    MM0, KK          /* KK is now M-loop counter */
 
740
ALIGN16
 
741
MNLOOP_K2:
 
742
   #ifdef BETA0
 
743
        MOVAB   (pB0), rA0
 
744
        MOVAB   (pA0), rC00
 
745
        MOVAPD  rC00, rC01
 
746
        mulpd   rA0, rC00
 
747
        MOVAB   (pA1), rC10
 
748
        MOVAPD  rC10, rC11
 
749
        mulpd   rA0, rC10
 
750
        MOVAB   (pB1), rA0
 
751
        mulpd   rA0, rC01
 
752
        mulpd   rA0, rC11
 
753
   #else
 
754
        movsd   (pC0), rC00
 
755
        movsd   CMUL(8)(pC0), rC10
 
756
        movsd   (pC0,itmp), rC01
 
757
        movsd   CMUL(8)(pC0,itmp), rC11
 
758
        #ifdef BETAX
 
759
           #ifdef ATL_GAS_x8632
 
760
              MOVAPD BETAOFF(%esp), rA1
 
761
              mulpd  rA1, rC00
 
762
              mulpd  rA1, rC10
 
763
              mulpd  rA1, rC01
 
764
              mulpd  rA1, rC11
 
765
           #else
 
766
              mulpd  BETA, rC00
 
767
              mulpd  BETA, rC10
 
768
              mulpd  BETA, rC01
 
769
              mulpd  BETA, rC11
 
770
           #endif
 
771
        #endif
 
772
        MOVAB   (pA0), rA0
 
773
        MOVAB   (pB0), rB0
 
774
        MOVAPD  rA0, ra0
 
775
        mulpd   rB0, rA0
 
776
        addpd   rA0, rC00
 
777
        MOVAB   (pA1), rA1
 
778
        mulpd   rA1, rB0
 
779
        addpd   rB0, rC10
 
780
        MOVAB   (pB1), rB0
 
781
        mulpd   rB0, ra0
 
782
        mulpd   rB0, rA1
 
783
        addpd   ra0, rC01
 
784
        addpd   rA1, rC11
 
785
   #endif
 
786
           add     $2*CMUL(8), pC0
 
787
#ifndef ATL_SSE3
 
788
        MOVAPD          rC00, rA0       /* rA0  = c00a c00b */
 
789
        MOVAPD          rC01, rB0       /* rB0  = c01a c01b */
 
790
        unpcklpd        rC10, rC00      /* rC00 = c00a c10a */
 
791
        unpcklpd        rC11, rC01      /* rC01 = c01a c11a */
 
792
        unpckhpd        rC10, rA0       /* rA0  = c00b c10b */
 
793
        unpckhpd        rC11, rB0       /* rB0  = c01b c11b */
 
794
        addpd           rA0, rC00       /* rC00 = c00ab c10ab */
 
795
        addpd           rB0, rC01       /* rC01 = c01ab c11ab */
 
796
#endif
 
797
        #ifdef ATL_SSE3
 
798
           haddpd  rC10, rC00
 
799
        #endif
 
800
           addq  incAm, pA0
 
801
        #ifdef ATL_SSE3
 
802
           haddpd  rC11, rC01
 
803
        #endif
 
804
           addq  incAm, pA1
 
805
           sub   $2, KK
 
806
   #ifdef DCPLX
 
807
        movlpd  rC00, -32(pC0)
 
808
        movhpd  rC00, -16(pC0)
 
809
        movlpd  rC01, -32(pC0,itmp)
 
810
        movhpd  rC01, -16(pC0,itmp)
 
811
   #else
 
812
        MOVUPD  rC00, -2*8(pC0)
 
813
        MOVUPD  rC01, -2*8(pC0,itmp)
 
814
   #endif
 
815
        jnz MNLOOP_K2                   /* end of M-loop */
 
816
 
 
817
        subq    incAn, pA0
 
818
        subq    incAn, pA1
 
819
        addq    incCn, pC0
 
820
        addq    incBn, pB0
 
821
        addq    incBn, pB1
 
822
        subq    $2, NN
 
823
        mov     MM0, KK
 
824
        jnz     MNLOOP_K2
 
825
#ifdef ATL_GAS_x8632
 
826
        movl    BETASZ(%esp), %ebp
 
827
        movl    BETASZ+4(%esp), %ebx
 
828
        movl    BETASZ+8(%esp), %esi
 
829
        movl    BETASZ+12(%esp), %edi
 
830
        movl    BETASZ+16(%esp), %esp    /* restore saved original SP */
 
831
#else
 
832
        movq    -8(%rsp), %rbp
 
833
        movq    -16(%rsp), %rbx
 
834
        movq    -24(%rsp), %r12
 
835
        movq    -32(%rsp), %r13
 
836
        movq    -40(%rsp), %r14
 
837
        movq    -48(%rsp), %r15
 
838
#endif
 
839
        ret
 
840
/*
 
841
 * Code specialized for K == 4; pA0 & pAB pt to start of arrays + 16
 
842
 * Assume C unaligned so we don't have to write this cleanup case twice.
 
843
 * This assumption costs you major perf. if you care about this case
 
844
 * (since load/store of C dominant cost when K=4).  This code is more for
 
845
 * correctness than perf. as presently written.
 
846
 */
 
847
K_IS_4:
 
848
#ifdef ATL_GAS_x8632
 
849
        movq    ldc, itmp
 
850
#endif
 
851
        movq    MM0, KK          /* KK is now M-loop counter */
 
852
ALIGN16
 
853
MNLOOP_K4:
 
854
   #ifdef BETA0
 
855
        MOVAB   -16(pB0), rA0
 
856
        MOVAB   -16(pA0), rC00
 
857
        MOVAPD  rC00, rC01
 
858
        mulpd   rA0, rC00
 
859
        MOVAB   -16(pA1), rC10
 
860
        MOVAPD  rC10, rC11
 
861
        mulpd   rA0, rC10
 
862
        MOVAB   -16(pB1), rA0
 
863
        mulpd   rA0, rC01
 
864
        MOVAB   (pB0), rB0
 
865
        mulpd   rA0, rC11
 
866
   #else
 
867
        movsd   (pC0), rC00
 
868
        movsd   CMUL(8)(pC0), rC10
 
869
        movsd   (pC0,itmp), rC01
 
870
        movsd   CMUL(8)(pC0,itmp), rC11
 
871
        #ifdef BETAX
 
872
           #ifdef ATL_GAS_x8632
 
873
              MOVAPD BETAOFF(%esp), rA1
 
874
              mulpd  rA1, rC00
 
875
              mulpd  rA1, rC10
 
876
              mulpd  rA1, rC01
 
877
              mulpd  rA1, rC11
 
878
           #else
 
879
              mulpd  BETA, rC00
 
880
              mulpd  BETA, rC10
 
881
              mulpd  BETA, rC01
 
882
              mulpd  BETA, rC11
 
883
           #endif
 
884
        #endif
 
885
        MOVAB   -16(pA0), rA0
 
886
        MOVAB   -16(pB0), rB0
 
887
        MOVAPD  rA0, ra0
 
888
        mulpd   rB0, rA0
 
889
        addpd   rA0, rC00
 
890
        MOVAB   -16(pA1), rA1
 
891
        mulpd   rA1, rB0
 
892
        addpd   rB0, rC10
 
893
        MOVAB   -16(pB1), rB0
 
894
        mulpd   rB0, ra0
 
895
        mulpd   rB0, rA1
 
896
        MOVAB   (pB0), rB0
 
897
        addpd   ra0, rC01
 
898
        addpd   rA1, rC11
 
899
   #endif
 
900
        MOVAB   (pA0), rA0
 
901
        MOVAPD  rA0, ra0
 
902
        mulpd   rB0, rA0
 
903
        addpd   rA0, rC00
 
904
        MOVAB   (pA1), rA1
 
905
        mulpd   rA1, rB0
 
906
        addpd   rB0, rC10
 
907
        MOVAB   (pB1), rB0
 
908
        mulpd   rB0, ra0
 
909
        mulpd   rB0, rA1
 
910
        addpd   ra0, rC01
 
911
        addpd   rA1, rC11
 
912
           add     $2*CMUL(8), pC0
 
913
#ifndef ATL_SSE3
 
914
        MOVAPD          rC00, rA0       /* rA0  = c00a c00b */
 
915
        MOVAPD          rC01, rB0       /* rB0  = c01a c01b */
 
916
        unpcklpd        rC10, rC00      /* rC00 = c00a c10a */
 
917
        unpcklpd        rC11, rC01      /* rC01 = c01a c11a */
 
918
        unpckhpd        rC10, rA0       /* rA0  = c00b c10b */
 
919
        unpckhpd        rC11, rB0       /* rB0  = c01b c11b */
 
920
        addpd           rA0, rC00       /* rC00 = c00ab c10ab */
 
921
        addpd           rB0, rC01       /* rC01 = c01ab c11ab */
 
922
#endif
 
923
        #ifdef ATL_SSE3
 
924
           haddpd  rC10, rC00
 
925
        #endif
 
926
           addq  incAm, pA0
 
927
        #ifdef ATL_SSE3
 
928
           haddpd  rC11, rC01
 
929
        #endif
 
930
           addq  incAm, pA1
 
931
           sub   $2, KK
 
932
   #ifdef DCPLX
 
933
        movlpd  rC00, -32(pC0)
 
934
        movhpd  rC00, -16(pC0)
 
935
        movlpd  rC01, -32(pC0,itmp)
 
936
        movhpd  rC01, -16(pC0,itmp)
 
937
   #else
 
938
        MOVUPD  rC00, -2*CMUL(8)(pC0)
 
939
        MOVUPD  rC01, -2*CMUL(8)(pC0,itmp)
 
940
   #endif
 
941
        jnz MNLOOP_K4                   /* end of M-loop */
 
942
 
 
943
        subq    incAn, pA0
 
944
        subq    incAn, pA1
 
945
        addq    incCn, pC0
 
946
        addq    incBn, pB0
 
947
        addq    incBn, pB1
 
948
        subq    $2, NN
 
949
        movq    MM0, KK
 
950
        jnz     MNLOOP_K4
 
951
#ifdef ATL_GAS_x8632
 
952
        movl    BETASZ(%esp), %ebp
 
953
        movl    BETASZ+4(%esp), %ebx
 
954
        movl    BETASZ+8(%esp), %esi
 
955
        movl    BETASZ+12(%esp), %edi
 
956
        movl    BETASZ+16(%esp), %esp    /* restore saved original SP */
 
957
#else
 
958
        movq    -8(%rsp), %rbp
 
959
        movq    -16(%rsp), %rbx
 
960
        movq    -24(%rsp), %r12
 
961
        movq    -32(%rsp), %r13
 
962
        movq    -40(%rsp), %r14
 
963
        movq    -48(%rsp), %r15
 
964
#endif
 
965
        ret