@@ -186,7 +186,7 @@ namespace lsp
186186 __ASM_EMIT (" stp q2, q3, [%[dst]], #0x20" )
187187 __ASM_EMIT (" stp q4, q5, [%[dst]], #0x20" )
188188 __ASM_EMIT (" stp q6, q7, [%[dst]], #0x20" )
189- __ASM_EMIT (" b.hs 1b" )
189+ __ASM_EMIT (" b.hs 1b" )
190190 // x16 block
191191 __ASM_EMIT (" 2:" )
192192 __ASM_EMIT (" adds %[count], %[count], #16" )
@@ -254,6 +254,115 @@ namespace lsp
254254 " v24"
255255 );
256256 }
257+
258+ void lerp_vkv (float *dst, const float *a, const float *b, float k, size_t count)
259+ {
260+ ARCH_AARCH64_ASM
261+ (
262+ // x32 blocks
263+ __ASM_EMIT (" subs %[count], %[count], #32" )
264+ __ASM_EMIT (" ld1r {v8.4s}, [%[b]]" ) // v8 = k
265+ __ASM_EMIT (" b.lo 2f" )
266+ __ASM_EMIT (" 1:" )
267+ __ASM_EMIT (" ldp q0, q1, [%[a]], #0x20" ) // v0 = a
268+ __ASM_EMIT (" ldp q24, q25, [%[k]], #0x20" ) // v24 = k
269+ __ASM_EMIT (" ldp q2, q3, [%[a]], #0x20" )
270+ __ASM_EMIT (" ldp q26, q27, [%[k]], #0x20" )
271+ __ASM_EMIT (" ldp q4, q5, [%[a]], #0x20" )
272+ __ASM_EMIT (" ldp q28, q29, [%[k]], #0x20" )
273+ __ASM_EMIT (" ldp q6, q7, [%[a]], #0x20" )
274+ __ASM_EMIT (" ldp q30, q31, [%[k]], #0x20" )
275+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
276+ __ASM_EMIT (" fsub v17.4s, v8.4s, v1.4s" )
277+ __ASM_EMIT (" fsub v18.4s, v8.4s, v2.4s" )
278+ __ASM_EMIT (" fsub v19.4s, v8.4s, v3.4s" )
279+ __ASM_EMIT (" fsub v20.4s, v8.4s, v4.4s" )
280+ __ASM_EMIT (" fsub v21.4s, v8.4s, v5.4s" )
281+ __ASM_EMIT (" fsub v22.4s, v8.4s, v6.4s" )
282+ __ASM_EMIT (" fsub v23.4s, v8.4s, v7.4s" )
283+ __ASM_EMIT (" fmla v0.4s, v16.4s, v24.4s" ) // v0 = a + (b-a)*k
284+ __ASM_EMIT (" fmla v1.4s, v17.4s, v25.4s" )
285+ __ASM_EMIT (" fmla v2.4s, v18.4s, v26.4s" )
286+ __ASM_EMIT (" fmla v3.4s, v19.4s, v27.4s" )
287+ __ASM_EMIT (" fmla v4.4s, v20.4s, v28.4s" )
288+ __ASM_EMIT (" fmla v5.4s, v21.4s, v29.4s" )
289+ __ASM_EMIT (" fmla v6.4s, v22.4s, v30.4s" )
290+ __ASM_EMIT (" fmla v7.4s, v23.4s, v31.4s" )
291+ __ASM_EMIT (" subs %[count], %[count], #32" )
292+ __ASM_EMIT (" stp q0, q1, [%[dst]], #0x20" )
293+ __ASM_EMIT (" stp q2, q3, [%[dst]], #0x20" )
294+ __ASM_EMIT (" stp q4, q5, [%[dst]], #0x20" )
295+ __ASM_EMIT (" stp q6, q7, [%[dst]], #0x20" )
296+ __ASM_EMIT (" b.hs 1b" )
297+ // x16 block
298+ __ASM_EMIT (" 2:" )
299+ __ASM_EMIT (" adds %[count], %[count], #16" )
300+ __ASM_EMIT (" b.lt 4f" )
301+ __ASM_EMIT (" ldp q0, q1, [%[a]], #0x20" ) // v0 = a
302+ __ASM_EMIT (" ldp q24, q25, [%[k]], #0x20" ) // v24 = k
303+ __ASM_EMIT (" ldp q2, q3, [%[a]], #0x20" )
304+ __ASM_EMIT (" ldp q26, q27, [%[k]], #0x20" )
305+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
306+ __ASM_EMIT (" fsub v17.4s, v8.4s, v1.4s" )
307+ __ASM_EMIT (" fsub v18.4s, v8.4s, v2.4s" )
308+ __ASM_EMIT (" fsub v19.4s, v8.4s, v3.4s" )
309+ __ASM_EMIT (" fmla v0.4s, v16.4s, v24.4s" ) // v0 = a + (b-a)*k
310+ __ASM_EMIT (" fmla v1.4s, v17.4s, v25.4s" )
311+ __ASM_EMIT (" fmla v2.4s, v18.4s, v26.4s" )
312+ __ASM_EMIT (" fmla v3.4s, v19.4s, v27.4s" )
313+ __ASM_EMIT (" sub %[count], %[count], #16" )
314+ __ASM_EMIT (" stp q0, q1, [%[dst]], #0x20" )
315+ __ASM_EMIT (" stp q2, q3, [%[dst]], #0x20" )
316+ // x8 block
317+ __ASM_EMIT (" 4:" )
318+ __ASM_EMIT (" adds %[count], %[count], #8" )
319+ __ASM_EMIT (" b.lt 6f" )
320+ __ASM_EMIT (" ldp q0, q1, [%[a]], #0x20" ) // v0 = a
321+ __ASM_EMIT (" ldp q24, q25, [%[k]], #0x20" ) // v24 = k
322+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
323+ __ASM_EMIT (" fsub v17.4s, v8.4s, v1.4s" )
324+ __ASM_EMIT (" fmla v0.4s, v16.4s, v24.4s" ) // v0 = a + (b-a)*k
325+ __ASM_EMIT (" fmla v1.4s, v17.4s, v25.4s" )
326+ __ASM_EMIT (" sub %[count], %[count], #8" )
327+ __ASM_EMIT (" stp q0, q1, [%[dst]], #0x20" )
328+ // x4 blocks
329+ __ASM_EMIT (" 6:" )
330+ __ASM_EMIT (" adds %[count], %[count], #4" )
331+ __ASM_EMIT (" b.lt 8f" )
332+ __ASM_EMIT (" ldr q0, [%[a]], #0x10" ) // v0 = a
333+ __ASM_EMIT (" ldr q24, [%[k]], #0x10" ) // v24 = k
334+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
335+ __ASM_EMIT (" fmla v0.4s, v16.4s, v24.4s" ) // v0 = a + (b-a)*k
336+ __ASM_EMIT (" sub %[count], %[count], #4" )
337+ __ASM_EMIT (" str q0, [%[dst]], #0x10" )
338+ // x1 blocks
339+ __ASM_EMIT (" 8:" )
340+ __ASM_EMIT (" adds %[count], %[count], #3" )
341+ __ASM_EMIT (" b.lt 10f" )
342+ __ASM_EMIT (" 9:" )
343+ __ASM_EMIT (" ld1r {v0.4s}, [%[a]], #0x04" ) // v0 = a
344+ __ASM_EMIT (" ld1r {v24.4s}, [%[k]], #0x04" ) // v24 = k
345+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
346+ __ASM_EMIT (" fmla v0.4s, v16.4s, v24.4s" ) // v0 = a + (b-a)*k
347+ __ASM_EMIT (" subs %[count], %[count], #1" )
348+ __ASM_EMIT (" st1 {v0.s}[0], [%[dst]], #0x04" )
349+ __ASM_EMIT (" b.ge 9b" )
350+ // end
351+ __ASM_EMIT (" 10:" )
352+
353+ : [dst] " +r" (dst), [a] " +r" (a), [k] " +r" (k),
354+ [count] " +r" (count)
355+ : [b] " r" (&b)
356+ : " cc" , " memory" ,
357+ " v0" , " v1" , " v2" , " v3" ,
358+ " v4" , " v5" , " v6" , " v7" ,
359+ " v8" ,
360+ " v16" , " v17" , " v18" , " v19" ,
361+ " v20" , " v21" , " v22" , " v23" ,
362+ " v24" , " v25" , " v26" , " v27" ,
363+ " v28" , " v29" , " v30" , " v31"
364+ );
365+ }
257366 } /* namespace asimd */
258367} /* namespace lsp */
259368
0 commit comments