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