blob: 344e41b3622761ff1589d3edd28b3913979b2459 [file] [log] [blame]
Gloria Wang79130732010-02-08 14:41:04 -08001@ Tremolo library
Gloria Wang2da723a2010-03-18 15:56:16 -07002@-----------------------------------------------------------------------
3@ Copyright (C) 2002-2009, Xiph.org Foundation
4@ Copyright (C) 2010, Robin Watts for Pinknoise Productions Ltd
5@ All rights reserved.
6
7@ Redistribution and use in source and binary forms, with or without
8@ modification, are permitted provided that the following conditions
9@ are met:
10
11@ * Redistributions of source code must retain the above copyright
12@ notice, this list of conditions and the following disclaimer.
13@ * Redistributions in binary form must reproduce the above
14@ copyright notice, this list of conditions and the following disclaimer
15@ in the documentation and/or other materials provided with the
16@ distribution.
17@ * Neither the names of the Xiph.org Foundation nor Pinknoise
18@ Productions Ltd nor the names of its contributors may be used to
19@ endorse or promote products derived from this software without
20@ specific prior written permission.
21@
22@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23@ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24@ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25@ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26@ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27@ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33@ ----------------------------------------------------------------------
Gloria Wang79130732010-02-08 14:41:04 -080034
35 .text
36
37 .global decode_packed_entry_number
38 .global decode_packed_entry_number_REALSTART
39 .global decode_map
40 .global vorbis_book_decodevv_add
41 .global _checksum
42
43 .extern oggpack_adv
44 .extern oggpack_look
45 .extern oggpack_eop
46 .extern crc_lookup
Ard Biesheuvel27736022014-08-08 08:30:00 +020047 .hidden crc_lookup
Gloria Wang79130732010-02-08 14:41:04 -080048
49decode_packed_entry_number_REALSTART:
50dpen_nobits:
51 MOV r0,r5 @ r0 = b
52 MOV r1,#1 @ r1 = 1
53 BL oggpack_adv @ oggpack_adv(b,1) /* Force eop */
54duff:
55 MVN r0,#0 @ return -1
56 LDMFD r13!,{r4-r8,r10,PC}
57
58dpen_readfailed:
59 SUBS r4,r4,#1 @ r4 = --read
60 BEQ dpen_nobits
61 MOV r0,r5 @ r0 = b
62 MOV r1,r4 @ r1 = read
63 ADR r14,dpen_read_return
64 B oggpack_look
65
66decode_packed_entry_number:
67 @ r0 = codebook *book
68 @ r1 = oggpack_buffer *b
69 STMFD r13!,{r4-r8,r10,r14}
70
71 LDMIA r0,{r4,r6,r7} @ r4 = read = book->max_length
72 @ r6 = book->dec_table
73 @ r7 = book->dec_method
74 MOV r5,r1 @ r5 = b
75
76 MOV r0,r5 @ r0 = b
77 MOV r1,r4 @ r1 = read
78 BL oggpack_look
79dpen_read_return:
80 CMP r0,#0
81 BLT dpen_readfailed
82
83 @ r0 = lok
84 @ r4 = read
85 @ r5 = b
86 @ r6 = dec_table
87 @ r7 = dec_method
88
89 CMP r7, #3
90 BGT meth4
91 BEQ meth3
92 CMP r7, #1
93 BGT meth2
94 BEQ meth1
95meth0:
96 RSB r1, r4, #0 @ r1 = i-read = 0-read
97 MOV r7, #0 @ r7 = chase
98m0_loop:
99 MOVS r0, r0, LSR #1 @ r0 = lok>>1 C = bottom bit
100 ADC r2, r6, r7, LSL #1 @ r8 = &t[chase*2+C]
101 LDRB r7, [r2]
102 ADDS r1, r1, #1 @ r1 = i-read++ (i-read<0 => i<read)
103 @ stall Xscale
104 CMPLT r7, #0x80
105 BLT m0_loop
106 AND r7, r7, #0x7F @ r7 = chase
107 CMP r1, #0 @ if (i-read >= 0) === (i >= read)
108 MVNGT r7, #0 @ if (i >= read) value to return = -1
109 ADD r1, r1, r4 @ r1 = i-read+read+1 = i +1
110 MOV r0, r5 @ r0 = b
111 BL oggpack_adv @ oggpack_adv(b, i+1);
112 MOV r0, r7 @ return chase
113 LDMFD r13!,{r4-r8,r10,PC}
114
115meth1:
116 @ r0 = lok
117 @ r4 = read
118 @ r5 = b
119 @ r6 = dec_table
120 RSB r1, r4, #0 @ r1 = i = -read
121 MOV r10,#0 @ r10= next = 0
122m1_loop:
123 MOV r7, r10 @ r7 = chase=next
124 MOVS r0, r0, LSR #1 @ r0 = lok>>1 C = bottom bit
125 ADC r8, r6, r7 @ r8 = t+chase+bit
126 LDRB r10,[r8], -r6 @ r10= next=t[chase+bit] r8=chase+bit
127 ADDS r1, r1, #1 @ r1 = i++
128 @ stall Xscale
129 CMPLT r10,#0x80 @ if (next & 0x80) == 0
130 BLT m1_loop
131
132 ADD r1, r1, r4 @ r1 = i+read
133 MOV r0, r5 @ r0 = b
134 BL oggpack_adv @ oggpack_adv(b, i)
135
136 CMP r10,#0x80
137 BLT duff
138
139 CMP r8, r7 @ if bit==0 (chase+bit==chase) (sets C)
140 LDRNEB r14,[r6, r7] @ r14= t[chase]
141 MOVEQ r14,#128
142 ADC r12,r8, r6 @ r12= chase+bit+1+t
143 LDRB r14,[r12,r14,LSR #7] @ r14= t[chase+bit+1+(!bit || t[chase]0x0x80)]
144 BIC r10,r10,#0x80 @ r3 = next &= ~0x80
145 @ stall Xscale
146 ORR r0, r14,r10,LSL #8 @ r7 = chase = (next<<8) | r14
147
148 LDMFD r13!,{r4-r8,r10,PC}
149
150
151meth2:
152 RSB r1, r4, #0 @ r1 = i-read = 0-read
153 MOV r7, #0 @ r7 = chase
154 MOV r6, r6, LSR #1
155m2_loop:
156 MOVS r0, r0, LSR #1 @ r0 = lok>>1 C = bottom bit
157 ADC r2, r6, r7, LSL #1 @ r8 = &t[chase*2+C]
158 LDRH r7, [r2, r2]
159 ADDS r1, r1, #1 @ r1 = i-read++ (i-read<0 => i<read)
160 @ stall Xscale
161 CMPLT r7, #0x8000
162 BLT m2_loop
163 BIC r7, r7, #0x8000 @ r7 = chase
164 CMP r1, #0 @ if (i-read >= 0) === (i >= read)
165 MVNGT r7, #0 @ if (i >= read) value to return = -1
166 ADD r1, r1, r4 @ r1 = i-read+read+1 = i +1
167 MOV r0, r5 @ r0 = b
168 BL oggpack_adv @ oggpack_adv(b, i+1);
169 MOV r0, r7 @ return chase
170 LDMFD r13!,{r4-r8,r10,PC}
171
172meth3:
173 @ r0 = lok
174 @ r4 = read
175 @ r5 = b
176 @ r6 = dec_table
177 RSB r1, r4, #0 @ r1 = i = -read
178 MOV r10,#0 @ r10= next = 0
179m3_loop:
180 MOV r7, r10 @ r7 = chase=next
181 MOVS r0, r0, LSR #1 @ r0 = lok>>1 C = bottom bit
182 ADC r8, r7, #0 @ r8 = chase+bit
183 MOV r8, r8, LSL #1 @ r8 = (chase+bit)<<1
184 LDRH r10,[r6, r8] @ r10= next=t[chase+bit]
185 ADDS r1, r1, #1 @ r1 = i++
186 @ stall Xscale
187 CMPLT r10,#0x8000 @ if (next & 0x8000) == 0
188 BLT m3_loop
189
190 ADD r1, r1, r4 @ r1 = i+read
191 MOV r0, r5 @ r0 = b
192 BL oggpack_adv @ oggpack_adv(b, i)
193
194 CMP r10,#0x8000
195 BLT duff
196
197 MOV r7, r7, LSL #1
198 CMP r8, r7 @ if bit==0 (chase+bit==chase) sets C
199 LDRNEH r14,[r6, r7] @ r14= t[chase]
200 MOVEQ r14,#0x8000
201 ADC r12,r8, r14,LSR #15 @ r12= 1+((chase+bit)<<1)+(!bit || t[chase]0x0x8000)
202 ADC r12,r12,r14,LSR #15 @ r12= t + (1+chase+bit+(!bit || t[chase]0x0x8000))<<1
203 LDRH r14,[r6, r12] @ r14= t[chase+bit+1
204 BIC r10,r10,#0x8000 @ r3 = next &= ~0x8000
205 @ stall Xscale
206 ORR r0, r14,r10,LSL #16 @ r7 = chase = (next<<16) | r14
207
208 LDMFD r13!,{r4-r8,r10,PC}
209
210meth4:
211 RSB r1, r4, #0 @ r1 = i-read = 0-read
212 MOV r7, #0 @ r7 = chase
213m4_loop:
214 MOVS r0, r0, LSR #1 @ r0 = lok>>1 C = bottom bit
215 ADC r2, r7, r7 @ r8 = chase*2+C
216 LDR r7, [r6, r2, LSL #2]
217 ADDS r1, r1, #1 @ r1 = i-read++ (i-read<0 => i<read)
218 @ stall Xscale
219 CMPLT r7, #0x80000000
220 BLT m4_loop
221 BIC r7, r7, #0x80000000 @ r7 = chase
222 CMP r1, #0 @ if (i-read >= 0) === (i >= read)
223 MVNGT r7, #0 @ if (i >= read) value to return = -1
224 ADD r1, r1, r4 @ r1 = i-read+read+1 = i +1
225 MOV r0, r5 @ r0 = b
226 BL oggpack_adv @ oggpack_adv(b, i+1);
227 MOV r0, r7 @ return chase
228 LDMFD r13!,{r4-r8,r10,PC}
229
230decode_map:
231 @ r0 = codebook *s
232 @ r1 = oggpack_buffer *b
233 @ r2 = int v
234 @ r3 = int point
235 STMFD r13!,{r4-r11,r14}
236
237 MOV r4, r0 @ r4 = s
238 MOV r5, r1 @ r5 = b
239 MOV r6, r2 @ r6 = v
240 MOV r7, r3 @ r7 = point
241 BL decode_packed_entry_number
242 MOV r8, r0
243
244 MOV r0, r5
245 BL oggpack_eop
246 CMP r0, #0
247 BNE dm_duff
248
249 @ r4 = s
250 @ r5 = b
251 @ r6 = v
252 @ r7 = point
253 @ r8 = entry
254
255 LDR r1, [r4,#12] @ r1 = s->dec_type
256 LDR r2, [r4,#16] @ r2 = s->q_bits
257 LDR r3, [r4,#20] @ r3 = s->dim
258 LDR r5, [r4,#24] @ r5 = s->q_delp
259 LDR r11,[r4,#28] @ r11= s->q_minp
260 LDR r12,[r4,#32] @ r12= s->q_del = mul
261 LDR r14,[r4,#36] @ r14= s->q_min
262 SUBS r11,r7, r11 @ r11= add = point - s->q_minp
263
264 MOVGT r14,r14,ASR r11 @ r14= add = s->q_min >> add (if add >0)
265 RSBLT r11,r11,#0
266 MOVLT r14,r14,LSL r11 @ r14= add = s->q_min << -add (if add < 0)
267
268 SUBS r5, r7, r5 @ r5 = shiftM = point - s->q_delp
269 LDR r7, [r4,#40] @ r7 = s->q_seq
270 RSBLT r5, r5, #0 @ if (shiftM<0) r5 =-shiftM
271 MOVLT r12,r12,LSL r5 @ r12=mul<<-shiftM
272 MOVLT r5, #0 @ r5 =shiftM = 0
273 MOVGT r14,r14,LSL r5 @ add <<= shiftM
274
275 CMP r7,#0 @ seqMask = (s->q_seq?-1:0)
276 MVNNE r7,#0
277
278 CMP r1, #2
279 BEQ dm2
280 BGT dm3
281 CMP r1,#0 @ probably never happens
282 BLE dm_duff
283dm1:
284 @ r1 = s->dec_type
285 @ r2 = s->q_bits
286 @ r3 = s->dim
287 @ r5 = shiftM
288 @ r6 = v
289 @ r7 = seqMask
290 @ r8 = entry
291 @ r12= mul
292 @ r14= add
293 MOV r0, #1
294 RSB r0, r0, r0, LSL r2 @ r0 = mask = (1<<s->q_bits)-1
295 MOV r11,#0 @ r11= prev = 0
296dm1_loop:
297 AND r1, r8, r0 @ r1 = v = entry & mask
298 MLA r1, r12, r1, r14 @ r1 = (add + mul*v)
299 MOV r8, r8, LSR r2 @ r8 = entry>>s->q_bits
300 SUBS r3, r3, #1
301 ADD r1, r11,r1, ASR r5 @ r1 = v = prev+((add+mul*v)>>shiftM)
302 AND r11,r1, r7 @ r11= prev = seqMask & v
303 STR r1, [r6], #4 @ *v++ = v
304 BGT dm1_loop
305
306 MOV r0, #0
307 LDMFD r13!,{r4-r11,PC}
308dm2:
309 @ r1 = s->dec_type
310 @ r2 = s->q_bits
311 @ r3 = s->dim
312 @ r4 = s
313 @ r5 = shiftM
314 @ r6 = v
315 @ r7 = seqMask
316 @ r8 = entry
317 @ r12= mul
318 @ r14= add
319 LDR r1, [r4,#44] @ r1 = s->q_pack
320 LDR r4, [r4,#48] @ r4 = s->q_val
321 MOV r11,#0 @ r11= prev
322 MOV r0, #1
323 RSB r0, r0, r0, LSL r1 @ r8 = mask = (1<<s->q_pack)-1
324 CMP r2,#8
325 BGT dm2_hword
326dm2_loop:
327 AND r2, r8, r0 @ r2 = entry & mask
328 LDRB r2, [r4, r2] @ r2 = v = q->val[entry & mask]
329 MOV r8, r8, LSR r1 @ r8 = entry>>q_pack
330 MLA r2, r12,r2, r14 @ r2 = (add+mul*v)
331 SUBS r3, r3, #1
332 ADD r2, r11,r2, ASR r5 @ r2 = v = prev+(add+mul*v)>>shiftM
333 AND r11,r2, r7 @ r11= prev = seqMask & v
334 STR r2, [r6], #4 @ *v++ = v
335 BGT dm2_loop
336 MOV r0, #0
337 LDMFD r13!,{r4-r11,PC}
338
339dm2_hword:
340 AND r2, r8, r0 @ r2 = entry & mask
341 MOV r2, r2, LSL #1 @ r2 = 2*r2
342 LDRH r2, [r4, r2] @ r2 = v = q->val[entry & mask]
343 MOV r8, r8, LSR r1 @ r8 = entry>>q_pack
344 MLA r2, r12,r2, r14 @ r2 = (add+mul*v)
345 SUBS r3, r3, #1
346 ADD r2, r11,r2, ASR r5 @ r2 = v = prev+(add+mul*v)>>shiftM
347 AND r11,r2, r7 @ r11= prev = seqMask & v
348 STR r2, [r6], #4 @ *v++ = v
349 BGT dm2_hword
350 MOV r0, #0
351 LDMFD r13!,{r4-r11,PC}
352
353dm3:
354 @ r1 = s->dec_type
355 @ r2 = s->q_bits
356 @ r3 = s->dim
357 @ r4 = s
358 @ r5 = shiftM
359 @ r6 = v
360 @ r7 = seqMask
361 @ r8 = entry
362 @ r12= mul
363 @ r14= add
364 LDR r1, [r4,#44] @ r1 = s->q_pack
Marco Nelissen77366312016-10-21 09:41:00 -0700365 LDR r4, [r4,#48] @ r4 = s->q_val
Gloria Wang79130732010-02-08 14:41:04 -0800366 CMP r2,#8
367 MOV r11,#0 @ r11= prev
368 MLA r4,r1,r8,r4 @ r4 = ptr = s->q_val+entry*s->q_pack
369
370 BGT dm3_hword
371dm3_loop:
372 LDRB r2, [r4], #1 @ r2 = v = *ptr++
373 SUBS r3, r3, #1
374 MLA r2, r12,r2, r14 @ r2 = (add+mul*v)
375 ADD r2, r11,r2, ASR r5 @ r2 = v = prev+(add+mul*v)>>shiftM
376 AND r11,r2, r7 @ r11= prev = seqMask & v
377 STR r2, [r6], #4 @ *v++ = v
378 BGT dm3_loop
379 MOV r0, #0
380 LDMFD r13!,{r4-r11,PC}
381
382dm3_hword:
383 LDRH r2, [r4], #2 @ r2 = *ptr++
384 SUBS r3, r3, #1
385 MLA r2, r12,r2, r14 @ r2 = (add+mul*v)
386 ADD r2, r11,r2, ASR r5 @ r2 = v = prev+(add+mul*v)>>shiftM
387 AND r11,r2, r7 @ r11= prev = seqMask & v
388 STR r2, [r6], #4 @ *v++ = v
389 BGT dm3_hword
390 MOV r0, #0
391 LDMFD r13!,{r4-r11,PC}
392
393dm_duff:
394 MVN r0,#0
395 LDMFD r13!,{r4-r11,PC}
396
397vorbis_book_decodevv_add:
398 @ r0 = codebook *book
399 @ r1 = ogg_int32_t **a
400 @ r2 = long offset
401 @ r3 = int ch
402 @ <> = b
403 @ <> = n
404 @ <> = point
405 STMFD r13!,{r4-r11,R14}
406 LDR r7, [r0, #13*4] @ r7 = used_entries
407 MOV r9, r0 @ r9 = book
408 MOV r10,r1 @ r10= 0xa[chptr] chptr=0
409 MOV r6, r3 @ r6 = ch
410 ADD r8, r10,r3, LSL #2 @ r8 = 0xa[ch]
411 MOV r11,r2 @ r11= offset
412 CMP r7, #0 @ if (used_entries <= 0)
413 BLE vbdvva_exit @ exit
414 LDR r5, [r13,#10*4] @ r5 = n
415vbdvva_loop1:
416 @ r5 = n
417 @ r6 = ch
418 @ r8 = 0xa[ch]
419 @ r9 = book
420 @ r10= 0xa[chptr]
421 @ r11= offset
422 MOV r0, r9 @ r0 = book
423 LDR r1, [r13,# 9*4] @ r1 = b
424 LDR r2, [r9, #14*4] @ r2 = v = dec_buf
425 LDR r3, [r13,#11*4] @ r3 = point
426 BL decode_map
427 CMP r0, #0
428 BNE vbdvva_fail
429
430 LDR r0, [r9, # 5*4] @ r0 = book->dim
431 LDR r1, [r9, #14*4] @ r1 = v = dec_buf
432vbdvva_loop2:
Marco Nelissenc7387942017-07-17 15:54:28 -0700433 CMP r5,#0
434 BLE vbdvva_exit
Gloria Wang79130732010-02-08 14:41:04 -0800435 LDR r2, [r10],#4 @ r2 = a[chptr++]
436 LDR r12,[r1], #4 @ r1 = v[j++]
437 CMP r10,r8 @ if (chptr == ch)
438 SUBEQ r10,r10,r6, LSL #2 @ chptr = 0
439 LDR r14,[r2, r11,LSL #2]! @ r2 = 0xa[chptr++][i] r14=[r12]
440 ADDEQ r11,r11,#1 @ i++
441 SUBEQ r5, r5, #1 @ n--
442 SUBS r0, r0, #1 @ r0--
443 ADD r12,r12,r14 @ r12= a[chptr++][i]+ v[j]
444 STR r12,[r2] @ r12= a[chptr++][i]+=v[j]
445 BGT vbdvva_loop2
446 CMP r5,#0
447 BGT vbdvva_loop1
448vbdvva_exit:
449 MOV r0, #0 @ return 0
450 LDMFD r13!,{r4-r11,PC}
451vbdvva_fail:
452 MVN r0, #0 @ return -1
453 LDMFD r13!,{r4-r11,PC}
454
455_checksum:
456 @ r0 = ogg_reference *or
457 @ r1 = bytes
458 STMFD r13!,{r5-r6,r14}
459
Ard Biesheuvele96d4492012-08-11 23:47:34 +0200460 ADR r6,.Lcrc_lookup
461 LDR r5,[r6]
462 ADD r5,r6
Gloria Wang79130732010-02-08 14:41:04 -0800463 MOV r14,#0 @ r14= crc_reg = 0
464 MOVS r12,r0
465 BEQ _cs_end
466_cs_loop1:
467 LDMIA r12,{r0,r2,r3,r12} @ r0 = or->buffer
468 @ r2 = or->begin
469 @ r3 = or->length
470 @ r12= or->next
471 LDR r0,[r0] @ r0 = or->buffer->data
472 CMP r1,r3 @ r3 = post = (bytes < or->length ?
473 MOVLT r3,r1 @ bytes : or->length)
474 MOVS r6,r3 @ r6 = j = post
475 BEQ _cs_no_bytes
476 ADD r0,r0,r2 @ r0 = or->buffer->data + or->begin
477_cs_loop2:
478 LDRB r2, [r0],#1 @ r2 = data[j]
479 @ stall
480 @ stall Xscale
481 EOR r2, r2, r14,LSR #24 @ r2 = (crc_reg>>24)^data[j]
482 LDR r2, [r5, r2, LSL #2] @ r2 = crc_lkp[(crc_reg>>24)^data[j]]
483 SUBS r6, r6, #1 @ j--
484 @ stall Xscale
485 EOR r14,r2, r14,LSL #8 @ r14= crc_reg = (crc_reg<<8)^r2
486 BGT _cs_loop2
487_cs_no_bytes:
488 SUBS r1, r1, r3
489 CMPNE r12,#0
490 BNE _cs_loop1
491_cs_end:
492 MOV r0,r14
493 LDMFD r13!,{r5-r6,PC}
494
Ard Biesheuvele96d4492012-08-11 23:47:34 +0200495.Lcrc_lookup:
496 .WORD crc_lookup-.Lcrc_lookup
497
Gloria Wang79130732010-02-08 14:41:04 -0800498 @ END