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