Fixed a bug in iSAC transform functions on ARM-Neon platform. Performance unchanged.

Bugs=none
Test=trybots, and file bit-exact tests; passed.

Description of the bug: Neon registers q4-q7 not saved before calling the outside FFT routines in the assembly functions.
Review URL: https://webrtc-codereview.appspot.com/1097006

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3480 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
kma@webrtc.org
2013-02-06 23:53:13 +00:00
parent 4fd5527ab1
commit d83b9fdf45

View File

@@ -28,7 +28,6 @@ GLOBAL_LABEL WebRtcIsacfix_kSinTab2
DEFINE_FUNCTION WebRtcIsacfix_Time2SpecNeon DEFINE_FUNCTION WebRtcIsacfix_Time2SpecNeon
.align 2 .align 2
push {r4-r11,lr} push {r4-r11,lr}
vpush {q4-q7}
sub sp, sp, #(16 + FRAMESAMPLES * 4) sub sp, sp, #(16 + FRAMESAMPLES * 4)
str r0, [sp] @ inre1Q9 str r0, [sp] @ inre1Q9
@@ -46,12 +45,12 @@ DEFINE_FUNCTION WebRtcIsacfix_Time2SpecNeon
mov r6, #(WebRtcIsacfix_kSinTab1 - WebRtcIsacfix_kCosTab1) mov r6, #(WebRtcIsacfix_kSinTab1 - WebRtcIsacfix_kCosTab1)
add r10, r9, r6 @ WebRtcIsacfix_kSinTab1 add r10, r9, r6 @ WebRtcIsacfix_kSinTab1
vmov.u32 q6, #0 @ Initialize the maximum values for tmpInIm. vmov.u32 q14, #0 @ Initialize the maximum values for tmpInIm.
vmov.u32 q7, #0 @ Initialize the maximum values for tmpInRe. vmov.u32 q15, #0 @ Initialize the maximum values for tmpInRe.
movw r6, #16921 @ 0.5 / sqrt(240) in Q19 movw r6, #16921 @ 0.5 / sqrt(240) in Q19
lsl r6, #5 @ Together with vqdmulh, net effect is ">> 26". lsl r6, #5 @ Together with vqdmulh, net effect is ">> 26".
mov r8, #(FRAMESAMPLES / 2) @ loop counter mov r8, #(FRAMESAMPLES / 2) @ loop counter
vdup.s32 q4, r6 vdup.s32 q11, r6
Time2Spec_TransformAndFindMax: Time2Spec_TransformAndFindMax:
@ Use ">> 26", instead of ">> 7", ">> 16" and then ">> 3" as in the C code. @ Use ">> 26", instead of ">> 7", ">> 16" and then ">> 3" as in the C code.
@@ -71,40 +70,40 @@ Time2Spec_TransformAndFindMax:
vmlsl.s16 q12, d2, d4 @ WebRtcIsacfix_kSinTab1[k] * inre1Q9[k] vmlsl.s16 q12, d2, d4 @ WebRtcIsacfix_kSinTab1[k] * inre1Q9[k]
vmlsl.s16 q13, d3, d5 @ WebRtcIsacfix_kSinTab1[k] * inre1Q9[k] vmlsl.s16 q13, d3, d5 @ WebRtcIsacfix_kSinTab1[k] * inre1Q9[k]
vqdmulh.s32 q0, q8, q4 @ xrQ16 * factQ19 vqdmulh.s32 q0, q8, q11 @ xrQ16 * factQ19
vqdmulh.s32 q1, q9, q4 @ xrQ16 * factQ19 vqdmulh.s32 q1, q9, q11 @ xrQ16 * factQ19
vqdmulh.s32 q2, q12, q4 @ xrQ16 * factQ19 vqdmulh.s32 q2, q12, q11 @ xrQ16 * factQ19
vqdmulh.s32 q3, q13, q4 @ xrQ16 * factQ19 vqdmulh.s32 q3, q13, q11 @ xrQ16 * factQ19
@ Find the absolute maximum in the vectors and store them in q6 and q7. @ Find the absolute maximum in the vectors and store them.
vabs.s32 q10, q0 vabs.s32 q8, q0
vabs.s32 q11, q1 vabs.s32 q9, q1
vabs.s32 q12, q2 vabs.s32 q12, q2
vst1.32 {q0, q1}, [r4]! @ tmpreQ16[k] vst1.32 {q0, q1}, [r4]! @ tmpreQ16[k]
vabs.s32 q13, q3 vabs.s32 q13, q3
vmax.u32 q6, q10 @ Use u32 so we don't lose the value 0x80000000. vmax.u32 q14, q8 @ Use u32 so we don't lose the value 0x80000000.
vmax.u32 q7, q12 vmax.u32 q15, q12
vst1.32 {q2, q3}, [r5]! @ tmpimQ16[k] vst1.32 {q2, q3}, [r5]! @ tmpimQ16[k]
vmax.u32 q7, q13 vmax.u32 q15, q13
vmax.u32 q6, q11 @ Maximum for outre1Q16[]. vmax.u32 q14, q9 @ Maximum for outre1Q16[].
bgt Time2Spec_TransformAndFindMax bgt Time2Spec_TransformAndFindMax
@ Find the maximum value in the Neon registers @ Find the maximum value in the Neon registers
vmax.u32 d12, d13 vmax.u32 d28, d29
vmax.u32 d14, d15 vmax.u32 d30, d31
vpmax.u32 d12, d12, d12 @ Both 32 bits words hold the same value tmpInIm. vpmax.u32 d28, d28, d28 @ Both 32 bits words hold the same value tmpInIm.
vpmax.u32 d14, d14, d14 @ Both 32 bits words hold the same value tmpInRe. vpmax.u32 d30, d30, d30 @ Both 32 bits words hold the same value tmpInRe.
vmax.s32 d14, d12, d14 @ if (yrQ16 > xrQ16) {xrQ16 = yrQ16}; vmax.s32 d30, d28, d30 @ if (yrQ16 > xrQ16) {xrQ16 = yrQ16};
ldr r4, [sp] @ inre1Q9 ldr r4, [sp] @ inre1Q9
vcls.s32 d15, d14 @ sh = WebRtcSpl_NormW32(tmpInRe); vcls.s32 d31, d30 @ sh = WebRtcSpl_NormW32(tmpInRe);
ldr r5, [sp, #4] @ inre2Q9 ldr r5, [sp, #4] @ inre2Q9
vmov.i32 d14, #24 vmov.i32 d30, #24
add r6, sp, #16 @ tmpreQ16; add r6, sp, #16 @ tmpreQ16;
vsub.s32 d15, d15, d14 @ sh = sh - 24; vsub.s32 d31, d31, d30 @ sh = sh - 24;
add r7, sp, #(16 + FRAMESAMPLES * 2) @ tmpimQ16; add r7, sp, #(16 + FRAMESAMPLES * 2) @ tmpimQ16;
vdup.s32 q8, d15[0] @ sh vdup.s32 q8, d31[0] @ sh
mov r8, #(FRAMESAMPLES / 2) @ loop counter mov r8, #(FRAMESAMPLES / 2) @ loop counter
@@ -115,23 +114,23 @@ Time2Spec_PreFftShift:
vrshl.s32 q0, q0, q8 vrshl.s32 q0, q0, q8
vld1.32 {q2, q3}, [r6]! @ tmpreQ16[] vld1.32 {q2, q3}, [r6]! @ tmpreQ16[]
vrshl.s32 q1, q1, q8 vrshl.s32 q1, q1, q8
vld1.32 {q4, q5}, [r7]! @ tmpimQ16[] vld1.32 {q10, q11}, [r7]! @ tmpimQ16[]
vrshl.s32 q2, q2, q8 vrshl.s32 q2, q2, q8
vld1.32 {q6, q7}, [r7]! @ tmpimQ16[] vld1.32 {q12, q13}, [r7]! @ tmpimQ16[]
vrshl.s32 q3, q3, q8 vrshl.s32 q3, q3, q8
vrshl.s32 q4, q4, q8 vrshl.s32 q10, q10, q8
vrshl.s32 q5, q5, q8 vrshl.s32 q11, q11, q8
vrshl.s32 q6, q6, q8 vrshl.s32 q12, q12, q8
vrshl.s32 q7, q7, q8 vrshl.s32 q13, q13, q8
vmovn.s32 d0, q0 vmovn.s32 d0, q0
vmovn.s32 d1, q1 vmovn.s32 d1, q1
vmovn.s32 d2, q2 vmovn.s32 d2, q2
vmovn.s32 d3, q3 vmovn.s32 d3, q3
vmovn.s32 d4, q4 vmovn.s32 d4, q10
vmovn.s32 d5, q5 vmovn.s32 d5, q11
vmovn.s32 d6, q6 vmovn.s32 d6, q12
vmovn.s32 d7, q7 vmovn.s32 d7, q13
vst1.16 {q0, q1}, [r4]! @ inre1Q9[] vst1.16 {q0, q1}, [r4]! @ inre1Q9[]
vst1.16 {q2, q3}, [r5]! @ inre2Q9[] vst1.16 {q2, q3}, [r5]! @ inre2Q9[]
@@ -194,28 +193,28 @@ Time2Spec_PostFftTransform:
vmlsl.s16 q12, d7, d5 @ WebRtcIsacfix_kSinTab2[k] * xiQ16 vmlsl.s16 q12, d7, d5 @ WebRtcIsacfix_kSinTab2[k] * xiQ16
vmull.s16 q13, d7, d4 @ WebRtcIsacfix_kSinTab2[k] * xrQ16 vmull.s16 q13, d7, d4 @ WebRtcIsacfix_kSinTab2[k] * xrQ16
vmlal.s16 q13, d6, d5 @ kCosTab2[k] * xiQ16 vmlal.s16 q13, d6, d5 @ kCosTab2[k] * xiQ16
vmull.s16 q6, d7, d1 @ WebRtcIsacfix_kSinTab2[k] * yrQ16 vmull.s16 q9, d7, d1 @ WebRtcIsacfix_kSinTab2[k] * yrQ16
vmlal.s16 q6, d6, d0 @ kCosTab2[k] * yiQ16 vmlal.s16 q9, d6, d0 @ kCosTab2[k] * yiQ16
vmull.s16 q7, d7, d0 @ WebRtcIsacfix_kSinTab2[k] * yiQ16 vmull.s16 q10, d7, d0 @ WebRtcIsacfix_kSinTab2[k] * yiQ16
vmlsl.s16 q7, d6, d1 @ kCosTab2[k] * yrQ16 vmlsl.s16 q10, d6, d1 @ kCosTab2[k] * yrQ16
vshl.s32 q12, q12, q15 vshl.s32 q12, q12, q15
vshl.s32 q13, q13, q15 vshl.s32 q13, q13, q15
vshl.s32 q6, q6, q15 vshl.s32 q9, q9, q15
vshl.s32 q7, q7, q15 vshl.s32 q10, q10, q15
vneg.s32 q8, q6 vneg.s32 q8, q9
vld1.16 {d0}, [r6]! @ inre1Q9 vld1.16 {d0}, [r6]! @ inre1Q9
vmovn.s32 d8, q12 vmovn.s32 d24, q12
vld1.16 {d1}, [r7]! @ inre2Q9 vld1.16 {d1}, [r7]! @ inre2Q9
vmovn.s32 d9, q13 vmovn.s32 d25, q13
vld1.16 {d2}, [r4] @ inre1Q9[FRAMESAMPLES / 2 - 4 - i] vld1.16 {d2}, [r4] @ inre1Q9[FRAMESAMPLES / 2 - 4 - i]
vmovn.s32 d5, q7 vmovn.s32 d5, q10
vld1.16 {d3}, [r5] @ inre2Q9[FRAMESAMPLES / 2 - 4 - i] vld1.16 {d3}, [r5] @ inre2Q9[FRAMESAMPLES / 2 - 4 - i]
vmovn.s32 d4, q8 vmovn.s32 d4, q8
vst1.16 {d8}, [r2]! @ outreQ7[k] vst1.16 {d24}, [r2]! @ outreQ7[k]
vrev64.16 q2, q2 @ Reverse the order of the samples. vrev64.16 q2, q2 @ Reverse the order of the samples.
vst1.16 {d9}, [r3]! @ outimQ7[k] vst1.16 {d25}, [r3]! @ outimQ7[k]
vst1.16 {d4}, [r11] @ outreQ7[FRAMESAMPLES / 2 - 1 - k] vst1.16 {d4}, [r11] @ outreQ7[FRAMESAMPLES / 2 - 1 - k]
vst1.16 {d5}, [r12] @ outimQ7[FRAMESAMPLES / 2 - 1 - k] vst1.16 {d5}, [r12] @ outimQ7[FRAMESAMPLES / 2 - 1 - k]
sub r11, #8 @ Update pointers for outreQ7[]. sub r11, #8 @ Update pointers for outreQ7[].
@@ -224,7 +223,6 @@ Time2Spec_PostFftTransform:
bgt Time2Spec_PostFftTransform bgt Time2Spec_PostFftTransform
add sp, sp, #(16 + FRAMESAMPLES * 4) add sp, sp, #(16 + FRAMESAMPLES * 4)
vpop {q4-q7}
pop {r4-r11,pc} pop {r4-r11,pc}
.align 8 .align 8
@@ -327,7 +325,7 @@ _WebRtcIsacfix_kSinTab1: @ Label for iOS
DEFINE_FUNCTION WebRtcIsacfix_Spec2TimeNeon DEFINE_FUNCTION WebRtcIsacfix_Spec2TimeNeon
.align 2 .align 2
push {r4-r11,lr} push {r4-r11,lr}
vpush {q4-q7}
sub sp, sp, #16 sub sp, sp, #16
str r0, [sp] @ inreQ7 str r0, [sp] @ inreQ7
str r1, [sp, #4] @ inimQ7 str r1, [sp, #4] @ inimQ7
@@ -344,6 +342,7 @@ DEFINE_FUNCTION WebRtcIsacfix_Spec2TimeNeon
adr r10, WebRtcIsacfix_kSinTab2 adr r10, WebRtcIsacfix_kSinTab2
add r9, r10, #(120*2 - 16) @ &WebRtcIsacfix_kSinTab2[119 - 8] add r9, r10, #(120*2 - 16) @ &WebRtcIsacfix_kSinTab2[119 - 8]
vpush {q4-q7}
mov r5, #-32 mov r5, #-32
mov r7, #-16 mov r7, #-16
@@ -464,16 +463,18 @@ TransformAndFindMax:
vmax.u32 d14, d15 vmax.u32 d14, d15
vpmax.u32 d12, d12, d12 @ Both 32 bits words hold the same value tmpInIm. vpmax.u32 d12, d12, d12 @ Both 32 bits words hold the same value tmpInIm.
vpmax.u32 d14, d14, d14 @ Both 32 bits words hold the same value tmpInRe. vpmax.u32 d14, d14, d14 @ Both 32 bits words hold the same value tmpInRe.
vmax.s32 d14, d12, d14 @ if (tmpInIm>tmpInRe) tmpInRe = tmpInIm; vmax.s32 d0, d12, d14 @ if (tmpInIm>tmpInRe) tmpInRe = tmpInIm;
vpop {q4-q7}
ldr r4, [sp] @ inreQ7 ldr r4, [sp] @ inreQ7
vcls.s32 d15, d14 @ sh = WebRtcSpl_NormW32(tmpInRe); vcls.s32 d1, d0 @ sh = WebRtcSpl_NormW32(tmpInRe);
ldr r5, [sp, #4] @ inimQ7 ldr r5, [sp, #4] @ inimQ7
vmov.i32 d14, #24 @ sh = sh-24; vmov.i32 d0, #24 @ sh = sh-24;
ldr r6, [sp, #8] @ outre1Q16 ldr r6, [sp, #8] @ outre1Q16
vsub.s32 d15, d15, d14 vsub.s32 d1, d1, d0
ldr r7, [sp, #12] @ outre2Q16 ldr r7, [sp, #12] @ outre2Q16
vdup.s32 q8, d15[0] @ sh vdup.s32 q8, d1[0] @ sh
mov r8, #(FRAMESAMPLES / 2) mov r8, #(FRAMESAMPLES / 2)
@@ -485,21 +486,21 @@ PreFftShift:
vrshl.s32 q1, q1, q8 vrshl.s32 q1, q1, q8
vrshl.s32 q2, q2, q8 vrshl.s32 q2, q2, q8
vrshl.s32 q3, q3, q8 vrshl.s32 q3, q3, q8
vld1.32 {q4, q5}, [r7]! @ outre2Q16[] vld1.32 {q10, q11}, [r7]! @ outre2Q16[]
vld1.32 {q6, q7}, [r7]! @ outre2Q16[] vld1.32 {q12, q13}, [r7]! @ outre2Q16[]
vrshl.s32 q4, q4, q8 vrshl.s32 q10, q10, q8
vrshl.s32 q5, q5, q8 vrshl.s32 q11, q11, q8
vrshl.s32 q6, q6, q8 vrshl.s32 q12, q12, q8
vrshl.s32 q7, q7, q8 vrshl.s32 q13, q13, q8
vmovn.s32 d0, q0 vmovn.s32 d0, q0
vmovn.s32 d1, q1 vmovn.s32 d1, q1
vmovn.s32 d2, q2 vmovn.s32 d2, q2
vmovn.s32 d3, q3 vmovn.s32 d3, q3
vmovn.s32 d4, q4 vmovn.s32 d4, q10
vmovn.s32 d5, q5 vmovn.s32 d5, q11
vmovn.s32 d6, q6 vmovn.s32 d6, q12
vmovn.s32 d7, q7 vmovn.s32 d7, q13
vst1.16 {q0, q1}, [r4]! @ inreQ7[] vst1.16 {q0, q1}, [r4]! @ inreQ7[]
vst1.16 {q2, q3}, [r5]! @ inimQ7[] vst1.16 {q2, q3}, [r5]! @ inimQ7[]
@@ -519,47 +520,47 @@ PreFftShift:
ldr r6, [sp, #8] @ outre1Q16 ldr r6, [sp, #8] @ outre1Q16
ldr r7, [sp, #12] @ outre2Q16 ldr r7, [sp, #12] @ outre2Q16
mov r8, #(FRAMESAMPLES / 2) mov r8, #(FRAMESAMPLES / 2)
vneg.s32 q5, q8 @ -sh vneg.s32 q15, q8 @ -sh
movw r0, #273 movw r0, #273
lsl r0, #15 @ Together with vqdmulh, net effect is ">> 16". lsl r0, #15 @ Together with vqdmulh, net effect is ">> 16".
vdup.s32 q4, r0 vdup.s32 q14, r0
PostFftShiftDivide: PostFftShiftDivide:
subs r8, #16 subs r8, #16
vld1.16 {q0, q1}, [r4]! @ inreQ7 vld1.16 {q0, q1}, [r4]! @ inreQ7
vmovl.s16 q6, d0 vmovl.s16 q10, d0
vmovl.s16 q7, d1 vmovl.s16 q11, d1
vld1.16 {q2, q3}, [r5]! @ inimQ7 vld1.16 {q2, q3}, [r5]! @ inimQ7
vmovl.s16 q8, d2 vmovl.s16 q8, d2
vmovl.s16 q9, d3 vmovl.s16 q9, d3
vshl.s32 q6, q6, q5 vshl.s32 q10, q10, q15
vshl.s32 q7, q7, q5 vshl.s32 q11, q11, q15
vshl.s32 q8, q8, q5 vshl.s32 q8, q8, q15
vshl.s32 q9, q9, q5 vshl.s32 q9, q9, q15
vqdmulh.s32 q6, q6, q4 vqdmulh.s32 q10, q10, q14
vqdmulh.s32 q7, q7, q4 vqdmulh.s32 q11, q11, q14
vqdmulh.s32 q8, q8, q4 vqdmulh.s32 q8, q8, q14
vqdmulh.s32 q9, q9, q4 vqdmulh.s32 q9, q9, q14
vmovl.s16 q0, d4 vmovl.s16 q0, d4
vmovl.s16 q1, d5 vmovl.s16 q1, d5
vmovl.s16 q2, d6 vmovl.s16 q2, d6
vmovl.s16 q3, d7 vmovl.s16 q3, d7
vshl.s32 q0, q0, q5 vshl.s32 q0, q0, q15
vshl.s32 q1, q1, q5 vshl.s32 q1, q1, q15
vshl.s32 q2, q2, q5 vshl.s32 q2, q2, q15
vshl.s32 q3, q3, q5 vshl.s32 q3, q3, q15
@ WEBRTC_SPL_MUL_16_32_RSFT16(273, outre2Q16[k]) @ WEBRTC_SPL_MUL_16_32_RSFT16(273, outre2Q16[k])
vqdmulh.s32 q0, q0, q4 vqdmulh.s32 q0, q0, q14
vqdmulh.s32 q1, q1, q4 vqdmulh.s32 q1, q1, q14
vst1.32 {q6, q7}, [r6]! @ outre1Q16[] vst1.32 {q10, q11}, [r6]! @ outre1Q16[]
vqdmulh.s32 q2, q2, q4 vqdmulh.s32 q2, q2, q14
vqdmulh.s32 q3, q3, q4 vqdmulh.s32 q3, q3, q14
vst1.32 {q8, q9}, [r6]! @ outre1Q16[] vst1.32 {q8, q9}, [r6]! @ outre1Q16[]
vst1.32 {q0, q1}, [r7]! @ outre2Q16[] vst1.32 {q0, q1}, [r7]! @ outre2Q16[]
vst1.32 {q2, q3}, [r7]! @ outre2Q16[] vst1.32 {q2, q3}, [r7]! @ outre2Q16[]
@@ -576,53 +577,53 @@ DemodulateAndSeparate:
subs r8, #8 subs r8, #8
vld1.16 {q0}, [r9, :64]! @ WebRtcIsacfix_kCosTab1[] vld1.16 {q0}, [r9, :64]! @ WebRtcIsacfix_kCosTab1[]
vmovl.s16 q6, d0 @ WebRtcIsacfix_kCosTab1[] vmovl.s16 q10, d0 @ WebRtcIsacfix_kCosTab1[]
vld1.16 {q1}, [r10, :64]! @ WebRtcIsacfix_kSinTab1[] vld1.16 {q1}, [r10, :64]! @ WebRtcIsacfix_kSinTab1[]
vmovl.s16 q7, d1 @ WebRtcIsacfix_kCosTab1[] vmovl.s16 q11, d1 @ WebRtcIsacfix_kCosTab1[]
vld1.32 {q2, q3}, [r2] @ outre1Q16 vld1.32 {q2, q3}, [r2] @ outre1Q16
vmovl.s16 q8, d2 @ WebRtcIsacfix_kSinTab1[] vmovl.s16 q12, d2 @ WebRtcIsacfix_kSinTab1[]
vld1.32 {q4, q5}, [r3] @ outre2Q16 vld1.32 {q14, q15}, [r3] @ outre2Q16
vmovl.s16 q9, d3 @ WebRtcIsacfix_kSinTab1[] vmovl.s16 q13, d3 @ WebRtcIsacfix_kSinTab1[]
vmull.s32 q10, d12, d4 @ WebRtcIsacfix_kCosTab1[k] * outre1Q16[k] vmull.s32 q0, d20, d4 @ WebRtcIsacfix_kCosTab1[k] * outre1Q16[k]
vmull.s32 q11, d13, d5 @ WebRtcIsacfix_kCosTab1[k] * outre1Q16[k] vmull.s32 q1, d21, d5 @ WebRtcIsacfix_kCosTab1[k] * outre1Q16[k]
vmull.s32 q12, d14, d6 @ WebRtcIsacfix_kCosTab1[k] * outre1Q16[k] vmull.s32 q8, d22, d6 @ WebRtcIsacfix_kCosTab1[k] * outre1Q16[k]
vmull.s32 q13, d15, d7 @ WebRtcIsacfix_kCosTab1[k] * outre1Q16[k] vmull.s32 q9, d23, d7 @ WebRtcIsacfix_kCosTab1[k] * outre1Q16[k]
vmlsl.s32 q10, d16, d8 @ += WebRtcIsacfix_kSinTab1[k] * outre2Q16[k] vmlsl.s32 q0, d24, d28 @ += WebRtcIsacfix_kSinTab1[k] * outre2Q16[k]
vmlsl.s32 q11, d17, d9 @ += WebRtcIsacfix_kSinTab1[k] * outre2Q16[k] vmlsl.s32 q1, d25, d29 @ += WebRtcIsacfix_kSinTab1[k] * outre2Q16[k]
vmlsl.s32 q12, d18, d10 @ += WebRtcIsacfix_kSinTab1[k] * outre2Q16[k] vmlsl.s32 q8, d26, d30 @ += WebRtcIsacfix_kSinTab1[k] * outre2Q16[k]
vmlsl.s32 q13, d19, d11 @ += WebRtcIsacfix_kSinTab1[k] * outre2Q16[k] vmlsl.s32 q9, d27, d31 @ += WebRtcIsacfix_kSinTab1[k] * outre2Q16[k]
vrshrn.s64 d20, q10, #10 @ xrQ16 vrshrn.s64 d0, q0, #10 @ xrQ16
vrshrn.s64 d21, q11, #10 @ xrQ16 vrshrn.s64 d1, q1, #10 @ xrQ16
vrshrn.s64 d22, q12, #10 @ xrQ16 vrshrn.s64 d2, q8, #10 @ xrQ16
vrshrn.s64 d23, q13, #10 @ xrQ16 vrshrn.s64 d3, q9, #10 @ xrQ16
vmull.s32 q12, d12, d8 @ WebRtcIsacfix_kCosTab1[k] * outre2Q16[k] vmull.s32 q8, d20, d28 @ WebRtcIsacfix_kCosTab1[k] * outre2Q16[k]
vmull.s32 q13, d13, d9 @ WebRtcIsacfix_kCosTab1[k] * outre2Q16[k] vmull.s32 q9, d21, d29 @ WebRtcIsacfix_kCosTab1[k] * outre2Q16[k]
vmull.s32 q14, d14, d10 @ WebRtcIsacfix_kCosTab1[k] * outre2Q16[k] vmull.s32 q14, d22, d30 @ WebRtcIsacfix_kCosTab1[k] * outre2Q16[k]
vmull.s32 q15, d15, d11 @ WebRtcIsacfix_kCosTab1[k] * outre2Q16[k] vmull.s32 q15, d23, d31 @ WebRtcIsacfix_kCosTab1[k] * outre2Q16[k]
vmlal.s32 q12, d16, d4 @ += WebRtcIsacfix_kSinTab1[k] * outre1Q16[k] vmlal.s32 q8, d24, d4 @ += WebRtcIsacfix_kSinTab1[k] * outre1Q16[k]
vmlal.s32 q13, d17, d5 @ += WebRtcIsacfix_kSinTab1[k] * outre1Q16[k] vmlal.s32 q9, d25, d5 @ += WebRtcIsacfix_kSinTab1[k] * outre1Q16[k]
vmlal.s32 q14, d18, d6 @ += WebRtcIsacfix_kSinTab1[k] * outre1Q16[k] vmlal.s32 q14, d26, d6 @ += WebRtcIsacfix_kSinTab1[k] * outre1Q16[k]
vmlal.s32 q15, d19, d7 @ += WebRtcIsacfix_kSinTab1[k] * outre1Q16[k] vmlal.s32 q15, d27, d7 @ += WebRtcIsacfix_kSinTab1[k] * outre1Q16[k]
vdup.s32 q4, r0 @ generic -> Neon doesn't cost extra cycles. vdup.s32 q11, r0 @ generic -> Neon doesn't cost extra cycles.
vrshrn.s64 d24, q12, #10 @ xiQ16 vrshrn.s64 d24, q8, #10 @ xiQ16
vrshrn.s64 d25, q13, #10 @ xiQ16 vrshrn.s64 d25, q9, #10 @ xiQ16
vqdmulh.s32 q0, q0, q11
vrshrn.s64 d26, q14, #10 @ xiQ16 vrshrn.s64 d26, q14, #10 @ xiQ16
vrshrn.s64 d27, q15, #10 @ xiQ16 vrshrn.s64 d27, q15, #10 @ xiQ16
@ WEBRTC_SPL_MUL_16_32_RSFT11(factQ11, xrQ16) @ WEBRTC_SPL_MUL_16_32_RSFT11(factQ11, xrQ16)
@ WEBRTC_SPL_MUL_16_32_RSFT11(factQ11, xiQ16) @ WEBRTC_SPL_MUL_16_32_RSFT11(factQ11, xiQ16)
vqdmulh.s32 q0, q10, q4 vqdmulh.s32 q1, q1, q11
vqdmulh.s32 q1, q11, q4 vqdmulh.s32 q2, q12, q11
vqdmulh.s32 q2, q12, q4 vqdmulh.s32 q3, q13, q11
vqdmulh.s32 q3, q13, q4
vst1.16 {q0, q1}, [r2]! @ outre1Q16[] vst1.16 {q0, q1}, [r2]! @ outre1Q16[]
vst1.16 {q2, q3}, [r3]! @ outre2Q16[] vst1.16 {q2, q3}, [r3]! @ outre2Q16[]
@@ -630,5 +631,4 @@ DemodulateAndSeparate:
bgt DemodulateAndSeparate bgt DemodulateAndSeparate
add sp, sp, #16 add sp, sp, #16
vpop {q4-q7}
pop {r4-r11,pc} pop {r4-r11,pc}