1/***************************************************************************
2Copyright (c) 2013, The OpenBLAS Project
3All rights reserved.
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are
6met:
71. Redistributions of source code must retain the above copyright
8notice, this list of conditions and the following disclaimer.
92. Redistributions in binary form must reproduce the above copyright
10notice, this list of conditions and the following disclaimer in
11the documentation and/or other materials provided with the
12distribution.
133. Neither the name of the OpenBLAS project nor the names of
14its contributors may be used to endorse or promote products
15derived from this software without specific prior written permission.
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBLAS PROJECT OR CONTRIBUTORS BE
20LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*****************************************************************************/
27
28/**************************************************************************************
29* 2013/11/28 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 A	[fp, #-248 ]
55#define LDC	[fp, #-252 ]
56#define M	[fp, #-256 ]
57#define N	[fp, #-260 ]
58#define K	[fp, #-264 ]
59
60#define FP_ZERO [fp, #-240]
61#define FP_ZERO_0 [fp, # -240]
62#define FP_ZERO_1 [fp, # -236]
63
64#define ALPHA_I	[fp, #-272]
65#define ALPHA_R	[fp, #-280]
66
67#if !defined(__ARM_PCS_VFP)
68#define OLD_ALPHAR_SOFTFP	[fp, #4]
69#define OLD_ALPHAI_SOFTFP	[fp, #12]
70#define OLD_A_SOFTFP	[fp, #20 ]
71#define B	[fp, #24 ]
72#define C	[fp, #28 ]
73#define OLD_LDC	[fp, #32 ]
74#else
75#define B	[fp, #4 ]
76#define C	[fp, #8 ]
77#define OLD_LDC	[fp, #12 ]
78#endif
79
80#define I	r0
81#define J	r1
82#define L	r2
83
84#define	AO	r5
85#define	BO	r6
86
87#define	CO1	r8
88#define	CO2	r9
89
90#define K1	r7
91#define BC	r12
92
93#define A_PRE	96
94#define B_PRE	96
95#define C_PRE	64
96
97#if defined(NN) || defined(NT) || defined(TN) || defined(TT)
98
99	#define	KMAC_R	vmls.f64
100	#define	KMAC_I	fmacd
101
102	#define	FMAC_R1	fmacd
103	#define	FMAC_R2	vmls.f64
104	#define	FMAC_I1	fmacd
105	#define	FMAC_I2	fmacd
106
107#elif defined(CN) || defined(CT)
108
109	#define	KMAC_R	fmacd
110	#define	KMAC_I	vmls.f64
111
112	#define	FMAC_R1	fmacd
113	#define	FMAC_R2	vmls.f64
114	#define	FMAC_I1	fmacd
115	#define	FMAC_I2	fmacd
116
117#elif defined(NC) || defined(TC)
118
119	#define	KMAC_R	fmacd
120	#define	KMAC_I	vmls.f64
121
122	#define	FMAC_R1	fmacd
123	#define	FMAC_R2	fmacd
124	#define	FMAC_I1	vmls.f64
125	#define	FMAC_I2	fmacd
126
127#else
128
129	#define	KMAC_R  vmls.f64
130	#define	KMAC_I	fmacd
131
132	#define	FMAC_R1	fmacd
133	#define	FMAC_R2	fmacd
134	#define	FMAC_I1	vmls.f64
135	#define	FMAC_I2	fmacd
136
137#endif
138
139
140
141/**************************************************************************************
142* Macro definitions
143**************************************************************************************/
144
145.macro INIT2x2
146
147	fldd			d8 , FP_ZERO
148	vmov.f64		d9 , d8
149	vmov.f64		d10, d8
150	vmov.f64		d11, d8
151	vmov.f64		d12, d8
152	vmov.f64		d13, d8
153	vmov.f64		d14, d8
154	vmov.f64		d15, d8
155
156.endm
157
158.macro KERNEL2x2_I
159	pld	[ AO, #A_PRE ]
160	pld	[ BO, #B_PRE ]
161
162	fldd	d0 , [ AO ]
163	fldd	d1 , [ AO, #8 ]
164
165	fldd	d2 , [ AO, #16 ]
166	fldd	d3 , [ AO, #24 ]
167
168	fldd	d4 , [ BO ]
169	fldd	d5 , [ BO, #8 ]
170
171	fldd	d6 , [ BO, #16 ]
172	fldd	d7 , [ BO, #24 ]
173
174	fmuld	d8  , d0,  d4
175	KMAC_R	d8  , d1,  d5
176	fmuld	d9  , d0,  d5
177	KMAC_I	d9  , d1,  d4
178
179	fmuld	d10 , d2,  d4
180	KMAC_R	d10 , d3,  d5
181	fmuld	d11 , d2,  d5
182	KMAC_I	d11 , d3,  d4
183
184	fmuld	d12 , d0,  d6
185	KMAC_R	d12 , d1,  d7
186	fmuld	d13 , d0,  d7
187	KMAC_I	d13 , d1,  d6
188
189	fmuld	d14 , d2,  d6
190	KMAC_R	d14 , d3,  d7
191	fmuld	d15 , d2,  d7
192	KMAC_I	d15 , d3,  d6
193
194	add	BO , BO, #32
195	add	AO , AO, #32
196
197.endm
198
199
200
201.macro KERNEL2x2_M1
202
203
204	fldd	d0 , [ AO ]
205	fldd	d4 , [ BO ]
206	fldd	d5 , [ BO, #8 ]
207
208	fmacd	d8  , d0,  d4
209	fldd	d1 , [ AO, #8 ]
210	fmacd	d9  , d0,  d5
211	fldd	d2 , [ AO, #16 ]
212	KMAC_R	d8  , d1,  d5
213	fldd	d3 , [ AO, #24 ]
214	KMAC_I	d9  , d1,  d4
215
216	fldd	d6 , [ BO, #16 ]
217	fmacd	d10 , d2,  d4
218	fldd	d7 , [ BO, #24 ]
219	fmacd	d11 , d2,  d5
220	KMAC_R	d10 , d3,  d5
221	pld	[ AO, #A_PRE ]
222	KMAC_I	d11 , d3,  d4
223
224	pld	[ BO, #B_PRE ]
225	fmacd	d12 , d0,  d6
226	fmacd	d13 , d0,  d7
227	KMAC_R	d12 , d1,  d7
228	KMAC_I	d13 , d1,  d6
229
230	fmacd	d14 , d2,  d6
231	fmacd	d15 , d2,  d7
232	add	BO , BO, #32
233	KMAC_R	d14 , d3,  d7
234	add	AO , AO, #32
235	KMAC_I	d15 , d3,  d6
236
237
238.endm
239
240.macro KERNEL2x2_M2
241
242	fldd	d0 , [ AO ]
243	fldd	d4 , [ BO ]
244	fldd	d5 , [ BO, #8 ]
245
246	fmacd	d8  , d0,  d4
247	fldd	d1 , [ AO, #8 ]
248	fmacd	d9  , d0,  d5
249	fldd	d2 , [ AO, #16 ]
250	KMAC_R	d8  , d1,  d5
251	fldd	d3 , [ AO, #24 ]
252	KMAC_I	d9  , d1,  d4
253
254	fldd	d6 , [ BO, #16 ]
255	fmacd	d10 , d2,  d4
256	fldd	d7 , [ BO, #24 ]
257	fmacd	d11 , d2,  d5
258	KMAC_R	d10 , d3,  d5
259	pld	[ AO, #A_PRE ]
260	KMAC_I	d11 , d3,  d4
261
262	pld	[ BO, #B_PRE ]
263	fmacd	d12 , d0,  d6
264	fmacd	d13 , d0,  d7
265	KMAC_R	d12 , d1,  d7
266	KMAC_I	d13 , d1,  d6
267
268	fmacd	d14 , d2,  d6
269	fmacd	d15 , d2,  d7
270	add	BO , BO, #32
271	KMAC_R	d14 , d3,  d7
272	add	AO , AO, #32
273	KMAC_I	d15 , d3,  d6
274
275
276.endm
277
278
279.macro KERNEL2x2_E
280
281	fldd	d0 , [ AO ]
282	fldd	d1 , [ AO, #8 ]
283	fldd	d2 , [ AO, #16 ]
284	fldd	d3 , [ AO, #24 ]
285
286	fldd	d4 , [ BO ]
287	fldd	d5 , [ BO, #8 ]
288	fldd	d6 , [ BO, #16 ]
289	fldd	d7 , [ BO, #24 ]
290
291	fmacd	d8  , d0,  d4
292	KMAC_R	d8  , d1,  d5
293	fmacd	d9  , d0,  d5
294	KMAC_I	d9  , d1,  d4
295
296	fmacd	d10 , d2,  d4
297	KMAC_R	d10 , d3,  d5
298	fmacd	d11 , d2,  d5
299	KMAC_I	d11 , d3,  d4
300
301	fmacd	d12 , d0,  d6
302	KMAC_R	d12 , d1,  d7
303	fmacd	d13 , d0,  d7
304	KMAC_I	d13 , d1,  d6
305
306	fmacd	d14 , d2,  d6
307	KMAC_R	d14 , d3,  d7
308	fmacd	d15 , d2,  d7
309	KMAC_I	d15 , d3,  d6
310
311	add	BO , BO, #32
312	add	AO , AO, #32
313
314.endm
315
316.macro KERNEL2x2_SUB
317
318	fldd	d0 , [ AO ]
319	fldd	d4 , [ BO ]
320	fldd	d5 , [ BO, #8 ]
321
322	fmacd	d8  , d0,  d4
323	fldd	d1 , [ AO, #8 ]
324	fmacd	d9  , d0,  d5
325	fldd	d2 , [ AO, #16 ]
326	KMAC_R	d8  , d1,  d5
327	fldd	d3 , [ AO, #24 ]
328	KMAC_I	d9  , d1,  d4
329
330	fldd	d6 , [ BO, #16 ]
331	fmacd	d10 , d2,  d4
332	fldd	d7 , [ BO, #24 ]
333	fmacd	d11 , d2,  d5
334	KMAC_R	d10 , d3,  d5
335	pld	[ AO, #A_PRE ]
336	KMAC_I	d11 , d3,  d4
337
338	pld	[ BO, #B_PRE ]
339	fmacd	d12 , d0,  d6
340	fmacd	d13 , d0,  d7
341	KMAC_R	d12 , d1,  d7
342	KMAC_I	d13 , d1,  d6
343
344	fmacd	d14 , d2,  d6
345	fmacd	d15 , d2,  d7
346	add	BO , BO, #32
347	KMAC_R	d14 , d3,  d7
348	add	AO , AO, #32
349	KMAC_I	d15 , d3,  d6
350
351
352.endm
353
354
355.macro SAVE2x2
356
357	ldr	r3  , LDC
358	add	CO2 , CO1, r3
359
360	fldd		d0, ALPHA_R
361	fldd		d1, ALPHA_I
362
363	vldmia.f64 CO1, { d4 - d7 }
364
365	FMAC_R1 d4 , d0 , d8
366	FMAC_I1 d5 , d0 , d9
367	FMAC_R2 d4 , d1 , d9
368	FMAC_I2	d5 , d1 , d8
369
370	FMAC_R1 d6 , d0 , d10
371	FMAC_I1 d7 , d0 , d11
372	FMAC_R2 d6 , d1 , d11
373	FMAC_I2	d7 , d1 , d10
374
375	vstmia.f64 CO1, { d4 - d7 }
376
377	vldmia.f64 CO2, { d4 - d7 }
378
379	FMAC_R1 d4 , d0 , d12
380	FMAC_I1 d5 , d0 , d13
381	FMAC_R2 d4 , d1 , d13
382	FMAC_I2	d5 , d1 , d12
383
384	FMAC_R1 d6 , d0 , d14
385	FMAC_I1 d7 , d0 , d15
386	FMAC_R2 d6 , d1 , d15
387	FMAC_I2	d7 , d1 , d14
388
389	vstmia.f64 CO2, { d4 - d7 }
390
391	add	CO1, CO1, #32
392
393.endm
394
395/******************************************************************************/
396
397.macro INIT1x2
398
399	fldd			d8 , FP_ZERO
400	vmov.f64		d9 , d8
401	vmov.f64		d12, d8
402	vmov.f64		d13, d8
403
404.endm
405
406.macro KERNEL1x2_I
407
408	fldd	d0 , [ AO ]
409	fldd	d1 , [ AO, #8 ]
410
411	fldd	d4 , [ BO ]
412	fldd	d5 , [ BO, #8 ]
413
414	fldd	d6 , [ BO, #16 ]
415	fldd	d7 , [ BO, #24 ]
416
417	fmuld	d8  , d0,  d4
418	KMAC_R	d8  , d1,  d5
419	fmuld	d9  , d0,  d5
420	KMAC_I	d9  , d1,  d4
421
422	fmuld	d12 , d0,  d6
423	KMAC_R	d12 , d1,  d7
424	fmuld	d13 , d0,  d7
425	KMAC_I	d13 , d1,  d6
426
427	add	BO , BO, #32
428	add	AO , AO, #16
429
430.endm
431
432
433
434.macro KERNEL1x2_M1
435
436	fldd	d0 , [ AO ]
437	fldd	d1 , [ AO, #8 ]
438
439	fldd	d4 , [ BO ]
440	fldd	d5 , [ BO, #8 ]
441	fldd	d6 , [ BO, #16 ]
442	fldd	d7 , [ BO, #24 ]
443
444	fmacd	d8  , d0,  d4
445	KMAC_R	d8  , d1,  d5
446	fmacd	d9  , d0,  d5
447	KMAC_I	d9  , d1,  d4
448
449	fmacd	d12 , d0,  d6
450	KMAC_R	d12 , d1,  d7
451	fmacd	d13 , d0,  d7
452	KMAC_I	d13 , d1,  d6
453
454	add	BO , BO, #32
455	add	AO , AO, #16
456
457.endm
458
459.macro KERNEL1x2_M2
460
461	fldd	d0 , [ AO ]
462	fldd	d1 , [ AO, #8 ]
463
464	fldd	d4 , [ BO ]
465	fldd	d5 , [ BO, #8 ]
466	fldd	d6 , [ BO, #16 ]
467	fldd	d7 , [ BO, #24 ]
468
469	fmacd	d8  , d0,  d4
470	KMAC_R	d8  , d1,  d5
471	fmacd	d9  , d0,  d5
472	KMAC_I	d9  , d1,  d4
473
474	fmacd	d12 , d0,  d6
475	KMAC_R	d12 , d1,  d7
476	fmacd	d13 , d0,  d7
477	KMAC_I	d13 , d1,  d6
478
479	add	BO , BO, #32
480	add	AO , AO, #16
481
482
483.endm
484
485
486.macro KERNEL1x2_E
487
488	fldd	d0 , [ AO ]
489	fldd	d1 , [ AO, #8 ]
490
491	fldd	d4 , [ BO ]
492	fldd	d5 , [ BO, #8 ]
493	fldd	d6 , [ BO, #16 ]
494	fldd	d7 , [ BO, #24 ]
495
496	fmacd	d8  , d0,  d4
497	KMAC_R	d8  , d1,  d5
498	fmacd	d9  , d0,  d5
499	KMAC_I	d9  , d1,  d4
500
501	fmacd	d12 , d0,  d6
502	KMAC_R	d12 , d1,  d7
503	fmacd	d13 , d0,  d7
504	KMAC_I	d13 , d1,  d6
505
506	add	BO , BO, #32
507	add	AO , AO, #16
508
509.endm
510
511.macro KERNEL1x2_SUB
512
513	fldd	d0 , [ AO ]
514	fldd	d1 , [ AO, #8 ]
515
516	fldd	d4 , [ BO ]
517	fldd	d5 , [ BO, #8 ]
518	fldd	d6 , [ BO, #16 ]
519	fldd	d7 , [ BO, #24 ]
520
521	fmacd	d8  , d0,  d4
522	KMAC_R	d8  , d1,  d5
523	fmacd	d9  , d0,  d5
524	KMAC_I	d9  , d1,  d4
525
526	fmacd	d12 , d0,  d6
527	KMAC_R	d12 , d1,  d7
528	fmacd	d13 , d0,  d7
529	KMAC_I	d13 , d1,  d6
530
531	add	BO , BO, #32
532	add	AO , AO, #16
533
534
535.endm
536
537
538.macro SAVE1x2
539
540	ldr	r3  , LDC
541	add	CO2 , CO1, r3
542
543	fldd		d0, ALPHA_R
544	fldd		d1, ALPHA_I
545
546	vldmia.f64 CO1, { d4 - d5 }
547
548	FMAC_R1 d4 , d0 , d8
549	FMAC_I1 d5 , d0 , d9
550	FMAC_R2 d4 , d1 , d9
551	FMAC_I2	d5 , d1 , d8
552
553	vstmia.f64 CO1, { d4 - d5 }
554
555	vldmia.f64 CO2, { d4 - d5 }
556
557	FMAC_R1 d4 , d0 , d12
558	FMAC_I1 d5 , d0 , d13
559	FMAC_R2 d4 , d1 , d13
560	FMAC_I2	d5 , d1 , d12
561
562	vstmia.f64 CO2, { d4 - d5 }
563
564	add	CO1, CO1, #16
565
566.endm
567
568
569/******************************************************************************/
570
571.macro INIT2x1
572
573	fldd			d8 , FP_ZERO
574	vmov.f64		d9 , d8
575	vmov.f64		d10, d8
576	vmov.f64		d11, d8
577
578.endm
579
580.macro KERNEL2x1_I
581
582	fldd	d0 , [ AO ]
583	fldd	d1 , [ AO, #8 ]
584
585	fldd	d2 , [ AO, #16 ]
586	fldd	d3 , [ AO, #24 ]
587
588	fldd	d4 , [ BO ]
589	fldd	d5 , [ BO, #8 ]
590
591	fmuld	d8  , d0,  d4
592	KMAC_R	d8  , d1,  d5
593	fmuld	d9  , d0,  d5
594	KMAC_I	d9  , d1,  d4
595
596	fmuld	d10 , d2,  d4
597	KMAC_R	d10 , d3,  d5
598	fmuld	d11 , d2,  d5
599	KMAC_I	d11 , d3,  d4
600
601	add	BO , BO, #16
602	add	AO , AO, #32
603
604.endm
605
606
607
608.macro KERNEL2x1_M1
609
610	fldd	d0 , [ AO ]
611	fldd	d1 , [ AO, #8 ]
612	fldd	d2 , [ AO, #16 ]
613	fldd	d3 , [ AO, #24 ]
614
615	fldd	d4 , [ BO ]
616	fldd	d5 , [ BO, #8 ]
617
618	fmacd	d8  , d0,  d4
619	KMAC_R	d8  , d1,  d5
620	fmacd	d9  , d0,  d5
621	KMAC_I	d9  , d1,  d4
622
623	fmacd	d10 , d2,  d4
624	KMAC_R	d10 , d3,  d5
625	fmacd	d11 , d2,  d5
626	KMAC_I	d11 , d3,  d4
627
628	add	BO , BO, #16
629	add	AO , AO, #32
630
631.endm
632
633.macro KERNEL2x1_M2
634
635	fldd	d0 , [ AO ]
636	fldd	d1 , [ AO, #8 ]
637	fldd	d2 , [ AO, #16 ]
638	fldd	d3 , [ AO, #24 ]
639
640	fldd	d4 , [ BO ]
641	fldd	d5 , [ BO, #8 ]
642
643	fmacd	d8  , d0,  d4
644	KMAC_R	d8  , d1,  d5
645	fmacd	d9  , d0,  d5
646	KMAC_I	d9  , d1,  d4
647
648	fmacd	d10 , d2,  d4
649	KMAC_R	d10 , d3,  d5
650	fmacd	d11 , d2,  d5
651	KMAC_I	d11 , d3,  d4
652
653	add	BO , BO, #16
654	add	AO , AO, #32
655
656
657.endm
658
659
660.macro KERNEL2x1_E
661
662	fldd	d0 , [ AO ]
663	fldd	d1 , [ AO, #8 ]
664	fldd	d2 , [ AO, #16 ]
665	fldd	d3 , [ AO, #24 ]
666
667	fldd	d4 , [ BO ]
668	fldd	d5 , [ BO, #8 ]
669
670	fmacd	d8  , d0,  d4
671	KMAC_R	d8  , d1,  d5
672	fmacd	d9  , d0,  d5
673	KMAC_I	d9  , d1,  d4
674
675	fmacd	d10 , d2,  d4
676	KMAC_R	d10 , d3,  d5
677	fmacd	d11 , d2,  d5
678	KMAC_I	d11 , d3,  d4
679
680	add	BO , BO, #16
681	add	AO , AO, #32
682
683.endm
684
685.macro KERNEL2x1_SUB
686
687	fldd	d0 , [ AO ]
688	fldd	d1 , [ AO, #8 ]
689	fldd	d2 , [ AO, #16 ]
690	fldd	d3 , [ AO, #24 ]
691
692	fldd	d4 , [ BO ]
693	fldd	d5 , [ BO, #8 ]
694
695	fmacd	d8  , d0,  d4
696	KMAC_R	d8  , d1,  d5
697	fmacd	d9  , d0,  d5
698	KMAC_I	d9  , d1,  d4
699
700	fmacd	d10 , d2,  d4
701	KMAC_R	d10 , d3,  d5
702	fmacd	d11 , d2,  d5
703	KMAC_I	d11 , d3,  d4
704
705	add	BO , BO, #16
706	add	AO , AO, #32
707
708
709.endm
710
711
712.macro SAVE2x1
713
714	fldd		d0, ALPHA_R
715	fldd		d1, ALPHA_I
716
717	vldmia.f64 CO1, { d4 - d7 }
718
719	FMAC_R1 d4 , d0 , d8
720	FMAC_I1 d5 , d0 , d9
721	FMAC_R2 d4 , d1 , d9
722	FMAC_I2	d5 , d1 , d8
723
724	FMAC_R1 d6 , d0 , d10
725	FMAC_I1 d7 , d0 , d11
726	FMAC_R2 d6 , d1 , d11
727	FMAC_I2	d7 , d1 , d10
728
729	vstmia.f64 CO1, { d4 - d7 }
730
731	add	CO1, CO1, #32
732
733.endm
734
735
736/******************************************************************************/
737
738.macro INIT1x1
739
740	fldd			d8 , FP_ZERO
741	vmov.f64		d9 , d8
742
743.endm
744
745.macro KERNEL1x1_I
746
747	fldd	d0 , [ AO ]
748	fldd	d1 , [ AO, #8 ]
749
750	fldd	d4 , [ BO ]
751	fldd	d5 , [ BO, #8 ]
752
753	fmuld	d8  , d0,  d4
754	KMAC_R	d8  , d1,  d5
755	fmuld	d9  , d0,  d5
756	KMAC_I	d9  , d1,  d4
757
758	add	BO , BO, #16
759	add	AO , AO, #16
760
761.endm
762
763
764
765.macro KERNEL1x1_M1
766
767	fldd	d0 , [ AO ]
768	fldd	d1 , [ AO, #8 ]
769
770	fldd	d4 , [ BO ]
771	fldd	d5 , [ BO, #8 ]
772
773	fmacd	d8  , d0,  d4
774	KMAC_R	d8  , d1,  d5
775	fmacd	d9  , d0,  d5
776	KMAC_I	d9  , d1,  d4
777
778	add	BO , BO, #16
779	add	AO , AO, #16
780
781.endm
782
783.macro KERNEL1x1_M2
784
785	fldd	d0 , [ AO ]
786	fldd	d1 , [ AO, #8 ]
787
788	fldd	d4 , [ BO ]
789	fldd	d5 , [ BO, #8 ]
790
791	fmacd	d8  , d0,  d4
792	KMAC_R	d8  , d1,  d5
793	fmacd	d9  , d0,  d5
794	KMAC_I	d9  , d1,  d4
795
796	add	BO , BO, #16
797	add	AO , AO, #16
798
799
800.endm
801
802
803.macro KERNEL1x1_E
804
805	fldd	d0 , [ AO ]
806	fldd	d1 , [ AO, #8 ]
807
808	fldd	d4 , [ BO ]
809	fldd	d5 , [ BO, #8 ]
810
811	fmacd	d8  , d0,  d4
812	KMAC_R	d8  , d1,  d5
813	fmacd	d9  , d0,  d5
814	KMAC_I	d9  , d1,  d4
815
816	add	BO , BO, #16
817	add	AO , AO, #16
818
819.endm
820
821.macro KERNEL1x1_SUB
822
823	fldd	d0 , [ AO ]
824	fldd	d1 , [ AO, #8 ]
825
826	fldd	d4 , [ BO ]
827	fldd	d5 , [ BO, #8 ]
828
829	fmacd	d8  , d0,  d4
830	KMAC_R	d8  , d1,  d5
831	fmacd	d9  , d0,  d5
832	KMAC_I	d9  , d1,  d4
833
834	add	BO , BO, #16
835	add	AO , AO, #16
836
837
838.endm
839
840
841.macro SAVE1x1
842
843	fldd		d0, ALPHA_R
844	fldd		d1, ALPHA_I
845
846	vldmia.f64 CO1, { d4 - d5 }
847
848	FMAC_R1 d4 , d0 , d8
849	FMAC_I1 d5 , d0 , d9
850	FMAC_R2 d4 , d1 , d9
851	FMAC_I2	d5 , d1 , d8
852
853	vstmia.f64 CO1, { d4 - d5 }
854
855	add	CO1, CO1, #16
856
857.endm
858
859
860/******************************************************************************/
861
862
863/**************************************************************************************
864* End of macro definitions
865**************************************************************************************/
866
867	PROLOGUE
868
869	.align 5
870
871	push	{r4 - r9, fp}
872	add	fp, sp, #24
873	sub	sp, sp, #STACKSIZE				// reserve stack
874
875#if !defined(__ARM_PCS_VFP)
876	vldr	OLD_ALPHA_R, OLD_ALPHAR_SOFTFP
877	vldr	OLD_ALPHA_I, OLD_ALPHAI_SOFTFP
878	ldr	OLD_A, OLD_A_SOFTFP
879#endif
880	str	OLD_M, M
881	str	OLD_N, N
882	str	OLD_K, K
883	str	OLD_A, A
884	vstr	OLD_ALPHA_R, ALPHA_R
885	vstr	OLD_ALPHA_I, ALPHA_I
886
887	sub	r3, fp, #128
888	vstm	r3, { d8 - d15} 				// store floating point registers
889
890        movs    r4, #0
891        str     r4, FP_ZERO
892        str     r4, FP_ZERO_1
893
894	ldr	r3, OLD_LDC
895	lsl	r3, r3, #4					// ldc = ldc * 8 * 2
896	str	r3, LDC
897
898	ldr	K1, K
899	ldr	BC, B
900
901	ldr	J, N
902	asrs	J, J, #1					// J = J / 2
903	ble	zgemm_kernel_L1_BEGIN
904
905zgemm_kernel_L2_BEGIN:
906
907	ldr	CO1, C						// CO1 = C
908	ldr	r4 , LDC
909	lsl	r4 , r4 , #1					// LDC * 2
910	add	r3 , r4, CO1
911	str	r3 , C						// store C
912
913	ldr	AO, A						// AO = A
914        pld     [AO , #A_PRE-64]
915        pld     [AO , #A_PRE-32]
916
917
918
919zgemm_kernel_L2_M2_BEGIN:
920
921	ldr	I, M
922	asrs	I, I, #1					// I = I / 2
923	ble	zgemm_kernel_L2_M1_BEGIN
924
925zgemm_kernel_L2_M2_20:
926
927
928	mov	BO, BC
929	asrs	L , K1, #3					// L = L / 8
930	cmp	L , #3
931	blt	zgemm_kernel_L2_M2_30
932	.align 5
933
934
935
936	KERNEL2x2_I
937	KERNEL2x2_M2
938	KERNEL2x2_M1
939	KERNEL2x2_M2
940
941	KERNEL2x2_M1
942	KERNEL2x2_M2
943	KERNEL2x2_M1
944	KERNEL2x2_M2
945
946	sub	L, L, #2
947
948zgemm_kernel_L2_M2_22:
949
950	KERNEL2x2_M1
951	KERNEL2x2_M2
952	KERNEL2x2_M1
953	KERNEL2x2_M2
954
955	KERNEL2x2_M1
956	KERNEL2x2_M2
957	KERNEL2x2_M1
958	KERNEL2x2_M2
959
960	subs	L, L, #1
961	bgt	zgemm_kernel_L2_M2_22
962
963	KERNEL2x2_M1
964	KERNEL2x2_M2
965	KERNEL2x2_M1
966	KERNEL2x2_M2
967
968	KERNEL2x2_M1
969	KERNEL2x2_M2
970	KERNEL2x2_M1
971	KERNEL2x2_E
972
973	b	 zgemm_kernel_L2_M2_44
974
975
976zgemm_kernel_L2_M2_30:
977	tst	L, #3
978	ble	zgemm_kernel_L2_M2_40
979
980	tst	L, #2
981	ble	zgemm_kernel_L2_M2_32
982
983	KERNEL2x2_I
984	KERNEL2x2_M2
985	KERNEL2x2_M1
986	KERNEL2x2_M2
987
988	KERNEL2x2_M1
989	KERNEL2x2_M2
990	KERNEL2x2_M1
991	KERNEL2x2_M2
992
993	KERNEL2x2_M1
994	KERNEL2x2_M2
995	KERNEL2x2_M1
996	KERNEL2x2_M2
997
998
999	KERNEL2x2_M1
1000	KERNEL2x2_M2
1001	KERNEL2x2_M1
1002	KERNEL2x2_E
1003
1004	b	 zgemm_kernel_L2_M2_44
1005
1006zgemm_kernel_L2_M2_32:
1007
1008	tst	L, #1
1009	ble	zgemm_kernel_L2_M2_40
1010
1011	KERNEL2x2_I
1012	KERNEL2x2_M2
1013	KERNEL2x2_M1
1014	KERNEL2x2_M2
1015
1016	KERNEL2x2_M1
1017	KERNEL2x2_M2
1018	KERNEL2x2_M1
1019	KERNEL2x2_E
1020
1021	b	 zgemm_kernel_L2_M2_44
1022
1023
1024zgemm_kernel_L2_M2_40:
1025
1026	INIT2x2
1027
1028
1029zgemm_kernel_L2_M2_44:
1030
1031	ands	L , K1, #7					// L = L % 8
1032	ble	zgemm_kernel_L2_M2_100
1033
1034zgemm_kernel_L2_M2_46:
1035
1036	KERNEL2x2_SUB
1037
1038	subs	L, L, #1
1039	bne	zgemm_kernel_L2_M2_46
1040
1041zgemm_kernel_L2_M2_100:
1042
1043	SAVE2x2
1044
1045zgemm_kernel_L2_M2_END:
1046
1047	subs	I, I, #1
1048	bne	zgemm_kernel_L2_M2_20
1049
1050
1051zgemm_kernel_L2_M1_BEGIN:
1052
1053	ldr	I, M
1054	tst	I, #1					// I = I % 2
1055	ble	zgemm_kernel_L2_END
1056
1057zgemm_kernel_L2_M1_20:
1058
1059	INIT1x2
1060
1061	mov	BO, BC
1062	asrs	L , K1, #3					// L = L / 8
1063	ble	zgemm_kernel_L2_M1_40
1064
1065zgemm_kernel_L2_M1_22:
1066
1067	KERNEL1x2_SUB
1068	KERNEL1x2_SUB
1069	KERNEL1x2_SUB
1070	KERNEL1x2_SUB
1071
1072	KERNEL1x2_SUB
1073	KERNEL1x2_SUB
1074	KERNEL1x2_SUB
1075	KERNEL1x2_SUB
1076
1077	subs	L, L, #1
1078	bgt	zgemm_kernel_L2_M1_22
1079
1080
1081zgemm_kernel_L2_M1_40:
1082
1083	ands	L , K1, #7					// L = L % 8
1084	ble	zgemm_kernel_L2_M1_100
1085
1086zgemm_kernel_L2_M1_42:
1087
1088	KERNEL1x2_SUB
1089
1090	subs	L, L, #1
1091	bgt	zgemm_kernel_L2_M1_42
1092
1093zgemm_kernel_L2_M1_100:
1094
1095	SAVE1x2
1096
1097
1098zgemm_kernel_L2_END:
1099
1100	mov	r3, BC
1101	mov	r4, K1
1102	lsl	r4, r4, #5					// k * 2 * 8 * 2
1103	add	r3, r3, r4					// B = B + K * 4 * 8
1104	mov	BC, r3
1105
1106	subs	J , #1						// j--
1107	bgt	zgemm_kernel_L2_BEGIN
1108
1109
1110
1111/*********************************************************************************************/
1112
1113zgemm_kernel_L1_BEGIN:
1114
1115	ldr	J , N
1116	tst	J , #1
1117	ble	zgemm_kernel_L999
1118
1119
1120	ldr	CO1, C						// CO1 = C
1121	ldr	r4 , LDC
1122	add	r3 , r4, CO1
1123	str	r3 , C						// store C
1124
1125	ldr	AO, A						// AO = A
1126
1127zgemm_kernel_L1_M2_BEGIN:
1128
1129	ldr	I, M
1130	asrs	I, I, #1					// I = I / 2
1131	ble	zgemm_kernel_L1_M1_BEGIN
1132
1133zgemm_kernel_L1_M2_20:
1134
1135
1136	mov	BO, BC
1137	asrs	L , K1, #3					// L = L / 8
1138	cmp	L , #3
1139	blt	zgemm_kernel_L1_M2_30
1140	.align 5
1141
1142
1143
1144	KERNEL2x1_I
1145	KERNEL2x1_M2
1146	KERNEL2x1_M1
1147	KERNEL2x1_M2
1148
1149	KERNEL2x1_M1
1150	KERNEL2x1_M2
1151	KERNEL2x1_M1
1152	KERNEL2x1_M2
1153
1154	sub	L, L, #2
1155
1156zgemm_kernel_L1_M2_22:
1157
1158	KERNEL2x1_M1
1159	KERNEL2x1_M2
1160	KERNEL2x1_M1
1161	KERNEL2x1_M2
1162
1163	KERNEL2x1_M1
1164	KERNEL2x1_M2
1165	KERNEL2x1_M1
1166	KERNEL2x1_M2
1167
1168	subs	L, L, #1
1169	bgt	zgemm_kernel_L1_M2_22
1170
1171	KERNEL2x1_M1
1172	KERNEL2x1_M2
1173	KERNEL2x1_M1
1174	KERNEL2x1_M2
1175
1176	KERNEL2x1_M1
1177	KERNEL2x1_M2
1178	KERNEL2x1_M1
1179	KERNEL2x1_E
1180
1181	b	 zgemm_kernel_L1_M2_44
1182
1183
1184zgemm_kernel_L1_M2_30:
1185	tst	L, #3
1186	ble	zgemm_kernel_L1_M2_40
1187
1188	tst	L, #2
1189	ble	zgemm_kernel_L1_M2_32
1190
1191	KERNEL2x1_I
1192	KERNEL2x1_M2
1193	KERNEL2x1_M1
1194	KERNEL2x1_M2
1195
1196	KERNEL2x1_M1
1197	KERNEL2x1_M2
1198	KERNEL2x1_M1
1199	KERNEL2x1_M2
1200
1201	KERNEL2x1_M1
1202	KERNEL2x1_M2
1203	KERNEL2x1_M1
1204	KERNEL2x1_M2
1205
1206
1207	KERNEL2x1_M1
1208	KERNEL2x1_M2
1209	KERNEL2x1_M1
1210	KERNEL2x1_E
1211
1212	b	 zgemm_kernel_L1_M2_44
1213
1214zgemm_kernel_L1_M2_32:
1215
1216	tst	L, #1
1217	ble	zgemm_kernel_L1_M2_40
1218
1219	KERNEL2x1_I
1220	KERNEL2x1_M2
1221	KERNEL2x1_M1
1222	KERNEL2x1_M2
1223
1224	KERNEL2x1_M1
1225	KERNEL2x1_M2
1226	KERNEL2x1_M1
1227	KERNEL2x1_E
1228
1229	b	 zgemm_kernel_L1_M2_44
1230
1231
1232zgemm_kernel_L1_M2_40:
1233
1234	INIT2x1
1235
1236
1237zgemm_kernel_L1_M2_44:
1238
1239	ands	L , K1, #7					// L = L % 8
1240	ble	zgemm_kernel_L1_M2_100
1241
1242zgemm_kernel_L1_M2_46:
1243
1244	KERNEL2x1_SUB
1245
1246	subs	L, L, #1
1247	bne	zgemm_kernel_L1_M2_46
1248
1249zgemm_kernel_L1_M2_100:
1250
1251	SAVE2x1
1252
1253zgemm_kernel_L1_M2_END:
1254
1255	subs	I, I, #1
1256	bne	zgemm_kernel_L1_M2_20
1257
1258
1259zgemm_kernel_L1_M1_BEGIN:
1260
1261	ldr	I, M
1262	tst	I, #1					// I = I % 2
1263	ble	zgemm_kernel_L1_END
1264
1265zgemm_kernel_L1_M1_20:
1266
1267	INIT1x1
1268
1269	mov	BO, BC
1270	asrs	L , K1, #3					// L = L / 8
1271	ble	zgemm_kernel_L1_M1_40
1272
1273zgemm_kernel_L1_M1_22:
1274
1275	KERNEL1x1_SUB
1276	KERNEL1x1_SUB
1277	KERNEL1x1_SUB
1278	KERNEL1x1_SUB
1279
1280	KERNEL1x1_SUB
1281	KERNEL1x1_SUB
1282	KERNEL1x1_SUB
1283	KERNEL1x1_SUB
1284
1285	subs	L, L, #1
1286	bgt	zgemm_kernel_L1_M1_22
1287
1288
1289zgemm_kernel_L1_M1_40:
1290
1291	ands	L , K1, #7					// L = L % 8
1292	ble	zgemm_kernel_L1_M1_100
1293
1294zgemm_kernel_L1_M1_42:
1295
1296	KERNEL1x1_SUB
1297
1298	subs	L, L, #1
1299	bgt	zgemm_kernel_L1_M1_42
1300
1301zgemm_kernel_L1_M1_100:
1302
1303	SAVE1x1
1304
1305
1306zgemm_kernel_L1_END:
1307
1308
1309
1310zgemm_kernel_L999:
1311
1312	sub	r3, fp, #128
1313	vldm	r3, { d8 - d15}					// restore floating point registers
1314
1315	movs	r0, #0						// set return value
1316	sub	sp, fp, #24
1317	pop	{r4 - r9, fp}
1318	bx	lr
1319
1320	EPILOGUE
1321
1322