summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin@xiph.org>2010-05-15 23:36:52 +0000
committerRobin Watts <robin@xiph.org>2010-05-15 23:36:52 +0000
commit77c9cbe128eebd006cb6bc0e9930833f9564eaf0 (patch)
tree12003f43ee4e29749c55decb92c1f2f5c4fbb980
parentc650be1bdd4d3a2746b4631953c0e887aef9cd2d (diff)
downloadtremor-77c9cbe128eebd006cb6bc0e9930833f9564eaf0.tar.gz
ARM implementation of floor1 render_line functions (normal and LOW_ACCURACY
versions). git-svn-id: https://svn.xiph.org/branches/lowmem-branch/Tremolo@17219 0101bb08-14d6-0310-b084-bc0e0c8e3800
-rw-r--r--Makefile.am5
-rw-r--r--floor1.c15
-rw-r--r--floor1ARM.s36
-rw-r--r--floor1LARM.s35
4 files changed, 89 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index 4bd5732..830ff77 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -8,8 +8,9 @@ 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
+# Build both low and full accuracy versions and the linker will only
+# include the appropriate versions.
+TARGET_SPECIFIC_SOURCES = mdctARM.s mdctLARM.s floor1ARM.s floor1LARM.s
else
TARGET_SPECIFIC_SOURCES =
endif
diff --git a/floor1.c b/floor1.c
index 5752968..f469ada 100644
--- a/floor1.c
+++ b/floor1.c
@@ -195,6 +195,13 @@ static int render_point(int x0,int x1,int y0,int y1,int x){
}
}
+#ifdef _ARM_ASSEM_
+void render_line_arm(int n, ogg_int32_t *d,const ogg_int32_t *floor,
+ int base, int err, int adx, int ady);
+void render_line_arm_low(int n, ogg_int32_t *d,const ogg_int32_t *floor,
+ int base, int err, int adx, int ady);
+#endif
+
static void render_line(int n,int x0,int x1,int y0,int y1,ogg_int32_t *d){
int dy;
int adx;
@@ -231,6 +238,13 @@ static void render_line(int n,int x0,int x1,int y0,int y1,ogg_int32_t *d){
err = 0;
}
+#ifdef _ARM_ASSEM_
+#ifdef _LOW_ACCURACY_
+ render_line_arm_low(n,d,floor,base,err,adx,ady);
+#else
+ render_line_arm(n,d,floor,base,err,adx,ady);
+#endif
+#else
do{
*d = MULT31_SHIFT15(*d,*floor);
d++;
@@ -242,6 +256,7 @@ static void render_line(int n,int x0,int x1,int y0,int y1,ogg_int32_t *d){
}
n--;
} while(n>0);
+#endif
}
int floor1_memosize(vorbis_info_floor *i){
diff --git a/floor1ARM.s b/floor1ARM.s
new file mode 100644
index 0000000..689b5c5
--- /dev/null
+++ b/floor1ARM.s
@@ -0,0 +1,36 @@
+; Tremolo library
+; Copyright (C) 2009 Robin Watts for Pinknoise Productions Ltd
+
+ AREA |.text|, CODE, READONLY
+
+ EXPORT render_line_arm
+
+render_line_arm
+ ; r0 = n
+ ; r1 = d
+ ; r2 = floor
+ ; r3 = base
+ ; <> = err
+ ; <> = adx
+ ; <> = ady
+ MOV r12,r13
+ STMFD r13!,{r4-r6,r11,r14}
+ LDMFD r12,{r11,r12,r14} ; r11 = err
+ ; r12 = adx
+ ; r14 = ady
+rl_loop
+ LDR r4,[r1] ; r4 = *d
+ LDR r5,[r2],r3,LSL #2 ; r5 = *floor r2 = floor+base
+ SUBS r11,r11,r14 ; err -= ady
+ ADDLT r11,r11,r12 ; if (err < 0) err+=adx
+ SMULL r6, r5, r4, r5 ; (r6,r5) = *d * *floor
+ ADDLT r2, r2, #4 ; floor+=1
+ MOVS r6, r6, LSR #15
+ ADC r5, r6, r5, LSL #17 ; r5 = MULT31_SHIFT15
+ STR r5,[r1],#4
+ SUBS r0, r0, #1
+ BGT rl_loop
+
+ LDMFD r13!,{r4-r6,r11,PC}
+
+ END
diff --git a/floor1LARM.s b/floor1LARM.s
new file mode 100644
index 0000000..d7ead1d
--- /dev/null
+++ b/floor1LARM.s
@@ -0,0 +1,35 @@
+; Tremolo library
+; Copyright (C) 2009 Robin Watts for Pinknoise Productions Ltd
+
+ AREA |.text|, CODE, READONLY
+
+ EXPORT render_line_arm_low
+
+render_line_arm_low
+ ; r0 = n
+ ; r1 = d
+ ; r2 = floor
+ ; r3 = base
+ ; <> = err
+ ; <> = adx
+ ; <> = ady
+ MOV r12,r13
+ STMFD r13!,{r4-r6,r11,r14}
+ LDMFD r12,{r11,r12,r14} ; r11 = err
+ ; r12 = adx
+ ; r14 = ady
+rl_loop
+ LDR r4, [r1] ; r4 = *d
+ LDR r5, [r2], r3,LSL #2 ; r5 = *floor r2 = floor+base
+ SUBS r11,r11,r14 ; err -= ady
+ MOV r4, r4, ASR #6
+ MUL r5, r4, r5 ; r5 = MULT31_SHIFT15
+ ADDLT r11,r11,r12 ; if (err < 0) err+=adx
+ ADDLT r2, r2, #4 ; floor+=1
+ SUBS r0, r0, #1
+ STR r5, [r1], #4
+ BGT rl_loop
+
+ LDMFD r13!,{r4-r6,r11,PC}
+
+ END