@@ -272,7 +272,7 @@ namespace lsp
272272 __ASM_EMIT (" ldp q28, q29, [%[k]], #0x20" )
273273 __ASM_EMIT (" ldp q6, q7, [%[a]], #0x20" )
274274 __ASM_EMIT (" ldp q30, q31, [%[k]], #0x20" )
275- __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
275+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
276276 __ASM_EMIT (" fsub v17.4s, v8.4s, v1.4s" )
277277 __ASM_EMIT (" fsub v18.4s, v8.4s, v2.4s" )
278278 __ASM_EMIT (" fsub v19.4s, v8.4s, v3.4s" )
@@ -302,7 +302,7 @@ namespace lsp
302302 __ASM_EMIT (" ldp q24, q25, [%[k]], #0x20" ) // v24 = k
303303 __ASM_EMIT (" ldp q2, q3, [%[a]], #0x20" )
304304 __ASM_EMIT (" ldp q26, q27, [%[k]], #0x20" )
305- __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
305+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
306306 __ASM_EMIT (" fsub v17.4s, v8.4s, v1.4s" )
307307 __ASM_EMIT (" fsub v18.4s, v8.4s, v2.4s" )
308308 __ASM_EMIT (" fsub v19.4s, v8.4s, v3.4s" )
@@ -319,7 +319,7 @@ namespace lsp
319319 __ASM_EMIT (" b.lt 6f" )
320320 __ASM_EMIT (" ldp q0, q1, [%[a]], #0x20" ) // v0 = a
321321 __ASM_EMIT (" ldp q24, q25, [%[k]], #0x20" ) // v24 = k
322- __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
322+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
323323 __ASM_EMIT (" fsub v17.4s, v8.4s, v1.4s" )
324324 __ASM_EMIT (" fmla v0.4s, v16.4s, v24.4s" ) // v0 = a + (b-a)*k
325325 __ASM_EMIT (" fmla v1.4s, v17.4s, v25.4s" )
@@ -331,7 +331,7 @@ namespace lsp
331331 __ASM_EMIT (" b.lt 8f" )
332332 __ASM_EMIT (" ldr q0, [%[a]], #0x10" ) // v0 = a
333333 __ASM_EMIT (" ldr q24, [%[k]], #0x10" ) // v24 = k
334- __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
334+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
335335 __ASM_EMIT (" fmla v0.4s, v16.4s, v24.4s" ) // v0 = a + (b-a)*k
336336 __ASM_EMIT (" sub %[count], %[count], #4" )
337337 __ASM_EMIT (" str q0, [%[dst]], #0x10" )
@@ -342,7 +342,7 @@ namespace lsp
342342 __ASM_EMIT (" 9:" )
343343 __ASM_EMIT (" ld1r {v0.4s}, [%[a]], #0x04" ) // v0 = a
344344 __ASM_EMIT (" ld1r {v24.4s}, [%[k]], #0x04" ) // v24 = k
345- __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
345+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
346346 __ASM_EMIT (" fmla v0.4s, v16.4s, v24.4s" ) // v0 = a + (b-a)*k
347347 __ASM_EMIT (" subs %[count], %[count], #1" )
348348 __ASM_EMIT (" st1 {v0.s}[0], [%[dst]], #0x04" )
@@ -363,6 +363,107 @@ namespace lsp
363363 " v28" , " v29" , " v30" , " v31"
364364 );
365365 }
366+
367+ void lerp_vkk (float *dst, const float *a, float b, float k, size_t count)
368+ {
369+ ARCH_AARCH64_ASM
370+ (
371+ // x32 blocks
372+ __ASM_EMIT (" subs %[count], %[count], #32" )
373+ __ASM_EMIT (" ld1r {v8.4s}, [%[b]]" ) // v8 = k
374+ __ASM_EMIT (" ld1r {v9.4s}, [%[k]]" ) // v9 = k
375+ __ASM_EMIT (" b.lo 2f" )
376+ __ASM_EMIT (" 1:" )
377+ __ASM_EMIT (" ldp q0, q1, [%[a]], #0x20" ) // v0 = a
378+ __ASM_EMIT (" ldp q2, q3, [%[a]], #0x20" )
379+ __ASM_EMIT (" ldp q4, q5, [%[a]], #0x20" )
380+ __ASM_EMIT (" ldp q6, q7, [%[a]], #0x20" )
381+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
382+ __ASM_EMIT (" fsub v17.4s, v8.4s, v1.4s" )
383+ __ASM_EMIT (" fsub v18.4s, v8.4s, v2.4s" )
384+ __ASM_EMIT (" fsub v19.4s, v8.4s, v3.4s" )
385+ __ASM_EMIT (" fsub v20.4s, v8.4s, v4.4s" )
386+ __ASM_EMIT (" fsub v21.4s, v8.4s, v5.4s" )
387+ __ASM_EMIT (" fsub v22.4s, v8.4s, v6.4s" )
388+ __ASM_EMIT (" fsub v23.4s, v8.4s, v7.4s" )
389+ __ASM_EMIT (" fmla v0.4s, v16.4s, v9.4s" ) // v0 = a + (b-a)*k
390+ __ASM_EMIT (" fmla v1.4s, v17.4s, v9.4s" )
391+ __ASM_EMIT (" fmla v2.4s, v18.4s, v9.4s" )
392+ __ASM_EMIT (" fmla v3.4s, v19.4s, v9.4s" )
393+ __ASM_EMIT (" fmla v4.4s, v20.4s, v9.4s" )
394+ __ASM_EMIT (" fmla v5.4s, v21.4s, v9.4s" )
395+ __ASM_EMIT (" fmla v6.4s, v22.4s, v9.4s" )
396+ __ASM_EMIT (" fmla v7.4s, v23.4s, v9.4s" )
397+ __ASM_EMIT (" subs %[count], %[count], #32" )
398+ __ASM_EMIT (" stp q0, q1, [%[dst]], #0x20" )
399+ __ASM_EMIT (" stp q2, q3, [%[dst]], #0x20" )
400+ __ASM_EMIT (" stp q4, q5, [%[dst]], #0x20" )
401+ __ASM_EMIT (" stp q6, q7, [%[dst]], #0x20" )
402+ __ASM_EMIT (" b.hs 1b" )
403+ // x16 block
404+ __ASM_EMIT (" 2:" )
405+ __ASM_EMIT (" adds %[count], %[count], #16" )
406+ __ASM_EMIT (" b.lt 4f" )
407+ __ASM_EMIT (" ldp q0, q1, [%[a]], #0x20" ) // v0 = a
408+ __ASM_EMIT (" ldp q2, q3, [%[a]], #0x20" )
409+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
410+ __ASM_EMIT (" fsub v17.4s, v8.4s, v1.4s" )
411+ __ASM_EMIT (" fsub v18.4s, v8.4s, v2.4s" )
412+ __ASM_EMIT (" fsub v19.4s, v8.4s, v3.4s" )
413+ __ASM_EMIT (" fmla v0.4s, v16.4s, v9.4s" ) // v0 = a + (b-a)*k
414+ __ASM_EMIT (" fmla v1.4s, v17.4s, v9.4s" )
415+ __ASM_EMIT (" fmla v2.4s, v18.4s, v9.4s" )
416+ __ASM_EMIT (" fmla v3.4s, v19.4s, v9.4s" )
417+ __ASM_EMIT (" sub %[count], %[count], #16" )
418+ __ASM_EMIT (" stp q0, q1, [%[dst]], #0x20" )
419+ __ASM_EMIT (" stp q2, q3, [%[dst]], #0x20" )
420+ // x8 block
421+ __ASM_EMIT (" 4:" )
422+ __ASM_EMIT (" adds %[count], %[count], #8" )
423+ __ASM_EMIT (" b.lt 6f" )
424+ __ASM_EMIT (" ldp q0, q1, [%[a]], #0x20" ) // v0 = a
425+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
426+ __ASM_EMIT (" fsub v17.4s, v8.4s, v1.4s" )
427+ __ASM_EMIT (" fmla v0.4s, v16.4s, v9.4s" ) // v0 = a + (b-a)*k
428+ __ASM_EMIT (" fmla v1.4s, v17.4s, v9.4s" )
429+ __ASM_EMIT (" sub %[count], %[count], #8" )
430+ __ASM_EMIT (" stp q0, q1, [%[dst]], #0x20" )
431+ // x4 blocks
432+ __ASM_EMIT (" 6:" )
433+ __ASM_EMIT (" adds %[count], %[count], #4" )
434+ __ASM_EMIT (" b.lt 8f" )
435+ __ASM_EMIT (" ldr q0, [%[a]], #0x10" ) // v0 = a
436+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
437+ __ASM_EMIT (" fmla v0.4s, v16.4s, v9.4s" ) // v0 = a + (b-a)*k
438+ __ASM_EMIT (" sub %[count], %[count], #4" )
439+ __ASM_EMIT (" str q0, [%[dst]], #0x10" )
440+ // x1 blocks
441+ __ASM_EMIT (" 8:" )
442+ __ASM_EMIT (" adds %[count], %[count], #3" )
443+ __ASM_EMIT (" b.lt 10f" )
444+ __ASM_EMIT (" 9:" )
445+ __ASM_EMIT (" ld1r {v0.4s}, [%[a]], #0x04" ) // v0 = a
446+ __ASM_EMIT (" fsub v16.4s, v8.4s, v0.4s" ) // v16 = b-a
447+ __ASM_EMIT (" fmla v0.4s, v16.4s, v9.4s" ) // v0 = a + (b-a)*k
448+ __ASM_EMIT (" subs %[count], %[count], #1" )
449+ __ASM_EMIT (" st1 {v0.s}[0], [%[dst]], #0x04" )
450+ __ASM_EMIT (" b.ge 9b" )
451+ // end
452+ __ASM_EMIT (" 10:" )
453+
454+ : [dst] " +r" (dst), [a] " +r" (a), [k] " +r" (k),
455+ [count] " +r" (count)
456+ : [b] " r" (&b)
457+ : " cc" , " memory" ,
458+ " v0" , " v1" , " v2" , " v3" ,
459+ " v4" , " v5" , " v6" , " v7" ,
460+ " v8" ,
461+ " v16" , " v17" , " v18" , " v19" ,
462+ " v20" , " v21" , " v22" , " v23" ,
463+ " v24" , " v25" , " v26" , " v27" ,
464+ " v28" , " v29" , " v30" , " v31"
465+ );
466+ }
366467 } /* namespace asimd */
367468} /* namespace lsp */
368469
0 commit comments