1 /***************************************************************************
2 Copyright (c) 2013, The OpenBLAS Project
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
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
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 *****************************************************************************/
28 /**************************************************************************************
34 **************************************************************************************/
45 #define OLD_ALPHA_R d0
46 #define OLD_ALPHA_I d1
48 /******************************************************
49 * [fp, #-128] - [fp, #-64] is reserved
50 * for store and restore of floating point
52 *******************************************************/
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 ]
62 #define FP_ZERO [fp, #-236]
63 #define FP_ZERO_0 [fp, #-236]
64 #define FP_ZERO_1 [fp, #-232]
66 #define ALPHA_I [fp, #-272]
67 #define ALPHA_R [fp, #-280]
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 ]
75 #define OLD_LDC [fp, #32 ]
76 #define OFFSET [fp, #36 ]
80 #define OLD_LDC [fp, #12 ]
81 #define OFFSET [fp, #16 ]
101 #if defined(NN) || defined(NT) || defined(TN) || defined(TT)
106 #define FMAC_R1 fnmuld
107 #define FMAC_R2 fnmacd
108 #define FMAC_I1 fmuld
109 #define FMAC_I2 fnmacd
111 #elif defined(CN) || defined(CT)
116 #define FMAC_R1 fmuld
117 #define FMAC_R2 fmacd
118 #define FMAC_I1 fnmuld
119 #define FMAC_I2 fmacd
121 #elif defined(NC) || defined(TC)
126 #define FMAC_R1 fmuld
127 #define FMAC_R2 fnmacd
128 #define FMAC_I1 fmuld
129 #define FMAC_I2 fmacd
136 #define FMAC_R1 fnmuld
137 #define FMAC_R2 fmacd
138 #define FMAC_I1 fnmuld
139 #define FMAC_I2 fnmacd
145 /**************************************************************************************
147 **************************************************************************************/
179 fldd d2 , [ AO, #16 ]
181 fldd d3 , [ AO, #24 ]
183 fldd d10, [ BO, #16 ]
186 fldd d11, [ BO, #24 ]
206 fldd d6 , [ AO, #16 ]
208 fldd d7 , [ AO, #24 ]
210 fldd d14, [ BO, #16 ]
212 fldd d15, [ BO, #24 ]
235 fldd d6 , [ AO, #16 ]
237 fldd d7 , [ AO, #24 ]
241 fldd d14, [ BO, #16 ]
244 fldd d15, [ BO, #24 ]
274 fldd d2 , [ AO, #16 ]
276 fldd d3 , [ AO, #24 ]
279 fldd d10, [ BO, #16 ]
282 fldd d11, [ BO, #24 ]
327 fldd d2 , [ AO, #16 ]
329 fldd d3 , [ AO, #24 ]
331 fldd d10, [ BO, #16 ]
334 fldd d11, [ BO, #24 ]
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
374 FMAC_R1 d4 , d0 , d16
375 FMAC_I1 d5 , d0 , d17
376 FMAC_R2 d4 , d1 , d17
377 FMAC_I2 d5 , d1 , d16
379 FMAC_R1 d6 , d0 , d18
380 FMAC_I1 d7 , d0 , d19
381 FMAC_R2 d6 , d1 , d19
382 FMAC_I2 d7 , d1 , d18
384 FMAC_R1 d8 , d0 , d20
385 FMAC_I1 d9 , d0 , d21
386 FMAC_R2 d8 , d1 , d21
387 FMAC_I2 d9 , d1 , d20
389 FMAC_R1 d10, d0 , d22
390 FMAC_I1 d11, d0 , d23
391 FMAC_R2 d10, d1 , d23
392 FMAC_I2 d11, d1 , d22
394 fstmiad CO1, { d4 - d7 }
395 fstmiad CO2, { d8 - d11 }
401 /******************************************************************************/
423 fldd d10, [ BO, #16 ]
424 fldd d11, [ BO, #24 ]
446 fldd d14, [ BO, #16 ]
447 fldd d15, [ BO, #24 ]
473 fldd d14, [ BO, #16 ]
474 fldd d15, [ BO, #24 ]
499 fldd d10, [ BO, #16 ]
500 fldd d11, [ BO, #24 ]
529 fldd d10, [ BO, #16 ]
530 fldd d11, [ BO, #24 ]
557 FADD_R d16, d24 , d16
558 FADD_I d17, d25 , d17
559 FADD_R d20, d28 , d20
560 FADD_I d21, d29 , d21
562 FMAC_R1 d4 , d0 , d16
563 FMAC_I1 d5 , d0 , d17
564 FMAC_R2 d4 , d1 , d17
565 FMAC_I2 d5 , d1 , d16
567 FMAC_R1 d8 , d0 , d20
568 FMAC_I1 d9 , d0 , d21
569 FMAC_R2 d8 , d1 , d21
570 FMAC_I2 d9 , d1 , d20
572 fstmiad CO1, { d4 - d5 }
573 fstmiad CO2, { d8 - d9 }
579 /******************************************************************************/
599 fldd d2 , [ AO, #16 ]
600 fldd d3 , [ AO, #24 ]
622 fldd d6 , [ AO, #16 ]
623 fldd d7 , [ AO, #24 ]
650 fldd d6 , [ AO, #16 ]
651 fldd d7 , [ AO, #24 ]
676 fldd d2 , [ AO, #16 ]
677 fldd d3 , [ AO, #24 ]
707 fldd d2 , [ AO, #16 ]
708 fldd d3 , [ AO, #24 ]
735 FADD_R d16, d24 , d16
736 FADD_I d17, d25 , d17
737 FADD_R d18, d26 , d18
738 FADD_I d19, d27 , d19
740 FMAC_R1 d4 , d0 , d16
741 FMAC_I1 d5 , d0 , d17
742 FMAC_R2 d4 , d1 , d17
743 FMAC_I2 d5 , d1 , d16
745 FMAC_R1 d6 , d0 , d18
746 FMAC_I1 d7 , d0 , d19
747 FMAC_R2 d6 , d1 , d19
748 FMAC_I2 d7 , d1 , d18
750 fstmiad CO1, { d4 - d7 }
756 /******************************************************************************/
867 FADD_R d16, d24 , d16
868 FADD_I d17, d25 , d17
870 FMAC_R1 d4 , d0 , d16
871 FMAC_I1 d5 , d0 , d17
872 FMAC_R2 d4 , d1 , d17
873 FMAC_I2 d5 , d1 , d16
875 fstmiad CO1, { d4 - d5 }
881 /******************************************************************************/
884 /**************************************************************************************
885 * End of macro definitions
886 **************************************************************************************/
894 sub sp, sp, #STACKSIZE // reserve stack
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
905 vstr OLD_ALPHA_R, ALPHA_R
906 vstr OLD_ALPHA_I, ALPHA_I
909 vstm r3, { d8 - d15} // store floating point registers
916 lsl r3, r3, #4 // ldc = ldc * 8 * 2
928 asrs J, J, #1 // J = J / 2
933 ldr CO1, C // CO1 = C
935 lsl r4 , r4 , #1 // LDC * 2
937 str r3 , C // store C
954 asrs I, I, #1 // I = I / 2
959 #if (defined(LEFT) && defined(TRANSA)) || \
960 (!defined(LEFT) && !defined(TRANSA))
966 lsls r4 , r3 , #5 // 2 * 8 * 2 double values
968 lsls r4 , r3 , #5 // 2 * 8 * 2 double values
975 #elif (defined(LEFT) && !defined(TRANSA)) || (!defined(LEFT) && defined(TRANSA))
983 add K1, K1, #2 // number of values in AO
985 add K1, K1, #2 // number of values in BO
991 asrs L , K1, #3 // L = L / 8
1093 ands L , K1, #7 // L = L % 8
1107 #if (defined(LEFT) && defined(TRANSA)) || \
1108 (!defined(LEFT) && !defined(TRANSA))
1112 lsls r4 , r3 , #5 // 2 * 8 * 2 double values
1114 lsls r4 , r3 , #5 // 2 * 8 * 2 double values
1120 add r3 , r3 , #2 // number of values in AO
1136 tst I, #1 // I = I % 2
1143 #if (defined(LEFT) && defined(TRANSA)) || \
1144 (!defined(LEFT) && !defined(TRANSA))
1150 lsls r4 , r3 , #5 // 2 * 8 * 2 double values
1152 lsls r4 , r3 , #4 // 1 * 8 * 2 double values
1159 #elif (defined(LEFT) && !defined(TRANSA)) || (!defined(LEFT) && defined(TRANSA))
1167 add K1, K1, #1 // number of values in AO
1169 add K1, K1, #2 // number of values in BO
1174 asrs L , K1, #3 // L = L / 8
1195 ands L , K1, #7 // L = L % 8
1209 #if (defined(LEFT) && defined(TRANSA)) || \
1210 (!defined(LEFT) && !defined(TRANSA))
1214 lsls r4 , r3 , #5 // 2 * 8 * 2 double values
1216 lsls r4 , r3 , #4 // 1 * 8 * 2 double values
1222 add r3 , r3 , #1 // number of values in AO
1232 lsl r4, r4, #5 // k * 2 * 8 * 2
1233 add r3, r3, r4 // B = B + K * 4 * 8
1238 add r3 , r3 , #2 // number of values in BO
1248 /*********************************************************************************************/
1257 ldr CO1, C // CO1 = C
1260 str r3 , C // store C
1273 asrs I, I, #1 // I = I / 2
1278 #if (defined(LEFT) && defined(TRANSA)) || \
1279 (!defined(LEFT) && !defined(TRANSA))
1285 lsls r4 , r3 , #4 // 1 * 8 * 2 double values
1287 lsls r4 , r3 , #5 // 2 * 8 * 2 double values
1294 #elif (defined(LEFT) && !defined(TRANSA)) || (!defined(LEFT) && defined(TRANSA))
1302 add K1, K1, #2 // number of values in AO
1304 add K1, K1, #1 // number of values in BO
1309 asrs L , K1, #3 // L = L / 8
1411 ands L , K1, #7 // L = L % 8
1425 #if (defined(LEFT) && defined(TRANSA)) || \
1426 (!defined(LEFT) && !defined(TRANSA))
1430 lsls r4 , r3 , #4 // 1 * 8 * 2 double values
1432 lsls r4 , r3 , #5 // 2 * 8 * 2 double values
1438 add r3 , r3 , #2 // number of values in AO
1453 tst I, #1 // I = I % 2
1460 #if (defined(LEFT) && defined(TRANSA)) || \
1461 (!defined(LEFT) && !defined(TRANSA))
1467 lsls r4 , r3 , #4 // 1 * 8 * 2 double values
1469 lsls r4 , r3 , #4 // 1 * 8 * 2 double values
1476 #elif (defined(LEFT) && !defined(TRANSA)) || (!defined(LEFT) && defined(TRANSA))
1484 add K1, K1, #1 // number of values in AO
1486 add K1, K1, #1 // number of values in BO
1491 asrs L , K1, #3 // L = L / 8
1512 ands L , K1, #7 // L = L % 8
1527 #if (defined(LEFT) && defined(TRANSA)) || \
1528 (!defined(LEFT) && !defined(TRANSA))
1532 lsls r4 , r3 , #4 // 1 * 8 * 2 double values
1534 lsls r4 , r3 , #4 // 1 * 8 * 2 double values
1540 add r3 , r3 , #1 // number of values in AO
1553 vldm r3, { d8 - d15} // restore floating point registers
1555 movs r0, #0 // set return value