arm: add softfp support in zgemm/ztrmm vfp kernels
[platform/upstream/openblas.git] / kernel / arm / ztrmm_kernel_2x2_vfpv3.S
1 /***************************************************************************
2 Copyright (c) 2013, The OpenBLAS Project
3 All rights reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 1. Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 2. Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in
11 the documentation and/or other materials provided with the
12 distribution.
13 3. Neither the name of the OpenBLAS project nor the names of
14 its contributors may be used to endorse or promote products
15 derived from this software without specific prior written permission.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBLAS PROJECT OR CONTRIBUTORS BE
20 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *****************************************************************************/
27
28 /**************************************************************************************
29 * 2013/10/16 Saar
30 *        BLASTEST               : OK
31 *        CTEST                  : OK
32 *        TEST                   : OK
33 *
34 **************************************************************************************/
35
36 #define ASSEMBLER
37 #include "common.h"
38
39 #define STACKSIZE 256
40
41 #define OLD_M   r0
42 #define OLD_N   r1
43 #define OLD_K   r2
44 #define OLD_A   r3
45 #define OLD_ALPHA_R d0
46 #define OLD_ALPHA_I d1
47
48 /******************************************************
49 * [fp, #-128] - [fp, #-64] is reserved
50 * for store and restore of floating point
51 * registers
52 *******************************************************/
53
54 #define KKK     [fp, #-240]
55 #define KK      [fp, #-244 ]
56 #define A       [fp, #-248 ]
57 #define LDC     [fp, #-252 ]
58 #define M       [fp, #-256 ]
59 #define N       [fp, #-260 ]
60 #define K       [fp, #-264 ]
61
62 #define FP_ZERO [fp, #-236]
63 #define FP_ZERO_0 [fp, #-236]
64 #define FP_ZERO_1 [fp, #-232]
65
66 #define ALPHA_I [fp, #-272]
67 #define ALPHA_R [fp, #-280]
68
69 #if !defined(__ARM_PCS_VFP)
70 #define OLD_ALPHAR_SOFTFP       [fp, #4]
71 #define OLD_ALPHAI_SOFTFP       [fp, #12]
72 #define OLD_A_SOFTFP    [fp, #20 ]
73 #define B       [fp, #24 ]
74 #define C       [fp, #28 ]
75 #define OLD_LDC [fp, #32 ]
76 #define OFFSET  [fp, #36 ]
77 #else
78 #define B       [fp, #4 ]
79 #define C       [fp, #8 ]
80 #define OLD_LDC [fp, #12 ]
81 #define OFFSET  [fp, #16 ]
82 #endif
83
84 #define I       r0
85 #define J       r1
86 #define L       r2
87
88 #define AO      r5
89 #define BO      r6
90
91 #define CO1     r8
92 #define CO2     r9
93
94 #define K1      r7
95 #define BC      r12
96
97 #define A_PRE   96
98 #define B_PRE   96
99 #define C_PRE   64
100
101 #if defined(NN) || defined(NT) || defined(TN) || defined(TT)
102
103         #define FADD_R  fsubd
104         #define FADD_I  faddd
105
106         #define FMAC_R1 fnmuld
107         #define FMAC_R2 fnmacd
108         #define FMAC_I1 fmuld
109         #define FMAC_I2 fnmacd
110
111 #elif defined(CN) || defined(CT)
112
113         #define FADD_R  faddd
114         #define FADD_I  fsubd
115
116         #define FMAC_R1 fmuld
117         #define FMAC_R2 fmacd
118         #define FMAC_I1 fnmuld
119         #define FMAC_I2 fmacd
120
121 #elif defined(NC) || defined(TC)
122
123         #define FADD_R  faddd
124         #define FADD_I  fsubd
125
126         #define FMAC_R1 fmuld
127         #define FMAC_R2 fnmacd
128         #define FMAC_I1 fmuld
129         #define FMAC_I2 fmacd
130
131 #else
132
133         #define FADD_R  fsubd
134         #define FADD_I  faddd
135
136         #define FMAC_R1 fnmuld
137         #define FMAC_R2 fmacd
138         #define FMAC_I1 fnmuld
139         #define FMAC_I2 fnmacd
140
141 #endif
142
143
144
145 /**************************************************************************************
146 * Macro definitions
147 **************************************************************************************/
148
149 .macro INIT2x2
150
151         fldd                    d16 , FP_ZERO
152         vmov.f64                d17, d16
153         vmov.f64                d18, d16
154         vmov.f64                d19, d16
155         vmov.f64                d20, d16
156         vmov.f64                d21, d16
157         vmov.f64                d22, d16
158         vmov.f64                d23, d16
159         vmov.f64                d24, d16
160         vmov.f64                d25, d16
161         vmov.f64                d26, d16
162         vmov.f64                d27, d16
163         vmov.f64                d28, d16
164         vmov.f64                d29, d16
165         vmov.f64                d30, d16
166         vmov.f64                d31, d16
167
168 .endm
169
170 .macro KERNEL2x2_I
171         pld     [ AO , #A_PRE ]
172         pld     [ BO , #B_PRE ]
173         fldd    d0 , [ AO ]
174         fldd    d1 , [ AO, #8 ]
175         fldd    d8 , [ BO ]
176         fldd    d9 , [ BO, #8 ]
177
178         fmuld   d16  , d0,  d8
179         fldd    d2 , [ AO, #16 ]
180         fmuld   d24  , d1,  d9
181         fldd    d3 , [ AO, #24 ]
182         fmuld   d17  , d0,  d9
183         fldd    d10, [ BO, #16 ]
184         fmuld   d25  , d1,  d8
185
186         fldd    d11, [ BO, #24 ]
187         fmuld   d18  , d2,  d8
188         add     BO , BO, #32
189         fmuld   d26  , d3,  d9
190         add     AO , AO, #32
191         fmuld   d19  , d2,  d9
192         pld     [ BO , #B_PRE ]
193         fmuld   d27  , d3,  d8
194
195         pld     [ AO , #A_PRE ]
196         fmuld   d20  , d0,  d10
197         fldd    d4 , [ AO, #0 ]
198         fmuld   d28  , d1,  d11
199         fldd    d5 , [ AO, #8 ]
200         fmuld   d21  , d0,  d11
201         fldd    d12, [ BO ]
202         fmuld   d29  , d1,  d10
203
204         fldd    d13, [ BO, #8 ]
205         fmuld   d22  , d2,  d10
206         fldd    d6 , [ AO, #16 ]
207         fmuld   d30  , d3,  d11
208         fldd    d7 , [ AO, #24 ]
209         fmuld   d23  , d2,  d11
210         fldd    d14, [ BO, #16 ]
211         fmuld   d31  , d3,  d10
212         fldd    d15, [ BO, #24 ]
213
214         add     BO , BO, #32
215         add     AO , AO, #32
216 .endm
217
218
219
220 .macro KERNEL2x2_M1
221         pld     [ AO , #A_PRE ]
222
223         fmacd   d16  , d0,  d8
224         pld     [ BO , #B_PRE ]
225         fmacd   d24  , d1,  d9
226         fldd    d4 , [ AO, #0 ]
227         fmacd   d17  , d0,  d9
228         fldd    d5 , [ AO, #8 ]
229         fmacd   d25  , d1,  d8
230
231         fldd    d12, [ BO ]
232         fmacd   d18  , d2,  d8
233         fldd    d13, [ BO, #8 ]
234         fmacd   d26  , d3,  d9
235         fldd    d6 , [ AO, #16 ]
236         fmacd   d19  , d2,  d9
237         fldd    d7 , [ AO, #24 ]
238         fmacd   d27  , d3,  d8
239
240         fmacd   d20  , d0,  d10
241         fldd    d14, [ BO, #16 ]
242         fmacd   d28  , d1,  d11
243         fmacd   d21  , d0,  d11
244         fldd    d15, [ BO, #24 ]
245         fmacd   d29  , d1,  d10
246
247         fmacd   d22  , d2,  d10
248         add     BO , BO, #32
249         fmacd   d30  , d3,  d11
250         fmacd   d23  , d2,  d11
251         add     AO , AO, #32
252         fmacd   d31  , d3,  d10
253
254 .endm
255
256 .macro KERNEL2x2_M2
257         pld     [ AO , #A_PRE ]
258
259         fmacd   d16  , d4,  d12
260         pld     [ BO , #B_PRE ]
261         fmacd   d24  , d5,  d13
262         fldd    d0 , [ AO, #0 ]
263         fmacd   d17  , d4,  d13
264         fldd    d1 , [ AO, #8 ]
265         fmacd   d25  , d5,  d12
266
267         fmacd   d18  , d6,  d12
268         fldd    d8 , [ BO ]
269         fmacd   d26  , d7,  d13
270         fldd    d9 , [ BO, #8 ]
271         fmacd   d19  , d6,  d13
272         fmacd   d27  , d7,  d12
273
274         fldd    d2 , [ AO, #16 ]
275         fmacd   d20  , d4,  d14
276         fldd    d3 , [ AO, #24 ]
277         fmacd   d28  , d5,  d15
278         fmacd   d21  , d4,  d15
279         fldd    d10, [ BO, #16 ]
280         fmacd   d29  , d5,  d14
281
282         fldd    d11, [ BO, #24 ]
283         fmacd   d22  , d6,  d14
284         fmacd   d30  , d7,  d15
285         add     BO , BO, #32
286         fmacd   d23  , d6,  d15
287         add     AO , AO, #32
288         fmacd   d31  , d7,  d14
289
290 .endm
291
292
293 .macro KERNEL2x2_E
294
295         fmacd   d16  , d4,  d12
296         fmacd   d24  , d5,  d13
297         fmacd   d17  , d4,  d13
298         fmacd   d25  , d5,  d12
299
300         fmacd   d18  , d6,  d12
301         fmacd   d26  , d7,  d13
302         fmacd   d19  , d6,  d13
303         fmacd   d27  , d7,  d12
304
305         fmacd   d20  , d4,  d14
306         fmacd   d28  , d5,  d15
307         fmacd   d21  , d4,  d15
308         fmacd   d29  , d5,  d14
309
310         fmacd   d22  , d6,  d14
311         fmacd   d30  , d7,  d15
312         fmacd   d23  , d6,  d15
313         fmacd   d31  , d7,  d14
314
315 .endm
316
317 .macro KERNEL2x2_SUB
318
319         pld     [ AO , #A_PRE ]
320         pld     [ BO , #B_PRE ]
321         fldd    d0 , [ AO ]
322         fldd    d1 , [ AO, #8 ]
323         fldd    d8 , [ BO ]
324         fldd    d9 , [ BO, #8 ]
325
326         fmacd   d16  , d0,  d8
327         fldd    d2 , [ AO, #16 ]
328         fmacd   d24  , d1,  d9
329         fldd    d3 , [ AO, #24 ]
330         fmacd   d17  , d0,  d9
331         fldd    d10, [ BO, #16 ]
332         fmacd   d25  , d1,  d8
333
334         fldd    d11, [ BO, #24 ]
335         fmacd   d18  , d2,  d8
336         fmacd   d26  , d3,  d9
337         fmacd   d19  , d2,  d9
338         fmacd   d27  , d3,  d8
339
340         fmacd   d20  , d0,  d10
341         fmacd   d28  , d1,  d11
342         fmacd   d21  , d0,  d11
343         fmacd   d29  , d1,  d10
344
345         fmacd   d22  , d2,  d10
346         add     BO , BO, #32
347         fmacd   d30  , d3,  d11
348         fmacd   d23  , d2,  d11
349         add     AO , AO, #32
350         fmacd   d31  , d3,  d10
351
352 .endm
353
354
355
356
357 .macro SAVE2x2
358
359         ldr     r3  , LDC
360         add     CO2 , CO1, r3
361         fldd            d0, ALPHA_R
362         fldd            d1, ALPHA_I
363
364
365         FADD_R  d16, d24 , d16
366         FADD_I  d17, d25 , d17
367         FADD_R  d18, d26 , d18
368         FADD_I  d19, d27 , d19
369         FADD_R  d20, d28 , d20
370         FADD_I  d21, d29 , d21
371         FADD_R  d22, d30 , d22
372         FADD_I  d23, d31 , d23
373
374         FMAC_R1 d4 , d0 , d16
375         FMAC_I1 d5 , d0 , d17
376         FMAC_R2 d4 , d1 , d17
377         FMAC_I2 d5 , d1 , d16
378
379         FMAC_R1 d6 , d0 , d18
380         FMAC_I1 d7 , d0 , d19
381         FMAC_R2 d6 , d1 , d19
382         FMAC_I2 d7 , d1 , d18
383
384         FMAC_R1 d8 , d0 , d20
385         FMAC_I1 d9 , d0 , d21
386         FMAC_R2 d8 , d1 , d21
387         FMAC_I2 d9 , d1 , d20
388
389         FMAC_R1 d10, d0 , d22
390         FMAC_I1 d11, d0 , d23
391         FMAC_R2 d10, d1 , d23
392         FMAC_I2 d11, d1 , d22
393
394         fstmiad CO1, { d4 - d7 }
395         fstmiad CO2, { d8 - d11 }
396
397         add     CO1, CO1, #32
398
399 .endm
400
401 /******************************************************************************/
402
403 .macro INIT1x2
404
405         fldd                    d16 , FP_ZERO
406         vmov.f64                d17, d16
407         vmov.f64                d20, d16
408         vmov.f64                d21, d16
409         vmov.f64                d24, d16
410         vmov.f64                d25, d16
411         vmov.f64                d28, d16
412         vmov.f64                d29, d16
413
414 .endm
415
416 .macro KERNEL1x2_I
417         pld     [ AO , #A_PRE ]
418         pld     [ BO , #B_PRE ]
419         fldd    d0 , [ AO ]
420         fldd    d1 , [ AO, #8 ]
421         fldd    d8 , [ BO ]
422         fldd    d9 , [ BO, #8 ]
423         fldd    d10, [ BO, #16 ]
424         fldd    d11, [ BO, #24 ]
425
426         fmuld   d16  , d0,  d8
427         fmuld   d24  , d1,  d9
428         fmuld   d17  , d0,  d9
429         fmuld   d25  , d1,  d8
430
431         fmuld   d20  , d0,  d10
432         fmuld   d28  , d1,  d11
433         fmuld   d21  , d0,  d11
434         fmuld   d29  , d1,  d10
435
436         add     BO , BO, #32
437         add     AO , AO, #16
438
439         pld     [ BO , #B_PRE ]
440
441         fldd    d4 , [ AO, #0 ]
442         fldd    d5 , [ AO, #8 ]
443
444         fldd    d12, [ BO ]
445         fldd    d13, [ BO, #8 ]
446         fldd    d14, [ BO, #16 ]
447         fldd    d15, [ BO, #24 ]
448
449         add     BO , BO, #32
450         add     AO , AO, #16
451 .endm
452
453
454
455 .macro KERNEL1x2_M1
456         pld     [ BO , #B_PRE ]
457
458         fmacd   d16  , d0,  d8
459         fmacd   d24  , d1,  d9
460         fmacd   d17  , d0,  d9
461         fmacd   d25  , d1,  d8
462
463         fmacd   d20  , d0,  d10
464         fmacd   d28  , d1,  d11
465         fmacd   d21  , d0,  d11
466         fmacd   d29  , d1,  d10
467
468         fldd    d4 , [ AO, #0 ]
469         fldd    d5 , [ AO, #8 ]
470
471         fldd    d12, [ BO ]
472         fldd    d13, [ BO, #8 ]
473         fldd    d14, [ BO, #16 ]
474         fldd    d15, [ BO, #24 ]
475
476         add     BO , BO, #32
477         add     AO , AO, #16
478 .endm
479
480 .macro KERNEL1x2_M2
481         pld     [ AO , #A_PRE ]
482         pld     [ BO , #B_PRE ]
483
484         fmacd   d16  , d4,  d12
485         fmacd   d24  , d5,  d13
486         fmacd   d17  , d4,  d13
487         fmacd   d25  , d5,  d12
488
489         fmacd   d20  , d4,  d14
490         fmacd   d28  , d5,  d15
491         fmacd   d21  , d4,  d15
492         fmacd   d29  , d5,  d14
493
494         fldd    d0 , [ AO, #0 ]
495         fldd    d1 , [ AO, #8 ]
496
497         fldd    d8 , [ BO ]
498         fldd    d9 , [ BO, #8 ]
499         fldd    d10, [ BO, #16 ]
500         fldd    d11, [ BO, #24 ]
501
502         add     BO , BO, #32
503         add     AO , AO, #16
504 .endm
505
506
507 .macro KERNEL1x2_E
508
509         fmacd   d16  , d4,  d12
510         fmacd   d24  , d5,  d13
511         fmacd   d17  , d4,  d13
512         fmacd   d25  , d5,  d12
513
514         fmacd   d20  , d4,  d14
515         fmacd   d28  , d5,  d15
516         fmacd   d21  , d4,  d15
517         fmacd   d29  , d5,  d14
518
519 .endm
520
521 .macro KERNEL1x2_SUB
522
523         pld     [ AO , #A_PRE ]
524         pld     [ BO , #B_PRE ]
525         fldd    d0 , [ AO ]
526         fldd    d1 , [ AO, #8 ]
527         fldd    d8 , [ BO ]
528         fldd    d9 , [ BO, #8 ]
529         fldd    d10, [ BO, #16 ]
530         fldd    d11, [ BO, #24 ]
531
532         fmacd   d16  , d0,  d8
533         fmacd   d24  , d1,  d9
534         fmacd   d17  , d0,  d9
535         fmacd   d25  , d1,  d8
536
537         fmacd   d20  , d0,  d10
538         fmacd   d28  , d1,  d11
539         fmacd   d21  , d0,  d11
540         fmacd   d29  , d1,  d10
541
542         add     BO , BO, #32
543         add     AO , AO, #16
544
545 .endm
546
547
548
549
550 .macro SAVE1x2
551
552         ldr     r3  , LDC
553         add     CO2 , CO1, r3
554         fldd            d0, ALPHA_R
555         fldd            d1, ALPHA_I
556
557         FADD_R  d16, d24 , d16
558         FADD_I  d17, d25 , d17
559         FADD_R  d20, d28 , d20
560         FADD_I  d21, d29 , d21
561
562         FMAC_R1 d4 , d0 , d16
563         FMAC_I1 d5 , d0 , d17
564         FMAC_R2 d4 , d1 , d17
565         FMAC_I2 d5 , d1 , d16
566
567         FMAC_R1 d8 , d0 , d20
568         FMAC_I1 d9 , d0 , d21
569         FMAC_R2 d8 , d1 , d21
570         FMAC_I2 d9 , d1 , d20
571
572         fstmiad CO1, { d4 - d5 }
573         fstmiad CO2, { d8 - d9  }
574
575         add     CO1, CO1, #16
576
577 .endm
578
579 /******************************************************************************/
580
581 .macro INIT2x1
582
583         fldd                    d16 , FP_ZERO
584         vmov.f64                d17, d16
585         vmov.f64                d18, d16
586         vmov.f64                d19, d16
587         vmov.f64                d24, d16
588         vmov.f64                d25, d16
589         vmov.f64                d26, d16
590         vmov.f64                d27, d16
591
592 .endm
593
594 .macro KERNEL2x1_I
595         pld     [ AO , #A_PRE ]
596         pld     [ BO , #B_PRE ]
597         fldd    d0 , [ AO ]
598         fldd    d1 , [ AO, #8 ]
599         fldd    d2 , [ AO, #16 ]
600         fldd    d3 , [ AO, #24 ]
601         fldd    d8 , [ BO ]
602         fldd    d9 , [ BO, #8 ]
603
604         fmuld   d16  , d0,  d8
605         fmuld   d24  , d1,  d9
606         fmuld   d17  , d0,  d9
607         fmuld   d25  , d1,  d8
608
609         fmuld   d18  , d2,  d8
610         fmuld   d26  , d3,  d9
611         fmuld   d19  , d2,  d9
612         fmuld   d27  , d3,  d8
613
614         add     BO , BO, #16
615         add     AO , AO, #32
616
617         pld     [ BO , #B_PRE ]
618         pld     [ AO , #A_PRE ]
619
620         fldd    d4 , [ AO, #0 ]
621         fldd    d5 , [ AO, #8 ]
622         fldd    d6 , [ AO, #16 ]
623         fldd    d7 , [ AO, #24 ]
624
625         fldd    d12, [ BO ]
626         fldd    d13, [ BO, #8 ]
627
628         add     BO , BO, #16
629         add     AO , AO, #32
630 .endm
631
632
633
634 .macro KERNEL2x1_M1
635         pld     [ AO , #A_PRE ]
636         pld     [ BO , #B_PRE ]
637
638         fmacd   d16  , d0,  d8
639         fmacd   d24  , d1,  d9
640         fmacd   d17  , d0,  d9
641         fmacd   d25  , d1,  d8
642
643         fmacd   d18  , d2,  d8
644         fmacd   d26  , d3,  d9
645         fmacd   d19  , d2,  d9
646         fmacd   d27  , d3,  d8
647
648         fldd    d4 , [ AO, #0 ]
649         fldd    d5 , [ AO, #8 ]
650         fldd    d6 , [ AO, #16 ]
651         fldd    d7 , [ AO, #24 ]
652
653         fldd    d12, [ BO ]
654         fldd    d13, [ BO, #8 ]
655
656         add     BO , BO, #16
657         add     AO , AO, #32
658 .endm
659
660 .macro KERNEL2x1_M2
661         pld     [ AO , #A_PRE ]
662         pld     [ BO , #B_PRE ]
663
664         fmacd   d16  , d4,  d12
665         fmacd   d24  , d5,  d13
666         fmacd   d17  , d4,  d13
667         fmacd   d25  , d5,  d12
668
669         fmacd   d18  , d6,  d12
670         fmacd   d26  , d7,  d13
671         fmacd   d19  , d6,  d13
672         fmacd   d27  , d7,  d12
673
674         fldd    d0 , [ AO, #0 ]
675         fldd    d1 , [ AO, #8 ]
676         fldd    d2 , [ AO, #16 ]
677         fldd    d3 , [ AO, #24 ]
678
679         fldd    d8 , [ BO ]
680         fldd    d9 , [ BO, #8 ]
681
682         add     BO , BO, #16
683         add     AO , AO, #32
684 .endm
685
686
687 .macro KERNEL2x1_E
688
689         fmacd   d16  , d4,  d12
690         fmacd   d24  , d5,  d13
691         fmacd   d17  , d4,  d13
692         fmacd   d25  , d5,  d12
693
694         fmacd   d18  , d6,  d12
695         fmacd   d26  , d7,  d13
696         fmacd   d19  , d6,  d13
697         fmacd   d27  , d7,  d12
698
699 .endm
700
701 .macro KERNEL2x1_SUB
702
703         pld     [ AO , #A_PRE ]
704         pld     [ BO , #B_PRE ]
705         fldd    d0 , [ AO ]
706         fldd    d1 , [ AO, #8 ]
707         fldd    d2 , [ AO, #16 ]
708         fldd    d3 , [ AO, #24 ]
709         fldd    d8 , [ BO ]
710         fldd    d9 , [ BO, #8 ]
711
712         fmacd   d16  , d0,  d8
713         fmacd   d24  , d1,  d9
714         fmacd   d17  , d0,  d9
715         fmacd   d25  , d1,  d8
716
717         fmacd   d18  , d2,  d8
718         fmacd   d26  , d3,  d9
719         fmacd   d19  , d2,  d9
720         fmacd   d27  , d3,  d8
721
722         add     BO , BO, #16
723         add     AO , AO, #32
724
725 .endm
726
727
728
729
730 .macro SAVE2x1
731
732         fldd            d0, ALPHA_R
733         fldd            d1, ALPHA_I
734
735         FADD_R  d16, d24 , d16
736         FADD_I  d17, d25 , d17
737         FADD_R  d18, d26 , d18
738         FADD_I  d19, d27 , d19
739
740         FMAC_R1 d4 , d0 , d16
741         FMAC_I1 d5 , d0 , d17
742         FMAC_R2 d4 , d1 , d17
743         FMAC_I2 d5 , d1 , d16
744
745         FMAC_R1 d6 , d0 , d18
746         FMAC_I1 d7 , d0 , d19
747         FMAC_R2 d6 , d1 , d19
748         FMAC_I2 d7 , d1 , d18
749
750         fstmiad CO1, { d4 - d7 }
751
752         add     CO1, CO1, #32
753
754 .endm
755
756 /******************************************************************************/
757
758 .macro INIT1x1
759
760         fldd                    d16 , FP_ZERO
761         vmov.f64                d17, d16
762         vmov.f64                d24, d16
763         vmov.f64                d25, d16
764
765 .endm
766
767 .macro KERNEL1x1_I
768         pld     [ AO , #A_PRE ]
769         pld     [ BO , #B_PRE ]
770         fldd    d0 , [ AO ]
771         fldd    d1 , [ AO, #8 ]
772         fldd    d8 , [ BO ]
773         fldd    d9 , [ BO, #8 ]
774
775         fmuld   d16  , d0,  d8
776         fmuld   d24  , d1,  d9
777         fmuld   d17  , d0,  d9
778         fmuld   d25  , d1,  d8
779
780         add     BO , BO, #16
781         add     AO , AO, #16
782
783         pld     [ BO , #B_PRE ]
784         pld     [ AO , #A_PRE ]
785
786         fldd    d4 , [ AO, #0 ]
787         fldd    d5 , [ AO, #8 ]
788
789         fldd    d12, [ BO ]
790         fldd    d13, [ BO, #8 ]
791
792         add     BO , BO, #16
793         add     AO , AO, #16
794 .endm
795
796
797
798 .macro KERNEL1x1_M1
799
800         fmacd   d16  , d0,  d8
801         fmacd   d24  , d1,  d9
802         fmacd   d17  , d0,  d9
803         fmacd   d25  , d1,  d8
804
805         fldd    d4 , [ AO, #0 ]
806         fldd    d5 , [ AO, #8 ]
807
808         fldd    d12, [ BO ]
809         fldd    d13, [ BO, #8 ]
810
811         add     BO , BO, #16
812         add     AO , AO, #16
813 .endm
814
815 .macro KERNEL1x1_M2
816
817         fmacd   d16  , d4,  d12
818         fmacd   d24  , d5,  d13
819         fmacd   d17  , d4,  d13
820         fmacd   d25  , d5,  d12
821
822         fldd    d0 , [ AO, #0 ]
823         fldd    d1 , [ AO, #8 ]
824
825         fldd    d8 , [ BO ]
826         fldd    d9 , [ BO, #8 ]
827
828         add     BO , BO, #16
829         add     AO , AO, #16
830 .endm
831
832
833 .macro KERNEL1x1_E
834
835         fmacd   d16  , d4,  d12
836         fmacd   d24  , d5,  d13
837         fmacd   d17  , d4,  d13
838         fmacd   d25  , d5,  d12
839
840 .endm
841
842 .macro KERNEL1x1_SUB
843
844         fldd    d0 , [ AO ]
845         fldd    d1 , [ AO, #8 ]
846         fldd    d8 , [ BO ]
847         fldd    d9 , [ BO, #8 ]
848
849         fmacd   d16  , d0,  d8
850         fmacd   d24  , d1,  d9
851         fmacd   d17  , d0,  d9
852         fmacd   d25  , d1,  d8
853
854         add     BO , BO, #16
855         add     AO , AO, #16
856
857 .endm
858
859
860
861
862 .macro SAVE1x1
863
864         fldd            d0, ALPHA_R
865         fldd            d1, ALPHA_I
866
867         FADD_R  d16, d24 , d16
868         FADD_I  d17, d25 , d17
869
870         FMAC_R1 d4 , d0 , d16
871         FMAC_I1 d5 , d0 , d17
872         FMAC_R2 d4 , d1 , d17
873         FMAC_I2 d5 , d1 , d16
874
875         fstmiad CO1, { d4 - d5 }
876
877         add     CO1, CO1, #16
878
879 .endm
880
881 /******************************************************************************/
882
883
884 /**************************************************************************************
885 * End of macro definitions
886 **************************************************************************************/
887
888         PROLOGUE
889
890         .align 5
891
892         push    {r4 - r9, fp}
893         add     fp, sp, #24
894         sub     sp, sp, #STACKSIZE                              // reserve stack
895
896 #if !defined(__ARM_PCS_VFP)
897         vldr    OLD_ALPHA_R, OLD_ALPHAR_SOFTFP
898         vldr    OLD_ALPHA_I, OLD_ALPHAI_SOFTFP
899         ldr     OLD_A, OLD_A_SOFTFP
900 #endif
901         str     OLD_M, M
902         str     OLD_N, N
903         str     OLD_K, K
904         str     OLD_A, A
905         vstr    OLD_ALPHA_R, ALPHA_R
906         vstr    OLD_ALPHA_I, ALPHA_I
907
908         sub     r3, fp, #128
909         vstm    r3, { d8 - d15}                                 // store floating point registers
910
911         movs    r4, #0
912         str     r4, FP_ZERO
913         str     r4, FP_ZERO_1
914
915         ldr     r3, OLD_LDC
916         lsl     r3, r3, #4                                      // ldc = ldc * 8 * 2
917         str     r3, LDC
918
919         ldr     r3, OFFSET
920 #ifndef LEFT
921         neg     r3 , r3
922 #endif
923         str     r3 , KK
924
925         ldr     BC, B
926
927         ldr     J, N
928         asrs    J, J, #1                                        // J = J / 2
929         ble     _L1_BEGIN
930
931 _L2_BEGIN:
932
933         ldr     CO1, C                                          // CO1 = C
934         ldr     r4 , LDC
935         lsl     r4 , r4 , #1                                    // LDC * 2
936         add     r3 , r4, CO1
937         str     r3 , C                                          // store C
938
939 #if defined(LEFT)
940         ldr     r3 , OFFSET
941         str     r3 , KK
942 #endif
943
944
945         ldr     AO, A                                           // AO = A
946         pld     [AO , #A_PRE-64]
947         pld     [AO , #A_PRE-32]
948
949
950
951 _L2_M2_BEGIN:
952
953         ldr     I, M
954         asrs    I, I, #1                                        // I = I / 2
955         ble     _L2_M1_BEGIN
956
957 _L2_M2_20:
958
959 #if  (defined(LEFT) &&  defined(TRANSA)) || \
960     (!defined(LEFT) && !defined(TRANSA))
961
962         mov     BO, BC
963 #else
964         mov     BO, BC
965         ldr     r3 , KK
966         lsls    r4 , r3 , #5                                    // 2 * 8 * 2 double values
967         add     BO , BO , r4
968         lsls    r4 , r3 , #5                                    // 2 * 8 * 2 double values
969         add     AO , AO , r4
970
971 #endif
972
973 #ifndef TRMMKERNEL
974         ldr     K1, K
975 #elif (defined(LEFT) && !defined(TRANSA)) || (!defined(LEFT) && defined(TRANSA))
976         ldr     K1, K
977         ldr     r3, KK
978         sub     K1, K1, r3
979         str     K1, KKK
980 #else
981         ldr     K1, KK
982 #ifdef LEFT
983         add     K1, K1, #2        // number of values in AO
984 #else
985         add     K1, K1, #2        // number of values in BO
986 #endif
987         str     K1, KKK
988 #endif
989
990
991         asrs    L , K1, #3                                      // L = L / 8
992         cmp     L , #3
993         blt     _L2_M2_30
994         .align 5
995
996
997
998         KERNEL2x2_I
999         KERNEL2x2_M2
1000         KERNEL2x2_M1
1001         KERNEL2x2_M2
1002
1003         KERNEL2x2_M1
1004         KERNEL2x2_M2
1005         KERNEL2x2_M1
1006         KERNEL2x2_M2
1007
1008         sub     L, L, #2
1009
1010 _L2_M2_22:
1011
1012         KERNEL2x2_M1
1013         KERNEL2x2_M2
1014         KERNEL2x2_M1
1015         KERNEL2x2_M2
1016
1017         KERNEL2x2_M1
1018         KERNEL2x2_M2
1019         KERNEL2x2_M1
1020         KERNEL2x2_M2
1021
1022         subs    L, L, #1
1023         bgt     _L2_M2_22
1024
1025         KERNEL2x2_M1
1026         KERNEL2x2_M2
1027         KERNEL2x2_M1
1028         KERNEL2x2_M2
1029
1030         KERNEL2x2_M1
1031         KERNEL2x2_M2
1032         KERNEL2x2_M1
1033         KERNEL2x2_E
1034
1035         b        _L2_M2_44
1036
1037
1038 _L2_M2_30:
1039         tst     L, #3
1040         ble     _L2_M2_40
1041
1042         tst     L, #2
1043         ble     _L2_M2_32
1044
1045         KERNEL2x2_I
1046         KERNEL2x2_M2
1047         KERNEL2x2_M1
1048         KERNEL2x2_M2
1049
1050         KERNEL2x2_M1
1051         KERNEL2x2_M2
1052         KERNEL2x2_M1
1053         KERNEL2x2_M2
1054
1055         KERNEL2x2_M1
1056         KERNEL2x2_M2
1057         KERNEL2x2_M1
1058         KERNEL2x2_M2
1059
1060
1061         KERNEL2x2_M1
1062         KERNEL2x2_M2
1063         KERNEL2x2_M1
1064         KERNEL2x2_E
1065
1066         b        _L2_M2_44
1067
1068 _L2_M2_32:
1069
1070         tst     L, #1
1071         ble     _L2_M2_40
1072
1073         KERNEL2x2_I
1074         KERNEL2x2_M2
1075         KERNEL2x2_M1
1076         KERNEL2x2_M2
1077
1078         KERNEL2x2_M1
1079         KERNEL2x2_M2
1080         KERNEL2x2_M1
1081         KERNEL2x2_E
1082
1083         b        _L2_M2_44
1084
1085
1086 _L2_M2_40:
1087
1088         INIT2x2
1089
1090
1091 _L2_M2_44:
1092
1093         ands    L , K1, #7                                      // L = L % 8
1094         ble     _L2_M2_100
1095
1096 _L2_M2_46:
1097
1098         KERNEL2x2_SUB
1099
1100         subs    L, L, #1
1101         bne     _L2_M2_46
1102
1103 _L2_M2_100:
1104
1105         SAVE2x2
1106
1107 #if  (defined(LEFT) &&  defined(TRANSA)) || \
1108     (!defined(LEFT) && !defined(TRANSA))
1109         ldr     r3 , K
1110         ldr     r4 , KKK
1111         sub     r3 , r3 , r4
1112         lsls    r4 , r3 , #5                    // 2 * 8 * 2 double values
1113         add     BO , BO , r4
1114         lsls    r4 , r3 , #5                    // 2 * 8 * 2 double values
1115         add     AO , AO , r4
1116 #endif
1117
1118 #if defined(LEFT)
1119         ldr     r3 , KK
1120         add     r3 , r3 , #2                    // number of values in AO
1121         str     r3 , KK
1122 #endif
1123
1124
1125
1126
1127 _L2_M2_END:
1128
1129         subs    I, I, #1
1130         bne     _L2_M2_20
1131
1132
1133 _L2_M1_BEGIN:
1134
1135         ldr     I, M
1136         tst     I, #1                                   // I = I % 2
1137         ble     _L2_END
1138
1139 _L2_M1_20:
1140
1141         INIT1x2
1142
1143 #if  (defined(LEFT) &&  defined(TRANSA)) || \
1144     (!defined(LEFT) && !defined(TRANSA))
1145
1146         mov     BO, BC
1147 #else
1148         mov     BO, BC
1149         ldr     r3 , KK
1150         lsls    r4 , r3 , #5                                    // 2 * 8 * 2 double values
1151         add     BO , BO , r4
1152         lsls    r4 , r3 , #4                                    // 1 * 8 * 2 double values
1153         add     AO , AO , r4
1154
1155 #endif
1156
1157 #ifndef TRMMKERNEL
1158         ldr     K1, K
1159 #elif (defined(LEFT) && !defined(TRANSA)) || (!defined(LEFT) && defined(TRANSA))
1160         ldr     K1, K
1161         ldr     r3, KK
1162         sub     K1, K1, r3
1163         str     K1, KKK
1164 #else
1165         ldr     K1, KK
1166 #ifdef LEFT
1167         add     K1, K1, #1        // number of values in AO
1168 #else
1169         add     K1, K1, #2        // number of values in BO
1170 #endif
1171         str     K1, KKK
1172 #endif
1173
1174         asrs    L , K1, #3                                      // L = L / 8
1175         ble     _L2_M1_40
1176
1177 _L2_M1_22:
1178
1179         KERNEL1x2_SUB
1180         KERNEL1x2_SUB
1181         KERNEL1x2_SUB
1182         KERNEL1x2_SUB
1183
1184         KERNEL1x2_SUB
1185         KERNEL1x2_SUB
1186         KERNEL1x2_SUB
1187         KERNEL1x2_SUB
1188
1189         subs    L, L, #1
1190         bgt     _L2_M1_22
1191
1192
1193 _L2_M1_40:
1194
1195         ands    L , K1, #7                                      // L = L % 8
1196         ble     _L2_M1_100
1197
1198 _L2_M1_42:
1199
1200         KERNEL1x2_SUB
1201
1202         subs    L, L, #1
1203         bgt     _L2_M1_42
1204
1205 _L2_M1_100:
1206
1207         SAVE1x2
1208
1209 #if  (defined(LEFT) &&  defined(TRANSA)) || \
1210     (!defined(LEFT) && !defined(TRANSA))
1211         ldr     r3 , K
1212         ldr     r4 , KKK
1213         sub     r3 , r3 , r4
1214         lsls    r4 , r3 , #5                    // 2 * 8 * 2 double values
1215         add     BO , BO , r4
1216         lsls    r4 , r3 , #4                    // 1 * 8 * 2 double values
1217         add     AO , AO , r4
1218 #endif
1219
1220 #if defined(LEFT)
1221         ldr     r3 , KK
1222         add     r3 , r3 , #1                    // number of values in AO
1223         str     r3 , KK
1224 #endif
1225
1226
1227
1228 _L2_END:
1229
1230         mov     r3, BC
1231         ldr     r4, K
1232         lsl     r4, r4, #5                                      // k * 2 * 8 * 2
1233         add     r3, r3, r4                                      // B = B + K * 4 * 8
1234         mov     BC, r3
1235
1236 #if !defined(LEFT)
1237         ldr     r3 , KK
1238         add     r3 , r3 , #2                                    // number of values in BO
1239         str     r3 , KK
1240 #endif
1241
1242
1243         subs    J , #1                                          // j--
1244         bgt     _L2_BEGIN
1245
1246
1247
1248 /*********************************************************************************************/
1249
1250 _L1_BEGIN:
1251
1252         ldr     J , N
1253         tst     J , #1
1254         ble     _L999
1255
1256
1257         ldr     CO1, C                                          // CO1 = C
1258         ldr     r4 , LDC
1259         add     r3 , r4, CO1
1260         str     r3 , C                                          // store C
1261
1262 #if defined(LEFT)
1263         ldr     r3 , OFFSET
1264         str     r3 , KK
1265 #endif
1266
1267
1268         ldr     AO, A                                           // AO = A
1269
1270 _L1_M2_BEGIN:
1271
1272         ldr     I, M
1273         asrs    I, I, #1                                        // I = I / 2
1274         ble     _L1_M1_BEGIN
1275
1276 _L1_M2_20:
1277
1278 #if  (defined(LEFT) &&  defined(TRANSA)) || \
1279     (!defined(LEFT) && !defined(TRANSA))
1280
1281         mov     BO, BC
1282 #else
1283         mov     BO, BC
1284         ldr     r3 , KK
1285         lsls    r4 , r3 , #4                                    // 1 * 8 * 2 double values
1286         add     BO , BO , r4
1287         lsls    r4 , r3 , #5                                    // 2 * 8 * 2 double values
1288         add     AO , AO , r4
1289
1290 #endif
1291
1292 #ifndef TRMMKERNEL
1293         ldr     K1, K
1294 #elif (defined(LEFT) && !defined(TRANSA)) || (!defined(LEFT) && defined(TRANSA))
1295         ldr     K1, K
1296         ldr     r3, KK
1297         sub     K1, K1, r3
1298         str     K1, KKK
1299 #else
1300         ldr     K1, KK
1301 #ifdef LEFT
1302         add     K1, K1, #2        // number of values in AO
1303 #else
1304         add     K1, K1, #1        // number of values in BO
1305 #endif
1306         str     K1, KKK
1307 #endif
1308
1309         asrs    L , K1, #3                                      // L = L / 8
1310         cmp     L , #3
1311         blt     _L1_M2_30
1312         .align 5
1313
1314
1315
1316         KERNEL2x1_I
1317         KERNEL2x1_M2
1318         KERNEL2x1_M1
1319         KERNEL2x1_M2
1320
1321         KERNEL2x1_M1
1322         KERNEL2x1_M2
1323         KERNEL2x1_M1
1324         KERNEL2x1_M2
1325
1326         sub     L, L, #2
1327
1328 _L1_M2_22:
1329
1330         KERNEL2x1_M1
1331         KERNEL2x1_M2
1332         KERNEL2x1_M1
1333         KERNEL2x1_M2
1334
1335         KERNEL2x1_M1
1336         KERNEL2x1_M2
1337         KERNEL2x1_M1
1338         KERNEL2x1_M2
1339
1340         subs    L, L, #1
1341         bgt     _L1_M2_22
1342
1343         KERNEL2x1_M1
1344         KERNEL2x1_M2
1345         KERNEL2x1_M1
1346         KERNEL2x1_M2
1347
1348         KERNEL2x1_M1
1349         KERNEL2x1_M2
1350         KERNEL2x1_M1
1351         KERNEL2x1_E
1352
1353         b        _L1_M2_44
1354
1355
1356 _L1_M2_30:
1357         tst     L, #3
1358         ble     _L1_M2_40
1359
1360         tst     L, #2
1361         ble     _L1_M2_32
1362
1363         KERNEL2x1_I
1364         KERNEL2x1_M2
1365         KERNEL2x1_M1
1366         KERNEL2x1_M2
1367
1368         KERNEL2x1_M1
1369         KERNEL2x1_M2
1370         KERNEL2x1_M1
1371         KERNEL2x1_M2
1372
1373         KERNEL2x1_M1
1374         KERNEL2x1_M2
1375         KERNEL2x1_M1
1376         KERNEL2x1_M2
1377
1378
1379         KERNEL2x1_M1
1380         KERNEL2x1_M2
1381         KERNEL2x1_M1
1382         KERNEL2x1_E
1383
1384         b        _L1_M2_44
1385
1386 _L1_M2_32:
1387
1388         tst     L, #1
1389         ble     _L1_M2_40
1390
1391         KERNEL2x1_I
1392         KERNEL2x1_M2
1393         KERNEL2x1_M1
1394         KERNEL2x1_M2
1395
1396         KERNEL2x1_M1
1397         KERNEL2x1_M2
1398         KERNEL2x1_M1
1399         KERNEL2x1_E
1400
1401         b        _L1_M2_44
1402
1403
1404 _L1_M2_40:
1405
1406         INIT2x1
1407
1408
1409 _L1_M2_44:
1410
1411         ands    L , K1, #7                                      // L = L % 8
1412         ble     _L1_M2_100
1413
1414 _L1_M2_46:
1415
1416         KERNEL2x1_SUB
1417
1418         subs    L, L, #1
1419         bne     _L1_M2_46
1420
1421 _L1_M2_100:
1422
1423         SAVE2x1
1424
1425 #if  (defined(LEFT) &&  defined(TRANSA)) || \
1426     (!defined(LEFT) && !defined(TRANSA))
1427         ldr     r3 , K
1428         ldr     r4 , KKK
1429         sub     r3 , r3 , r4
1430         lsls    r4 , r3 , #4                    // 1 * 8 * 2 double values
1431         add     BO , BO , r4
1432         lsls    r4 , r3 , #5                    // 2 * 8 * 2 double values
1433         add     AO , AO , r4
1434 #endif
1435
1436 #if defined(LEFT)
1437         ldr     r3 , KK
1438         add     r3 , r3 , #2                    // number of values in AO
1439         str     r3 , KK
1440 #endif
1441
1442
1443
1444 _L1_M2_END:
1445
1446         subs    I, I, #1
1447         bne     _L1_M2_20
1448
1449
1450 _L1_M1_BEGIN:
1451
1452         ldr     I, M
1453         tst     I, #1                                   // I = I % 2
1454         ble     _L1_END
1455
1456 _L1_M1_20:
1457
1458         INIT1x1
1459
1460 #if  (defined(LEFT) &&  defined(TRANSA)) || \
1461     (!defined(LEFT) && !defined(TRANSA))
1462
1463         mov     BO, BC
1464 #else
1465         mov     BO, BC
1466         ldr     r3 , KK
1467         lsls    r4 , r3 , #4                                    // 1 * 8 * 2 double values
1468         add     BO , BO , r4
1469         lsls    r4 , r3 , #4                                    // 1 * 8 * 2 double values
1470         add     AO , AO , r4
1471
1472 #endif
1473
1474 #ifndef TRMMKERNEL
1475         ldr     K1, K
1476 #elif (defined(LEFT) && !defined(TRANSA)) || (!defined(LEFT) && defined(TRANSA))
1477         ldr     K1, K
1478         ldr     r3, KK
1479         sub     K1, K1, r3
1480         str     K1, KKK
1481 #else
1482         ldr     K1, KK
1483 #ifdef LEFT
1484         add     K1, K1, #1        // number of values in AO
1485 #else
1486         add     K1, K1, #1        // number of values in BO
1487 #endif
1488         str     K1, KKK
1489 #endif
1490
1491         asrs    L , K1, #3                                      // L = L / 8
1492         ble     _L1_M1_40
1493
1494 _L1_M1_22:
1495
1496         KERNEL1x1_SUB
1497         KERNEL1x1_SUB
1498         KERNEL1x1_SUB
1499         KERNEL1x1_SUB
1500
1501         KERNEL1x1_SUB
1502         KERNEL1x1_SUB
1503         KERNEL1x1_SUB
1504         KERNEL1x1_SUB
1505
1506         subs    L, L, #1
1507         bgt     _L1_M1_22
1508
1509
1510 _L1_M1_40:
1511
1512         ands    L , K1, #7                                      // L = L % 8
1513         ble     _L1_M1_100
1514
1515 _L1_M1_42:
1516
1517         KERNEL1x1_SUB
1518
1519         subs    L, L, #1
1520         bgt     _L1_M1_42
1521
1522 _L1_M1_100:
1523
1524         SAVE1x1
1525
1526
1527 #if  (defined(LEFT) &&  defined(TRANSA)) || \
1528     (!defined(LEFT) && !defined(TRANSA))
1529         ldr     r3 , K
1530         ldr     r4 , KKK
1531         sub     r3 , r3 , r4
1532         lsls    r4 , r3 , #4                    // 1 * 8 * 2 double values
1533         add     BO , BO , r4
1534         lsls    r4 , r3 , #4                    // 1 * 8 * 2 double values
1535         add     AO , AO , r4
1536 #endif
1537
1538 #if defined(LEFT)
1539         ldr     r3 , KK
1540         add     r3 , r3 , #1                    // number of values in AO
1541         str     r3 , KK
1542 #endif
1543
1544
1545
1546 _L1_END:
1547
1548
1549
1550 _L999:
1551
1552         sub     r3, fp, #128
1553         vldm    r3, { d8 - d15}                                 // restore floating point registers
1554
1555         movs    r0, #0                                          // set return value
1556         sub     sp, fp, #24
1557         pop     {r4 - r9, fp}
1558         bx      lr
1559
1560         EPILOGUE
1561