summaryrefslogtreecommitdiff
path: root/apps/codecs/libtta/filter_arm.S
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libtta/filter_arm.S')
-rw-r--r--apps/codecs/libtta/filter_arm.S203
1 files changed, 203 insertions, 0 deletions
diff --git a/apps/codecs/libtta/filter_arm.S b/apps/codecs/libtta/filter_arm.S
new file mode 100644
index 0000000000..37c515d3a9
--- /dev/null
+++ b/apps/codecs/libtta/filter_arm.S
@@ -0,0 +1,203 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Yoshihisa Uchida
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23
24/*
25 * The following are assembler optimised version of
26 * void hybrid_filter(fltst *fs, int *in)
27 */
28
29#ifdef USE_IRAM
30 .section .icode, "ax", %progbits
31#else
32 .text
33#endif
34 .align
35 .global hybrid_filter
36 .type hybrid_filter, %function
37
38hybrid_filter:
39 @ input: r0 = fs, r1 = in
40 stmdb sp!, {r4 - r12, lr}
41
42 @ get fs members
43 @ r2 pA := fs->dl + fs->index
44 @ r3 pM := fs->dx + fs->index
45 @ r4 pB := fs->qm
46 @ r5 fs->index
47 @ r6 fs->error
48 @ lr sum := fs->round
49
50 add r2, r0, #148 @ r2 = fs->dl
51 add r3, r0, #52 @ r3 = fs->dx
52 add r4, r0, #20 @ r4 = fs->qm
53 ldmia r0, {r5, r6, lr} @ r5 = fs->index
54 @ r6 = fs->error
55 @ lr = fs->round
56 mov r5, r5, asl #2
57 add r2, r2, r5 @ r2 = fs->dl + fs->index
58 add r3, r3, r5 @ r3 = fs->dx + fs->index
59
60 cmp r6, #0
61 bne .hf_positive
62
63 @ case fs->error == 0
64
65 add r3, r3, #32
66 ldmia r4!, {r5, r6, r7, r8 }
67 ldmia r2!, {r9, r10, r11, r12}
68 mla lr, r5, r9, lr
69 mla lr, r6, r10, lr
70 mla lr, r7, r11, lr
71 mla lr, r8, r12, lr
72 ldmia r4!, {r5, r6, r7, r8 }
73 b .hf2
74
75.hf_positive:
76 blt .hf_negative
77
78 @ case fs->error > 0
79
80 ldmia r4, {r5, r6, r7, r8 }
81 ldmia r3!, {r9, r10, r11, r12}
82 add r5, r5, r9
83 add r6, r6, r10
84 add r7, r7, r11
85 add r8, r8, r12
86 stmia r4!, {r5, r6, r7, r8 } @ update fs->qm[0], ..., fs->qm[3]
87 ldmia r2!, {r9, r10, r11, r12}
88 mla lr, r5, r9, lr
89 mla lr, r6, r10, lr
90 mla lr, r7, r11, lr
91 mla lr, r8, r12, lr
92 ldmia r4, {r5, r6, r7, r8 }
93 ldmia r3!, {r9, r10, r11, r12}
94 add r5, r5, r9
95 add r6, r6, r10
96 add r7, r7, r11
97 add r8, r8, r12
98 stmia r4!, {r5, r6, r7, r8 } @ update fs->qm[4], ..., fs->qm[7]
99 b .hf2
100
101.hf_negative:
102 @ case fs->error < 0
103
104 ldmia r4, {r5, r6, r7, r8 }
105 ldmia r3!, {r9, r10, r11, r12}
106 sub r5, r5, r9
107 sub r6, r6, r10
108 sub r7, r7, r11
109 sub r8, r8, r12
110 stmia r4!, {r5, r6, r7, r8 } @ update fs->qm[0], ..., fs->qm[3]
111 ldmia r2!, {r9, r10, r11, r12}
112 mla lr, r5, r9, lr
113 mla lr, r6, r10, lr
114 mla lr, r7, r11, lr
115 mla lr, r8, r12, lr
116 ldmia r4, {r5, r6, r7, r8 }
117 ldmia r3!, {r9, r10, r11, r12}
118 sub r5, r5, r9
119 sub r6, r6, r10
120 sub r7, r7, r11
121 sub r8, r8, r12
122 stmia r4!, {r5, r6, r7, r8 } @ update fs->qm[4], ..., fs->qm[7]
123
124.hf2:
125 ldmia r2!, {r9, r10, r11, r12}
126 mla lr, r5, r9, lr
127 mla lr, r6, r10, lr
128 mla lr, r7, r11, lr
129 mla lr, r8, r12, lr
130
131 @ fs->error = *in;
132 @ *in += (sum >> fs->shift)
133 @ *pA = *in
134
135 ldr r5, [r1] @ r5 = *in
136 ldr r6, [r0, #12] @ r6 = fs->shift
137 add lr, r5, lr, asr r6
138 str lr, [r1] @ *in += (sum >> fs->shift)
139
140 @ update fs->index
141
142 ldr r1, [r0] @ r1 = fs->index
143 add r1, r1, #1
144 ands r1, r1, #15 @ set Z flag (after this, CPSR must keep !!)
145 stmia r0, {r1, r5} @ fs->index = (++fs->index & 15)
146 @ fs->error = (original) *in
147
148 @ change *pM, *(pM-1), *(pM-2), *(pM-3)
149 @ r9 = *(pA-4), r5 = *(pM-3)
150 @ r10 = *(pA-3), r6 = *(pM-2)
151 @ r11 = *(pA-2), r7 = *(pM-1)
152 @ r12 = *(pA-1), r8 = *(pM-0)
153 @ lr = *(pA-0)
154
155 mov r4, #1
156 orr r5, r4, r9, asr #30
157 orr r6, r4, r10, asr #30
158 orr r7, r4, r11, asr #30
159 orr r8, r4, r12, asr #30
160 mov r6, r6, lsl #1
161 mov r7, r7, lsl #1
162 mov r8, r8, lsl #2
163
164 @ change *(pA-1), *(pA-2), *(pA-3)
165 sub r12, lr, r12
166 sub r11, r12, r11
167 sub r10, r11, r10
168
169 @ check fs->index is zero
170 beq .hf_memshl
171
172 @ set to the memory: *pA, *(pA-1), *(pA-2), *(pA-3), *pM, *(pM-1), *(pM-2), *(pM-3)
173 stmda r2, {r10, r11, r12, lr}
174 stmda r3, {r5, r6, r7, r8}
175 ldmfd sp!, {r4-r12, pc} @ hybrid_filter end (when fs->index != 0)
176
177.hf_memshl:
178 @ memshl (fs->dl)
179 @ r9 = fs->dl[16 + 3]
180 @ r10 = fs->dl[16 + 4]
181 @ r11 = fs->dl[16 + 5]
182 @ r12 = fs->dl[16 + 6]
183 @ lr = fs->dl[16 + 7]
184
185 add r2, r0, #212 @ r2 = fs->dl + 16
186 ldmia r2, {r1, r3, r4}
187 sub r2, r2, #64 @ r2 = fs->dl
188 stmia r2, {r1, r3, r4, r9 - r12, lr}
189
190 @ memshl (fs->dx)
191 @ r5 = fs->dx[16 + 4]
192 @ r6 = fs->dx[16 + 5]
193 @ r7 = fs->dx[16 + 6]
194 @ r8 = fs->dx[16 + 7]
195
196 add r9, r0, #116 @ r9 = fs->dx + 16
197 ldmia r9, {r1, r2, r3, r4}
198 sub r9, r9, #64 @ r9 = fs->dx
199 stmia r9, {r1 - r8}
200 ldmfd sp!, {r4 - r12, pc} @ hybrid_filter end (when fs->index == 0)
201
202hybrid_filter_end:
203 .size hybrid_filter, hybrid_filter_end - hybrid_filter