pimp_mixer_arm.S 7.95 KB
Newer Older
1
/* pimp_mixer_arm.S -- ARM optimized mixer code
Erik Faye-Lund's avatar
Erik Faye-Lund committed
2
 * Copyright (C) 2005-2006 Jørn Nystad and Erik Faye-Lund
3
4
5
 * For conditions of distribution and use, see copyright notice in LICENSE.TXT
 */
 
Erik Faye-Lund's avatar
Erik Faye-Lund committed
6
7
8
9
10
.text
.section .iwram
.arm
.align 2

11
@ no mixing:                 361612
Erik Faye-Lund's avatar
Erik Faye-Lund committed
12
@ without bresenham:
13
14
@   inline-asm version:     1211037
@   current:                1150788
Erik Faye-Lund's avatar
Erik Faye-Lund committed
15
@ with bresenham:
16
17
@   inline-asm version:     1163062
@   current:                1105083
Erik Faye-Lund's avatar
Erik Faye-Lund committed
18
19


20
21
22
@irq-safe:   1121327
@irq-unsafe: 1105083

PoroCYon's avatar
PoroCYon committed
23
#include "pimp_config.h"
Erik Faye-Lund's avatar
Erik Faye-Lund committed
24

PoroCYon's avatar
PoroCYon committed
25
#ifndef PIMP_MIXER_IRQ_SAFE
Erik Faye-Lund's avatar
Erik Faye-Lund committed
26
27
.stack_store:
.word 0
28
29
30
31
.ime_store:
.word 0
#endif

PoroCYon's avatar
PoroCYon committed
32
#ifdef PIMP_MIXER_USE_BRESENHAM_MIXER
33
34
35
36
37
.sample_data_store:
.word 0
#endif

.mixer_jumptable:
Erik Faye-Lund's avatar
Erik Faye-Lund committed
38
39
40
41
42
43
44
45
46
.word .mix0
.word .mix1
.word .mix2
.word .mix3
.word .mix4
.word .mix5
.word .mix6
.word .mix7

47
48
49
.global pimp_mixer_mix_samples
.type pimp_mixer_mix_samples, %function
pimp_mixer_mix_samples:
Erik Faye-Lund's avatar
Erik Faye-Lund committed
50
	stmfd sp!, {r4-r12, lr} @ store all registers but parameters and stack
51
	
PoroCYon's avatar
PoroCYon committed
52
#ifdef PIMP_MIXER_NO_MIXING
Erik Faye-Lund's avatar
Erik Faye-Lund committed
53
54
55
	ldmfd sp!, {r4-r12, lr} @ restore rest of registers
	bx lr                   @ return to caller
#endif
56
	
PoroCYon's avatar
PoroCYon committed
57
#ifndef PIMP_MIXER_IRQ_SAFE
Erik Faye-Lund's avatar
Erik Faye-Lund committed
58
	str sp, .stack_store    @ store stack pointer so we can use that register in our mixer (note, interrupts must be disabled for this to be safe)
59
#endif
Erik Faye-Lund's avatar
Erik Faye-Lund committed
60
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
61
62
63
64
65
66
#define TARGET              r0
#define COUNTER             r1
#define SAMPLE_DATA         r2
#define VOLUME              r3
#define SAMPLE_CURSOR       lr
#define SAMPLE_CURSOR_DELTA r12
67
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
68
69
70
71
72
73
	@ load rest of parameters
	ldr SAMPLE_CURSOR, [sp, #40]
	ldr SAMPLE_CURSOR_DELTA, [sp, #44]
	
	@ find how many samples to fixup
	and r4, COUNTER, #7
74
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
75
	@ fixup, jump to the correct position
Erik Faye-Lund's avatar
Erik Faye-Lund committed
76
77
	adr r5, .mixer_jumptable
	ldr pc, [r5, r4, lsl #2]
Erik Faye-Lund's avatar
Erik Faye-Lund committed
78
79
80
81
82
83
84
85
	
	@ fixup code unrolled 7 times
.mix7:
	ldr   r6, [TARGET]
	ldrb  r5, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r6, r5, VOLUME, r6
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	str   r6, [TARGET], #4
Erik Faye-Lund's avatar
Erik Faye-Lund committed
86
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
87
88
89
90
91
92
.mix6:
	ldr   r6, [TARGET]
	ldrb  r5, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r6, r5, VOLUME, r6
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	str   r6, [TARGET], #4
Erik Faye-Lund's avatar
Erik Faye-Lund committed
93
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
94
95
96
97
98
99
.mix5:
	ldr   r6, [TARGET]
	ldrb  r5, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r6, r5, VOLUME, r6
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	str   r6, [TARGET], #4
Erik Faye-Lund's avatar
Erik Faye-Lund committed
100
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
101
102
103
104
105
106
.mix4:
	ldr   r6, [TARGET]
	ldrb  r5, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r6, r5, VOLUME, r6
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	str   r6, [TARGET], #4
Erik Faye-Lund's avatar
Erik Faye-Lund committed
107
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
108
109
110
111
112
113
.mix3:
	ldr   r6, [TARGET]
	ldrb  r5, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r6, r5, VOLUME, r6
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	str   r6, [TARGET], #4
Erik Faye-Lund's avatar
Erik Faye-Lund committed
114
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
115
116
117
118
119
120
.mix2:
	ldr   r6, [TARGET]
	ldrb  r5, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r6, r5, VOLUME, r6
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	str   r6, [TARGET], #4
Erik Faye-Lund's avatar
Erik Faye-Lund committed
121
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
122
123
124
125
126
127
.mix1:
	ldr   r6, [TARGET]
	ldrb  r5, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r6, r5, VOLUME, r6
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	str   r6, [TARGET], #4
Erik Faye-Lund's avatar
Erik Faye-Lund committed
128
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
129
130
131
132
.mix0:
	
	movs COUNTER, COUNTER, asr #3 @ divide counter by 8
	beq .ret                      @ if no more samples, return
Erik Faye-Lund's avatar
Erik Faye-Lund committed
133
	
PoroCYon's avatar
PoroCYon committed
134
#ifndef PIMP_MIXER_IRQ_SAFE
135
136
137
138
139
140
	ldr r4, =0x4000208 @ load address of REG_IME
	ldr r5, [r4]       @ load value of REG_IME
	str r5, .ime_store @ stash for later
	eor r6, r6
	str r6, [r4]       @ disable interrupt	
#endif
Erik Faye-Lund's avatar
Erik Faye-Lund committed
141
	
PoroCYon's avatar
PoroCYon committed
142
#ifdef PIMP_MIXER_USE_BRESENHAM_MIXER
143
144
145
146
147
	// if ((sample_cursor_delta & ~((1UL << 12) - 1)) == 0)
	@ check if bresenham mixer can be used or not 
	ldr r4, =0xfffff000         @ ~((1UL << 12) - 1))
	tst SAMPLE_CURSOR_DELTA, r4 @ any bits set?
	beq .bresenham_mixer        @ no? lets go!
Erik Faye-Lund's avatar
Erik Faye-Lund committed
148
#endif
Erik Faye-Lund's avatar
Erik Faye-Lund committed
149
	
PoroCYon's avatar
PoroCYon committed
150
#ifdef PIMP_MIXER_IRQ_SAFE
151
152
153
#define TEMP                r11
#define UNROLL_RANGE        r4-r10
#else
Erik Faye-Lund's avatar
Erik Faye-Lund committed
154
#define TEMP                sp
155
156
#define UNROLL_RANGE        r4-r11
#endif
Erik Faye-Lund's avatar
Erik Faye-Lund committed
157
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
158
159
160
161
162
163
.simple_loop:
	ldmia TARGET, {UNROLL_RANGE}
	
	ldrb  TEMP, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r4, TEMP, VOLUME, r4
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
Erik Faye-Lund's avatar
Erik Faye-Lund committed
164
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
165
166
167
	ldrb  TEMP, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r5, TEMP, VOLUME, r5
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
Erik Faye-Lund's avatar
Erik Faye-Lund committed
168
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
169
170
171
	ldrb  TEMP, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r6, TEMP, VOLUME, r6
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
Erik Faye-Lund's avatar
Erik Faye-Lund committed
172
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
173
174
175
176
177
178
179
	ldrb  TEMP, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r7, TEMP, VOLUME, r7
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	
	ldrb  TEMP, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r8, TEMP, VOLUME, r8
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
Erik Faye-Lund's avatar
Erik Faye-Lund committed
180
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
181
182
183
	ldrb  TEMP, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r9, TEMP, VOLUME, r9
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
Erik Faye-Lund's avatar
Erik Faye-Lund committed
184
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
185
186
187
	ldrb  TEMP, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r10, TEMP, VOLUME, r10
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
Erik Faye-Lund's avatar
Erik Faye-Lund committed
188
	
PoroCYon's avatar
PoroCYon committed
189
#ifndef PIMP_MIXER_IRQ_SAFE
Erik Faye-Lund's avatar
Erik Faye-Lund committed
190
191
192
	ldrb  TEMP, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r11, TEMP, VOLUME, r11
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
Erik Faye-Lund's avatar
Erik Faye-Lund committed
193
	
194
195
	stmia TARGET!, {UNROLL_RANGE}
#else
Erik Faye-Lund's avatar
Erik Faye-Lund committed
196
	stmia TARGET!, {UNROLL_RANGE}
197
	
198
	@ mix a single sample
199
200
201
202
203
204
205
	ldr   r10, [TARGET]
	ldrb  TEMP, [SAMPLE_DATA, SAMPLE_CURSOR, lsr #12]
	mla   r10, TEMP, VOLUME, r10
	add   SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	str   r10, [TARGET], #4	
#endif
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
206
207
	subs COUNTER, COUNTER, #1
	bne .simple_loop
Erik Faye-Lund's avatar
Erik Faye-Lund committed
208
	
PoroCYon's avatar
PoroCYon committed
209
#ifndef PIMP_MIXER_IRQ_SAFE
210
211
212
	ldr r4, =0x4000208 @ load address of REG_IME
	ldr r5, .ime_store @ stash for later
	str r5, [r4]       @ write value to REG_IME
213
214

	ldr sp, .stack_store    @ restore stack pointer
215
#endif
Erik Faye-Lund's avatar
Erik Faye-Lund committed
216
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
217
218
219
.ret:
	@ clean return
	mov r0, SAMPLE_CURSOR
Erik Faye-Lund's avatar
Erik Faye-Lund committed
220
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
221
222
	ldmfd sp!, {r4-r12, lr} @ restore rest of registers
	bx lr                   @ return to caller
Erik Faye-Lund's avatar
Erik Faye-Lund committed
223
	
PoroCYon's avatar
PoroCYon committed
224
#ifdef PIMP_MIXER_USE_BRESENHAM_MIXER
Erik Faye-Lund's avatar
Erik Faye-Lund committed
225
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
226
.bresenham_mixer:
227
228
	str SAMPLE_DATA, .sample_data_store                  @ stash away SAMPLE_DATA for later use
	add SAMPLE_DATA, SAMPLE_DATA, SAMPLE_CURSOR, lsr #12 @ modify pointer so it points to the fist sample in frame
Erik Faye-Lund's avatar
Erik Faye-Lund committed
229
230
231
	
	mov SAMPLE_CURSOR, SAMPLE_CURSOR, asl #20
	mov SAMPLE_CURSOR_DELTA, SAMPLE_CURSOR_DELTA, asl #20
Erik Faye-Lund's avatar
Erik Faye-Lund committed
232
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
233
	ldrb  TEMP, [SAMPLE_DATA], #1
234
	mul   TEMP, VOLUME, TEMP
Erik Faye-Lund's avatar
Erik Faye-Lund committed
235
.bresenham_loop:
236
	ldmia TARGET, {UNROLL_RANGE}
Erik Faye-Lund's avatar
Erik Faye-Lund committed
237
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
238
239
240
241
	add   r4, TEMP, r4
	adds  SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	ldrcsb TEMP, [SAMPLE_DATA], #1
	mulcs  TEMP, VOLUME, TEMP
Erik Faye-Lund's avatar
Erik Faye-Lund committed
242
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
243
244
245
246
	add   r5, TEMP, r5
	adds  SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	ldrcsb TEMP, [SAMPLE_DATA], #1
	mulcs  TEMP, VOLUME, TEMP
Erik Faye-Lund's avatar
Erik Faye-Lund committed
247
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
248
249
250
251
	add   r6, TEMP, r6
	adds  SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	ldrcsb TEMP, [SAMPLE_DATA], #1
	mulcs  TEMP, VOLUME, TEMP
Erik Faye-Lund's avatar
Erik Faye-Lund committed
252
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
253
254
255
256
	add   r7, TEMP, r7
	adds  SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	ldrcsb TEMP, [SAMPLE_DATA], #1
	mulcs  TEMP, VOLUME, TEMP
Erik Faye-Lund's avatar
Erik Faye-Lund committed
257
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
258
259
260
261
	add   r8, TEMP, r8
	adds  SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	ldrcsb TEMP, [SAMPLE_DATA], #1
	mulcs  TEMP, VOLUME, TEMP
Erik Faye-Lund's avatar
Erik Faye-Lund committed
262
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
263
264
265
266
	add   r9, TEMP, r9
	adds  SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	ldrcsb TEMP, [SAMPLE_DATA], #1
	mulcs  TEMP, VOLUME, TEMP
Erik Faye-Lund's avatar
Erik Faye-Lund committed
267
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
268
269
270
271
	add   r10, TEMP, r10
	adds  SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	ldrcsb TEMP, [SAMPLE_DATA], #1
	mulcs  TEMP, VOLUME, TEMP
Erik Faye-Lund's avatar
Erik Faye-Lund committed
272
	
PoroCYon's avatar
PoroCYon committed
273
#ifndef PIMP_MIXER_IRQ_SAFE
Erik Faye-Lund's avatar
Erik Faye-Lund committed
274
275
276
277
278
	add   r11, TEMP, r11
	adds  SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	ldrcsb TEMP, [SAMPLE_DATA], #1
	mulcs  TEMP, VOLUME, TEMP

279
280
281
	stmia TARGET!, {UNROLL_RANGE}
#else
	stmia TARGET!, {UNROLL_RANGE}
Erik Faye-Lund's avatar
Erik Faye-Lund committed
282
	
283
284
285
286
287
288
289
	ldr   r10, [TARGET]
	add   r10, TEMP, r10
	adds  SAMPLE_CURSOR, SAMPLE_CURSOR, SAMPLE_CURSOR_DELTA
	ldrcsb TEMP, [SAMPLE_DATA], #1
	mulcs  TEMP, VOLUME, TEMP
	str   r10, [TARGET], #4		
#endif
Erik Faye-Lund's avatar
Erik Faye-Lund committed
290
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
291
292
	subs  COUNTER, COUNTER, #1
	bne .bresenham_loop
Erik Faye-Lund's avatar
Erik Faye-Lund committed
293
	
PoroCYon's avatar
PoroCYon committed
294
#ifndef PIMP_MIXER_IRQ_SAFE
295
296
297
298
299
	ldr r4, =0x4000208 @ load address of REG_IME
	ldr r5, .ime_store @ stash for later
	str r5, [r4]       @ write value to REG_IME
	
	ldr sp, .stack_store       @ restore stack pointer
300
301
#endif

302
	ldr r0, .sample_data_store @ restore the old sample data
Erik Faye-Lund's avatar
Erik Faye-Lund committed
303
304
305
306
307
308
309
310
311
312
313
	
	@ calculate how the sample cursor changed
	sub r0, SAMPLE_DATA, r0
	sub r0, r0, #1
	mov r0, r0, lsl #12
	add r0, SAMPLE_CURSOR, asr #20
	
	@ return to caller
	ldmfd sp!, {r4-r12, lr} @ restore rest of registers
	bx lr
#endif