summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin@xiph.org>2010-05-15 20:40:20 +0000
committerRobin Watts <robin@xiph.org>2010-05-15 20:40:20 +0000
commitc650be1bdd4d3a2746b4631953c0e887aef9cd2d (patch)
tree7f75a54a36fa089739121bdc94dc8d7fa8e627ff
parent7726777045d50734e851570b448294226ec0580d (diff)
downloadtremor-c650be1bdd4d3a2746b4631953c0e887aef9cd2d.tar.gz
ARM mdct implementations, and changes to the C code to call them.
Also changes in the configure.ac file to correctly include the assembly files on ARM targets. This is 'my first autoconf' stuff, so any hints/pointers on how to do it better gratefully accepted. git-svn-id: https://svn.xiph.org/branches/lowmem-branch/Tremolo@17218 0101bb08-14d6-0310-b084-bc0e0c8e3800
-rw-r--r--Makefile.am8
-rw-r--r--configure.in5
-rw-r--r--mdct.c95
-rw-r--r--mdctARM.s1187
-rw-r--r--mdctLARM.s1175
-rw-r--r--mdct_lookup.h10
6 files changed, 2474 insertions, 6 deletions
diff --git a/Makefile.am b/Makefile.am
index 1d18b1a..4bd5732 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,6 +7,13 @@ pkgconfig_DATA = vorbisidec.pc
lib_LTLIBRARIES = libvorbisidec.la
+if ARM_TARGET
+# Build 'em both and let God sort 'em out
+TARGET_SPECIFIC_SOURCES = mdctARM.s mdctLARM.s
+else
+TARGET_SPECIFIC_SOURCES =
+endif
+
libvorbisidec_la_SOURCES = mdct.c dsp.c info.c misc.c \
floor1.c floor0.c vorbisfile.c \
res012.c mapping0.c codebook.c \
@@ -15,6 +22,7 @@ libvorbisidec_la_SOURCES = mdct.c dsp.c info.c misc.c \
os.h mdct.h ivorbisfile.h lsp_lookup.h\
window_lookup.h floor_lookup.c \
codec_internal.h ogg.h \
+ $(TARGET_SPECIFIC_SOURCES) \
asm_arm.h ivorbiscodec.h
libvorbisidec_la_LDFLAGS = -version-info @V_LIB_CURRENT@:@V_LIB_REVISION@:@V_LIB_AGE@
diff --git a/configure.in b/configure.in
index c696ed1..3f60f55 100644
--- a/configure.in
+++ b/configure.in
@@ -37,6 +37,7 @@ AC_PROG_CPP
CFLAGS="$cflags_save"
AM_PROG_LIBTOOL
+AM_PROG_AS
dnl --------------------------------------------------
dnl Set build flags based on environment
@@ -44,11 +45,13 @@ dnl --------------------------------------------------
dnl Set some target options
+arm_target=0
cflags_save="$CFLAGS"
ldflags_save="$LDFLAGS"
if test -z "$GCC"; then
case $host in
arm-*-*)
+ arm_target=1
DEBUG="-g -D_ARM_ASSEM_"
CFLAGS="-O -D_ARM_ASSEM_"
PROFILE="-p -g -O -D_ARM_ASSEM" ;;
@@ -61,6 +64,7 @@ else
case $host in
arm-*-*)
+ arm_target=1
DEBUG="-g -Wall -W -D__NO_MATH_INLINES -fsigned-char -D_ARM_ASSEM_"
CFLAGS="-O2 -Wall -D_ARM_ASSEM_ -fsigned-char"
PROFILE="-Wall -pg -g -O2 -D_ARM_ASSEM_ -fsigned-char -fno-inline-functions";;
@@ -74,6 +78,7 @@ fi
CFLAGS="$CFLAGS $cflags_save -D_REENTRANT"
LDFLAGS="$LDFLAGS $ldflags_save"
+AM_CONDITIONAL(ARM_TARGET, test x$arm_target = 1)
# Test whenever ld supports -version-script
AC_PROG_LD
diff --git a/mdct.c b/mdct.c
index 2201531..4093afa 100644
--- a/mdct.c
+++ b/mdct.c
@@ -38,6 +38,43 @@
#include "mdct.h"
#include "mdct_lookup.h"
+#ifdef _ARM_ASSEM_
+
+/* We have 2 different variants of ARM routines, according to whether we
+ * are using _LOW_ACCURACY_ or not. We suffix the calling routines
+ * appropriately to call the right version. */
+/* FIXME: This could be avoided by people being smarter with configure. */
+#ifdef _LOW_ACCURACY_
+#define ARM_SUFFIX(A) A ## _arm_low
+#else
+#define ARM_SUFFIX(A) A ## _arm
+#endif
+
+extern ogg_int16_t *ARM_SUFFIX(mdct_unroll_prelap)(ogg_int16_t *out,
+ DATA_TYPE *post,
+ DATA_TYPE *l,
+ int step);
+extern ogg_int16_t *ARM_SUFFIX(mdct_unroll_part2)(ogg_int16_t *out,
+ DATA_TYPE *post,
+ DATA_TYPE *l,
+ DATA_TYPE *r,
+ int step,
+ LOOKUP_T *wL,
+ LOOKUP_T *wR);
+extern ogg_int16_t *ARM_SUFFIX(mdct_unroll_part3)(ogg_int16_t *out,
+ DATA_TYPE *post,
+ DATA_TYPE *l,
+ DATA_TYPE *r,
+ int step,
+ LOOKUP_T *wL,
+ LOOKUP_T *wR);
+extern ogg_int16_t *ARM_SUFFIX(mdct_unroll_postlap)(ogg_int16_t *out,
+ DATA_TYPE *post,
+ DATA_TYPE *l,
+ int step);
+#endif
+
+#ifndef _ARM_ASSEM_
STIN void presymmetry(DATA_TYPE *in,int n2,int step){
DATA_TYPE *aX;
DATA_TYPE *bX;
@@ -289,14 +326,15 @@ STIN void mdct_step7(DATA_TYPE *x,int n,int step){
w0 += 2;
}while(w0<w1);
}
+#endif
STIN void mdct_step8(DATA_TYPE *x, int n, int step){
LOOKUP_T *T;
LOOKUP_T *V;
DATA_TYPE *iX =x+(n>>1);
- step>>=2;
switch(step) {
+#ifndef _ARM_ASSEM_
default:
T=(step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1;
do{
@@ -306,6 +344,7 @@ STIN void mdct_step8(DATA_TYPE *x, int n, int step){
x +=2;
}while(x<iX);
break;
+#endif
case 1:
{
@@ -377,11 +416,16 @@ STIN void mdct_step8(DATA_TYPE *x, int n, int step){
}
}
+#ifdef _ARM_ASSEM_
+void ARM_SUFFIX(mdct_backward)(int n, DATA_TYPE *in);
+#endif
+
/* partial; doesn't perform last-step deinterleave/unrolling. That
can be done more efficiently during pcm output */
void mdct_backward(int n, DATA_TYPE *in){
- int shift;
int step;
+#ifndef _ARM_ASSEM_
+ int shift;
for (shift=4;!(n&(1<<shift));shift++);
shift=13-shift;
@@ -391,16 +435,25 @@ void mdct_backward(int n, DATA_TYPE *in){
mdct_butterflies(in,n>>1,shift);
mdct_bitreverse(in,n,shift);
mdct_step7(in,n,step);
- mdct_step8(in,n,step);
+ mdct_step8(in,n,step>>2);
+#else
+ step = ARM_SUFFIX(mdct_backward)(n, in);
+ if (step < 1)
+ mdct_step8(in,n,step);
+#endif
}
-void mdct_shift_right(int n, DATA_TYPE *in, DATA_TYPE *right){
+void mdct_shift_right(int n, DATA_TYPE *in, DATA_TYPE *right) {
+#ifdef _ARM_ASSEM_
+ ARM_SUFFIX(mdct_shift_right)(n, in, right);
+#else
int i;
n>>=2;
in+=1;
for(i=0;i<n;i++)
right[i]=in[i<<1];
+#endif
}
void mdct_unroll_lap(int n0,int n1,
@@ -433,10 +486,18 @@ void mdct_unroll_lap(int n0,int n1,
r -= off;
start -= off;
end -= n;
+#ifndef _ARM_ASSEM_
while(r>post){
*out = CLIP_TO_15((*--r)>>9);
out+=step;
}
+#else
+ out = ARM_SUFFIX(mdct_unroll_prelap)(out,post,r,step);
+ n -= off;
+ if (n < 0)
+ n = 0;
+ r -= n;
+#endif
}
/* cross-lap; two halves due to wrap-around */
@@ -449,11 +510,22 @@ void mdct_unroll_lap(int n0,int n1,
wR -= off;
wL += off;
end -= n;
+#ifndef _ARM_ASSEM_
while(r>post){
l-=2;
*out = CLIP_TO_15((MULT31(*--r,*--wR) + MULT31(*l,*wL++))>>9);
out+=step;
}
+#else
+ out = ARM_SUFFIX(mdct_unroll_part2)(out, post, l, r, step, wL, wR);
+ n -= off;
+ if (n < 0)
+ n = 0;
+ l -= 2*n;
+ r -= n;
+ wR -= n;
+ wL += n;
+#endif
n = (end<halfLap?end:halfLap);
off = (start<halfLap?start:halfLap);
@@ -464,11 +536,22 @@ void mdct_unroll_lap(int n0,int n1,
end -= n;
wR -= off;
wL += off;
+#ifndef _ARM_ASSEM_
while(r<post){
*out = CLIP_TO_15((MULT31(*r++,*--wR) - MULT31(*l,*wL++))>>9);
out+=step;
l+=2;
}
+#else
+ out = ARM_SUFFIX(mdct_unroll_part3)(out, post, l, r, step, wL, wR);
+ n -= off;
+ if (n < 0)
+ n = 0;
+ l += 2*n;
+ r += n;
+ wR -= n;
+ wL += n;
+#endif
/* preceeding direct-copy lapping from previous frame, if any */
if(postLap){
@@ -476,11 +559,15 @@ void mdct_unroll_lap(int n0,int n1,
off = (start<postLap?start:postLap);
post = l+n*2;
l += off*2;
+#ifndef _ARM_ASSEM_
while(l<post){
*out = CLIP_TO_15((-*l)>>9);
out+=step;
l+=2;
}
+#else
+ out = ARM_SUFFIX(mdct_unroll_postlap)(out,post,l,step);
+#endif
}
}
diff --git a/mdctARM.s b/mdctARM.s
new file mode 100644
index 0000000..a2dc5bb
--- /dev/null
+++ b/mdctARM.s
@@ -0,0 +1,1187 @@
+; Tremolo library
+; Copyright (C) 2009 Robin Watts for Pinknoise Productions Ltd
+
+ AREA |.text|, CODE, READONLY
+
+ ; full accuracy version
+
+ EXPORT mdct_backward_arm
+ EXPORT mdct_shift_right_arm
+ EXPORT mdct_unroll_prelap_arm
+ EXPORT mdct_unroll_part2_arm
+ EXPORT mdct_unroll_part3_arm
+ EXPORT mdct_unroll_postlap_arm
+
+ IMPORT sincos_lookup0
+ IMPORT sincos_lookup1
+
+mdct_unroll_prelap_arm
+ ; r0 = out
+ ; r1 = post
+ ; r2 = r
+ ; r3 = step
+ STMFD r13!,{r4-r7,r14}
+ MVN r4, #0x8000
+ MOV r3, r3, LSL #1
+ SUB r1, r2, r1 ; r1 = r - post
+ SUBS r1, r1, #16 ; r1 = r - post - 16
+ BLT unroll_over
+unroll_loop
+ LDMDB r2!,{r5,r6,r7,r12}
+
+ MOV r5, r5, ASR #9 ; r5 = (*--r)>>9
+ MOV r6, r6, ASR #9 ; r6 = (*--r)>>9
+ MOV r7, r7, ASR #9 ; r7 = (*--r)>>9
+ MOV r12,r12,ASR #9 ; r12= (*--r)>>9
+
+ MOV r14,r12,ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r12,r4, r14,ASR #31
+ STRH r12,[r0], r3
+
+ MOV r14,r7, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r7, r4, r14,ASR #31
+ STRH r7, [r0], r3
+
+ MOV r14,r6, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r6, r4, r14,ASR #31
+ STRH r6, [r0], r3
+
+ MOV r14,r5, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r5, r4, r14,ASR #31
+ STRH r5, [r0], r3
+
+ SUBS r1, r1, #16
+ BGE unroll_loop
+
+unroll_over
+ ADDS r1, r1, #16
+ BLE unroll_end
+unroll_loop2
+ LDR r5,[r2,#-4]!
+ ; stall
+ ; stall (Xscale)
+ MOV r5, r5, ASR #9 ; r5 = (*--r)>>9
+ MOV r14,r5, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r5, r4, r14,ASR #31
+ STRH r5, [r0], r3
+ SUBS r1, r1, #4
+ BGT unroll_loop2
+unroll_end
+ LDMFD r13!,{r4-r7,PC}
+
+mdct_unroll_postlap_arm
+ ; r0 = out
+ ; r1 = post
+ ; r2 = l
+ ; r3 = step
+ STMFD r13!,{r4-r7,r14}
+ MVN r4, #0x8000
+ MOV r3, r3, LSL #1
+ SUB r1, r1, r2 ; r1 = post - l
+ MOV r1, r1, ASR #1 ; r1 = (post - l)>>1
+ SUBS r1, r1, #16 ; r1 = ((post - l)>>1) - 4
+ BLT unroll_over3
+unroll_loop3
+ LDR r12,[r2],#8
+ LDR r7, [r2],#8
+ LDR r6, [r2],#8
+ LDR r5, [r2],#8
+
+ RSB r12,r12,#0
+ RSB r5, r5, #0
+ RSB r6, r6, #0
+ RSB r7, r7, #0
+
+ MOV r12, r12,ASR #9 ; r12= (-*l)>>9
+ MOV r5, r5, ASR #9 ; r5 = (-*l)>>9
+ MOV r6, r6, ASR #9 ; r6 = (-*l)>>9
+ MOV r7, r7, ASR #9 ; r7 = (-*l)>>9
+
+ MOV r14,r12,ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r12,r4, r14,ASR #31
+ STRH r12,[r0], r3
+
+ MOV r14,r7, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r7, r4, r14,ASR #31
+ STRH r7, [r0], r3
+
+ MOV r14,r6, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r6, r4, r14,ASR #31
+ STRH r6, [r0], r3
+
+ MOV r14,r5, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r5, r4, r14,ASR #31
+ STRH r5, [r0], r3
+
+ SUBS r1, r1, #16
+ BGE unroll_loop3
+
+unroll_over3
+ ADDS r1, r1, #16
+ BLE unroll_over4
+unroll_loop4
+ LDR r5,[r2], #8
+ ; stall
+ ; stall (Xscale)
+ RSB r5, r5, #0
+ MOV r5, r5, ASR #9 ; r5 = (-*l)>>9
+ MOV r14,r5, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r5, r4, r14,ASR #31
+ STRH r5, [r0], r3
+ SUBS r1, r1, #4
+ BGT unroll_loop4
+unroll_over4
+ LDMFD r13!,{r4-r7,PC}
+
+mdct_unroll_part2_arm
+ ; r0 = out
+ ; r1 = post
+ ; r2 = l
+ ; r3 = r
+ ; <> = step
+ ; <> = wL
+ ; <> = wR
+ MOV r12,r13
+ STMFD r13!,{r4,r6-r11,r14}
+ LDMFD r12,{r8,r9,r10} ; r8 = step
+ ; r9 = wL
+ ; r10= wR
+ MVN r4, #0x8000
+ MOV r8, r8, LSL #1
+ SUBS r1, r3, r1 ; r1 = (r - post)
+ BLE unroll_over5
+unroll_loop5
+ LDR r12,[r2, #-8]! ; r12= *l (but l -= 2 first)
+ LDR r11,[r9],#4 ; r11= *wL++
+ LDR r7, [r3, #-4]! ; r7 = *--r
+ LDR r6, [r10,#-4]! ; r6 = *--wR
+
+ ; Can save a cycle here, at the cost of 1bit errors in rounding
+ SMULL r14,r11,r12,r11 ; (r14,r11) = *l * *wL++
+ SMULL r14,r6, r7, r6 ; (r14,r6) = *--r * *--wR
+ ADD r6, r6, r11
+ MOV r6, r6, ASR #8
+ MOV r14,r6, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r6, r4, r14,ASR #31
+ STRH r6, [r0], r8
+
+ SUBS r1, r1, #4
+ BGT unroll_loop5
+
+unroll_over5
+ LDMFD r13!,{r4,r6-r11,PC}
+
+mdct_unroll_part3_arm
+ ; r0 = out
+ ; r1 = post
+ ; r2 = l
+ ; r3 = r
+ ; <> = step
+ ; <> = wL
+ ; <> = wR
+ MOV r12,r13
+ STMFD r13!,{r4,r6-r11,r14}
+ LDMFD r12,{r8,r9,r10} ; r8 = step
+ ; r9 = wL
+ ; r10= wR
+ MVN r4, #0x8000
+ MOV r8, r8, LSL #1
+ SUBS r1, r1, r3 ; r1 = (post - r)
+ BLE unroll_over6
+unroll_loop6
+ LDR r12,[r2],#8 ; r12= *l (but l += 2 first)
+ LDR r11,[r9],#4 ; r11= *wL++
+ LDR r7, [r3],#4 ; r7 = *r++
+ LDR r6, [r10,#-4]! ; r6 = *--wR
+
+ ; Can save a cycle here, at the cost of 1bit errors in rounding
+ SMULL r14,r11,r12,r11 ; (r14,r11) = *l * *wL++
+ SMULL r14,r6, r7, r6 ; (r14,r6) = *--r * *--wR
+ SUB r6, r6, r11
+ MOV r6, r6, ASR #8
+ MOV r14,r6, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r6, r4, r14,ASR #31
+ STRH r6, [r0], r8
+
+ SUBS r1, r1, #4
+ BGT unroll_loop6
+
+unroll_over6
+ LDMFD r13!,{r4,r6-r11,PC}
+
+mdct_shift_right_arm
+ ; r0 = n
+ ; r1 = in
+ ; r2 = right
+ STMFD r13!,{r4-r11,r14}
+
+ MOV r0, r0, LSR #2 ; n >>= 2
+ ADD r1, r1, #4
+
+ SUBS r0, r0, #8
+ BLT sr_less_than_8
+sr_loop
+ LDR r3, [r1], #8
+ LDR r4, [r1], #8
+ LDR r5, [r1], #8
+ LDR r6, [r1], #8
+ LDR r7, [r1], #8
+ LDR r8, [r1], #8
+ LDR r12,[r1], #8
+ LDR r14,[r1], #8
+ SUBS r0, r0, #8
+ STMIA r2!,{r3,r4,r5,r6,r7,r8,r12,r14}
+ BGE sr_loop
+sr_less_than_8
+ ADDS r0, r0, #8
+ BEQ sr_end
+sr_loop2
+ LDR r3, [r1], #8
+ SUBS r0, r0, #1
+ STR r3, [r2], #4
+ BGT sr_loop2
+sr_end
+ LDMFD r13!,{r4-r11,PC}
+
+mdct_backward_arm
+ ; r0 = n
+ ; r1 = in
+ STMFD r13!,{r4-r11,r14}
+
+ MOV r2,#1<<4 ; r2 = 1<<shift
+ MOV r3,#13-4 ; r3 = 13-shift
+find_shift_loop
+ TST r0,r2 ; if (n & (1<<shift)) == 0
+ MOV r2,r2,LSL #1
+ SUBEQ r3,r3,#1 ; shift--
+ BEQ find_shift_loop
+ MOV r2,#2
+ MOV r2,r2,LSL r3 ; r2 = step = 2<<shift
+
+ ; presymmetry
+ ; r0 = n (a multiple of 4)
+ ; r1 = in
+ ; r2 = step
+ ; r3 = shift
+
+ ADD r4, r1, r0, LSL #1 ; r4 = aX = in+(n>>1)
+ ADD r14,r1, r0 ; r14= in+(n>>2)
+ SUB r4, r4, #3*4 ; r4 = aX = in+n2-3
+ LDR r5, =sincos_lookup0 ; r5 = T=sincos_lookup0
+
+presymmetry_loop1
+ LDR r7, [r4,#8] ; r6 = s2 = aX[2]
+ LDR r11,[r5,#4] ; r11= T[1]
+ LDR r6, [r4] ; r6 = s0 = aX[0]
+ LDR r10,[r5],r2,LSL #2 ; r10= T[0] T += step
+
+ ; XPROD31(s0, s2, T[0], T[1], &aX[0], &ax[2])
+ SMULL r8, r9, r7, r11 ; (r8, r9) = s2*T[1]
+ ; stall
+ ; stall ?
+ SMLAL r8, r9, r6, r10 ; (r8, r9) += s0*T[0]
+ RSB r6, r6, #0
+ ; stall ?
+ SMULL r8, r12,r7, r10 ; (r8, r12) = s2*T[0]
+ MOV r9, r9, LSL #1
+ ; stall ?
+ SMLAL r8, r12,r6, r11 ; (r8, r12) -= s0*T[1]
+ STR r9, [r4],#-16 ; aX[0] = r9
+ CMP r4,r14
+ MOV r12,r12,LSL #1
+ STR r12,[r4,#8+16] ; aX[2] = r12
+
+ BGE presymmetry_loop1 ; while (aX >= in+n4)
+
+presymmetry_loop2
+ LDR r6,[r4] ; r6 = s0 = aX[0]
+ LDR r10,[r5,#4] ; r10= T[1]
+ LDR r7,[r4,#8] ; r6 = s2 = aX[2]
+ LDR r11,[r5],-r2,LSL #2 ; r11= T[0] T -= step
+
+ ; XPROD31(s0, s2, T[1], T[0], &aX[0], &ax[2])
+ SMULL r8, r9, r6, r10 ; (r8, r9) = s0*T[1]
+ ; stall
+ ; stall ?
+ SMLAL r8, r9, r7, r11 ; (r8, r9) += s2*T[0]
+ RSB r6, r6, #0
+ ; stall ?
+ SMULL r8, r12,r7, r10 ; (r8, r12) = s2*T[1]
+ MOV r9, r9, LSL #1
+ ; stall ?
+ SMLAL r8, r12,r6, r11 ; (r8, r12) -= s0*T[0]
+ STR r9, [r4],#-16 ; aX[0] = r9
+ CMP r4,r1
+ MOV r12,r12,LSL #1
+ STR r12,[r4,#8+16] ; aX[2] = r12
+
+ BGE presymmetry_loop2 ; while (aX >= in)
+
+ ; r0 = n
+ ; r1 = in
+ ; r2 = step
+ ; r3 = shift
+ STMFD r13!,{r3}
+ LDR r5, =sincos_lookup0 ; r5 = T=sincos_lookup0
+ ADD r4, r1, r0, LSL #1 ; r4 = aX = in+(n>>1)
+ SUB r4, r4, #4*4 ; r4 = aX = in+(n>>1)-4
+ LDR r11,[r5,#4] ; r11= T[1]
+ LDR r10,[r5],r2, LSL #2 ; r10= T[0] T += step
+presymmetry_loop3
+ LDR r8,[r1],#16 ; r8 = ro0 = bX[0]
+ LDR r9,[r1,#8-16] ; r9 = ro2 = bX[2]
+ LDR r6,[r4] ; r6 = ri0 = aX[0]
+
+ ; XNPROD31( ro2, ro0, T[1], T[0], &aX[0], &aX[2] )
+ ; aX[0] = (ro2*T[1] - ro0*T[0])>>31 aX[2] = (ro0*T[1] + ro2*T[0])>>31
+ SMULL r14,r12,r8, r11 ; (r14,r12) = ro0*T[1]
+ RSB r8,r8,#0 ; r8 = -ro0
+ ; Stall ?
+ SMLAL r14,r12,r9, r10 ; (r14,r12) += ro2*T[0]
+ LDR r7,[r4,#8] ; r7 = ri2 = aX[2]
+ ; Stall ?
+ SMULL r14,r3, r9, r11 ; (r14,r3) = ro2*T[1]
+ MOV r12,r12,LSL #1
+ LDR r11,[r5,#4] ; r11= T[1]
+ SMLAL r14,r3, r8, r10 ; (r14,r3) -= ro0*T[0]
+ LDR r10,[r5],r2, LSL #2 ; r10= T[0] T += step
+ STR r12,[r4,#8]
+ MOV r3, r3, LSL #1
+ STR r3, [r4],#-16
+
+ ; XNPROD31( ri2, ri0, T[0], T[1], &bX[0], &bX[2] )
+ ; bX[0] = (ri2*T[0] - ri0*T[1])>>31 bX[2] = (ri0*T[0] + ri2*T[1])>>31
+ SMULL r14,r12,r6, r10 ; (r14,r12) = ri0*T[0]
+ RSB r6,r6,#0 ; r6 = -ri0
+ ; stall ?
+ SMLAL r14,r12,r7, r11 ; (r14,r12) += ri2*T[1]
+ ; stall ?
+ ; stall ?
+ SMULL r14,r3, r7, r10 ; (r14,r3) = ri2*T[0]
+ MOV r12,r12,LSL #1
+ ; stall ?
+ SMLAL r14,r3, r6, r11 ; (r14,r3) -= ri0*T[1]
+ CMP r4,r1
+ STR r12,[r1,#8-16]
+ MOV r3, r3, LSL #1
+ STR r3, [r1,#-16]
+
+ BGE presymmetry_loop3
+
+ SUB r1,r1,r0 ; r1 = in -= n>>2 (i.e. restore in)
+
+ LDR r3,[r13]
+ STR r2,[r13,#-4]!
+
+ ; mdct_butterflies
+ ; r0 = n = (points * 2)
+ ; r1 = in = x
+ ; r2 = i
+ ; r3 = shift
+ STMFD r13!,{r0-r1}
+ RSBS r4,r3,#6 ; r4 = stages = 7-shift then --stages
+ LDR r5,=sincos_lookup0
+ BLE no_generics
+ MOV r14,#4 ; r14= 4 (i=0)
+ MOV r6, r14,LSL r3 ; r6 = (4<<i)<<shift
+mdct_butterflies_loop1
+ MOV r0, r0, LSR #1 ; r0 = points>>i = POINTS
+ MOV r2, r14,LSR #2 ; r2 = (1<<i)-j (j=0)
+ STMFD r13!,{r4,r14}
+mdct_butterflies_loop2
+
+ ; mdct_butterfly_generic(x+POINTS*j, POINTS, 4<<(i+shift))
+ ; mdct_butterfly_generic(r1, r0, r6)
+ ; r0 = points
+ ; r1 = x
+ ; preserve r2 (external loop counter)
+ ; preserve r3
+ ; preserve r4 (external loop counter)
+ ; r5 = T = sincos_lookup0
+ ; r6 = step
+ ; preserve r14
+
+ STR r2,[r13,#-4]! ; stack r2
+ ADD r1,r1,r0,LSL #1 ; r1 = x2+4 = x + (POINTS>>1)
+ ADD r7,r1,r0,LSL #1 ; r7 = x1+4 = x + POINTS
+ ADD r12,r5,#1024*4 ; r12= sincos_lookup0+1024
+
+mdct_bufferfly_generic_loop1
+ LDMDB r7!,{r2,r3,r8,r11} ; r2 = x1[0]
+ ; r3 = x1[1]
+ ; r8 = x1[2]
+ ; r11= x1[3] x1 -= 4
+ LDMDB r1!,{r4,r9,r10,r14} ; r4 = x2[0]
+ ; r9 = x2[1]
+ ; r10= x2[2]
+ ; r14= x2[3] x2 -= 4
+
+ SUB r2, r2, r3 ; r2 = s0 = x1[0] - x1[1]
+ ADD r3, r2, r3, LSL #1 ; r3 = x1[0] + x1[1] (-> x1[0])
+ SUB r11,r11,r8 ; r11= s1 = x1[3] - x1[2]
+ ADD r8, r11,r8, LSL #1 ; r8 = x1[3] + x1[2] (-> x1[2])
+ SUB r9, r9, r4 ; r9 = s2 = x2[1] - x2[0]
+ ADD r4, r9, r4, LSL #1 ; r4 = x2[1] + x2[0] (-> x1[1])
+ SUB r14,r14,r10 ; r14= s3 = x2[3] - x2[2]
+ ADD r10,r14,r10,LSL #1 ; r10= x2[3] + x2[2] (-> x1[3])
+ STMIA r7,{r3,r4,r8,r10}
+
+ ; r0 = points
+ ; r1 = x2
+ ; r2 = s0
+ ; r3 free
+ ; r4 free
+ ; r5 = T
+ ; r6 = step
+ ; r7 = x1
+ ; r8 free
+ ; r9 = s2
+ ; r10 free
+ ; r11= s1
+ ; r12= limit
+ ; r14= s3
+
+ LDR r8, [r5,#4] ; r8 = T[1]
+ LDR r10,[r5],r6,LSL #2 ; r10= T[0] T += step
+
+ ; XPROD31(s1, s0, T[0], T[1], &x2[0], &x2[2])
+ ; x2[0] = (s1*T[0] + s0*T[1])>>31 x2[2] = (s0*T[0] - s1*T[1])>>31
+ ; stall Xscale
+ SMULL r4, r3, r2, r8 ; (r4, r3) = s0*T[1]
+ SMLAL r4, r3, r11,r10 ; (r4, r3) += s1*T[0]
+ RSB r11,r11,#0
+ SMULL r11,r4, r8, r11 ; (r11,r4) = -s1*T[1]
+ SMLAL r11,r4, r2, r10 ; (r11,r4) += s0*T[0]
+ MOV r2, r3, LSL #1 ; r2 = r3<<1 = Value for x2[0]
+
+ ; XPROD31(s2, s3, T[0], T[1], &x2[1], &x2[3])
+ ; x2[1] = (s2*T[0] + s3*T[1])>>31 x2[3] = (s3*T[0] - s2*T[1])>>31
+ SMULL r11,r3, r9, r10 ; (r11,r3) = s2*T[0]
+ MOV r4, r4, LSL #1 ; r4 = r4<<1 = Value for x2[2]
+ SMLAL r11,r3, r14,r8 ; (r11,r3) += s3*T[1]
+ RSB r9, r9, #0
+ SMULL r10,r11,r14,r10 ; (r10,r11) = s3*T[0]
+ MOV r3, r3, LSL #1 ; r3 = r3<<1 = Value for x2[1]
+ SMLAL r10,r11,r9,r8 ; (r10,r11) -= s2*T[1]
+ CMP r5, r12
+ MOV r11,r11,LSL #1 ; r11= r11<<1 = Value for x2[3]
+
+ STMIA r1,{r2,r3,r4,r11}
+
+ BLT mdct_bufferfly_generic_loop1
+
+ SUB r12,r12,#1024*4
+mdct_bufferfly_generic_loop2
+ LDMDB r7!,{r2,r3,r9,r10} ; r2 = x1[0]
+ ; r3 = x1[1]
+ ; r9 = x1[2]
+ ; r10= x1[3] x1 -= 4
+ LDMDB r1!,{r4,r8,r11,r14} ; r4 = x2[0]
+ ; r8 = x2[1]
+ ; r11= x2[2]
+ ; r14= x2[3] x2 -= 4
+
+ SUB r2, r2, r3 ; r2 = s0 = x1[0] - x1[1]
+ ADD r3, r2, r3, LSL #1 ; r3 = x1[0] + x1[1] (-> x1[0])
+ SUB r9, r9,r10 ; r9 = s1 = x1[2] - x1[3]
+ ADD r10,r9,r10, LSL #1 ; r10= x1[2] + x1[3] (-> x1[2])
+ SUB r4, r4, r8 ; r4 = s2 = x2[0] - x2[1]
+ ADD r8, r4, r8, LSL #1 ; r8 = x2[0] + x2[1] (-> x1[1])
+ SUB r14,r14,r11 ; r14= s3 = x2[3] - x2[2]
+ ADD r11,r14,r11,LSL #1 ; r11= x2[3] + x2[2] (-> x1[3])
+ STMIA r7,{r3,r8,r10,r11}
+
+ ; r0 = points
+ ; r1 = x2
+ ; r2 = s0
+ ; r3 free
+ ; r4 = s2
+ ; r5 = T
+ ; r6 = step
+ ; r7 = x1
+ ; r8 free
+ ; r9 = s1
+ ; r10 free
+ ; r11 free
+ ; r12= limit
+ ; r14= s3
+
+ LDR r8, [r5,#4] ; r8 = T[1]
+ LDR r10,[r5],-r6,LSL #2 ; r10= T[0] T -= step
+
+ ; XNPROD31(s0, s1, T[0], T[1], &x2[0], &x2[2])
+ ; x2[0] = (s0*T[0] - s1*T[1])>>31 x2[2] = (s1*T[0] + s0*T[1])>>31
+ ; stall Xscale
+ SMULL r3, r11,r2, r8 ; (r3, r11) = s0*T[1]
+ SMLAL r3, r11,r9, r10 ; (r3, r11) += s1*T[0]
+ RSB r9, r9, #0
+ SMULL r3, r2, r10,r2 ; (r3, r2) = s0*T[0]
+ SMLAL r3, r2, r9, r8 ; (r3, r2) += -s1*T[1]
+ MOV r9, r11,LSL #1 ; r9 = r11<<1 = Value for x2[2]
+
+ ; XNPROD31(s3, s2, T[0], T[1], &x2[1], &x2[3])
+ ; x2[1] = (s3*T[0] - s2*T[1])>>31 x2[3] = (s2*T[0] + s3*T[1])>>31
+ SMULL r3, r11,r4, r10 ; (r3,r11) = s2*T[0]
+ MOV r2, r2, LSL #1 ; r2 = r2<<1 = Value for x2[0]
+ SMLAL r3, r11,r14,r8 ; (r3,r11) += s3*T[1]
+ RSB r4, r4, #0
+ SMULL r10,r3,r14,r10 ; (r10,r3) = s3*T[0]
+ MOV r11,r11,LSL #1 ; r11= r11<<1 = Value for x2[3]
+ SMLAL r10,r3, r4, r8 ; (r10,r3) -= s2*T[1]
+ CMP r5, r12
+ MOV r3, r3, LSL #1 ; r3 = r3<<1 = Value for x2[1]
+
+ STMIA r1,{r2,r3,r9,r11}
+
+ BGT mdct_bufferfly_generic_loop2
+
+ LDR r2,[r13],#4 ; unstack r2
+ ADD r1, r1, r0, LSL #2 ; r1 = x+POINTS*j
+ ; stall Xscale
+ SUBS r2, r2, #1 ; r2-- (j++)
+ BGT mdct_butterflies_loop2
+
+ LDMFD r13!,{r4,r14}
+
+ LDR r1,[r13,#4]
+
+ SUBS r4, r4, #1 ; stages--
+ MOV r14,r14,LSL #1 ; r14= 4<<i (i++)
+ MOV r6, r6, LSL #1 ; r6 = step <<= 1 (i++)
+ BGE mdct_butterflies_loop1
+ LDMFD r13,{r0-r1}
+no_generics
+ ; mdct_butterflies part2 (loop around mdct_bufferfly_32)
+ ; r0 = points
+ ; r1 = in
+ ; r2 = step
+ ; r3 = shift
+
+mdct_bufferflies_loop3
+ ; mdct_bufferfly_32
+
+ ; block1
+ ADD r4, r1, #16*4 ; r4 = &in[16]
+ LDMIA r4,{r5,r6,r9,r10} ; r5 = x[16]
+ ; r6 = x[17]
+ ; r9 = x[18]
+ ; r10= x[19]
+ LDMIA r1,{r7,r8,r11,r12} ; r7 = x[0]
+ ; r8 = x[1]
+ ; r11= x[2]
+ ; r12= x[3]
+ SUB r5, r5, r6 ; r5 = s0 = x[16] - x[17]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[16] + x[17] -> x[16]
+ SUB r9, r9, r10 ; r9 = s1 = x[18] - x[19]
+ ADD r10,r9, r10,LSL #1 ; r10= x[18] + x[19] -> x[18]
+ SUB r8, r8, r7 ; r8 = s2 = x[ 1] - x[ 0]
+ ADD r7, r8, r7, LSL #1 ; r7 = x[ 1] + x[ 0] -> x[17]
+ SUB r12,r12,r11 ; r12= s3 = x[ 3] - x[ 2]
+ ADD r11,r12,r11, LSL #1 ; r11= x[ 3] + x[ 2] -> x[19]
+ STMIA r4!,{r6,r7,r10,r11}
+
+ LDR r6,cPI1_8
+ LDR r7,cPI3_8
+
+ ; XNPROD31( s0, s1, cPI3_8, cPI1_8, &x[ 0], &x[ 2] )
+ ; x[0] = s0*cPI3_8 - s1*cPI1_8 x[2] = s1*cPI3_8 + s0*cPI1_8
+ ; stall Xscale
+ SMULL r14,r11,r5, r6 ; (r14,r11) = s0*cPI1_8
+ SMLAL r14,r11,r9, r7 ; (r14,r11) += s1*cPI3_8
+ RSB r9, r9, #0
+ SMULL r14,r5, r7, r5 ; (r14,r5) = s0*cPI3_8
+ SMLAL r14,r5, r9, r6 ; (r14,r5) -= s1*cPI1_8
+ MOV r11,r11,LSL #1
+ MOV r5, r5, LSL #1
+
+ ; XPROD31 ( s2, s3, cPI1_8, cPI3_8, &x[ 1], &x[ 3] )
+ ; x[1] = s2*cPI1_8 + s3*cPI3_8 x[3] = s3*cPI1_8 - s2*cPI3_8
+ SMULL r14,r9, r8, r6 ; (r14,r9) = s2*cPI1_8
+ SMLAL r14,r9, r12,r7 ; (r14,r9) += s3*cPI3_8
+ RSB r8,r8,#0
+ SMULL r14,r12,r6, r12 ; (r14,r12) = s3*cPI1_8
+ SMLAL r14,r12,r8, r7 ; (r14,r12) -= s2*cPI3_8
+ MOV r9, r9, LSL #1
+ MOV r12,r12,LSL #1
+ STMIA r1!,{r5,r9,r11,r12}
+
+ ; block2
+ LDMIA r4,{r5,r6,r9,r10} ; r5 = x[20]
+ ; r6 = x[21]
+ ; r9 = x[22]
+ ; r10= x[23]
+ LDMIA r1,{r7,r8,r11,r12} ; r7 = x[4]
+ ; r8 = x[5]
+ ; r11= x[6]
+ ; r12= x[7]
+ SUB r5, r5, r6 ; r5 = s0 = x[20] - x[21]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[20] + x[21] -> x[20]
+ SUB r9, r9, r10 ; r9 = s1 = x[22] - x[23]
+ ADD r10,r9, r10,LSL #1 ; r10= x[22] + x[23] -> x[22]
+ SUB r8, r8, r7 ; r8 = s2 = x[ 5] - x[ 4]
+ ADD r7, r8, r7, LSL #1 ; r7 = x[ 5] + x[ 4] -> x[21]
+ SUB r12,r12,r11 ; r12= s3 = x[ 7] - x[ 6]
+ ADD r11,r12,r11, LSL #1 ; r11= x[ 7] + x[ 6] -> x[23]
+ LDR r14,cPI2_8
+ STMIA r4!,{r6,r7,r10,r11}
+
+ SUB r5, r5, r9 ; r5 = s0 - s1
+ ADD r9, r5, r9, LSL #1 ; r9 = s0 + s1
+ SMULL r6, r5, r14,r5 ; (r6,r5) = (s0-s1)*cPI2_8
+ SUB r12,r12,r8 ; r12= s3 - s2
+ ADD r8, r12,r8, LSL #1 ; r8 = s3 + s2
+
+ SMULL r6, r8, r14,r8 ; (r6,r8) = (s3+s2)*cPI2_8
+ MOV r5, r5, LSL #1
+ SMULL r6, r9, r14,r9 ; (r6,r9) = (s0+s1)*cPI2_8
+ MOV r8, r8, LSL #1
+ SMULL r6, r12,r14,r12 ; (r6,r12) = (s3-s2)*cPI2_8
+ MOV r9, r9, LSL #1
+ MOV r12,r12,LSL #1
+ STMIA r1!,{r5,r8,r9,r12}
+
+ ; block3
+ LDMIA r4,{r5,r6,r9,r10} ; r5 = x[24]
+ ; r6 = x[25]
+ ; r9 = x[25]
+ ; r10= x[26]
+ LDMIA r1,{r7,r8,r11,r12} ; r7 = x[8]
+ ; r8 = x[9]
+ ; r11= x[10]
+ ; r12= x[11]
+ SUB r5, r5, r6 ; r5 = s0 = x[24] - x[25]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[24] + x[25] -> x[25]
+ SUB r9, r9, r10 ; r9 = s1 = x[26] - x[27]
+ ADD r10,r9, r10,LSL #1 ; r10= x[26] + x[27] -> x[26]
+ SUB r8, r8, r7 ; r8 = s2 = x[ 9] - x[ 8]
+ ADD r7, r8, r7, LSL #1 ; r7 = x[ 9] + x[ 8] -> x[25]
+ SUB r12,r12,r11 ; r12= s3 = x[11] - x[10]
+ ADD r11,r12,r11, LSL #1 ; r11= x[11] + x[10] -> x[27]
+ STMIA r4!,{r6,r7,r10,r11}
+
+ LDR r6,cPI3_8
+ LDR r7,cPI1_8
+
+ ; XNPROD31( s0, s1, cPI1_8, cPI3_8, &x[ 8], &x[10] )
+ ; x[8] = s0*cPI1_8 - s1*cPI3_8 x[10] = s1*cPI1_8 + s0*cPI3_8
+ ; stall Xscale
+ SMULL r14,r11,r5, r6 ; (r14,r11) = s0*cPI3_8
+ SMLAL r14,r11,r9, r7 ; (r14,r11) += s1*cPI1_8
+ RSB r9, r9, #0
+ SMULL r14,r5, r7, r5 ; (r14,r5) = s0*cPI1_8
+ SMLAL r14,r5, r9, r6 ; (r14,r5) -= s1*cPI3_8
+ MOV r11,r11,LSL #1
+ MOV r5, r5, LSL #1
+
+ ; XPROD31 ( s2, s3, cPI3_8, cPI1_8, &x[ 9], &x[11] )
+ ; x[9] = s2*cPI3_8 + s3*cPI1_8 x[11] = s3*cPI3_8 - s2*cPI1_8
+ SMULL r14,r9, r8, r6 ; (r14,r9) = s2*cPI3_8
+ SMLAL r14,r9, r12,r7 ; (r14,r9) += s3*cPI1_8
+ RSB r8,r8,#0
+ SMULL r14,r12,r6, r12 ; (r14,r12) = s3*cPI3_8
+ SMLAL r14,r12,r8, r7 ; (r14,r12) -= s2*cPI1_8
+ MOV r9, r9, LSL #1
+ MOV r12,r12,LSL #1
+ STMIA r1!,{r5,r9,r11,r12}
+
+ ; block4
+ LDMIA r4,{r5,r6,r10,r11} ; r5 = x[28]
+ ; r6 = x[29]
+ ; r10= x[30]
+ ; r11= x[31]
+ LDMIA r1,{r8,r9,r12,r14} ; r8 = x[12]
+ ; r9 = x[13]
+ ; r12= x[14]
+ ; r14= x[15]
+ SUB r5, r5, r6 ; r5 = s0 = x[28] - x[29]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[28] + x[29] -> x[28]
+ SUB r7, r14,r12 ; r7 = s3 = x[15] - x[14]
+ ADD r12,r7, r12, LSL #1 ; r12= x[15] + x[14] -> x[31]
+ SUB r10,r10,r11 ; r10= s1 = x[30] - x[31]
+ ADD r11,r10,r11,LSL #1 ; r11= x[30] + x[31] -> x[30]
+ SUB r14, r8, r9 ; r14= s2 = x[12] - x[13]
+ ADD r9, r14, r9, LSL #1 ; r9 = x[12] + x[13] -> x[29]
+ STMIA r4!,{r6,r9,r11,r12}
+ STMIA r1!,{r5,r7,r10,r14}
+
+ ; mdct_butterfly16 (1st version)
+ ; block 1
+ SUB r1,r1,#16*4
+ ADD r4,r1,#8*4
+ LDMIA r4,{r5,r6,r9,r10} ; r5 = x[ 8]
+ ; r6 = x[ 9]
+ ; r9 = x[10]
+ ; r10= x[11]
+ LDMIA r1,{r7,r8,r11,r12} ; r7 = x[0]
+ ; r8 = x[1]
+ ; r11= x[2]
+ ; r12= x[3]
+ SUB r5, r5, r6 ; r5 = s0 = x[ 8] - x[ 9]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[ 8] + x[ 9] -> x[ 8]
+ SUB r9, r9, r10 ; r9 = s1 = x[10] - x[11]
+ ADD r10,r9, r10,LSL #1 ; r10= x[10] + x[11] -> x[10]
+ SUB r8, r8, r7 ; r8 = s2 = x[ 1] - x[ 0]
+ ADD r7, r8, r7, LSL #1 ; r7 = x[ 1] + x[ 0] -> x[ 9]
+ SUB r12,r12,r11 ; r12= s3 = x[ 3] - x[ 2]
+ ADD r11,r12,r11, LSL #1 ; r11= x[ 3] + x[ 2] -> x[11]
+ LDR r14,cPI2_8
+ STMIA r4!,{r6,r7,r10,r11}
+
+ SUB r5, r5, r9 ; r5 = s0 - s1
+ ADD r9, r5, r9, LSL #1 ; r9 = s0 + s1
+ SMULL r6, r5, r14,r5 ; (r6,r5) = (s0-s1)*cPI2_8
+ SUB r12,r12,r8 ; r12= s3 - s2
+ ADD r8, r12,r8, LSL #1 ; r8 = s3 + s2
+
+ SMULL r6, r8, r14,r8 ; (r6,r8) = (s3+s2)*cPI2_8
+ MOV r5, r5, LSL #1
+ SMULL r6, r9, r14,r9 ; (r6,r9) = (s0+s1)*cPI2_8
+ MOV r8, r8, LSL #1
+ SMULL r6, r12,r14,r12 ; (r6,r12) = (s3-s2)*cPI2_8
+ MOV r9, r9, LSL #1
+ MOV r12,r12,LSL #1
+ STMIA r1!,{r5,r8,r9,r12}
+
+ ; block4
+ LDMIA r4,{r5,r6,r9,r10} ; r5 = x[12]
+ ; r6 = x[13]
+ ; r9 = x[14]
+ ; r10= x[15]
+ LDMIA r1,{r7,r8,r11,r12} ; r7 = x[ 4]
+ ; r8 = x[ 5]
+ ; r11= x[ 6]
+ ; r12= x[ 7]
+ SUB r14,r7, r8 ; r14= s0 = x[ 4] - x[ 5]
+ ADD r8, r14,r8, LSL #1 ; r8 = x[ 4] + x[ 5] -> x[13]
+ SUB r7, r12,r11 ; r7 = s1 = x[ 7] - x[ 6]
+ ADD r11,r7, r11, LSL #1 ; r11= x[ 7] + x[ 6] -> x[15]
+ SUB r5, r5, r6 ; r5 = s2 = x[12] - x[13]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[12] + x[13] -> x[12]
+ SUB r12,r9, r10 ; r12= s3 = x[14] - x[15]
+ ADD r10,r12,r10,LSL #1 ; r10= x[14] + x[15] -> x[14]
+ STMIA r4!,{r6,r8,r10,r11}
+ STMIA r1!,{r5,r7,r12,r14}
+
+ ; mdct_butterfly_8
+ LDMDB r1,{r6,r7,r8,r9,r10,r11,r12,r14}
+ ; r6 = x[0]
+ ; r7 = x[1]
+ ; r8 = x[2]
+ ; r9 = x[3]
+ ; r10= x[4]
+ ; r11= x[5]
+ ; r12= x[6]
+ ; r14= x[7]
+ ADD r6, r6, r7 ; r6 = s0 = x[0] + x[1]
+ SUB r7, r6, r7, LSL #1 ; r7 = s1 = x[0] - x[1]
+ ADD r8, r8, r9 ; r8 = s2 = x[2] + x[3]
+ SUB r9, r8, r9, LSL #1 ; r9 = s3 = x[2] - x[3]
+ ADD r10,r10,r11 ; r10= s4 = x[4] + x[5]
+ SUB r11,r10,r11,LSL #1 ; r11= s5 = x[4] - x[5]
+ ADD r12,r12,r14 ; r12= s6 = x[6] + x[7]
+ SUB r14,r12,r14,LSL #1 ; r14= s7 = x[6] - x[7]
+
+ ADD r2, r11,r9 ; r2 = x[0] = s5 + s3
+ SUB r4, r2, r9, LSL #1 ; r4 = x[2] = s5 - s3
+ SUB r3, r14,r7 ; r3 = x[1] = s7 - s1
+ ADD r5, r3, r7, LSL #1 ; r5 = x[3] = s7 + s1
+ SUB r10,r10,r6 ; r10= x[4] = s4 - s0
+ SUB r11,r12,r8 ; r11= x[5] = s6 - s2
+ ADD r12,r10,r6, LSL #1 ; r12= x[6] = s4 + s0
+ ADD r14,r11,r8, LSL #1 ; r14= x[7] = s6 + s2
+ STMDB r1,{r2,r3,r4,r5,r10,r11,r12,r14}
+
+ ; mdct_butterfly_8
+ LDMIA r1,{r6,r7,r8,r9,r10,r11,r12,r14}
+ ; r6 = x[0]
+ ; r7 = x[1]
+ ; r8 = x[2]
+ ; r9 = x[3]
+ ; r10= x[4]
+ ; r11= x[5]
+ ; r12= x[6]
+ ; r14= x[7]
+ ADD r6, r6, r7 ; r6 = s0 = x[0] + x[1]
+ SUB r7, r6, r7, LSL #1 ; r7 = s1 = x[0] - x[1]
+ ADD r8, r8, r9 ; r8 = s2 = x[2] + x[3]
+ SUB r9, r8, r9, LSL #1 ; r9 = s3 = x[2] - x[3]
+ ADD r10,r10,r11 ; r10= s4 = x[4] + x[5]
+ SUB r11,r10,r11,LSL #1 ; r11= s5 = x[4] - x[5]
+ ADD r12,r12,r14 ; r12= s6 = x[6] + x[7]
+ SUB r14,r12,r14,LSL #1 ; r14= s7 = x[6] - x[7]
+
+ ADD r2, r11,r9 ; r2 = x[0] = s5 + s3
+ SUB r4, r2, r9, LSL #1 ; r4 = x[2] = s5 - s3
+ SUB r3, r14,r7 ; r3 = x[1] = s7 - s1
+ ADD r5, r3, r7, LSL #1 ; r5 = x[3] = s7 + s1
+ SUB r10,r10,r6 ; r10= x[4] = s4 - s0
+ SUB r11,r12,r8 ; r11= x[5] = s6 - s2
+ ADD r12,r10,r6, LSL #1 ; r12= x[6] = s4 + s0
+ ADD r14,r11,r8, LSL #1 ; r14= x[7] = s6 + s2
+ STMIA r1,{r2,r3,r4,r5,r10,r11,r12,r14}
+
+ ; block 2
+ ADD r1,r1,#16*4-8*4
+ ADD r4,r1,#8*4
+ LDMIA r4,{r5,r6,r9,r10} ; r5 = x[ 8]
+ ; r6 = x[ 9]
+ ; r9 = x[10]
+ ; r10= x[11]
+ LDMIA r1,{r7,r8,r11,r12} ; r7 = x[0]
+ ; r8 = x[1]
+ ; r11= x[2]
+ ; r12= x[3]
+ SUB r5, r5, r6 ; r5 = s0 = x[ 8] - x[ 9]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[ 8] + x[ 9] -> x[ 8]
+ SUB r9, r9, r10 ; r9 = s1 = x[10] - x[11]
+ ADD r10,r9, r10,LSL #1 ; r10= x[10] + x[11] -> x[10]
+ SUB r8, r8, r7 ; r8 = s2 = x[ 1] - x[ 0]
+ ADD r7, r8, r7, LSL #1 ; r7 = x[ 1] + x[ 0] -> x[ 9]
+ SUB r12,r12,r11 ; r12= s3 = x[ 3] - x[ 2]
+ ADD r11,r12,r11, LSL #1 ; r11= x[ 3] + x[ 2] -> x[11]
+ LDR r14,cPI2_8
+ STMIA r4!,{r6,r7,r10,r11}
+
+ SUB r5, r5, r9 ; r5 = s0 - s1
+ ADD r9, r5, r9, LSL #1 ; r9 = s0 + s1
+ SMULL r6, r5, r14,r5 ; (r6,r5) = (s0-s1)*cPI2_8
+ SUB r12,r12,r8 ; r12= s3 - s2
+ ADD r8, r12,r8, LSL #1 ; r8 = s3 + s2
+
+ SMULL r6, r8, r14,r8 ; (r6,r8) = (s3+s2)*cPI2_8
+ MOV r5, r5, LSL #1
+ SMULL r6, r9, r14,r9 ; (r6,r9) = (s0+s1)*cPI2_8
+ MOV r8, r8, LSL #1
+ SMULL r6, r12,r14,r12 ; (r6,r12) = (s3-s2)*cPI2_8
+ MOV r9, r9, LSL #1
+ MOV r12,r12,LSL #1
+ STMIA r1!,{r5,r8,r9,r12}
+
+ ; block4
+ LDMIA r4,{r5,r6,r9,r10} ; r5 = x[12]
+ ; r6 = x[13]
+ ; r9 = x[14]
+ ; r10= x[15]
+ LDMIA r1,{r7,r8,r11,r12} ; r7 = x[ 4]
+ ; r8 = x[ 5]
+ ; r11= x[ 6]
+ ; r12= x[ 7]
+ SUB r5, r5, r6 ; r5 = s2 = x[12] - x[13]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[12] + x[13] -> x[12]
+ SUB r9, r9, r10 ; r9 = s3 = x[14] - x[15]
+ ADD r10,r9, r10,LSL #1 ; r10= x[14] + x[15] -> x[14]
+ SUB r14,r7, r8 ; r14= s0 = x[ 4] - x[ 5]
+ ADD r8, r14,r8, LSL #1 ; r8 = x[ 4] + x[ 5] -> x[13]
+ SUB r7, r12,r11 ; r7 = s1 = x[ 7] - x[ 6]
+ ADD r11,r7, r11, LSL #1 ; r11= x[ 7] + x[ 6] -> x[15]
+ STMIA r4!,{r6,r8,r10,r11}
+ STMIA r1!,{r5,r7,r9,r14}
+
+ ; mdct_butterfly_8
+ LDMDB r1,{r6,r7,r8,r9,r10,r11,r12,r14}
+ ; r6 = x[0]
+ ; r7 = x[1]
+ ; r8 = x[2]
+ ; r9 = x[3]
+ ; r10= x[4]
+ ; r11= x[5]
+ ; r12= x[6]
+ ; r14= x[7]
+ ADD r6, r6, r7 ; r6 = s0 = x[0] + x[1]
+ SUB r7, r6, r7, LSL #1 ; r7 = s1 = x[0] - x[1]
+ ADD r8, r8, r9 ; r8 = s2 = x[2] + x[3]
+ SUB r9, r8, r9, LSL #1 ; r9 = s3 = x[2] - x[3]
+ ADD r10,r10,r11 ; r10= s4 = x[4] + x[5]
+ SUB r11,r10,r11,LSL #1 ; r11= s5 = x[4] - x[5]
+ ADD r12,r12,r14 ; r12= s6 = x[6] + x[7]
+ SUB r14,r12,r14,LSL #1 ; r14= s7 = x[6] - x[7]
+
+ ADD r2, r11,r9 ; r2 = x[0] = s5 + s3
+ SUB r4, r2, r9, LSL #1 ; r4 = x[2] = s5 - s3
+ SUB r3, r14,r7 ; r3 = x[1] = s7 - s1
+ ADD r5, r3, r7, LSL #1 ; r5 = x[3] = s7 + s1
+ SUB r10,r10,r6 ; r10= x[4] = s4 - s0
+ SUB r11,r12,r8 ; r11= x[5] = s6 - s2
+ ADD r12,r10,r6, LSL #1 ; r12= x[6] = s4 + s0
+ ADD r14,r11,r8, LSL #1 ; r14= x[7] = s6 + s2
+ STMDB r1,{r2,r3,r4,r5,r10,r11,r12,r14}
+
+ ; mdct_butterfly_8
+ LDMIA r1,{r6,r7,r8,r9,r10,r11,r12,r14}
+ ; r6 = x[0]
+ ; r7 = x[1]
+ ; r8 = x[2]
+ ; r9 = x[3]
+ ; r10= x[4]
+ ; r11= x[5]
+ ; r12= x[6]
+ ; r14= x[7]
+ ADD r6, r6, r7 ; r6 = s0 = x[0] + x[1]
+ SUB r7, r6, r7, LSL #1 ; r7 = s1 = x[0] - x[1]
+ ADD r8, r8, r9 ; r8 = s2 = x[2] + x[3]
+ SUB r9, r8, r9, LSL #1 ; r9 = s3 = x[2] - x[3]
+ ADD r10,r10,r11 ; r10= s4 = x[4] + x[5]
+ SUB r11,r10,r11,LSL #1 ; r11= s5 = x[4] - x[5]
+ ADD r12,r12,r14 ; r12= s6 = x[6] + x[7]
+ SUB r14,r12,r14,LSL #1 ; r14= s7 = x[6] - x[7]
+
+ ADD r2, r11,r9 ; r2 = x[0] = s5 + s3
+ SUB r4, r2, r9, LSL #1 ; r4 = x[2] = s5 - s3
+ SUB r3, r14,r7 ; r3 = x[1] = s7 - s1
+ ADD r5, r3, r7, LSL #1 ; r5 = x[3] = s7 + s1
+ SUB r10,r10,r6 ; r10= x[4] = s4 - s0
+ SUB r11,r12,r8 ; r11= x[5] = s6 - s2
+ ADD r12,r10,r6, LSL #1 ; r12= x[6] = s4 + s0
+ ADD r14,r11,r8, LSL #1 ; r14= x[7] = s6 + s2
+ STMIA r1,{r2,r3,r4,r5,r10,r11,r12,r14}
+
+ ADD r1,r1,#8*4
+ SUBS r0,r0,#64
+ BGT mdct_bufferflies_loop3
+
+ LDMFD r13,{r0-r3}
+
+mdct_bitreverse_arm
+ ; r0 = points = n
+ ; r1 = in
+ ; r2 = step
+ ; r3 = shift
+
+ MOV r4, #0 ; r4 = bit = 0
+ ADD r5, r1, r0, LSL #1 ; r5 = w = x + (n>>1)
+ ADR r6, bitrev
+ SUB r5, r5, #8
+brev_lp
+ LDRB r7, [r6, r4, LSR #6]
+ AND r8, r4, #0x3f
+ LDRB r8, [r6, r8]
+ ADD r4, r4, #1 ; bit++
+ ; stall XScale
+ ORR r7, r7, r8, LSL #6 ; r7 = bitrev[bit]
+ MOV r7, r7, LSR r3
+ ADD r9, r1, r7, LSL #2 ; r9 = xx = x + (b>>shift)
+ CMP r5, r9 ; if (w > xx)
+ LDR r10,[r5],#-8 ; r10 = w[0] w -= 2
+ LDRGT r11,[r5,#12] ; r11 = w[1]
+ LDRGT r12,[r9] ; r12 = xx[0]
+ LDRGT r14,[r9,#4] ; r14 = xx[1]
+ STRGT r10,[r9] ; xx[0]= w[0]
+ STRGT r11,[r9,#4] ; xx[1]= w[1]
+ STRGT r12,[r5,#8] ; w[0] = xx[0]
+ STRGT r14,[r5,#12] ; w[1] = xx[1]
+ CMP r5,r1
+ BGT brev_lp
+
+ ; mdct_step7
+ ; r0 = points
+ ; r1 = in
+ ; r2 = step
+ ; r3 = shift
+
+ CMP r2, #4 ; r5 = T = (step>=4) ?
+ LDRGE r5, =sincos_lookup0 ; sincos_lookup0 +
+ LDRLT r5, =sincos_lookup1 ; sincos_lookup0 +
+ ADD r7, r1, r0, LSL #1 ; r7 = w1 = x + (n>>1)
+ ADDGE r5, r5, r2, LSL #1 ; (step>>1)
+ ADD r8, r5, #1024*4 ; r8 = Ttop
+step7_loop1
+ LDR r6, [r1] ; r6 = w0[0]
+ LDR r9, [r1,#4] ; r9 = w0[1]
+ LDR r10,[r7,#-8]! ; r10= w1[0] w1 -= 2
+ LDR r11,[r7,#4] ; r11= w1[1]
+ LDR r14,[r5,#4] ; r14= T[1]
+ LDR r12,[r5],r2,LSL #2 ; r12= T[0] T += step
+
+ ADD r6, r6, r10 ; r6 = s0 = w0[0] + w1[0]
+ SUB r10,r6, r10,LSL #1 ; r10= s1b= w0[0] - w1[0]
+ SUB r11,r11,r9 ; r11= s1 = w1[1] - w0[1]
+ ADD r9, r11,r9, LSL #1 ; r9 = s0b= w1[1] + w0[1]
+
+ ; Can save 1 cycle by using SMULL SMLAL - at the cost of being
+ ; 1 off.
+ SMULL r0, r3, r6, r14 ; (r0,r3) = s0*T[1]
+ SMULL r0, r4, r11,r12 ; (r0,r4) += s1*T[0] = s2
+ ADD r3, r3, r4
+ SMULL r0, r14,r11,r14 ; (r0,r14) = s1*T[1]
+ SMULL r0, r12,r6, r12 ; (r0,r12) += s0*T[0] = s3
+ SUB r14,r14,r12
+
+ ; r9 = s0b<<1
+ ; r10= s1b<<1
+ ADD r9, r3, r9, ASR #1 ; r9 = s0b + s2
+ SUB r3, r9, r3, LSL #1 ; r3 = s0b - s2
+
+ SUB r12,r14,r10,ASR #1 ; r12= s3 - s1b
+ ADD r10,r14,r10,ASR #1 ; r10= s3 + s1b
+ STR r9, [r1],#4
+ STR r10,[r1],#4 ; w0 += 2
+ STR r3, [r7]
+ STR r12,[r7,#4]
+
+ CMP r5,r8
+ BLT step7_loop1
+
+step7_loop2
+ LDR r6, [r1] ; r6 = w0[0]
+ LDR r9, [r1,#4] ; r9 = w0[1]
+ LDR r10,[r7,#-8]! ; r10= w1[0] w1 -= 2
+ LDR r11,[r7,#4] ; r11= w1[1]
+ LDR r14,[r5,-r2,LSL #2]! ; r12= T[1] T -= step
+ LDR r12,[r5,#4] ; r14= T[0]
+
+ ADD r6, r6, r10 ; r6 = s0 = w0[0] + w1[0]
+ SUB r10,r6, r10,LSL #1 ; r10= s1b= w0[0] - w1[0]
+ SUB r11,r11,r9 ; r11= s1 = w1[1] - w0[1]
+ ADD r9, r11,r9, LSL #1 ; r9 = s0b= w1[1] + w0[1]
+
+ ; Can save 1 cycle by using SMULL SMLAL - at the cost of being
+ ; 1 off.
+ SMULL r0, r3, r6, r14 ; (r0,r3) = s0*T[0]
+ SMULL r0, r4, r11,r12 ; (r0,r4) += s1*T[1] = s2
+ ADD r3, r3, r4
+ SMULL r0, r14,r11,r14 ; (r0,r14) = s1*T[0]
+ SMULL r0, r12,r6, r12 ; (r0,r12) += s0*T[1] = s3
+ SUB r14,r14,r12
+
+ ; r9 = s0b<<1
+ ; r10= s1b<<1
+ ADD r9, r3, r9, ASR #1 ; r9 = s0b + s2
+ SUB r3, r9, r3, LSL #1 ; r3 = s0b - s2
+
+ SUB r12,r14,r10,ASR #1 ; r12= s3 - s1b
+ ADD r10,r14,r10,ASR #1 ; r10= s3 + s1b
+ STR r9, [r1],#4
+ STR r10,[r1],#4 ; w0 += 2
+ STR r3, [r7]
+ STR r12,[r7,#4]
+
+ CMP r1,r7
+ BLT step7_loop2
+
+ LDMFD r13!,{r0-r3}
+
+ ; r0 = points
+ ; r1 = in
+ ; r2 = step
+ ; r3 = shift
+ MOV r2, r2, ASR #2 ; r2 = step >>= 2
+ CMP r2, #0
+ CMPNE r2, #1
+ BEQ mdct_end
+
+ ; step > 1 (default case)
+ CMP r2, #4 ; r5 = T = (step>=4) ?
+ LDRGE r5, =sincos_lookup0 ; sincos_lookup0 +
+ LDRLT r5, =sincos_lookup1 ; sincos_lookup1
+ ADD r7, r1, r0, LSL #1 ; r7 = iX = x + (n>>1)
+ ADDGE r5, r5, r2, LSL #1 ; (step>>1)
+mdct_step8_default
+ LDR r6, [r1],#4 ; r6 = s0 = x[0]
+ LDR r8, [r1],#4 ; r8 = -s1 = x[1]
+ LDR r12,[r5,#4] ; r12= T[1]
+ LDR r14,[r5],r2,LSL #2 ; r14= T[0] T += step
+ RSB r8, r8, #0 ; r8 = s1
+
+ ; XPROD31(s0, s1, T[0], T[1], x, x+1)
+ ; x[0] = s0 * T[0] + s1 * T[1] x[1] = s1 * T[0] - s0 * T[1]
+ SMULL r9, r10, r8, r12 ; (r9,r10) = s1 * T[1]
+ CMP r1, r7
+ SMLAL r9, r10, r6, r14 ; (r9,r10) += s0 * T[0]
+ RSB r6, r6, #0 ; r6 = -s0
+ SMULL r9, r11, r8, r14 ; (r9,r11) = s1 * T[0]
+ MOV r10,r10,LSL #1
+ SMLAL r9, r11, r6, r12 ; (r9,r11) -= s0 * T[1]
+ STR r10,[r1,#-8]
+ MOV r11,r11,LSL #1
+ STR r11,[r1,#-4]
+ BLT mdct_step8_default
+
+mdct_end
+ MOV r0, r2
+ LDMFD r13!,{r4-r11,PC}
+
+cPI1_8
+ DCD 0x7641af3d
+cPI2_8
+ DCD 0x5a82799a
+cPI3_8
+ DCD 0x30fbc54d
+bitrev
+ DCB 0
+ DCB 32
+ DCB 16
+ DCB 48
+ DCB 8
+ DCB 40
+ DCB 24
+ DCB 56
+ DCB 4
+ DCB 36
+ DCB 20
+ DCB 52
+ DCB 12
+ DCB 44
+ DCB 28
+ DCB 60
+ DCB 2
+ DCB 34
+ DCB 18
+ DCB 50
+ DCB 10
+ DCB 42
+ DCB 26
+ DCB 58
+ DCB 6
+ DCB 38
+ DCB 22
+ DCB 54
+ DCB 14
+ DCB 46
+ DCB 30
+ DCB 62
+ DCB 1
+ DCB 33
+ DCB 17
+ DCB 49
+ DCB 9
+ DCB 41
+ DCB 25
+ DCB 57
+ DCB 5
+ DCB 37
+ DCB 21
+ DCB 53
+ DCB 13
+ DCB 45
+ DCB 29
+ DCB 61
+ DCB 3
+ DCB 35
+ DCB 19
+ DCB 51
+ DCB 11
+ DCB 43
+ DCB 27
+ DCB 59
+ DCB 7
+ DCB 39
+ DCB 23
+ DCB 55
+ DCB 15
+ DCB 47
+ DCB 31
+ DCB 63
+
+ END
diff --git a/mdctLARM.s b/mdctLARM.s
new file mode 100644
index 0000000..9fb397e
--- /dev/null
+++ b/mdctLARM.s
@@ -0,0 +1,1175 @@
+; Tremolo library
+; Copyright (C) 2009 Robin Watts for Pinknoise Productions Ltd
+
+ AREA |.text|, CODE, READONLY
+
+ ; low accuracy version
+
+ EXPORT mdct_backward_arm_low
+ EXPORT mdct_shift_right_arm_low
+ EXPORT mdct_unroll_prelap_arm_low
+ EXPORT mdct_unroll_part2_arm_low
+ EXPORT mdct_unroll_part3_arm_low
+ EXPORT mdct_unroll_postlap_arm_low
+
+ IMPORT sincos_lookup0
+ IMPORT sincos_lookup1
+
+mdct_unroll_prelap_arm_low
+ ; r0 = out
+ ; r1 = post
+ ; r2 = r
+ ; r3 = step
+ STMFD r13!,{r4-r7,r14}
+ MVN r4, #0x8000
+ MOV r3, r3, LSL #1
+ SUB r1, r2, r1 ; r1 = r - post
+ SUBS r1, r1, #16 ; r1 = r - post - 16
+ BLT unroll_over
+unroll_loop
+ LDMDB r2!,{r5,r6,r7,r12}
+
+ MOV r5, r5, ASR #9 ; r5 = (*--r)>>9
+ MOV r6, r6, ASR #9 ; r6 = (*--r)>>9
+ MOV r7, r7, ASR #9 ; r7 = (*--r)>>9
+ MOV r12,r12,ASR #9 ; r12= (*--r)>>9
+
+ MOV r14,r12,ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r12,r4, r14,ASR #31
+ STRH r12,[r0], r3
+
+ MOV r14,r7, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r7, r4, r14,ASR #31
+ STRH r7, [r0], r3
+
+ MOV r14,r6, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r6, r4, r14,ASR #31
+ STRH r6, [r0], r3
+
+ MOV r14,r5, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r5, r4, r14,ASR #31
+ STRH r5, [r0], r3
+
+ SUBS r1, r1, #16
+ BGE unroll_loop
+
+unroll_over
+ ADDS r1, r1, #16
+ BLE unroll_end
+unroll_loop2
+ LDR r5,[r2,#-4]!
+ ; stall
+ ; stall (Xscale)
+ MOV r5, r5, ASR #9 ; r5 = (*--r)>>9
+ MOV r14,r5, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r5, r4, r14,ASR #31
+ STRH r5, [r0], r3
+ SUBS r1, r1, #4
+ BGT unroll_loop2
+unroll_end
+ LDMFD r13!,{r4-r7,PC}
+
+mdct_unroll_postlap_arm_low
+ ; r0 = out
+ ; r1 = post
+ ; r2 = l
+ ; r3 = step
+ STMFD r13!,{r4-r7,r14}
+ MVN r4, #0x8000
+ MOV r3, r3, LSL #1
+ SUB r1, r1, r2 ; r1 = post - l
+ MOV r1, r1, ASR #1 ; r1 = (post - l)>>1
+ SUBS r1, r1, #16 ; r1 = ((post - l)>>1) - 4
+ BLT unroll_over3
+unroll_loop3
+ LDR r12,[r2],#8
+ LDR r7, [r2],#8
+ LDR r6, [r2],#8
+ LDR r5, [r2],#8
+
+ RSB r12,r12,#0
+ RSB r5, r5, #0
+ RSB r6, r6, #0
+ RSB r7, r7, #0
+
+ MOV r12, r12,ASR #9 ; r12= (-*l)>>9
+ MOV r5, r5, ASR #9 ; r5 = (-*l)>>9
+ MOV r6, r6, ASR #9 ; r6 = (-*l)>>9
+ MOV r7, r7, ASR #9 ; r7 = (-*l)>>9
+
+ MOV r14,r12,ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r12,r4, r14,ASR #31
+ STRH r12,[r0], r3
+
+ MOV r14,r7, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r7, r4, r14,ASR #31
+ STRH r7, [r0], r3
+
+ MOV r14,r6, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r6, r4, r14,ASR #31
+ STRH r6, [r0], r3
+
+ MOV r14,r5, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r5, r4, r14,ASR #31
+ STRH r5, [r0], r3
+
+ SUBS r1, r1, #16
+ BGE unroll_loop3
+
+unroll_over3
+ ADDS r1, r1, #16
+ BLE unroll_over4
+unroll_loop4
+ LDR r5,[r2], #8
+ ; stall
+ ; stall (Xscale)
+ RSB r5, r5, #0
+ MOV r5, r5, ASR #9 ; r5 = (-*l)>>9
+ MOV r14,r5, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r5, r4, r14,ASR #31
+ STRH r5, [r0], r3
+ SUBS r1, r1, #4
+ BGT unroll_loop4
+unroll_over4
+ LDMFD r13!,{r4-r7,PC}
+
+mdct_unroll_part2_arm_low
+ ; r0 = out
+ ; r1 = post
+ ; r2 = l
+ ; r3 = r
+ ; <> = step
+ ; <> = wL
+ ; <> = wR
+ MOV r12,r13
+ STMFD r13!,{r4,r6-r11,r14}
+ LDMFD r12,{r8,r9,r10} ; r8 = step
+ ; r9 = wL
+ ; r10= wR
+ MVN r4, #0x8000
+ MOV r8, r8, LSL #1
+ SUBS r1, r3, r1 ; r1 = (r - post)
+ BLE unroll_over5
+unroll_loop5
+ LDR r12,[r2, #-8]! ; r12= *l (but l -= 2 first)
+ LDR r7, [r3, #-4]! ; r7 = *--r
+ LDRB r6, [r10,#-1]! ; r6 = *--wR
+ LDRB r11,[r9],#1 ; r11= *wL++
+
+ MOV r12, r12, ASR #8
+ ; Can save a cycle here, at the cost of 1bit errors in rounding
+ MUL r11,r12,r11 ; r11 = *l * *wL++
+ MOV r7, r7, ASR #8
+ MLA r6, r7, r6, r11 ; r6 = *--r * *--wR
+ MOV r6, r6, ASR #9
+ MOV r14,r6, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r6, r4, r14,ASR #31
+ STRH r6, [r0], r8
+
+ SUBS r1, r1, #4
+ BGT unroll_loop5
+
+unroll_over5
+ LDMFD r13!,{r4,r6-r11,PC}
+
+mdct_unroll_part3_arm_low
+ ; r0 = out
+ ; r1 = post
+ ; r2 = l
+ ; r3 = r
+ ; <> = step
+ ; <> = wL
+ ; <> = wR
+ MOV r12,r13
+ STMFD r13!,{r4,r6-r11,r14}
+ LDMFD r12,{r8,r9,r10} ; r8 = step
+ ; r9 = wL
+ ; r10= wR
+ MVN r4, #0x8000
+ MOV r8, r8, LSL #1
+ SUBS r1, r1, r3 ; r1 = (post - r)
+ BLE unroll_over6
+unroll_loop6
+ LDR r12,[r2],#8 ; r12= *l (but l += 2 first)
+ LDR r7, [r3],#4 ; r7 = *r++
+ LDRB r11,[r9],#1 ; r11= *wL++
+ LDRB r6, [r10,#-1]! ; r6 = *--wR
+
+ ; Can save a cycle here, at the cost of 1bit errors in rounding
+ MOV r12,r12,ASR #8
+ MUL r11,r12,r11 ; (r14,r11) = *l * *wL++
+ MOV r7, r7, ASR #8
+ MUL r6, r7, r6 ; (r14,r6) = *--r * *--wR
+ SUB r6, r6, r11
+ MOV r6, r6, ASR #9
+ MOV r14,r6, ASR #15
+ TEQ r14,r14,ASR #31 ; if r14==0 || r14==-1 then in range
+ EORNE r6, r4, r14,ASR #31
+ STRH r6, [r0], r8
+
+ SUBS r1, r1, #4
+ BGT unroll_loop6
+
+unroll_over6
+ LDMFD r13!,{r4,r6-r11,PC}
+
+mdct_shift_right_arm_low
+ ; r0 = n
+ ; r1 = in
+ ; r2 = right
+ STMFD r13!,{r4-r11,r14}
+
+ MOV r0, r0, LSR #2 ; n >>= 2
+ ADD r1, r1, #4
+
+ SUBS r0, r0, #8
+ BLT sr_less_than_8
+sr_loop
+ LDR r3, [r1], #8
+ LDR r4, [r1], #8
+ LDR r5, [r1], #8
+ LDR r6, [r1], #8
+ LDR r7, [r1], #8
+ LDR r8, [r1], #8
+ LDR r12,[r1], #8
+ LDR r14,[r1], #8
+ SUBS r0, r0, #8
+ STMIA r2!,{r3,r4,r5,r6,r7,r8,r12,r14}
+ BGE sr_loop
+sr_less_than_8
+ ADDS r0, r0, #8
+ BEQ sr_end
+sr_loop2
+ LDR r3, [r1], #8
+ SUBS r0, r0, #1
+ STR r3, [r2], #4
+ BGT sr_loop2
+sr_end
+ LDMFD r13!,{r4-r11,PC}
+
+mdct_backward_arm_low
+ ; r0 = n
+ ; r1 = in
+ STMFD r13!,{r4-r11,r14}
+
+ MOV r2, #1<<4 ; r2 = 1<<shift
+ MOV r3, #13-4 ; r3 = 13-shift
+find_shift_loop
+ TST r0, r2 ; if (n & (1<<shift)) == 0
+ MOV r2, r2, LSL #1
+ SUBEQ r3, r3, #1 ; shift--
+ BEQ find_shift_loop
+ MOV r2, #2
+ MOV r2, r2, LSL r3 ; r2 = step = 2<<shift
+
+ ; presymmetry
+ ; r0 = n (a multiple of 4)
+ ; r1 = in
+ ; r2 = step
+ ; r3 = shift
+
+ ADD r4, r1, r0, LSL #1 ; r4 = aX = in+(n>>1)
+ ADD r14,r1, r0 ; r14= in+(n>>2)
+ SUB r4, r4, #3*4 ; r4 = aX = in+n2-3
+ LDR r5, =sincos_lookup0 ; r5 = T=sincos_lookup0
+
+presymmetry_loop1
+ LDR r7, [r4,#8] ; r6 = s2 = aX[2]
+ LDRB r11,[r5,#1] ; r11= T[1]
+ LDR r6, [r4],#-16 ; r6 = s0 = aX[0]
+ LDRB r10,[r5],r2 ; r10= T[0] T += step
+ MOV r6, r6, ASR #8
+ MOV r7, r7, ASR #8
+
+ ; XPROD31(s0, s2, T[0], T[1], &aX[0], &ax[2])
+ MUL r9, r6, r10 ; r9 = s0*T[0]
+ RSB r6, r6, #0
+ MLA r9, r7, r11,r9 ; r9 += s2*T[1]
+ CMP r4, r14
+ MUL r12,r7, r10 ; r12 = s2*T[0]
+ STR r9, [r4,#16] ; aX[0] = r9
+ MLA r12,r6, r11,r12 ; r12 -= s0*T[1]
+ STR r12,[r4,#8+16] ; aX[2] = r12
+
+ BGE presymmetry_loop1 ; while (aX >= in+n4)
+
+presymmetry_loop2
+ LDR r6, [r4],#-16 ; r6 = s0 = aX[0]
+ LDRB r10,[r5,#1] ; r10= T[1]
+ LDR r7, [r4,#16+8] ; r6 = s2 = aX[2]
+ LDRB r11,[r5],-r2 ; r11= T[0] T -= step
+ MOV r6, r6, ASR #8
+ MOV r7, r7, ASR #8
+
+ ; XPROD31(s0, s2, T[1], T[0], &aX[0], &ax[2])
+ MUL r9, r6, r10 ; r9 = s0*T[1]
+ RSB r6, r6, #0
+ MLA r9, r7, r11,r9 ; r9 += s2*T[0]
+ CMP r4, r1
+ MUL r12,r7, r10 ; r12 = s2*T[1]
+ STR r9, [r4,#16] ; aX[0] = r9
+ MLA r12,r6, r11,r12 ; r12 -= s0*T[0]
+ STR r12,[r4,#8+16] ; aX[2] = r12
+
+ BGE presymmetry_loop2 ; while (aX >= in)
+
+ ; r0 = n
+ ; r1 = in
+ ; r2 = step
+ ; r3 = shift
+ STMFD r13!,{r3}
+ LDR r5, =sincos_lookup0 ; r5 = T=sincos_lookup0
+ ADD r4, r1, r0, LSL #1 ; r4 = aX = in+(n>>1)
+ SUB r4, r4, #4*4 ; r4 = aX = in+(n>>1)-4
+ LDRB r11,[r5,#1] ; r11= T[1]
+ LDRB r10,[r5],r2 ; r10= T[0] T += step
+presymmetry_loop3
+ LDR r8, [r1],#16 ; r8 = ro0 = bX[0]
+ LDR r9, [r1,#8-16] ; r9 = ro2 = bX[2]
+ LDR r6, [r4],#-16 ; r6 = ri0 = aX[0]
+ LDR r7, [r4,#8+16] ; r7 = ri2 = aX[2]
+ MOV r8, r8, ASR #8
+ MOV r9, r9, ASR #8
+ MOV r6, r6, ASR #8
+
+ ; XNPROD31( ro2, ro0, T[1], T[0], &aX[0], &aX[2] )
+ ; aX[0] = (ro2*T[1] - ro0*T[0])>>31 aX[2] = (ro0*T[1] + ro2*T[0])>>31
+ MUL r12,r8, r11 ; r12 = ro0*T[1]
+ MOV r7, r7, ASR #8
+ MLA r12,r9, r10,r12 ; r12 += ro2*T[0]
+ RSB r8, r8, #0 ; r8 = -ro0
+ MUL r3, r9, r11 ; r3 = ro2*T[1]
+ LDRB r11,[r5,#1] ; r11= T[1]
+ MLA r3, r8, r10,r3 ; r3 -= ro0*T[0]
+ LDRB r10,[r5],r2 ; r10= T[0] T += step
+ STR r12,[r4,#16+8]
+ STR r3, [r4,#16]
+
+ ; XNPROD31( ri2, ri0, T[0], T[1], &bX[0], &bX[2] )
+ ; bX[0] = (ri2*T[0] - ri0*T[1])>>31 bX[2] = (ri0*T[0] + ri2*T[1])>>31
+ MUL r12,r6, r10 ; r12 = ri0*T[0]
+ RSB r6, r6, #0 ; r6 = -ri0
+ MLA r12,r7, r11,r12 ; r12 += ri2*T[1]
+ CMP r4, r1
+ MUL r3, r7, r10 ; r3 = ri2*T[0]
+ STR r12,[r1,#8-16]
+ MLA r3, r6, r11,r3 ; r3 -= ri0*T[1]
+ STR r3, [r1,#-16]
+
+ BGE presymmetry_loop3
+
+ SUB r1,r1,r0 ; r1 = in -= n>>2 (i.e. restore in)
+
+ LDR r3,[r13]
+ STR r2,[r13,#-4]!
+
+ ; mdct_butterflies
+ ; r0 = n = (points * 2)
+ ; r1 = in = x
+ ; r2 = i
+ ; r3 = shift
+ STMFD r13!,{r0-r1}
+ RSBS r4,r3,#6 ; r4 = stages = 7-shift then --stages
+ LDR r5,=sincos_lookup0
+ BLE no_generics
+ MOV r14,#4 ; r14= 4 (i=0)
+ MOV r6, r14,LSL r3 ; r6 = (4<<i)<<shift
+mdct_butterflies_loop1
+ MOV r0, r0, LSR #1 ; r0 = points>>i = POINTS
+ MOV r2, r14,LSR #2 ; r2 = (1<<i)-j (j=0)
+ STMFD r13!,{r4,r14}
+mdct_butterflies_loop2
+
+ ; mdct_butterfly_generic(x+POINTS*j, POINTS, 4<<(i+shift))
+ ; mdct_butterfly_generic(r1, r0, r6)
+ ; r0 = points
+ ; r1 = x
+ ; preserve r2 (external loop counter)
+ ; preserve r3
+ ; preserve r4 (external loop counter)
+ ; r5 = T = sincos_lookup0
+ ; r6 = step
+ ; preserve r14
+
+ STR r2,[r13,#-4]! ; stack r2
+ ADD r1,r1,r0,LSL #1 ; r1 = x2+4 = x + (POINTS>>1)
+ ADD r7,r1,r0,LSL #1 ; r7 = x1+4 = x + POINTS
+ ADD r12,r5,#1024 ; r12= sincos_lookup0+1024
+
+mdct_bufferfly_generic_loop1
+ LDMDB r7!,{r2,r3,r8,r11} ; r2 = x1[0]
+ ; r3 = x1[1]
+ ; r8 = x1[2]
+ ; r11= x1[3] x1 -= 4
+ LDMDB r1!,{r4,r9,r10,r14} ; r4 = x2[0]
+ ; r9 = x2[1]
+ ; r10= x2[2]
+ ; r14= x2[3] x2 -= 4
+
+ SUB r2, r2, r3 ; r2 = s0 = x1[0] - x1[1]
+ ADD r3, r2, r3, LSL #1 ; r3 = x1[0] + x1[1] (-> x1[0])
+ SUB r11,r11,r8 ; r11= s1 = x1[3] - x1[2]
+ ADD r8, r11,r8, LSL #1 ; r8 = x1[3] + x1[2] (-> x1[2])
+ SUB r9, r9, r4 ; r9 = s2 = x2[1] - x2[0]
+ ADD r4, r9, r4, LSL #1 ; r4 = x2[1] + x2[0] (-> x1[1])
+ SUB r14,r14,r10 ; r14= s3 = x2[3] - x2[2]
+ ADD r10,r14,r10,LSL #1 ; r10= x2[3] + x2[2] (-> x1[3])
+ STMIA r7,{r3,r4,r8,r10}
+
+ ; r0 = points
+ ; r1 = x2
+ ; r2 = s0
+ ; r3 free
+ ; r4 free
+ ; r5 = T
+ ; r6 = step
+ ; r7 = x1
+ ; r8 free
+ ; r9 = s2
+ ; r10 free
+ ; r11= s1
+ ; r12= limit
+ ; r14= s3
+
+ LDRB r8, [r5,#1] ; r8 = T[1]
+ LDRB r10,[r5],r6 ; r10= T[0] T += step
+ MOV r2, r2, ASR #8
+ MOV r11,r11,ASR #8
+ MOV r9, r9, ASR #8
+ MOV r14,r14,ASR #8
+
+ ; XPROD31(s1, s0, T[0], T[1], &x2[0], &x2[2])
+ ; x2[0] = (s1*T[0] + s0*T[1])>>31 x2[2] = (s0*T[0] - s1*T[1])>>31
+ ; stall Xscale
+ MUL r3, r2, r8 ; r3 = s0*T[1]
+ MLA r3, r11,r10,r3 ; r3 += s1*T[0]
+ RSB r11,r11,#0
+ MUL r4, r8, r11 ; r4 = -s1*T[1]
+ MLA r4, r2, r10,r4 ; r4 += s0*T[0] = Value for x2[2]
+ MOV r2, r3 ; r2 = r3 = Value for x2[0]
+
+ ; XPROD31(s2, s3, T[0], T[1], &x2[1], &x2[3])
+ ; x2[1] = (s2*T[0] + s3*T[1])>>31 x2[3] = (s3*T[0] - s2*T[1])>>31
+ MUL r3, r9, r10 ; r3 = s2*T[0]
+ MLA r3, r14,r8, r3 ; r3 += s3*T[1] = Value for x2[1]
+ RSB r9, r9, #0
+ MUL r11,r14,r10 ; r11 = s3*T[0]
+ MLA r11,r9, r8, r11 ; r11 -= s2*T[1] = Value for x2[3]
+ CMP r5, r12
+
+ STMIA r1,{r2,r3,r4,r11}
+
+ BLT mdct_bufferfly_generic_loop1
+
+ SUB r12,r12,#1024
+mdct_bufferfly_generic_loop2
+ LDMDB r7!,{r2,r3,r9,r10} ; r2 = x1[0]
+ ; r3 = x1[1]
+ ; r9 = x1[2]
+ ; r10= x1[3] x1 -= 4
+ LDMDB r1!,{r4,r8,r11,r14} ; r4 = x2[0]
+ ; r8 = x2[1]
+ ; r11= x2[2]
+ ; r14= x2[3] x2 -= 4
+
+ SUB r2, r2, r3 ; r2 = s0 = x1[0] - x1[1]
+ ADD r3, r2, r3, LSL #1 ; r3 = x1[0] + x1[1] (-> x1[0])
+ SUB r9, r9,r10 ; r9 = s1 = x1[2] - x1[3]
+ ADD r10,r9,r10, LSL #1 ; r10= x1[2] + x1[3] (-> x1[2])
+ SUB r4, r4, r8 ; r4 = s2 = x2[0] - x2[1]
+ ADD r8, r4, r8, LSL #1 ; r8 = x2[0] + x2[1] (-> x1[1])
+ SUB r14,r14,r11 ; r14= s3 = x2[3] - x2[2]
+ ADD r11,r14,r11,LSL #1 ; r11= x2[3] + x2[2] (-> x1[3])
+ STMIA r7,{r3,r8,r10,r11}
+
+ ; r0 = points
+ ; r1 = x2
+ ; r2 = s0
+ ; r3 free
+ ; r4 = s2
+ ; r5 = T
+ ; r6 = step
+ ; r7 = x1
+ ; r8 free
+ ; r9 = s1
+ ; r10 free
+ ; r11 free
+ ; r12= limit
+ ; r14= s3
+
+ LDRB r8, [r5,#1] ; r8 = T[1]
+ LDRB r10,[r5],-r6 ; r10= T[0] T -= step
+ MOV r2, r2, ASR #8
+ MOV r9, r9, ASR #8
+ MOV r4, r4, ASR #8
+ MOV r14,r14,ASR #8
+
+ ; XNPROD31(s0, s1, T[0], T[1], &x2[0], &x2[2])
+ ; x2[0] = (s0*T[0] - s1*T[1])>>31 x2[2] = (s1*T[0] + s0*T[1])>>31
+ ; stall Xscale
+ MUL r11,r2, r8 ; r11 = s0*T[1]
+ MLA r11,r9, r10,r11 ; r11 += s1*T[0]
+ RSB r9, r9, #0
+ MUL r2, r10,r2 ; r2 = s0*T[0]
+ MLA r2, r9, r8, r2 ; r2 += -s1*T[1] = Value for x2[0]
+ MOV r9, r11 ; r9 = r11 = Value for x2[2]
+
+ ; XNPROD31(s3, s2, T[0], T[1], &x2[1], &x2[3])
+ ; x2[1] = (s3*T[0] - s2*T[1])>>31 x2[3] = (s2*T[0] + s3*T[1])>>31
+ MUL r11,r4, r10 ; r11 = s2*T[0]
+ MLA r11,r14,r8, r11 ; r11 += s3*T[1] = Value for x2[3]
+ RSB r4, r4, #0
+ MUL r3, r14,r10 ; r3 = s3*T[0]
+ MLA r3, r4, r8, r3 ; r3 -= s2*T[1] = Value for x2[1]
+ CMP r5, r12
+
+ STMIA r1,{r2,r3,r9,r11}
+
+ BGT mdct_bufferfly_generic_loop2
+
+ LDR r2,[r13],#4 ; unstack r2
+ ADD r1, r1, r0, LSL #2 ; r1 = x+POINTS*j
+ ; stall Xscale
+ SUBS r2, r2, #1 ; r2-- (j++)
+ BGT mdct_butterflies_loop2
+
+ LDMFD r13!,{r4,r14}
+
+ LDR r1,[r13,#4]
+
+ SUBS r4, r4, #1 ; stages--
+ MOV r14,r14,LSL #1 ; r14= 4<<i (i++)
+ MOV r6, r6, LSL #1 ; r6 = step <<= 1 (i++)
+ BGE mdct_butterflies_loop1
+ LDMFD r13,{r0-r1}
+
+no_generics
+ ; mdct_butterflies part2 (loop around mdct_bufferfly_32)
+ ; r0 = points
+ ; r1 = in
+ ; r2 = step
+ ; r3 = shift
+
+mdct_bufferflies_loop3
+ ; mdct_bufferfly_32
+
+ ; block1
+ ADD r4, r1, #16*4 ; r4 = &in[16]
+ LDMIA r4,{r5,r6,r9,r10} ; r5 = x[16]
+ ; r6 = x[17]
+ ; r9 = x[18]
+ ; r10= x[19]
+ LDMIA r1,{r7,r8,r11,r12} ; r7 = x[0]
+ ; r8 = x[1]
+ ; r11= x[2]
+ ; r12= x[3]
+ SUB r5, r5, r6 ; r5 = s0 = x[16] - x[17]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[16] + x[17] -> x[16]
+ SUB r9, r9, r10 ; r9 = s1 = x[18] - x[19]
+ ADD r10,r9, r10,LSL #1 ; r10= x[18] + x[19] -> x[18]
+ SUB r8, r8, r7 ; r8 = s2 = x[ 1] - x[ 0]
+ ADD r7, r8, r7, LSL #1 ; r7 = x[ 1] + x[ 0] -> x[17]
+ SUB r12,r12,r11 ; r12= s3 = x[ 3] - x[ 2]
+ ADD r11,r12,r11, LSL #1 ; r11= x[ 3] + x[ 2] -> x[19]
+ STMIA r4!,{r6,r7,r10,r11}
+
+ MOV r6,#0xed ; r6 =cPI1_8
+ MOV r7,#0x62 ; r7 =cPI3_8
+
+ MOV r5, r5, ASR #8
+ MOV r9, r9, ASR #8
+ MOV r8, r8, ASR #8
+ MOV r12,r12,ASR #8
+
+ ; XNPROD31( s0, s1, cPI3_8, cPI1_8, &x[ 0], &x[ 2] )
+ ; x[0] = s0*cPI3_8 - s1*cPI1_8 x[2] = s1*cPI3_8 + s0*cPI1_8
+ ; stall Xscale
+ MUL r11,r5, r6 ; r11 = s0*cPI1_8
+ MLA r11,r9, r7, r11 ; r11 += s1*cPI3_8
+ RSB r9, r9, #0
+ MUL r5, r7, r5 ; r5 = s0*cPI3_8
+ MLA r5, r9, r6, r5 ; r5 -= s1*cPI1_8
+
+ ; XPROD31 ( s2, s3, cPI1_8, cPI3_8, &x[ 1], &x[ 3] )
+ ; x[1] = s2*cPI1_8 + s3*cPI3_8 x[3] = s3*cPI1_8 - s2*cPI3_8
+ MUL r9, r8, r6 ; r9 = s2*cPI1_8
+ MLA r9, r12,r7, r9 ; r9 += s3*cPI3_8
+ RSB r8,r8,#0
+ MUL r12,r6, r12 ; r12 = s3*cPI1_8
+ MLA r12,r8, r7, r12 ; r12 -= s2*cPI3_8
+ STMIA r1!,{r5,r9,r11,r12}
+
+ ; block2
+ LDMIA r4,{r5,r6,r9,r10} ; r5 = x[20]
+ ; r6 = x[21]
+ ; r9 = x[22]
+ ; r10= x[23]
+ LDMIA r1,{r7,r8,r11,r12} ; r7 = x[4]
+ ; r8 = x[5]
+ ; r11= x[6]
+ ; r12= x[7]
+ SUB r5, r5, r6 ; r5 = s0 = x[20] - x[21]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[20] + x[21] -> x[20]
+ SUB r9, r9, r10 ; r9 = s1 = x[22] - x[23]
+ ADD r10,r9, r10,LSL #1 ; r10= x[22] + x[23] -> x[22]
+ SUB r8, r8, r7 ; r8 = s2 = x[ 5] - x[ 4]
+ ADD r7, r8, r7, LSL #1 ; r7 = x[ 5] + x[ 4] -> x[21]
+ SUB r12,r12,r11 ; r12= s3 = x[ 7] - x[ 6]
+ ADD r11,r12,r11, LSL #1 ; r11= x[ 7] + x[ 6] -> x[23]
+ MOV r14,#0xb5 ; cPI2_8
+ STMIA r4!,{r6,r7,r10,r11}
+
+ SUB r5, r5, r9 ; r5 = s0 - s1
+ ADD r9, r5, r9, LSL #1 ; r9 = s0 + s1
+ MOV r5, r5, ASR #8
+ MUL r5, r14,r5 ; r5 = (s0-s1)*cPI2_8
+ SUB r12,r12,r8 ; r12= s3 - s2
+ ADD r8, r12,r8, LSL #1 ; r8 = s3 + s2
+
+ MOV r8, r8, ASR #8
+ MUL r8, r14,r8 ; r8 = (s3+s2)*cPI2_8
+ MOV r9, r9, ASR #8
+ MUL r9, r14,r9 ; r9 = (s0+s1)*cPI2_8
+ MOV r12,r12,ASR #8
+ MUL r12,r14,r12 ; r12 = (s3-s2)*cPI2_8
+ STMIA r1!,{r5,r8,r9,r12}
+
+ ; block3
+ LDMIA r4,{r5,r6,r9,r10} ; r5 = x[24]
+ ; r6 = x[25]
+ ; r9 = x[25]
+ ; r10= x[26]
+ LDMIA r1,{r7,r8,r11,r12} ; r7 = x[8]
+ ; r8 = x[9]
+ ; r11= x[10]
+ ; r12= x[11]
+ SUB r5, r5, r6 ; r5 = s0 = x[24] - x[25]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[24] + x[25] -> x[25]
+ SUB r9, r9, r10 ; r9 = s1 = x[26] - x[27]
+ ADD r10,r9, r10,LSL #1 ; r10= x[26] + x[27] -> x[26]
+ SUB r8, r8, r7 ; r8 = s2 = x[ 9] - x[ 8]
+ ADD r7, r8, r7, LSL #1 ; r7 = x[ 9] + x[ 8] -> x[25]
+ SUB r12,r12,r11 ; r12= s3 = x[11] - x[10]
+ ADD r11,r12,r11, LSL #1 ; r11= x[11] + x[10] -> x[27]
+ STMIA r4!,{r6,r7,r10,r11}
+
+ MOV r6,#0x62 ; r6 = cPI3_8
+ MOV r7,#0xED ; r7 = cPI1_8
+
+ ; XNPROD31( s0, s1, cPI1_8, cPI3_8, &x[ 8], &x[10] )
+ ; x[8] = s0*cPI1_8 - s1*cPI3_8 x[10] = s1*cPI1_8 + s0*cPI3_8
+ ; stall Xscale
+ MOV r5, r5, ASR #8
+ MUL r11,r5, r6 ; r11 = s0*cPI3_8
+ MOV r9, r9, ASR #8
+ MLA r11,r9, r7, r11 ; r11 += s1*cPI1_8
+ RSB r9, r9, #0
+ MUL r5, r7, r5 ; r5 = s0*cPI1_8
+ MLA r5, r9, r6, r5 ; r5 -= s1*cPI3_8
+
+ ; XPROD31 ( s2, s3, cPI3_8, cPI1_8, &x[ 9], &x[11] )
+ ; x[9] = s2*cPI3_8 + s3*cPI1_8 x[11] = s3*cPI3_8 - s2*cPI1_8
+ MOV r8, r8, ASR #8
+ MUL r9, r8, r6 ; r9 = s2*cPI3_8
+ MOV r12,r12,ASR #8
+ MLA r9, r12,r7, r9 ; r9 += s3*cPI1_8
+ RSB r8,r8,#0
+ MUL r12,r6, r12 ; r12 = s3*cPI3_8
+ MLA r12,r8, r7, r12 ; r12 -= s2*cPI1_8
+ STMIA r1!,{r5,r9,r11,r12}
+
+ ; block4
+ LDMIA r4,{r5,r6,r10,r11} ; r5 = x[28]
+ ; r6 = x[29]
+ ; r10= x[30]
+ ; r11= x[31]
+ LDMIA r1,{r8,r9,r12,r14} ; r8 = x[12]
+ ; r9 = x[13]
+ ; r12= x[14]
+ ; r14= x[15]
+ SUB r5, r5, r6 ; r5 = s0 = x[28] - x[29]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[28] + x[29] -> x[28]
+ SUB r7, r14,r12 ; r7 = s3 = x[15] - x[14]
+ ADD r12,r7, r12, LSL #1 ; r12= x[15] + x[14] -> x[31]
+ SUB r10,r10,r11 ; r10= s1 = x[30] - x[31]
+ ADD r11,r10,r11,LSL #1 ; r11= x[30] + x[31] -> x[30]
+ SUB r14, r8, r9 ; r14= s2 = x[12] - x[13]
+ ADD r9, r14, r9, LSL #1 ; r9 = x[12] + x[13] -> x[29]
+ STMIA r4!,{r6,r9,r11,r12}
+ STMIA r1!,{r5,r7,r10,r14}
+
+ ; mdct_butterfly16 (1st version)
+ ; block 1
+ SUB r1,r1,#16*4
+ ADD r4,r1,#8*4
+ LDMIA r4,{r5,r6,r9,r10} ; r5 = x[ 8]
+ ; r6 = x[ 9]
+ ; r9 = x[10]
+ ; r10= x[11]
+ LDMIA r1,{r7,r8,r11,r12} ; r7 = x[0]
+ ; r8 = x[1]
+ ; r11= x[2]
+ ; r12= x[3]
+ SUB r5, r5, r6 ; r5 = s0 = x[ 8] - x[ 9]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[ 8] + x[ 9] -> x[ 8]
+ SUB r9, r9, r10 ; r9 = s1 = x[10] - x[11]
+ ADD r10,r9, r10,LSL #1 ; r10= x[10] + x[11] -> x[10]
+ SUB r8, r8, r7 ; r8 = s2 = x[ 1] - x[ 0]
+ ADD r7, r8, r7, LSL #1 ; r7 = x[ 1] + x[ 0] -> x[ 9]
+ SUB r12,r12,r11 ; r12= s3 = x[ 3] - x[ 2]
+ ADD r11,r12,r11, LSL #1 ; r11= x[ 3] + x[ 2] -> x[11]
+ MOV r14,#0xB5 ; r14= cPI2_8
+ STMIA r4!,{r6,r7,r10,r11}
+
+ SUB r5, r5, r9 ; r5 = s0 - s1
+ ADD r9, r5, r9, LSL #1 ; r9 = s0 + s1
+ MOV r5, r5, ASR #8
+ MUL r5, r14,r5 ; r5 = (s0-s1)*cPI2_8
+ SUB r12,r12,r8 ; r12= s3 - s2
+ ADD r8, r12,r8, LSL #1 ; r8 = s3 + s2
+
+ MOV r8, r8, ASR #8
+ MUL r8, r14,r8 ; r8 = (s3+s2)*cPI2_8
+ MOV r9, r9, ASR #8
+ MUL r9, r14,r9 ; r9 = (s0+s1)*cPI2_8
+ MOV r12,r12,ASR #8
+ MUL r12,r14,r12 ; r12 = (s3-s2)*cPI2_8
+ STMIA r1!,{r5,r8,r9,r12}
+
+ ; block2
+ LDMIA r4,{r5,r6,r9,r10} ; r5 = x[12]
+ ; r6 = x[13]
+ ; r9 = x[14]
+ ; r10= x[15]
+ LDMIA r1,{r7,r8,r11,r12} ; r7 = x[ 4]
+ ; r8 = x[ 5]
+ ; r11= x[ 6]
+ ; r12= x[ 7]
+ SUB r14,r7, r8 ; r14= s0 = x[ 4] - x[ 5]
+ ADD r8, r14,r8, LSL #1 ; r8 = x[ 4] + x[ 5] -> x[13]
+ SUB r7, r12,r11 ; r7 = s1 = x[ 7] - x[ 6]
+ ADD r11,r7, r11, LSL #1 ; r11= x[ 7] + x[ 6] -> x[15]
+ SUB r5, r5, r6 ; r5 = s2 = x[12] - x[13]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[12] + x[13] -> x[12]
+ SUB r12,r9, r10 ; r12= s3 = x[14] - x[15]
+ ADD r10,r12,r10,LSL #1 ; r10= x[14] + x[15] -> x[14]
+ STMIA r4!,{r6,r8,r10,r11}
+ STMIA r1!,{r5,r7,r12,r14}
+
+ ; mdct_butterfly_8
+ LDMDB r1,{r6,r7,r8,r9,r10,r11,r12,r14}
+ ; r6 = x[0]
+ ; r7 = x[1]
+ ; r8 = x[2]
+ ; r9 = x[3]
+ ; r10= x[4]
+ ; r11= x[5]
+ ; r12= x[6]
+ ; r14= x[7]
+ ADD r6, r6, r7 ; r6 = s0 = x[0] + x[1]
+ SUB r7, r6, r7, LSL #1 ; r7 = s1 = x[0] - x[1]
+ ADD r8, r8, r9 ; r8 = s2 = x[2] + x[3]
+ SUB r9, r8, r9, LSL #1 ; r9 = s3 = x[2] - x[3]
+ ADD r10,r10,r11 ; r10= s4 = x[4] + x[5]
+ SUB r11,r10,r11,LSL #1 ; r11= s5 = x[4] - x[5]
+ ADD r12,r12,r14 ; r12= s6 = x[6] + x[7]
+ SUB r14,r12,r14,LSL #1 ; r14= s7 = x[6] - x[7]
+
+ ADD r2, r11,r9 ; r2 = x[0] = s5 + s3
+ SUB r4, r2, r9, LSL #1 ; r4 = x[2] = s5 - s3
+ SUB r3, r14,r7 ; r3 = x[1] = s7 - s1
+ ADD r5, r3, r7, LSL #1 ; r5 = x[3] = s7 + s1
+ SUB r10,r10,r6 ; r10= x[4] = s4 - s0
+ SUB r11,r12,r8 ; r11= x[5] = s6 - s2
+ ADD r12,r10,r6, LSL #1 ; r12= x[6] = s4 + s0
+ ADD r14,r11,r8, LSL #1 ; r14= x[7] = s6 + s2
+ STMDB r1,{r2,r3,r4,r5,r10,r11,r12,r14}
+
+ ; mdct_butterfly_8
+ LDMIA r1,{r6,r7,r8,r9,r10,r11,r12,r14}
+ ; r6 = x[0]
+ ; r7 = x[1]
+ ; r8 = x[2]
+ ; r9 = x[3]
+ ; r10= x[4]
+ ; r11= x[5]
+ ; r12= x[6]
+ ; r14= x[7]
+ ADD r6, r6, r7 ; r6 = s0 = x[0] + x[1]
+ SUB r7, r6, r7, LSL #1 ; r7 = s1 = x[0] - x[1]
+ ADD r8, r8, r9 ; r8 = s2 = x[2] + x[3]
+ SUB r9, r8, r9, LSL #1 ; r9 = s3 = x[2] - x[3]
+ ADD r10,r10,r11 ; r10= s4 = x[4] + x[5]
+ SUB r11,r10,r11,LSL #1 ; r11= s5 = x[4] - x[5]
+ ADD r12,r12,r14 ; r12= s6 = x[6] + x[7]
+ SUB r14,r12,r14,LSL #1 ; r14= s7 = x[6] - x[7]
+
+ ADD r2, r11,r9 ; r2 = x[0] = s5 + s3
+ SUB r4, r2, r9, LSL #1 ; r4 = x[2] = s5 - s3
+ SUB r3, r14,r7 ; r3 = x[1] = s7 - s1
+ ADD r5, r3, r7, LSL #1 ; r5 = x[3] = s7 + s1
+ SUB r10,r10,r6 ; r10= x[4] = s4 - s0
+ SUB r11,r12,r8 ; r11= x[5] = s6 - s2
+ ADD r12,r10,r6, LSL #1 ; r12= x[6] = s4 + s0
+ ADD r14,r11,r8, LSL #1 ; r14= x[7] = s6 + s2
+ STMIA r1,{r2,r3,r4,r5,r10,r11,r12,r14}
+
+ ; mdct_butterfly16 (2nd version)
+ ; block 1
+ ADD r1,r1,#16*4-8*4
+ ADD r4,r1,#8*4
+ LDMIA r4,{r5,r6,r9,r10} ; r5 = x[ 8]
+ ; r6 = x[ 9]
+ ; r9 = x[10]
+ ; r10= x[11]
+ LDMIA r1,{r7,r8,r11,r12} ; r7 = x[0]
+ ; r8 = x[1]
+ ; r11= x[2]
+ ; r12= x[3]
+ SUB r5, r5, r6 ; r5 = s0 = x[ 8] - x[ 9]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[ 8] + x[ 9] -> x[ 8]
+ SUB r9, r9, r10 ; r9 = s1 = x[10] - x[11]
+ ADD r10,r9, r10,LSL #1 ; r10= x[10] + x[11] -> x[10]
+ SUB r8, r8, r7 ; r8 = s2 = x[ 1] - x[ 0]
+ ADD r7, r8, r7, LSL #1 ; r7 = x[ 1] + x[ 0] -> x[ 9]
+ SUB r12,r12,r11 ; r12= s3 = x[ 3] - x[ 2]
+ ADD r11,r12,r11, LSL #1 ; r11= x[ 3] + x[ 2] -> x[11]
+ MOV r14,#0xb5 ; r14= cPI2_8
+ STMIA r4!,{r6,r7,r10,r11}
+
+ SUB r5, r5, r9 ; r5 = s0 - s1
+ ADD r9, r5, r9, LSL #1 ; r9 = s0 + s1
+ MOV r5, r5, ASR #8
+ MUL r5, r14,r5 ; r5 = (s0-s1)*cPI2_8
+ SUB r12,r12,r8 ; r12= s3 - s2
+ ADD r8, r12,r8, LSL #1 ; r8 = s3 + s2
+
+ MOV r8, r8, ASR #8
+ MUL r8, r14,r8 ; r8 = (s3+s2)*cPI2_8
+ MOV r9, r9, ASR #8
+ MUL r9, r14,r9 ; r9 = (s0+s1)*cPI2_8
+ MOV r12,r12,ASR #8
+ MUL r12,r14,r12 ; r12 = (s3-s2)*cPI2_8
+ STMIA r1!,{r5,r8,r9,r12}
+
+ ; block2
+ LDMIA r4,{r5,r6,r9,r10} ; r5 = x[12]
+ ; r6 = x[13]
+ ; r9 = x[14]
+ ; r10= x[15]
+ LDMIA r1,{r7,r8,r11,r12} ; r7 = x[ 4]
+ ; r8 = x[ 5]
+ ; r11= x[ 6]
+ ; r12= x[ 7]
+ SUB r5, r5, r6 ; r5 = s2 = x[12] - x[13]
+ ADD r6, r5, r6, LSL #1 ; r6 = x[12] + x[13] -> x[12]
+ SUB r9, r9, r10 ; r9 = s3 = x[14] - x[15]
+ ADD r10,r9, r10,LSL #1 ; r10= x[14] + x[15] -> x[14]
+ SUB r14,r7, r8 ; r14= s0 = x[ 4] - x[ 5]
+ ADD r8, r14,r8, LSL #1 ; r8 = x[ 4] + x[ 5] -> x[13]
+ SUB r7, r12,r11 ; r7 = s1 = x[ 7] - x[ 6]
+ ADD r11,r7, r11, LSL #1 ; r11= x[ 7] + x[ 6] -> x[15]
+ STMIA r4!,{r6,r8,r10,r11}
+ STMIA r1!,{r5,r7,r9,r14}
+
+ ; mdct_butterfly_8
+ LDMDB r1,{r6,r7,r8,r9,r10,r11,r12,r14}
+ ; r6 = x[0]
+ ; r7 = x[1]
+ ; r8 = x[2]
+ ; r9 = x[3]
+ ; r10= x[4]
+ ; r11= x[5]
+ ; r12= x[6]
+ ; r14= x[7]
+ ADD r6, r6, r7 ; r6 = s0 = x[0] + x[1]
+ SUB r7, r6, r7, LSL #1 ; r7 = s1 = x[0] - x[1]
+ ADD r8, r8, r9 ; r8 = s2 = x[2] + x[3]
+ SUB r9, r8, r9, LSL #1 ; r9 = s3 = x[2] - x[3]
+ ADD r10,r10,r11 ; r10= s4 = x[4] + x[5]
+ SUB r11,r10,r11,LSL #1 ; r11= s5 = x[4] - x[5]
+ ADD r12,r12,r14 ; r12= s6 = x[6] + x[7]
+ SUB r14,r12,r14,LSL #1 ; r14= s7 = x[6] - x[7]
+
+ ADD r2, r11,r9 ; r2 = x[0] = s5 + s3
+ SUB r4, r2, r9, LSL #1 ; r4 = x[2] = s5 - s3
+ SUB r3, r14,r7 ; r3 = x[1] = s7 - s1
+ ADD r5, r3, r7, LSL #1 ; r5 = x[3] = s7 + s1
+ SUB r10,r10,r6 ; r10= x[4] = s4 - s0
+ SUB r11,r12,r8 ; r11= x[5] = s6 - s2
+ ADD r12,r10,r6, LSL #1 ; r12= x[6] = s4 + s0
+ ADD r14,r11,r8, LSL #1 ; r14= x[7] = s6 + s2
+ STMDB r1,{r2,r3,r4,r5,r10,r11,r12,r14}
+
+ ; mdct_butterfly_8
+ LDMIA r1,{r6,r7,r8,r9,r10,r11,r12,r14}
+ ; r6 = x[0]
+ ; r7 = x[1]
+ ; r8 = x[2]
+ ; r9 = x[3]
+ ; r10= x[4]
+ ; r11= x[5]
+ ; r12= x[6]
+ ; r14= x[7]
+ ADD r6, r6, r7 ; r6 = s0 = x[0] + x[1]
+ SUB r7, r6, r7, LSL #1 ; r7 = s1 = x[0] - x[1]
+ ADD r8, r8, r9 ; r8 = s2 = x[2] + x[3]
+ SUB r9, r8, r9, LSL #1 ; r9 = s3 = x[2] - x[3]
+ ADD r10,r10,r11 ; r10= s4 = x[4] + x[5]
+ SUB r11,r10,r11,LSL #1 ; r11= s5 = x[4] - x[5]
+ ADD r12,r12,r14 ; r12= s6 = x[6] + x[7]
+ SUB r14,r12,r14,LSL #1 ; r14= s7 = x[6] - x[7]
+
+ ADD r2, r11,r9 ; r2 = x[0] = s5 + s3
+ SUB r4, r2, r9, LSL #1 ; r4 = x[2] = s5 - s3
+ SUB r3, r14,r7 ; r3 = x[1] = s7 - s1
+ ADD r5, r3, r7, LSL #1 ; r5 = x[3] = s7 + s1
+ SUB r10,r10,r6 ; r10= x[4] = s4 - s0
+ SUB r11,r12,r8 ; r11= x[5] = s6 - s2
+ ADD r12,r10,r6, LSL #1 ; r12= x[6] = s4 + s0
+ ADD r14,r11,r8, LSL #1 ; r14= x[7] = s6 + s2
+ STMIA r1,{r2,r3,r4,r5,r10,r11,r12,r14}
+
+ ADD r1,r1,#8*4
+ SUBS r0,r0,#64
+ BGT mdct_bufferflies_loop3
+
+ LDMFD r13,{r0-r3}
+
+mdct_bitreverse_arm_low
+ ; r0 = points
+ ; r1 = in
+ ; r2 = step
+ ; r3 = shift
+
+ MOV r4, #0 ; r4 = bit = 0
+ ADD r5, r1, r0, LSL #1 ; r5 = w = x + (n>>1)
+ ADR r6, bitrev
+ SUB r5, r5, #8
+brev_lp
+ LDRB r7, [r6, r4, LSR #6]
+ AND r8, r4, #0x3f
+ LDRB r8, [r6, r8]
+ ADD r4, r4, #1 ; bit++
+ ; stall XScale
+ ORR r7, r7, r8, LSL #6 ; r7 = bitrev[bit]
+ MOV r7, r7, LSR r3
+ ADD r9, r1, r7, LSL #2 ; r9 = xx = x + (b>>shift)
+ CMP r5, r9 ; if (w > xx)
+ LDR r10,[r5],#-8 ; r10 = w[0] w -= 2
+ LDRGT r11,[r5,#12] ; r11 = w[1]
+ LDRGT r12,[r9] ; r12 = xx[0]
+ LDRGT r14,[r9,#4] ; r14 = xx[1]
+ STRGT r10,[r9] ; xx[0]= w[0]
+ STRGT r11,[r9,#4] ; xx[1]= w[1]
+ STRGT r12,[r5,#8] ; w[0] = xx[0]
+ STRGT r14,[r5,#12] ; w[1] = xx[1]
+ CMP r5,r1
+ BGT brev_lp
+
+ ; mdct_step7
+ ; r0 = points
+ ; r1 = in
+ ; r2 = step
+ ; r3 = shift
+
+ CMP r2, #4 ; r5 = T = (step>=4) ?
+ LDRGE r5, =sincos_lookup0 ; sincos_lookup0 +
+ LDRLT r5, =sincos_lookup1 ; sincos_lookup0 +
+ ADD r7, r1, r0, LSL #1 ; r7 = w1 = x + (n>>1)
+ ADDGE r5, r5, r2, LSR #1 ; (step>>1)
+ ADD r8, r5, #1024 ; r8 = Ttop
+step7_loop1
+ LDR r6, [r1] ; r6 = w0[0]
+ LDR r9, [r1,#4] ; r9 = w0[1]
+ LDR r10,[r7,#-8]! ; r10= w1[0] w1 -= 2
+ LDR r11,[r7,#4] ; r11= w1[1]
+ LDRB r14,[r5,#1] ; r14= T[1]
+ LDRB r12,[r5],r2 ; r12= T[0] T += step
+
+ ADD r6, r6, r10 ; r6 = s0 = w0[0] + w1[0]
+ SUB r10,r6, r10,LSL #1 ; r10= s1b= w0[0] - w1[0]
+ SUB r11,r11,r9 ; r11= s1 = w1[1] - w0[1]
+ ADD r9, r11,r9, LSL #1 ; r9 = s0b= w1[1] + w0[1]
+
+ MOV r6, r6, ASR #9
+ MUL r3, r6, r14 ; r3 = s0*T[1]
+ MOV r11,r11,ASR #9
+ MUL r4, r11,r12 ; r4 += s1*T[0] = s2
+ ADD r3, r3, r4
+ MUL r14,r11,r14 ; r14 = s1*T[1]
+ MUL r12,r6, r12 ; r12 += s0*T[0] = s3
+ SUB r14,r14,r12
+
+ ; r9 = s0b<<1
+ ; r10= s1b<<1
+ ADD r9, r3, r9, ASR #1 ; r9 = s0b + s2
+ SUB r3, r9, r3, LSL #1 ; r3 = s0b - s2
+
+ SUB r12,r14,r10,ASR #1 ; r12= s3 - s1b
+ ADD r10,r14,r10,ASR #1 ; r10= s3 + s1b
+ STR r9, [r1],#4
+ STR r10,[r1],#4 ; w0 += 2
+ STR r3, [r7]
+ STR r12,[r7,#4]
+
+ CMP r5,r8
+ BLT step7_loop1
+
+step7_loop2
+ LDR r6, [r1] ; r6 = w0[0]
+ LDR r9, [r1,#4] ; r9 = w0[1]
+ LDR r10,[r7,#-8]! ; r10= w1[0] w1 -= 2
+ LDR r11,[r7,#4] ; r11= w1[1]
+ LDRB r14,[r5,-r2]! ; r12= T[1] T -= step
+ LDRB r12,[r5,#1] ; r14= T[0]
+
+ ADD r6, r6, r10 ; r6 = s0 = w0[0] + w1[0]
+ SUB r10,r6, r10,LSL #1 ; r10= s1b= w0[0] - w1[0]
+ SUB r11,r11,r9 ; r11= s1 = w1[1] - w0[1]
+ ADD r9, r11,r9, LSL #1 ; r9 = s0b= w1[1] + w0[1]
+
+ MOV r6, r6, ASR #9
+ MUL r3, r6, r14 ; r3 = s0*T[0]
+ MOV r11,r11,ASR #9
+ MUL r4, r11,r12 ; r4 += s1*T[1] = s2
+ ADD r3, r3, r4
+ MUL r14,r11,r14 ; r14 = s1*T[0]
+ MUL r12,r6, r12 ; r12 += s0*T[1] = s3
+ SUB r14,r14,r12
+
+ ; r9 = s0b<<1
+ ; r10= s1b<<1
+ ADD r9, r3, r9, ASR #1 ; r9 = s0b + s2
+ SUB r3, r9, r3, LSL #1 ; r3 = s0b - s2
+
+ SUB r12,r14,r10,ASR #1 ; r12= s3 - s1b
+ ADD r10,r14,r10,ASR #1 ; r10= s3 + s1b
+ STR r9, [r1],#4
+ STR r10,[r1],#4 ; w0 += 2
+ STR r3, [r7]
+ STR r12,[r7,#4]
+
+ CMP r1,r7
+ BLT step7_loop2
+
+ LDMFD r13!,{r0-r3}
+
+ ; r0 = points
+ ; r1 = in
+ ; r2 = step
+ ; r3 = shift
+ MOV r2, r2, ASR #2 ; r2 = step >>= 2
+ CMP r2, #0
+ CMPNE r2, #1
+ BEQ mdct_end
+
+ ; step > 1 (default case)
+ CMP r2, #4 ; r5 = T = (step>=4) ?
+ LDRGE r5, =sincos_lookup0 ; sincos_lookup0 +
+ LDRLT r5, =sincos_lookup1 ; sincos_lookup1
+ ADD r7, r1, r0, LSL #1 ; r7 = iX = x + (n>>1)
+ ADDGE r5, r5, r2, LSR #1 ; (step>>1)
+mdct_step8_default
+ LDR r6, [r1],#4 ; r6 = s0 = x[0]
+ LDR r8, [r1],#4 ; r8 = -s1 = x[1]
+ LDRB r12,[r5,#1] ; r12= T[1]
+ LDRB r14,[r5],r2 ; r14= T[0] T += step
+ RSB r8, r8, #0 ; r8 = s1
+
+ ; XPROD31(s0, s1, T[0], T[1], x, x+1)
+ ; x[0] = s0 * T[0] + s1 * T[1] x[1] = s1 * T[0] - s0 * T[1]
+ MOV r6, r6, ASR #8
+ MOV r8, r8, ASR #8
+ MUL r10,r8, r12 ; r10 = s1 * T[1]
+ CMP r1, r7
+ MLA r10,r6, r14,r10 ; r10 += s0 * T[0]
+ RSB r6, r6, #0 ; r6 = -s0
+ MUL r11,r8, r14 ; r11 = s1 * T[0]
+ MLA r11,r6, r12,r11 ; r11 -= s0 * T[1]
+ STR r10,[r1,#-8]
+ STR r11,[r1,#-4]
+ BLT mdct_step8_default
+
+mdct_end
+ MOV r0, r2
+ LDMFD r13!,{r4-r11,PC}
+
+bitrev
+ DCB 0
+ DCB 32
+ DCB 16
+ DCB 48
+ DCB 8
+ DCB 40
+ DCB 24
+ DCB 56
+ DCB 4
+ DCB 36
+ DCB 20
+ DCB 52
+ DCB 12
+ DCB 44
+ DCB 28
+ DCB 60
+ DCB 2
+ DCB 34
+ DCB 18
+ DCB 50
+ DCB 10
+ DCB 42
+ DCB 26
+ DCB 58
+ DCB 6
+ DCB 38
+ DCB 22
+ DCB 54
+ DCB 14
+ DCB 46
+ DCB 30
+ DCB 62
+ DCB 1
+ DCB 33
+ DCB 17
+ DCB 49
+ DCB 9
+ DCB 41
+ DCB 25
+ DCB 57
+ DCB 5
+ DCB 37
+ DCB 21
+ DCB 53
+ DCB 13
+ DCB 45
+ DCB 29
+ DCB 61
+ DCB 3
+ DCB 35
+ DCB 19
+ DCB 51
+ DCB 11
+ DCB 43
+ DCB 27
+ DCB 59
+ DCB 7
+ DCB 39
+ DCB 23
+ DCB 55
+ DCB 15
+ DCB 47
+ DCB 31
+ DCB 63
+
+ END
diff --git a/mdct_lookup.h b/mdct_lookup.h
index 970e199..734e5ff 100644
--- a/mdct_lookup.h
+++ b/mdct_lookup.h
@@ -18,7 +18,10 @@
#include "os_types.h"
/* {sin(2*i*PI/4096), cos(2*i*PI/4096)}, with i = 0 to 512 */
-static LOOKUP_T sincos_lookup0[1026] = {
+#ifndef _ARM_ASSEM_
+static
+#endif
+LOOKUP_T sincos_lookup0[1026] = {
X(0x00000000), X(0x7fffffff), X(0x003243f5), X(0x7ffff621),
X(0x006487e3), X(0x7fffd886), X(0x0096cbc1), X(0x7fffa72c),
X(0x00c90f88), X(0x7fff6216), X(0x00fb5330), X(0x7fff0943),
@@ -279,7 +282,10 @@ static LOOKUP_T sincos_lookup0[1026] = {
};
/* {sin((2*i+1)*PI/4096), cos((2*i+1)*PI/4096)}, with i = 0 to 511 */
-static LOOKUP_T sincos_lookup1[1024] = {
+#ifndef _ARM_ASSEM_
+static
+#endif
+LOOKUP_T sincos_lookup1[1024] = {
X(0x001921fb), X(0x7ffffd88), X(0x004b65ee), X(0x7fffe9cb),
X(0x007da9d4), X(0x7fffc251), X(0x00afeda8), X(0x7fff8719),
X(0x00e23160), X(0x7fff3824), X(0x011474f6), X(0x7ffed572),