You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
4.0 KiB
195 lines
4.0 KiB
.text
|
|
|
|
.align 2
|
|
.global neon_fm_kernel
|
|
.type neon_fm_kernel, %function
|
|
neon_fm_kernel:
|
|
@ On entry:
|
|
@ r0 = pointer to input
|
|
@ r1 = pointer to mix input
|
|
@ r2 = pointer to output
|
|
@ r3 = number of samples (n)
|
|
@ stack[1] = phase0
|
|
@ stack[2] = freq
|
|
@ stack[3] = gain
|
|
@ stack[4] = dgain
|
|
@ Note: pointers must have 128 bit (16 byte) alignment
|
|
@ Note: n mod 12 must be either 0 or 4, and n >= 12
|
|
@ Register layout:
|
|
@ q0 phase accum
|
|
@ q1 gain
|
|
@ q2 0x7fffff
|
|
@ q3 poly coefs
|
|
@ q4-q6 data block 1
|
|
@ q7-q9 data block 2
|
|
@ q10-q12 data block 3
|
|
@ q13-q15 data block 4
|
|
@ [r4] phase bump
|
|
@ [r5] gain bump
|
|
push {r4-r5}
|
|
vpush {q4-q7}
|
|
@ TODO: maybe get rid of pipeline stalls in setep
|
|
add r5, sp, #(4 * 18)
|
|
vld1.32 {d0[], d1[]}, [r5]! @ phase
|
|
vld1.32 {d14[], d15[]}, [r5]! @ freq
|
|
adr r4, neon_fm_kernel_const
|
|
vld1.32 {q5}, [r4:128]!
|
|
vld1.32 {q2}, [r4,:128]!
|
|
vld1.32 {q3}, [r4,:128]!
|
|
vmla.i32 q0, q7, q5
|
|
sub sp, #48
|
|
vld1.32 {d2[], d3[]}, [r5]! @ gain
|
|
vld1.32 {d12[], d13[]}, [r5]! @ dgain
|
|
vmla.i32 q1, q6, q5
|
|
vshl.i32 q7, #2
|
|
vcvt.f32.s32 q1, q1, #24
|
|
|
|
add r4, sp, #15
|
|
and r4, #-16 @ align to 16-byte boundary
|
|
vst1.32 {q7}, [r4:128]
|
|
vcvt.f32.s32 q6, q6, #22
|
|
add r5, r4, #16
|
|
vst1.32 {q6}, [r5:128]
|
|
|
|
@vld1.32 {q7}, [r4:128]
|
|
vadd.i32 q8, q0, q7
|
|
sub r3, #4
|
|
|
|
vld1.32 {q4}, [r0:128]!
|
|
vld1.32 {q5}, [r0:128]!
|
|
vadd.i32 q4, q0
|
|
vadd.i32 q9, q8, q7
|
|
vadd.i32 q5, q8
|
|
vld1.32 {q6}, [r0:128]!
|
|
vmov.i32 q15, #0x800000
|
|
vadd.i32 q6, q9
|
|
vtst.32 q13, q4, q15
|
|
vtst.32 q14, q5, q15
|
|
vtst.32 q15, q6, q15
|
|
vadd.i32 q0, q9, q7
|
|
vmov.i32 q7, #0x400000
|
|
b neon_fm_kernel_2
|
|
neon_fm_kernel_1:
|
|
vld1.32 {q4}, [r0:128]!
|
|
vld1.32 {q5}, [r0:128]!
|
|
vadd.i32 q4, q0
|
|
vadd.i32 q9, q8, q7
|
|
vadd.i32 q5, q8
|
|
vld1.32 {q6}, [r0:128]!
|
|
vst1.32 {q11}, [r2:128]!
|
|
vmov.i32 q15, #0x800000
|
|
vadd.i32 q6, q9
|
|
vtst.32 q13, q4, q15
|
|
vtst.32 q14, q5, q15
|
|
vtst.32 q15, q6, q15
|
|
vadd.i32 q0, q9, q7
|
|
vmov.i32 q7, #0x400000
|
|
vst1.32 {q12}, [r2:128]!
|
|
neon_fm_kernel_2:
|
|
vand q4, q2
|
|
vand q5, q2
|
|
vand q6, q2
|
|
vsub.i32 q4, q7
|
|
vsub.i32 q5, q7
|
|
vsub.i32 q6, q7
|
|
vcvt.f32.s32 q4, q4, #22
|
|
vcvt.f32.s32 q5, q5, #22
|
|
vcvt.f32.s32 q6, q6, #22
|
|
vmul.f32 q4, q4
|
|
vmul.f32 q5, q5
|
|
vmul.f32 q6, q6
|
|
|
|
vdup.32 q7, d6[1]
|
|
vdup.32 q8, d6[1]
|
|
vdup.32 q9, d6[1]
|
|
vmla.f32 q7, q4, d6[0]
|
|
vmla.f32 q8, q5, d6[0]
|
|
vmla.f32 q9, q6, d6[0]
|
|
vdup.32 q10, d7[0]
|
|
vdup.32 q11, d7[0]
|
|
vdup.32 q12, d7[0]
|
|
vmla.f32 q10, q4, q7
|
|
vmla.f32 q11, q5, q8
|
|
vmla.f32 q12, q6, q9
|
|
vdup.32 q7, d7[1]
|
|
vdup.32 q8, d7[1]
|
|
vdup.32 q9, d7[1]
|
|
vmla.f32 q7, q4, q10
|
|
vmla.f32 q8, q5, q11
|
|
vmla.f32 q9, q6, q12
|
|
vld1.32 {q10}, [r5:128]
|
|
vadd.f32 q11, q1, q10
|
|
vmul.f32 q7, q1
|
|
vadd.f32 q12, q11, q10
|
|
vmul.f32 q8, q11
|
|
vmul.f32 q9, q12
|
|
vld1.32 {q4}, [r1:128]!
|
|
vadd.f32 q1, q12, q10
|
|
vcvt.s32.f32 q10, q7, #24
|
|
vld1.32 {q5}, [r1:128]!
|
|
vcvt.s32.f32 q11, q8, #24
|
|
vcvt.s32.f32 q12, q9, #24
|
|
vld1.32 {q6}, [r1:128]!
|
|
vld1.32 {q7}, [r4:128]
|
|
veor q10, q13
|
|
veor q11, q14
|
|
veor q12, q15
|
|
vadd.i32 q10, q4
|
|
vadd.i32 q11, q5
|
|
vadd.i32 q12, q6
|
|
vadd.i32 q8, q0, q7
|
|
vst1.32 {q10}, [r2:128]!
|
|
subs r3, #12
|
|
bgt neon_fm_kernel_1
|
|
beq neon_fm_kernel_3
|
|
@ does not handle n mod 12 == 8
|
|
|
|
add sp, #48
|
|
vpop {q4-q7}
|
|
vst1.32 {q11}, [r2:128]!
|
|
pop {r4-r5}
|
|
vst1.32 {q12}, [r2:128]!
|
|
bx lr
|
|
neon_fm_kernel_3:
|
|
@ finish last chunk of 4
|
|
vld1.32 {q4}, [r0:128]!
|
|
vadd.i32 q4, q0
|
|
vmov.i32 q15, #0x800000
|
|
vst1.32 {q11}, [r2:128]!
|
|
vtst.32 q13, q4, q15
|
|
vmov.i32 q7, #0x400000
|
|
vand q4, q2
|
|
vst1.32 {q12}, [r2:128]!
|
|
vsub.i32 q4, q7
|
|
vcvt.f32.s32 q4, q4, #22
|
|
vmul.f32 q4, q4
|
|
|
|
vdup.32 q7, d6[1]
|
|
vmla.f32 q7, q4, d6[0]
|
|
vdup.32 q10, d7[0]
|
|
vmla.f32 q10, q4, q7
|
|
vdup.32 q7, d7[1]
|
|
vmla.f32 q7, q4, q10
|
|
vmul.f32 q7, q1
|
|
vld1.32 {q4}, [r1:128]!
|
|
vcvt.s32.f32 q10, q7, #24
|
|
veor q10, q13
|
|
vadd.i32 q10, q4
|
|
vst1.32 {q10}, [r2:128]!
|
|
add sp, #48
|
|
vpop {q4-q7}
|
|
pop {r4-r5}
|
|
bx lr
|
|
|
|
.size neon_fm_kernel, .-neon_fm_kernel
|
|
|
|
.balign 16
|
|
neon_fm_kernel_const:
|
|
.word 0, 1, 2, 3
|
|
.word 0x7fffff, 0x7fffff, 0x7fffff, 0x7fffff
|
|
.float -0.01880853017455781, 0.25215252666796095, -1.2333439964934032, 1.0
|
|
|
|
@ vars for bumping
|
|
.float 1.0, 1.0, 1.0, 1.0
|
|
.word 0, 0, 0, 0
|
|
.float 0.0, 0.0, 0.0, 0.0
|
|
|