blob: afa9727be89b4079c94f59aae59bccc361dc467b [file] [log] [blame]
Frank Barchard90ce7892020-02-10 23:35:45 -08001// Auto-generated file. Do not edit!
2// Template: src/f32-igemm/4x8-aarch32-neon-cortex-a75.S.in
3// Generator: tools/xngen
4//
5// Copyright 2019 Google LLC
6//
7// This source code is licensed under the BSD-style license found in the
8// LICENSE file in the root directory of this source tree.
9
10#include <xnnpack/assembly.h>
11
12.syntax unified
13
14// void xnn_f32_igemm_ukernel_4x8__aarch32_neon_cortex_a75(
15// size_t mr, r0
16// size_t nc, r1
Frank Barchard52261a82020-02-12 18:31:39 -080017// size_t kc, r2 -> r5 -> sp + 68
18// size_t ks, r3 -> sp + 72 -> r14
19// const float**restrict a, sp + 112 -> r2
20// const void*restrict w, sp + 116 -> r9
21// uint8_t*restrict c, sp + 120 -> r11
22// size_t cm_stride, sp + 124 -> (r6)
23// size_t cn_stride, sp + 128 -> (r7)
24// size_t a_offset, sp + 132 -> (r5)
25// const float* zero, sp + 136 -> (r7)
Marat Dukhaneb09a6b2020-04-08 17:34:32 -070026// minmax_params*params, sp + 140 -> (r5)
Frank Barchard90ce7892020-02-10 23:35:45 -080027
28// inner loop registers
29
30// A0 r3 d0
31// A1 r12 d1
32// A2 r10 d2
33// A3 r0 d3
34
35// B r9 d8, d9, d10, d11
36// B d12, d13, d14, d15
37
38// C0 r11 d16-d17 q8 d18-d19 q9
39// C1 r4 d20-d21 q10 d22-d23 q11
40// C2 r8 d24-d25 q12 d26-d27 q13
41// C3 r6 d28-d29 q14 d30-d31 q15
42
43// Clamp (r5) d4 d5 d6 d7
44
45BEGIN_FUNCTION xnn_f32_igemm_ukernel_4x8__aarch32_neon_cortex_a75
46 .arm
47#ifndef __APPLE__
48 .arch armv7-a
49 .fpu neon
50#endif
Frank Barchard52261a82020-02-12 18:31:39 -080051 // Push 112 bytes
Frank Barchard90ce7892020-02-10 23:35:45 -080052 // r2 will be reloaded in outer loop. r3 is ks
53 PUSH {r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r14} // +44
Frank Barchard52261a82020-02-12 18:31:39 -080054 SUB sp, sp, 4 // 4
55 VPUSH {d8-d15} // +64 = 112
Frank Barchard90ce7892020-02-10 23:35:45 -080056
Frank Barchard52261a82020-02-12 18:31:39 -080057 LDR r11, [sp, 120] // c
58 LDR r6, [sp, 124] // cm_stride
59 LDR r2, [sp, 112] // a
60 LDR r9, [sp, 116] // w
Frank Barchardc1a06972020-02-12 11:34:17 -080061 MOV r14, r3 // p = ks
Frank Barchard90ce7892020-02-10 23:35:45 -080062
63 // Clamp C pointers
64 CMP r0, 2 // if mr >= 2
65 ADD r4, r11, r6 // c1 = c0 + cm_stride
66 MOVLO r4, r11 // c1
67 // if mr > 2
68 ADD r8, r4, r6 // c2 = c1 + cm_stride
69 MOVLS r8, r4 // c2
70 CMP r0, 4 // if mr >=4
71 ADD r6, r8, r6 // c3 = c2 + cm_stride
72 MOVLO r6, r8 // c3
73
74 .p2align 3
750:
76 # Load initial bias from w into accumulators
77 VLDM r9!, {d16-d19} // Bias
78 VMOV q10, q8
79 VMOV q11, q9
80 VMOV q12, q8
81 VMOV q13, q9
82 VMOV q14, q8
83 VMOV q15, q9
84
85
861:
87 # Load next 4 A pointers
88 LDR r3, [r2, 0]
89 LDR r12, [r2, 4]
90 LDR r10, [r2, 8]
91 LDR r0, [r2, 12]
92 ADD r2, r2, 16
93
94 // Add a_offset
Frank Barchard52261a82020-02-12 18:31:39 -080095 LDR r5, [sp, 132] // a_offset
96 LDR r7, [sp, 136] // zero
Frank Barchard90ce7892020-02-10 23:35:45 -080097 CMP r3, r7 // if a0 == zero
98 ADD r3, r3, r5 // a0 += a_offset
99 MOVEQ r3, r7 // a0 = zero, else += a0 + a_offset
100 CMP r12, r7 // if a1 == zero
101 ADD r12, r12, r5 // a1 += a_offset
102 MOVEQ r12, r7 // a1 = zero, else += a1 + a_offset
103 CMP r10, r7 // if a2 == zero
104 ADD r10, r10, r5 // a2 += a_offset
105 MOVEQ r10, r7 // a2 = zero, else += a2 + a_offset
106 CMP r0, r7 // if a3 == zero
107 ADD r0, r0, r5 // a3 += a_offset
Frank Barchard52261a82020-02-12 18:31:39 -0800108 LDR r5, [sp, 68] // kc
Frank Barchard90ce7892020-02-10 23:35:45 -0800109 MOVEQ r0, r7 // a3 = zero, else += a3 + a_offset
110
111
112 SUBS r5, r5, 16 // kc - 16
Frank Barchardc1a06972020-02-12 11:34:17 -0800113 BLO 5f // less than 4 channels?
Frank Barchard90ce7892020-02-10 23:35:45 -0800114
115 // Prologue
116 VLD1.32 {d0}, [r3]! // A0
117 VLDM r9!, {d8-d11} // B0
118 VLD1.32 {d1}, [r12]! // A1
119 VLD1.32 {d2}, [r10]! // A2
120 VLD1.32 {d3}, [ r0]! // A3
121
122 SUBS r5, r5, 16
123 BLO 3f // less than 4 channels? skip main loop
124
125 .p2align 3
126
127 // Main loop - 4 floats of A (16 bytes)
1282:
129 VMLA.F32 q8, q4, d0[0]
130 VLDM r9!, {d12-d15} // B1
131 VMLA.F32 q10, q4, d1[0]
132 VMLA.F32 q12, q4, d2[0]
133 VLD1.32 {d4}, [r3]! // A0
134 VMLA.F32 q14, q4, d3[0]
135 VMLA.F32 q9, q5, d0[0]
136 VLD1.32 {d5}, [r12]! // A1
137 VMLA.F32 q11, q5, d1[0]
138 VMLA.F32 q13, q5, d2[0]
139 VMLA.F32 q15, q5, d3[0]
140 VLD1.32 {d6}, [r10]! // A2
141 VMLA.F32 q8, q6, d0[1]
142 VMLA.F32 q10, q6, d1[1]
143 VLD1.32 {d7}, [ r0]! // A3
144 VMLA.F32 q12, q6, d2[1]
145 VMLA.F32 q14, q6, d3[1]
146 VLDM r9!, {d8-d11} // B0
147 VMLA.F32 q9, q7, d0[1]
148 VMLA.F32 q11, q7, d1[1]
149 VMLA.F32 q13, q7, d2[1]
150 VMLA.F32 q15, q7, d3[1]
151
152 VMLA.F32 q8, q4, d4[0]
153 VLDM r9!, {d12-d15} // B1
154 VMLA.F32 q10, q4, d5[0]
155 VMLA.F32 q12, q4, d6[0]
156 VLD1.32 {d0}, [r3]! // A0
157 VMLA.F32 q14, q4, d7[0]
158 VMLA.F32 q9, q5, d4[0]
159 VLD1.32 {d1}, [r12]! // A1
160 VMLA.F32 q11, q5, d5[0]
161 VMLA.F32 q13, q5, d6[0]
162 VLD1.32 {d2}, [r10]! // A2
163 VMLA.F32 q15, q5, d7[0]
164 VMLA.F32 q8, q6, d4[1]
165 VLD1.32 {d3}, [ r0]! // A3
166 VMLA.F32 q10, q6, d5[1]
167 VMLA.F32 q12, q6, d6[1]
168 VMLA.F32 q14, q6, d7[1]
169 VLDM r9!, {d8-d11} // B0
170 VMLA.F32 q9, q7, d4[1]
171 VMLA.F32 q11, q7, d5[1]
172 SUBS r5, r5, 16
173 VMLA.F32 q13, q7, d6[1]
174 VMLA.F32 q15, q7, d7[1]
175 BHS 2b
176
177 // Epilogue
1783:
179 VMLA.F32 q8, q4, d0[0]
180 VLDM r9!, {d12-d15} // B1
181 VMLA.F32 q10, q4, d1[0]
182 VMLA.F32 q12, q4, d2[0]
183 VLD1.32 {d4}, [r3]! // A0
184 VMLA.F32 q14, q4, d3[0]
185 VMLA.F32 q9, q5, d0[0]
186 VLD1.32 {d5}, [r12]! // A1
187 VMLA.F32 q11, q5, d1[0]
188 VMLA.F32 q13, q5, d2[0]
189 VMLA.F32 q15, q5, d3[0]
190 VLD1.32 {d6}, [r10]! // A2
191 VMLA.F32 q8, q6, d0[1]
192 VMLA.F32 q10, q6, d1[1]
193 VLD1.32 {d7}, [ r0]! // A3
194 VMLA.F32 q12, q6, d2[1]
195 VMLA.F32 q14, q6, d3[1]
196 VLDM r9!, {d8-d11} // B0
197 VMLA.F32 q9, q7, d0[1]
198 VMLA.F32 q11, q7, d1[1]
199 VMLA.F32 q13, q7, d2[1]
200 VMLA.F32 q15, q7, d3[1]
201
202 VMLA.F32 q8, q4, d4[0]
203 VLDM r9!, {d12-d15} // B1
204 VMLA.F32 q10, q4, d5[0]
205 VMLA.F32 q12, q4, d6[0]
206 VMLA.F32 q14, q4, d7[0]
207 VMLA.F32 q9, q5, d4[0]
208 VMLA.F32 q11, q5, d5[0]
209 VMLA.F32 q13, q5, d6[0]
210 VMLA.F32 q15, q5, d7[0]
211 VMLA.F32 q8, q6, d4[1]
212 VMLA.F32 q10, q6, d5[1]
213 VMLA.F32 q12, q6, d6[1]
214 VMLA.F32 q14, q6, d7[1]
215 VMLA.F32 q9, q7, d4[1]
216 VMLA.F32 q11, q7, d5[1]
217 VMLA.F32 q13, q7, d6[1]
218 VMLA.F32 q15, q7, d7[1]
219
Frank Barchard90ce7892020-02-10 23:35:45 -0800220 // Is there a remainder?- 1 to 3 floats of A (4, 8 or 12 bytes)
221 TST r5, 12
Frank Barchardc1a06972020-02-12 11:34:17 -0800222 BNE 5f
Frank Barchard90ce7892020-02-10 23:35:45 -0800223
224 .p2align 3
Frank Barchardc1a06972020-02-12 11:34:17 -08002254:
Frank Barchard90ce7892020-02-10 23:35:45 -0800226 # ks loop
227 SUBS r14, r14, 16 // ks -= MR * sizeof(void*)
Frank Barchard16d72722020-02-12 15:46:20 -0800228 BHI 1b
Frank Barchard90ce7892020-02-10 23:35:45 -0800229
230 // Load params pointer
Marat Dukhaneb09a6b2020-04-08 17:34:32 -0700231 LDR r5, [sp, 140] // params
Frank Barchard52261a82020-02-12 18:31:39 -0800232 LDR r7, [sp, 128] // cn_stride
233 LDR r14, [sp, 72] // p = ks
Frank Barchard90ce7892020-02-10 23:35:45 -0800234
Marat Dukhaneb09a6b2020-04-08 17:34:32 -0700235 // Load min/max values
Frank Barchard90ce7892020-02-10 23:35:45 -0800236 VLD1.32 {d4[],d5[]}, [r5]!
237 SUBS r1, r1, 8
238 VLD1.32 {d6[],d7[]}, [r5]
239
240 // Clamp
Marat Dukhana51cf482020-04-08 16:16:19 -0700241 VMAX.F32 q8, q8, q2
242 VMAX.F32 q9, q9, q2
243 VMAX.F32 q10, q10, q2
244 VMAX.F32 q11, q11, q2
245 VMAX.F32 q12, q12, q2
246 VMAX.F32 q13, q13, q2
247 VMAX.F32 q14, q14, q2
248 VMAX.F32 q15, q15, q2
249 VMIN.F32 q8, q8, q3
250 VMIN.F32 q9, q9, q3
251 VMIN.F32 q10, q10, q3
252 VMIN.F32 q11, q11, q3
253 VMIN.F32 q12, q12, q3
254 VMIN.F32 q13, q13, q3
255 VMIN.F32 q14, q14, q3
256 VMIN.F32 q15, q15, q3
Frank Barchard90ce7892020-02-10 23:35:45 -0800257
258 // Store full 4 x 8
259 BLO 10f
Frank Barchard52261a82020-02-12 18:31:39 -0800260 VST1.32 {d28-d31}, [r6], r7
261 VST1.32 {d24-d27}, [r8], r7
262 VST1.32 {d20-d23}, [r4], r7
Frank Barchard90ce7892020-02-10 23:35:45 -0800263 VST1.32 {d16-d19}, [r11], r7
264 SUB r2, r2, r14 // a -= ks
265 BHI 0b
266
Frank Barchard90ce7892020-02-10 23:35:45 -0800267 VPOP {d8-d15}
Frank Barchard52261a82020-02-12 18:31:39 -0800268 ADD sp, sp, 12 // skip pad, r2, r3
Frank Barchard90ce7892020-02-10 23:35:45 -0800269 POP {r4, r5, r6, r7, r8, r9, r10, r11, pc}
270
271 .p2align 3
Frank Barchardc1a06972020-02-12 11:34:17 -08002725:
Frank Barchard90ce7892020-02-10 23:35:45 -0800273 // Is there a remainder?- 2 floats of A (8 bytes)
274 TST r5, 8
Frank Barchardc1a06972020-02-12 11:34:17 -0800275 BEQ 6f
Frank Barchard90ce7892020-02-10 23:35:45 -0800276
277 // Remainder - 2 floats of A (8 bytes)
278 VLD1.32 {d0}, [r3]! // A0
279 VLDM r9!, {d8-d11} // B0
280 VLD1.32 {d1}, [r12]! // A1
281 VLD1.32 {d2}, [r10]! // A2
282 VLD1.32 {d3}, [ r0]! // A3
283
284 VMLA.F32 q8, q4, d0[0]
285 VMLA.F32 q9, q5, d0[0]
286 VMLA.F32 q10, q4, d1[0]
287 VMLA.F32 q11, q5, d1[0]
288 VLDM r9!, {d12-d15} // B1
289 VMLA.F32 q12, q4, d2[0]
290 VMLA.F32 q13, q5, d2[0]
291 VMLA.F32 q14, q4, d3[0]
292 VMLA.F32 q15, q5, d3[0]
293 VMLA.F32 q8, q6, d0[1]
294 VMLA.F32 q9, q7, d0[1]
295 VMLA.F32 q10, q6, d1[1]
296 VMLA.F32 q11, q7, d1[1]
297 VMLA.F32 q12, q6, d2[1]
298 VMLA.F32 q13, q7, d2[1]
299 VMLA.F32 q14, q6, d3[1]
300 VMLA.F32 q15, q7, d3[1]
Frank Barchardc1a06972020-02-12 11:34:17 -0800301
Frank Barchard90ce7892020-02-10 23:35:45 -0800302 // Is there a remainder?- 1 floats of A (4 bytes)
303 TST r5, 4
Frank Barchardc1a06972020-02-12 11:34:17 -0800304 BEQ 4b
Frank Barchard90ce7892020-02-10 23:35:45 -0800305
Frank Barchardc1a06972020-02-12 11:34:17 -08003066:
Frank Barchard90ce7892020-02-10 23:35:45 -0800307 // Remainder- 1 floats of A (4 bytes)
308 VLDM r3!, {s0} // A0
309 VLDM r9!, {d8-d11} // B0
310 VLDM r12!, {s2} // A1
311 VLDM r10!, {s4} // A2
312 VLDM r0!, {s6} // A3
313 VMLA.F32 q8, q4, d0[0]
314 VMLA.F32 q9, q5, d0[0]
315 VMLA.F32 q10, q4, d1[0]
316 VMLA.F32 q11, q5, d1[0]
317 VMLA.F32 q12, q4, d2[0]
318 VMLA.F32 q13, q5, d2[0]
319 VMLA.F32 q14, q4, d3[0]
320 VMLA.F32 q15, q5, d3[0]
Frank Barchardc1a06972020-02-12 11:34:17 -0800321 B 4b
Frank Barchard90ce7892020-02-10 23:35:45 -0800322
323 // Store odd width
32410:
325 TST r1, 4
326 BEQ 11f
327 VST1.32 {d28-d29}, [r6]!
328 VMOV q14, q15
329 VST1.32 {d24-d25}, [r8]!
330 VMOV q12, q13
331 VST1.32 {d20-d21}, [r4]!
332 VMOV q10, q11
333 VST1.32 {d16-d17}, [r11]!
334 VMOV q8, q9
335
33611:
337 TST r1, 2
338 BEQ 12f
339 VST1.32 {d28}, [r6]!
340 VMOV d28, d29
341 VST1.32 {d24}, [r8]!
342 VMOV d24, d25
343 VST1.32 {d20}, [r4]!
344 VMOV d20, d21
345 VST1.32 {d16}, [r11]!
346 VMOV d16, d17
347
34812:
349 TST r1, 1
350 BEQ 13f
351 VST1.32 {d28[0]}, [r6]!
352 VST1.32 {d24[0]}, [r8]!
353 VST1.32 {d20[0]}, [r4]!
354 VST1.32 {d16[0]}, [r11]!
355
35613:
357 VPOP {d8-d15}
Frank Barchard52261a82020-02-12 18:31:39 -0800358 ADD sp, sp, 12 // skip pad, r2, r3
Frank Barchard90ce7892020-02-10 23:35:45 -0800359 POP {r4, r5, r6, r7, r8, r9, r10, r11, pc}
360
361END_FUNCTION xnn_f32_igemm_ukernel_4x8__aarch32_neon_cortex_a75
362
363#ifdef __ELF__
364.section ".note.GNU-stack","",%progbits
365#endif
366
367
368