@@ -314,6 +314,84 @@ namespace lsp
314314 );
315315 }
316316
317+ void lerp_kvv (float *dst, float a, const float *b, const float *k, size_t count)
318+ {
319+ ARCH_ARM_ASM
320+ (
321+ // x16 blocks
322+ __ASM_EMIT (" subs %[count], #16" )
323+ __ASM_EMIT (" vld1.32 {d16[], d17[]}, [%[a]]" ) // q8 = a
324+ __ASM_EMIT (" blo 2f" )
325+ __ASM_EMIT (" 1:" )
326+ __ASM_EMIT (" vldm %[b]!, {q12-q15}" ) // q12 = b
327+ __ASM_EMIT (" vmov q0, q8" ) // q0 = a
328+ __ASM_EMIT (" vmov q1, q8" )
329+ __ASM_EMIT (" vmov q2, q8" )
330+ __ASM_EMIT (" vmov q3, q8" )
331+ __ASM_EMIT (" vldm %[k]!, {q4-q7}" ) // q4 = k
332+ __ASM_EMIT (" vsub.f32 q12, q12, q0" ) // q12 = b-a
333+ __ASM_EMIT (" vsub.f32 q13, q13, q1" )
334+ __ASM_EMIT (" vsub.f32 q14, q14, q2" )
335+ __ASM_EMIT (" vsub.f32 q15, q15, q3" )
336+ __ASM_EMIT (" vmla.f32 q0, q12, q4" ) // q0 = a + (b-a)*k
337+ __ASM_EMIT (" vmla.f32 q1, q13, q5" )
338+ __ASM_EMIT (" vmla.f32 q2, q14, q6" )
339+ __ASM_EMIT (" vmla.f32 q3, q15, q7" )
340+ __ASM_EMIT (" subs %[count], #16" )
341+ __ASM_EMIT (" vstm %[dst]!, {q0-q3}" )
342+ __ASM_EMIT (" bhs 1b" )
343+ // x8 block
344+ __ASM_EMIT (" 2:" )
345+ __ASM_EMIT (" adds %[count], #8" )
346+ __ASM_EMIT (" blt 4f" )
347+ __ASM_EMIT (" vldm %[b]!, {q12-q13}" ) // q12 = b
348+ __ASM_EMIT (" vmov q0, q8" ) // q0 = a
349+ __ASM_EMIT (" vmov q1, q8" )
350+ __ASM_EMIT (" vldm %[k]!, {q4-q5}" ) // q4 = k
351+ __ASM_EMIT (" vsub.f32 q12, q12, q0" ) // q12 = b-a
352+ __ASM_EMIT (" vsub.f32 q13, q13, q1" )
353+ __ASM_EMIT (" vmla.f32 q0, q12, q4" ) // q0 = a + (b-a)*k
354+ __ASM_EMIT (" vmla.f32 q1, q13, q5" )
355+ __ASM_EMIT (" sub %[count], #8" )
356+ __ASM_EMIT (" vstm %[dst]!, {q0-q1}" )
357+ // x4 blocks
358+ __ASM_EMIT (" 4:" )
359+ __ASM_EMIT (" adds %[count], #4" )
360+ __ASM_EMIT (" blt 6f" )
361+ __ASM_EMIT (" vldm %[b]!, {q12}" ) // q12 = b
362+ __ASM_EMIT (" vmov q0, q8" ) // q0 = a
363+ __ASM_EMIT (" vldm %[k]!, {q4}" ) // q4 = k
364+ __ASM_EMIT (" vsub.f32 q12, q12, q0" ) // q12 = b-a
365+ __ASM_EMIT (" vmla.f32 q0, q12, q4" ) // q0 = a + (b-a)*k
366+ __ASM_EMIT (" sub %[count], #4" )
367+ __ASM_EMIT (" vstm %[dst]!, {q0}" )
368+ // x1 blocks
369+ __ASM_EMIT (" 6:" )
370+ __ASM_EMIT (" adds %[count], #3" )
371+ __ASM_EMIT (" blt 8f" )
372+ __ASM_EMIT (" 7:" )
373+ __ASM_EMIT (" vld1.32 {d24[], d25[]}, [%[b]]!" ) // q12 = b
374+ __ASM_EMIT (" vmov q0, q8" ) // q0 = a
375+ __ASM_EMIT (" vld1.32 {d8[], d9[]}, [%[k]]!" ) // q4 = k
376+ __ASM_EMIT (" vsub.f32 q12, q12, q0" ) // q12 = b-a
377+ __ASM_EMIT (" vmla.f32 q0, q12, q4" ) // q0 = a + (b-a)*k
378+ __ASM_EMIT (" subs %[count], #1" )
379+ __ASM_EMIT (" vst1.32 {d0[0]}, [%[dst]]!" )
380+ __ASM_EMIT (" bge 7b" )
381+ // end
382+ __ASM_EMIT (" 8:" )
383+
384+ : [dst] " +r" (dst), [b] " +r" (b), [k] " +r" (k),
385+ [count] " +r" (count)
386+ : [a] " r" (&a)
387+ : " cc" , " memory" ,
388+ " q0" , " q1" , " q2" , " q3" ,
389+ " q4" , " q5" , " q6" , " q7" ,
390+ " q8" ,
391+ " q12" , " q13" , " q14" , " q15"
392+ );
393+ }
394+
317395 } /* namespace neon_d32 */
318396} /* namespace lsp */
319397
0 commit comments