updated cgemv and zgemv kernels for armv6
[platform/upstream/openblas.git] / kernel / arm / cgemv_t_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_N           r1
48
49 #define M       r0
50 #define AO1     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 #define N       [fp, #-252 ]
67 #define A       [fp, #-256 ]
68
69
70 #define X_PRE   512
71 #define A_PRE   512
72
73 /**************************************************************************************
74 * Macro definitions
75 **************************************************************************************/
76
77 #if !defined(CONJ) && !defined(XCONJ)
78
79         #define KMAC_R  fnmacs
80         #define KMAC_I  fmacs
81
82         #define FMAC_R1 fmacs
83         #define FMAC_R2 fnmacs
84         #define FMAC_I1 fmacs
85         #define FMAC_I2 fmacs
86
87 #elif defined(CONJ) && !defined(XCONJ)
88
89         #define KMAC_R  fmacs
90         #define KMAC_I  fnmacs
91
92         #define FMAC_R1 fmacs
93         #define FMAC_R2 fnmacs
94         #define FMAC_I1 fmacs
95         #define FMAC_I2 fmacs
96
97 #elif !defined(CONJ) && defined(XCONJ)
98
99         #define KMAC_R  fmacs
100         #define KMAC_I  fnmacs
101
102         #define FMAC_R1 fmacs
103         #define FMAC_R2 fmacs
104         #define FMAC_I1 fnmacs
105         #define FMAC_I2 fmacs
106
107 #else
108
109         #define KMAC_R  fnmacs
110         #define KMAC_I  fmacs
111
112         #define FMAC_R1 fmacs
113         #define FMAC_R2 fmacs
114         #define FMAC_I1 fnmacs
115         #define FMAC_I2 fmacs
116
117 #endif
118
119
120
121 .macro INIT_F2
122
123         flds            s12, FP_ZERO
124         vmov.f32        s13, s12
125         vmov.f32        s14, s12
126         vmov.f32        s15, s12
127
128 .endm
129
130 .macro KERNEL_F2X4
131
132         KERNEL_F2X1
133         KERNEL_F2X1
134         KERNEL_F2X1
135         KERNEL_F2X1
136
137 .endm
138
139 .macro KERNEL_F2X1
140
141         fldmias XO! ,  { s2 - s3 }
142         fldmias AO1!,  { s4 - s5 }
143         fldmias AO2!,  { s8 - s9   }
144
145         fmacs   s12 , s4 , s2
146         fmacs   s13 , s4 , s3
147         KMAC_R  s12 , s5 , s3
148         KMAC_I  s13 , s5 , s2
149
150         fmacs   s14 , s8 , s2
151         fmacs   s15 , s8 , s3
152         KMAC_R  s14 , s9 , s3
153         KMAC_I  s15 , s9 , s2
154
155 .endm
156
157 .macro  SAVE_F2
158
159         fldmias YO,  { s4 - s7 }
160
161         FMAC_R1 s4 , s0 , s12
162         FMAC_I1 s5 , s0 , s13
163         FMAC_R2 s4 , s1 , s13
164         FMAC_I2 s5 , s1 , s12
165
166         FMAC_R1 s6 , s0 , s14
167         FMAC_I1 s7 , s0 , s15
168         FMAC_R2 s6 , s1 , s15
169         FMAC_I2 s7 , s1 , s14
170
171         fstmias YO!, { s4 - s7 }
172
173 .endm
174
175 /************************************************************************************************/
176
177 .macro INIT_F1
178
179         flds            s12, FP_ZERO
180         vmov.f32        s13, s12
181
182 .endm
183
184 .macro KERNEL_F1X4
185
186         KERNEL_F1X1
187         KERNEL_F1X1
188         KERNEL_F1X1
189         KERNEL_F1X1
190
191 .endm
192
193 .macro KERNEL_F1X1
194
195         fldmias XO! ,  { s2 - s3 }
196         fldmias AO1!,  { s4 - s5 }
197
198         fmacs   s12 , s4 , s2
199         fmacs   s13 , s4 , s3
200         KMAC_R  s12 , s5 , s3
201         KMAC_I  s13 , s5 , s2
202
203 .endm
204
205 .macro  SAVE_F1
206
207         fldmias YO,  { s4 - s5 }
208
209         FMAC_R1 s4 , s0 , s12
210         FMAC_I1 s5 , s0 , s13
211         FMAC_R2 s4 , s1 , s13
212         FMAC_I2 s5 , s1 , s12
213
214         fstmias YO!, { s4 - s5 }
215
216 .endm
217
218 /************************************************************************************************/
219
220 .macro INIT_S2
221
222         flds            s12, FP_ZERO
223         vmov.f32        s13, s12
224         vmov.f32        s14, s12
225         vmov.f32        s15, s12
226
227 .endm
228
229 .macro KERNEL_S2X4
230
231         KERNEL_S2X1
232         KERNEL_S2X1
233         KERNEL_S2X1
234         KERNEL_S2X1
235
236 .endm
237
238 .macro KERNEL_S2X1
239
240         fldmias XO  ,  { s2 - s3 }
241         fldmias AO1!,  { s4 - s5 }
242         fldmias AO2!,  { s8 - s9   }
243
244         fmacs   s12 , s4 , s2
245         fmacs   s13 , s4 , s3
246         KMAC_R  s12 , s5 , s3
247         KMAC_I  s13 , s5 , s2
248
249         fmacs   s14 , s8 , s2
250         fmacs   s15 , s8 , s3
251         KMAC_R  s14 , s9 , s3
252         KMAC_I  s15 , s9 , s2
253
254         add     XO, XO, INC_X
255
256 .endm
257
258 .macro  SAVE_S2
259
260         fldmias YO,  { s4 - s5 }
261
262         FMAC_R1 s4 , s0 , s12
263         FMAC_I1 s5 , s0 , s13
264         FMAC_R2 s4 , s1 , s13
265         FMAC_I2 s5 , s1 , s12
266
267         fstmias YO,  { s4 - s5 }
268
269         add     YO, YO, INC_Y
270
271         fldmias YO,  { s6 - s7 }
272
273         FMAC_R1 s6 , s0 , s14
274         FMAC_I1 s7 , s0 , s15
275         FMAC_R2 s6 , s1 , s15
276         FMAC_I2 s7 , s1 , s14
277
278         fstmias YO,  { s6 - s7 }
279
280         add     YO, YO, INC_Y
281
282 .endm
283
284 /************************************************************************************************/
285
286 .macro INIT_S1
287
288         flds            s12, FP_ZERO
289         vmov.f32        s13, s12
290
291 .endm
292
293 .macro KERNEL_S1X4
294
295         KERNEL_S1X1
296         KERNEL_S1X1
297         KERNEL_S1X1
298         KERNEL_S1X1
299
300 .endm
301
302 .macro KERNEL_S1X1
303
304         fldmias XO  ,  { s2 - s3 }
305         fldmias AO1!,  { s4 - s5 }
306
307         fmacs   s12 , s4 , s2
308         fmacs   s13 , s4 , s3
309         KMAC_R  s12 , s5 , s3
310         KMAC_I  s13 , s5 , s2
311
312         add     XO, XO, INC_X
313
314 .endm
315
316 .macro  SAVE_S1
317
318         fldmias YO,  { s4 - s5 }
319
320         FMAC_R1 s4 , s0 , s12
321         FMAC_I1 s5 , s0 , s13
322         FMAC_R2 s4 , s1 , s13
323         FMAC_I2 s5 , s1 , s12
324
325         fstmias YO,  { s4 - s5 }
326
327         add     YO, YO, INC_Y
328
329 .endm
330
331
332
333 /**************************************************************************************
334 * End of macro definitions
335 **************************************************************************************/
336
337         PROLOGUE
338
339         .align 5
340         push    {r4 - r9 , fp}
341         add     fp, sp, #28
342         sub     sp, sp, #STACKSIZE                              // reserve stack
343
344         sub     r12, fp, #192
345
346 #if     defined(DOUBLE)
347         vstm    r12, { d8 - d15 }                                 // store floating point registers
348 #else
349         vstm    r12, { s8 - s15 }                                 // store floating point registers
350 #endif
351
352         movs    r12, #0
353         str     r12, FP_ZERO
354         str     r12, FP_ZERO_1
355
356         cmp     M, #0
357         ble     cgemvt_kernel_L999
358
359         cmp     OLD_N, #0
360         ble     cgemvt_kernel_L999
361
362         str     OLD_A, A
363         str     OLD_N, N
364
365         ldr    INC_X , OLD_INC_X
366         ldr    INC_Y , OLD_INC_Y
367
368         cmp     INC_X, #0
369         beq     cgemvt_kernel_L999
370
371         cmp     INC_Y, #0
372         beq     cgemvt_kernel_L999
373
374         ldr     LDA, OLD_LDA
375
376
377 #if defined(DOUBLE)
378         lsl     LDA, LDA, #4                            // LDA * SIZE
379 #else
380         lsl     LDA, LDA, #3                            // LDA * SIZE
381 #endif
382
383         cmp     INC_X, #1
384         bne     cgemvt_kernel_S2_BEGIN
385
386         cmp     INC_Y, #1
387         bne     cgemvt_kernel_S2_BEGIN
388
389
390 cgemvt_kernel_F2_BEGIN:
391
392         ldr     YO , Y
393
394         ldr     J, N
395         asrs    J, J, #1                                        // J = N / 2
396         ble     cgemvt_kernel_F1_BEGIN
397
398 cgemvt_kernel_F2X4:
399
400         ldr     AO1, A
401         add     AO2, AO1, LDA
402         add     r3 , AO2, LDA
403         str     r3 , A
404
405         ldr     XO , X
406
407         INIT_F2
408
409         asrs    I, M, #2                                        // I = M / 4
410         ble     cgemvt_kernel_F2X1
411
412
413 cgemvt_kernel_F2X4_10:
414
415         KERNEL_F2X4
416
417         subs    I, I, #1
418         bne     cgemvt_kernel_F2X4_10
419
420
421 cgemvt_kernel_F2X1:
422
423         ands    I, M , #3
424         ble     cgemvt_kernel_F2_END
425
426 cgemvt_kernel_F2X1_10:
427
428         KERNEL_F2X1
429
430         subs    I, I, #1
431         bne     cgemvt_kernel_F2X1_10
432
433
434 cgemvt_kernel_F2_END:
435
436         SAVE_F2
437
438         subs    J , J , #1
439         bne     cgemvt_kernel_F2X4
440
441
442 cgemvt_kernel_F1_BEGIN:
443
444         ldr     J, N
445         ands    J, J, #1
446         ble     cgemvt_kernel_L999
447
448 cgemvt_kernel_F1X4:
449
450         ldr     AO1, A
451
452         ldr     XO , X
453
454         INIT_F1
455
456         asrs    I, M, #2                                        // I = M / 4
457         ble     cgemvt_kernel_F1X1
458
459
460 cgemvt_kernel_F1X4_10:
461
462         KERNEL_F1X4
463
464         subs    I, I, #1
465         bne     cgemvt_kernel_F1X4_10
466
467
468 cgemvt_kernel_F1X1:
469
470         ands    I, M , #3
471         ble     cgemvt_kernel_F1_END
472
473 cgemvt_kernel_F1X1_10:
474
475         KERNEL_F1X1
476
477         subs    I, I, #1
478         bne     cgemvt_kernel_F1X1_10
479
480
481 cgemvt_kernel_F1_END:
482
483         SAVE_F1
484
485         b       cgemvt_kernel_L999
486
487
488
489 /*************************************************************************************************************/
490
491 cgemvt_kernel_S2_BEGIN:
492
493 #if defined(DOUBLE)
494         lsl     INC_X, INC_X, #4                                // INC_X * SIZE
495         lsl     INC_Y, INC_Y, #4                                // INC_Y * SIZE
496 #else
497         lsl     INC_X, INC_X, #3                                // INC_X * SIZE
498         lsl     INC_Y, INC_Y, #3                                // INC_Y * SIZE
499 #endif
500
501         ldr     YO , Y
502
503         ldr     J, N
504         asrs    J, J, #1                                        // J = N / 2
505         ble     cgemvt_kernel_S1_BEGIN
506
507 cgemvt_kernel_S2X4:
508
509         ldr     AO1, A
510         add     AO2, AO1, LDA
511         add     r3 , AO2, LDA
512         str     r3 , A
513
514         ldr     XO , X
515
516         INIT_S2
517
518         asrs    I, M, #2                                        // I = M / 4
519         ble     cgemvt_kernel_S2X1
520
521
522 cgemvt_kernel_S2X4_10:
523
524         KERNEL_S2X4
525
526         subs    I, I, #1
527         bne     cgemvt_kernel_S2X4_10
528
529
530 cgemvt_kernel_S2X1:
531
532         ands    I, M , #3
533         ble     cgemvt_kernel_S2_END
534
535 cgemvt_kernel_S2X1_10:
536
537         KERNEL_S2X1
538
539         subs    I, I, #1
540         bne     cgemvt_kernel_S2X1_10
541
542
543 cgemvt_kernel_S2_END:
544
545         SAVE_S2
546
547         subs    J , J , #1
548         bne     cgemvt_kernel_S2X4
549
550
551 cgemvt_kernel_S1_BEGIN:
552
553         ldr     J, N
554         ands    J, J, #1
555         ble     cgemvt_kernel_L999
556
557 cgemvt_kernel_S1X4:
558
559         ldr     AO1, A
560
561         ldr     XO , X
562
563         INIT_S1
564
565         asrs    I, M, #2                                        // I = M / 4
566         ble     cgemvt_kernel_S1X1
567
568
569 cgemvt_kernel_S1X4_10:
570
571         KERNEL_S1X4
572
573         subs    I, I, #1
574         bne     cgemvt_kernel_S1X4_10
575
576
577 cgemvt_kernel_S1X1:
578
579         ands    I, M , #3
580         ble     cgemvt_kernel_S1_END
581
582 cgemvt_kernel_S1X1_10:
583
584         KERNEL_S1X1
585
586         subs    I, I, #1
587         bne     cgemvt_kernel_S1X1_10
588
589
590 cgemvt_kernel_S1_END:
591
592         SAVE_S1
593
594
595
596 /*************************************************************************************************************/
597
598 cgemvt_kernel_L999:
599
600         sub     r3, fp, #192
601
602 #if     defined(DOUBLE)
603         vldm    r3, { d8 - d15 }                                 // restore floating point registers
604 #else
605         vldm    r3, { s8 - s15 }                                 // restore floating point registers
606 #endif
607
608         mov     r0, #0          // set return value
609
610         sub     sp, fp, #28
611         pop     {r4 -r9 ,fp}
612         bx      lr
613
614         EPILOGUE
615