Remove all trailing whitespace except lapack-netlib
[platform/upstream/openblas.git] / kernel / arm / zgemv_n_vfp.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/11/29 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_LDA         [fp, #0 ]
42 #define X               [fp, #4 ]
43 #define OLD_INC_X       [fp, #8 ]
44 #define Y               [fp, #12 ]
45 #define OLD_INC_Y       [fp, #16 ]
46 #define OLD_A           r3
47 #define OLD_M           r0
48
49 #define AO1     r0
50 #define N       r1
51 #define J       r2
52
53 #define AO2     r4
54 #define XO      r5
55 #define YO      r6
56 #define LDA     r7
57 #define INC_X   r8
58 #define INC_Y   r9
59
60 #define I       r12
61
62 #define ALPHA_I [fp, #-236]
63 #define ALPHA_R [fp, #-244]
64
65 #define M       [fp, #-252 ]
66 #define A       [fp, #-256 ]
67
68
69 #define X_PRE   64
70 #define Y_PRE   0
71 #define A_PRE   0
72
73 /**************************************************************************************/
74
75 #if !defined(CONJ) && !defined(XCONJ)
76
77         #define KMAC_R  fnmacd
78         #define KMAC_I  fmacd
79
80         #define FMAC_R1 fmacd
81         #define FMAC_R2 fnmacd
82         #define FMAC_I1 fmacd
83         #define FMAC_I2 fmacd
84
85 #elif defined(CONJ) && !defined(XCONJ)
86
87         #define KMAC_R  fmacd
88         #define KMAC_I  fnmacd
89
90         #define FMAC_R1 fmacd
91         #define FMAC_R2 fnmacd
92         #define FMAC_I1 fmacd
93         #define FMAC_I2 fmacd
94
95 #elif !defined(CONJ) && defined(XCONJ)
96
97         #define KMAC_R  fmacd
98         #define KMAC_I  fnmacd
99
100         #define FMAC_R1 fmacd
101         #define FMAC_R2 fmacd
102         #define FMAC_I1 fnmacd
103         #define FMAC_I2 fmacd
104
105 #else
106
107         #define KMAC_R  fnmacd
108         #define KMAC_I  fmacd
109
110         #define FMAC_R1 fmacd
111         #define FMAC_R2 fmacd
112         #define FMAC_I1 fnmacd
113         #define FMAC_I2 fmacd
114
115 #endif
116
117 .macro INIT_F4
118
119         pld     [ YO, #Y_PRE ]
120         vsub.f64                d8 , d8 , d8
121         vmov.f64                d9 , d8
122         vmov.f64                d10, d8
123         vmov.f64                d11, d8
124         vmov.f64                d12, d8
125         vmov.f64                d13, d8
126         vmov.f64                d14, d8
127         vmov.f64                d15, d8
128
129 .endm
130
131 .macro KERNEL_F4X4
132
133         pld     [ XO, #X_PRE ]
134         KERNEL_F4X1
135         KERNEL_F4X1
136         pld     [ XO, #X_PRE ]
137         KERNEL_F4X1
138         KERNEL_F4X1
139
140 .endm
141
142 .macro KERNEL_F4X1
143
144         fldd    d0 , [ AO1 ]
145
146         fldd    d4 , [ XO ]
147         fldd    d5 , [ XO, #8 ]
148
149         pld     [ AO2, #A_PRE ]
150
151         fldd    d1 , [ AO1, #8  ]
152         fmacd   d8  , d0,  d4
153         fldd    d2 , [ AO1, #16 ]
154         fmacd   d9  , d0,  d5
155         fldd    d3 , [ AO1, #24 ]
156         fmacd   d10 , d2,  d4
157         fldd    d0 , [ AO1, #32 ]
158         fmacd   d11 , d2,  d5
159
160         KMAC_R  d8  , d1,  d5
161         KMAC_I  d9  , d1,  d4
162         KMAC_R  d10 , d3,  d5
163         fldd    d1 , [ AO1, #40 ]
164         KMAC_I  d11 , d3,  d4
165
166         fldd    d2 , [ AO1, #48 ]
167
168         fmacd   d12 , d0,  d4
169         fldd    d3 , [ AO1, #56 ]
170         fmacd   d13 , d0,  d5
171         pld     [ AO2, #A_PRE+32 ]
172         fmacd   d14 , d2,  d4
173         fmacd   d15 , d2,  d5
174
175         KMAC_R  d12 , d1,  d5
176         add     XO , XO, #16
177         KMAC_I  d13 , d1,  d4
178         add     AO1 , AO1, LDA
179         KMAC_R  d14 , d3,  d5
180         add     AO2 , AO2, LDA
181         KMAC_I  d15 , d3,  d4
182
183 .endm
184
185 .macro SAVE_F4
186
187         fldd            d0, ALPHA_R
188         fldd            d1, ALPHA_I
189
190         fldmiad YO, { d4 - d7 }
191
192         FMAC_R1 d4 , d0 , d8
193         FMAC_I1 d5 , d0 , d9
194         FMAC_R2 d4 , d1 , d9
195         FMAC_I2 d5 , d1 , d8
196
197         FMAC_R1 d6 , d0 , d10
198         FMAC_I1 d7 , d0 , d11
199         FMAC_R2 d6 , d1 , d11
200         FMAC_I2 d7 , d1 , d10
201
202         fstmiad YO!, { d4 - d7 }
203
204         fldmiad YO, { d4 - d7 }
205
206         FMAC_R1 d4 , d0 , d12
207         FMAC_I1 d5 , d0 , d13
208         FMAC_R2 d4 , d1 , d13
209         FMAC_I2 d5 , d1 , d12
210
211         FMAC_R1 d6 , d0 , d14
212         FMAC_I1 d7 , d0 , d15
213         FMAC_R2 d6 , d1 , d15
214         FMAC_I2 d7 , d1 , d14
215
216         fstmiad YO!, { d4 - d7 }
217
218 .endm
219
220
221
222
223 .macro INIT_F1
224
225         vsub.f64                d8 , d8 , d8
226         vmov.f64                d9 , d8
227
228 .endm
229
230 .macro KERNEL_F1X1
231
232         fldd    d0 , [ AO1 ]
233         fldd    d1 , [ AO1, #8 ]
234
235         fldd    d4 , [ XO ]
236         fldd    d5 , [ XO, #8 ]
237
238         fmacd   d8  , d0,  d4
239         fmacd   d9  , d0,  d5
240
241         KMAC_R  d8  , d1,  d5
242         KMAC_I  d9  , d1,  d4
243
244         add     XO , XO, #16
245         add     AO1 , AO1, LDA
246
247
248 .endm
249
250 .macro SAVE_F1
251
252         fldd            d0, ALPHA_R
253         fldd            d1, ALPHA_I
254
255         fldmiad YO, { d4 - d5 }
256
257         FMAC_R1 d4 , d0 , d8
258         FMAC_I1 d5 , d0 , d9
259         FMAC_R2 d4 , d1 , d9
260         FMAC_I2 d5 , d1 , d8
261
262         fstmiad YO, { d4 - d5 }
263
264         add     YO, YO, #16
265
266 .endm
267
268 /****************************************************************************************/
269
270 .macro INIT_S4
271
272         vsub.f64                d8 , d8 , d8
273         vmov.f64                d9 , d8
274         vmov.f64                d10, d8
275         vmov.f64                d11, d8
276         vmov.f64                d12, d8
277         vmov.f64                d13, d8
278         vmov.f64                d14, d8
279         vmov.f64                d15, d8
280
281 .endm
282
283 .macro KERNEL_S4X4
284
285         KERNEL_S4X1
286         KERNEL_S4X1
287         KERNEL_S4X1
288         KERNEL_S4X1
289
290 .endm
291
292 .macro KERNEL_S4X1
293
294         fldd    d0 , [ AO1 ]
295         fldd    d1 , [ AO1, #8  ]
296         fldd    d2 , [ AO1, #16 ]
297         fldd    d3 , [ AO1, #24 ]
298
299         fldd    d4 , [ XO ]
300         fldd    d5 , [ XO, #8 ]
301
302         fmacd   d8  , d0,  d4
303         fmacd   d9  , d0,  d5
304         fmacd   d10 , d2,  d4
305         fmacd   d11 , d2,  d5
306
307         KMAC_R  d8  , d1,  d5
308         KMAC_I  d9  , d1,  d4
309         KMAC_R  d10 , d3,  d5
310         KMAC_I  d11 , d3,  d4
311
312         fldd    d0 , [ AO1, #32 ]
313         fldd    d1 , [ AO1, #40 ]
314         fldd    d2 , [ AO1, #48 ]
315         fldd    d3 , [ AO1, #56 ]
316
317         fmacd   d12 , d0,  d4
318         fmacd   d13 , d0,  d5
319         fmacd   d14 , d2,  d4
320         fmacd   d15 , d2,  d5
321
322         KMAC_R  d12 , d1,  d5
323         KMAC_I  d13 , d1,  d4
324         KMAC_R  d14 , d3,  d5
325         KMAC_I  d15 , d3,  d4
326
327         add     XO , XO, INC_X
328         add     AO1 , AO1, LDA
329         add     AO2 , AO2, LDA
330
331 .endm
332
333 .macro SAVE_S4
334
335         fldd            d0, ALPHA_R
336         fldd            d1, ALPHA_I
337
338         fldmiad YO, { d4 - d5 }
339
340         FMAC_R1 d4 , d0 , d8
341         FMAC_I1 d5 , d0 , d9
342         FMAC_R2 d4 , d1 , d9
343         FMAC_I2 d5 , d1 , d8
344
345         fstmiad YO, { d4 - d5 }
346
347         add     YO, YO, INC_Y
348
349         fldmiad YO, { d6 - d7 }
350
351         FMAC_R1 d6 , d0 , d10
352         FMAC_I1 d7 , d0 , d11
353         FMAC_R2 d6 , d1 , d11
354         FMAC_I2 d7 , d1 , d10
355
356         fstmiad YO, { d6 - d7 }
357
358         add     YO, YO, INC_Y
359
360         fldmiad YO, { d4 - d5 }
361
362         FMAC_R1 d4 , d0 , d12
363         FMAC_I1 d5 , d0 , d13
364         FMAC_R2 d4 , d1 , d13
365         FMAC_I2 d5 , d1 , d12
366
367         fstmiad YO, { d4 - d5 }
368
369         add     YO, YO, INC_Y
370
371         fldmiad YO, { d6 - d7 }
372
373         FMAC_R1 d6 , d0 , d14
374         FMAC_I1 d7 , d0 , d15
375         FMAC_R2 d6 , d1 , d15
376         FMAC_I2 d7 , d1 , d14
377
378         fstmiad YO, { d6 - d7 }
379
380         add     YO, YO, INC_Y
381
382 .endm
383
384
385
386
387 .macro INIT_S1
388
389         vsub.f64                d8 , d8 , d8
390         vmov.f64                d9 , d8
391
392 .endm
393
394 .macro KERNEL_S1X1
395
396         fldd    d0 , [ AO1 ]
397         fldd    d1 , [ AO1, #8 ]
398
399         fldd    d4 , [ XO ]
400         fldd    d5 , [ XO, #8 ]
401
402         fmacd   d8  , d0,  d4
403         fmacd   d9  , d0,  d5
404
405         KMAC_R  d8  , d1,  d5
406         KMAC_I  d9  , d1,  d4
407
408         add     XO , XO, INC_X
409         add     AO1 , AO1, LDA
410
411
412 .endm
413
414 .macro SAVE_S1
415
416         fldd            d0, ALPHA_R
417         fldd            d1, ALPHA_I
418
419         fldmiad YO, { d4 - d5 }
420
421         FMAC_R1 d4 , d0 , d8
422         FMAC_I1 d5 , d0 , d9
423         FMAC_R2 d4 , d1 , d9
424         FMAC_I2 d5 , d1 , d8
425
426         fstmiad YO, { d4 - d5 }
427
428         add     YO, YO, INC_Y
429
430 .endm
431
432
433
434 /**************************************************************************************
435 * End of macro definitions
436 **************************************************************************************/
437
438         PROLOGUE
439
440         .align 5
441         push    {r4 - r9 , fp}
442         add     fp, sp, #28
443         sub     sp, sp, #STACKSIZE                              // reserve stack
444
445         sub     r12, fp, #192
446
447 #if     defined(DOUBLE)
448         vstm    r12, { d8 - d15 }                                 // store floating point registers
449 #else
450         vstm    r12, { s8 - s15 }                                 // store floating point registers
451 #endif
452
453         cmp     OLD_M, #0
454         ble     zgemvn_kernel_L999
455
456         cmp     N, #0
457         ble     zgemvn_kernel_L999
458
459         str     OLD_A, A
460         str     OLD_M, M
461         vstr    d0 , ALPHA_R
462         vstr    d1 , ALPHA_I
463
464
465         ldr    INC_X , OLD_INC_X
466         ldr    INC_Y , OLD_INC_Y
467
468         cmp     INC_X, #0
469         beq     zgemvn_kernel_L999
470
471         cmp     INC_Y, #0
472         beq     zgemvn_kernel_L999
473
474         ldr     LDA, OLD_LDA
475
476
477 #if defined(DOUBLE)
478         lsl     LDA, LDA, #4                            // LDA * SIZE * 2
479 #else
480         lsl     LDA, LDA, #3                            // LDA * SIZE * 2
481 #endif
482
483         cmp     INC_X, #1
484         bne     zgemvn_kernel_S4_BEGIN
485
486         cmp     INC_Y, #1
487         bne     zgemvn_kernel_S4_BEGIN
488
489
490 zgemvn_kernel_F4_BEGIN:
491
492         ldr     YO , Y
493
494         ldr     I, M
495         asrs    I, I, #2                                        // I = M / 4
496         ble     zgemvn_kernel_F1_BEGIN
497
498 zgemvn_kernel_F4X4:
499
500         ldr     AO1, A
501         add     AO2, AO1, LDA
502         add     r3 , AO1, #64
503         str     r3 , A
504
505         add     AO2, AO2, LDA
506         add     AO2, AO2, LDA
507
508         ldr     XO , X
509
510         INIT_F4
511
512         asrs    J, N, #2                                        // J = N / 4
513         ble     zgemvn_kernel_F4X1
514
515
516 zgemvn_kernel_F4X4_10:
517
518         KERNEL_F4X4
519
520         subs    J, J, #1
521         bne     zgemvn_kernel_F4X4_10
522
523
524 zgemvn_kernel_F4X1:
525
526         ands    J, N , #3
527         ble     zgemvn_kernel_F4_END
528
529 zgemvn_kernel_F4X1_10:
530
531         KERNEL_F4X1
532
533         subs    J, J, #1
534         bne     zgemvn_kernel_F4X1_10
535
536
537 zgemvn_kernel_F4_END:
538
539         SAVE_F4
540
541         subs    I , I , #1
542         bne     zgemvn_kernel_F4X4
543
544
545 zgemvn_kernel_F1_BEGIN:
546
547         ldr     I, M
548         ands    I,  I , #3
549         ble     zgemvn_kernel_L999
550
551 zgemvn_kernel_F1X1:
552
553         ldr     AO1, A
554         add     r3, AO1, #16
555         str     r3, A
556
557         ldr     XO , X
558
559         INIT_F1
560
561         mov     J, N
562
563
564 zgemvn_kernel_F1X1_10:
565
566         KERNEL_F1X1
567
568         subs    J, J, #1
569         bne     zgemvn_kernel_F1X1_10
570
571
572 zgemvn_kernel_F1_END:
573
574         SAVE_F1
575
576         subs    I , I , #1
577         bne     zgemvn_kernel_F1X1
578
579         b       zgemvn_kernel_L999
580
581
582
583 /*************************************************************************************************************/
584
585 zgemvn_kernel_S4_BEGIN:
586
587 #if defined(DOUBLE)
588         lsl     INC_X, INC_X, #4                                // INC_X * SIZE * 2
589         lsl     INC_Y, INC_Y, #4                                // INC_Y * SIZE * 2
590 #else
591         lsl     INC_X, INC_X, #3                                // INC_X * SIZE * 2
592         lsl     INC_Y, INC_Y, #3                                // INC_Y * SIZE * 2
593 #endif
594
595         ldr     YO , Y
596
597         ldr     I, M
598         asrs    I, I, #2                                        // I = M / 4
599         ble     zgemvn_kernel_S1_BEGIN
600
601 zgemvn_kernel_S4X4:
602
603         ldr     AO1, A
604         add     AO2, AO1, LDA
605         add     r3 , AO1, #64
606         str     r3 , A
607
608         ldr     XO , X
609
610         INIT_S4
611
612         asrs    J, N, #2                                        // J = N / 4
613         ble     zgemvn_kernel_S4X1
614
615
616 zgemvn_kernel_S4X4_10:
617
618         KERNEL_S4X4
619
620         subs    J, J, #1
621         bne     zgemvn_kernel_S4X4_10
622
623
624 zgemvn_kernel_S4X1:
625
626         ands    J, N , #3
627         ble     zgemvn_kernel_S4_END
628
629 zgemvn_kernel_S4X1_10:
630
631         KERNEL_S4X1
632
633         subs    J, J, #1
634         bne     zgemvn_kernel_S4X1_10
635
636
637 zgemvn_kernel_S4_END:
638
639         SAVE_S4
640
641         subs    I , I , #1
642         bne     zgemvn_kernel_S4X4
643
644
645 zgemvn_kernel_S1_BEGIN:
646
647         ldr     I, M
648         ands    I,  I , #3
649         ble     zgemvn_kernel_L999
650
651 zgemvn_kernel_S1X1:
652
653         ldr     AO1, A
654         add     r3, AO1, #16
655         str     r3, A
656
657         ldr     XO , X
658
659         INIT_S1
660
661         mov     J, N
662
663
664 zgemvn_kernel_S1X1_10:
665
666         KERNEL_S1X1
667
668         subs    J, J, #1
669         bne     zgemvn_kernel_S1X1_10
670
671
672 zgemvn_kernel_S1_END:
673
674         SAVE_S1
675
676         subs    I , I , #1
677         bne     zgemvn_kernel_S1X1
678
679
680 /*************************************************************************************************************/
681
682 zgemvn_kernel_L999:
683
684         sub     r3, fp, #192
685
686 #if     defined(DOUBLE)
687         vldm    r3, { d8 - d15 }                                 // restore floating point registers
688 #else
689         vldm    r3, { s8 - s15 }                                 // restore floating point registers
690 #endif
691
692         mov     r0, #0          // set return value
693
694         sub     sp, fp, #28
695         pop     {r4 -r9 ,fp}
696         bx      lr
697
698         EPILOGUE
699