1@ Tremolo library 2@----------------------------------------------------------------------- 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@ ---------------------------------------------------------------------- 34 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 .type decode_packed_entry_number, %function 44 .type decode_packed_entry_number_REALSTART, %function 45 .type decode_map, %function 46 .type vorbis_book_decodevv_add, %function 47 .type _checksum, %function 48 49 .extern oggpack_adv 50 .extern oggpack_look 51 .extern oggpack_eop 52 .extern crc_lookup 53 .hidden crc_lookup 54 55decode_packed_entry_number_REALSTART: 56dpen_nobits: 57 MOV r0,r5 @ r0 = b 58 MOV r1,#1 @ r1 = 1 59 BL oggpack_adv @ oggpack_adv(b,1) /* Force eop */ 60duff: 61 MVN r0,#0 @ return -1 62 LDMFD r13!,{r4-r8,r10,PC} 63 64dpen_readfailed: 65 SUBS r4,r4,#1 @ r4 = --read 66 BEQ dpen_nobits 67 MOV r0,r5 @ r0 = b 68 MOV r1,r4 @ r1 = read 69 ADR r14,dpen_read_return 70 B oggpack_look 71 72decode_packed_entry_number: 73 @ r0 = codebook *book 74 @ r1 = oggpack_buffer *b 75 STMFD r13!,{r4-r8,r10,r14} 76 77 LDMIA r0,{r4,r6,r7} @ r4 = read = book->max_length 78 @ r6 = book->dec_table 79 @ r7 = book->dec_method 80 MOV r5,r1 @ r5 = b 81 82 MOV r0,r5 @ r0 = b 83 MOV r1,r4 @ r1 = read 84 BL oggpack_look 85dpen_read_return: 86 CMP r0,#0 87 BLT dpen_readfailed 88 89 @ r0 = lok 90 @ r4 = read 91 @ r5 = b 92 @ r6 = dec_table 93 @ r7 = dec_method 94 95 CMP r7, #3 96 BGT meth4 97 BEQ meth3 98 CMP r7, #1 99 BGT meth2 100 BEQ meth1 101meth0: 102 RSB r1, r4, #0 @ r1 = i-read = 0-read 103 MOV r7, #0 @ r7 = chase 104m0_loop: 105 MOVS r0, r0, LSR #1 @ r0 = lok>>1 C = bottom bit 106 ADC r2, r6, r7, LSL #1 @ r8 = &t[chase*2+C] 107 LDRB r7, [r2] 108 ADDS r1, r1, #1 @ r1 = i-read++ (i-read<0 => i<read) 109 @ stall Xscale 110 CMPLT r7, #0x80 111 BLT m0_loop 112 AND r7, r7, #0x7F @ r7 = chase 113 CMP r1, #0 @ if (i-read >= 0) === (i >= read) 114 MVNGT r7, #0 @ if (i >= read) value to return = -1 115 ADD r1, r1, r4 @ r1 = i-read+read+1 = i +1 116 MOV r0, r5 @ r0 = b 117 BL oggpack_adv @ oggpack_adv(b, i+1); 118 MOV r0, r7 @ return chase 119 LDMFD r13!,{r4-r8,r10,PC} 120 121meth1: 122 @ r0 = lok 123 @ r4 = read 124 @ r5 = b 125 @ r6 = dec_table 126 RSB r1, r4, #0 @ r1 = i = -read 127 MOV r10,#0 @ r10= next = 0 128m1_loop: 129 MOV r7, r10 @ r7 = chase=next 130 MOVS r0, r0, LSR #1 @ r0 = lok>>1 C = bottom bit 131 ADC r8, r6, r7 @ r8 = t+chase+bit 132 LDRB r10,[r8], -r6 @ r10= next=t[chase+bit] r8=chase+bit 133 ADDS r1, r1, #1 @ r1 = i++ 134 @ stall Xscale 135 CMPLT r10,#0x80 @ if (next & 0x80) == 0 136 BLT m1_loop 137 138 ADD r1, r1, r4 @ r1 = i+read 139 MOV r0, r5 @ r0 = b 140 BL oggpack_adv @ oggpack_adv(b, i) 141 142 CMP r10,#0x80 143 BLT duff 144 145 CMP r8, r7 @ if bit==0 (chase+bit==chase) (sets C) 146 LDRBNE r14,[r6, r7] @ r14= t[chase] 147 MOVEQ r14,#128 148 ADC r12,r8, r6 @ r12= chase+bit+1+t 149 LDRB r14,[r12,r14,LSR #7] @ r14= t[chase+bit+1+(!bit || t[chase]0x0x80)] 150 BIC r10,r10,#0x80 @ r3 = next &= ~0x80 151 @ stall Xscale 152 ORR r0, r14,r10,LSL #8 @ r7 = chase = (next<<8) | r14 153 154 LDMFD r13!,{r4-r8,r10,PC} 155 156 157meth2: 158 RSB r1, r4, #0 @ r1 = i-read = 0-read 159 MOV r7, #0 @ r7 = chase 160 MOV r6, r6, LSR #1 161m2_loop: 162 MOVS r0, r0, LSR #1 @ r0 = lok>>1 C = bottom bit 163 ADC r2, r6, r7, LSL #1 @ r8 = &t[chase*2+C] 164 LDRH r7, [r2, r2] 165 ADDS r1, r1, #1 @ r1 = i-read++ (i-read<0 => i<read) 166 @ stall Xscale 167 CMPLT r7, #0x8000 168 BLT m2_loop 169 BIC r7, r7, #0x8000 @ r7 = chase 170 CMP r1, #0 @ if (i-read >= 0) === (i >= read) 171 MVNGT r7, #0 @ if (i >= read) value to return = -1 172 ADD r1, r1, r4 @ r1 = i-read+read+1 = i +1 173 MOV r0, r5 @ r0 = b 174 BL oggpack_adv @ oggpack_adv(b, i+1); 175 MOV r0, r7 @ return chase 176 LDMFD r13!,{r4-r8,r10,PC} 177 178meth3: 179 @ r0 = lok 180 @ r4 = read 181 @ r5 = b 182 @ r6 = dec_table 183 RSB r1, r4, #0 @ r1 = i = -read 184 MOV r10,#0 @ r10= next = 0 185m3_loop: 186 MOV r7, r10 @ r7 = chase=next 187 MOVS r0, r0, LSR #1 @ r0 = lok>>1 C = bottom bit 188 ADC r8, r7, #0 @ r8 = chase+bit 189 MOV r8, r8, LSL #1 @ r8 = (chase+bit)<<1 190 LDRH r10,[r6, r8] @ r10= next=t[chase+bit] 191 ADDS r1, r1, #1 @ r1 = i++ 192 @ stall Xscale 193 CMPLT r10,#0x8000 @ if (next & 0x8000) == 0 194 BLT m3_loop 195 196 ADD r1, r1, r4 @ r1 = i+read 197 MOV r0, r5 @ r0 = b 198 BL oggpack_adv @ oggpack_adv(b, i) 199 200 CMP r10,#0x8000 201 BLT duff 202 203 MOV r7, r7, LSL #1 204 CMP r8, r7 @ if bit==0 (chase+bit==chase) sets C 205 LDRHNE r14,[r6, r7] @ r14= t[chase] 206 MOVEQ r14,#0x8000 207 ADC r12,r8, r14,LSR #15 @ r12= 1+((chase+bit)<<1)+(!bit || t[chase]0x0x8000) 208 ADC r12,r12,r14,LSR #15 @ r12= t + (1+chase+bit+(!bit || t[chase]0x0x8000))<<1 209 LDRH r14,[r6, r12] @ r14= t[chase+bit+1 210 BIC r10,r10,#0x8000 @ r3 = next &= ~0x8000 211 @ stall Xscale 212 ORR r0, r14,r10,LSL #16 @ r7 = chase = (next<<16) | r14 213 214 LDMFD r13!,{r4-r8,r10,PC} 215 216meth4: 217 RSB r1, r4, #0 @ r1 = i-read = 0-read 218 MOV r7, #0 @ r7 = chase 219m4_loop: 220 MOVS r0, r0, LSR #1 @ r0 = lok>>1 C = bottom bit 221 ADC r2, r7, r7 @ r8 = chase*2+C 222 LDR r7, [r6, r2, LSL #2] 223 ADDS r1, r1, #1 @ r1 = i-read++ (i-read<0 => i<read) 224 @ stall Xscale 225 CMPLT r7, #0x80000000 226 BLT m4_loop 227 BIC r7, r7, #0x80000000 @ r7 = chase 228 CMP r1, #0 @ if (i-read >= 0) === (i >= read) 229 MVNGT r7, #0 @ if (i >= read) value to return = -1 230 ADD r1, r1, r4 @ r1 = i-read+read+1 = i +1 231 MOV r0, r5 @ r0 = b 232 BL oggpack_adv @ oggpack_adv(b, i+1); 233 MOV r0, r7 @ return chase 234 LDMFD r13!,{r4-r8,r10,PC} 235 236decode_map: 237 @ r0 = codebook *s 238 @ r1 = oggpack_buffer *b 239 @ r2 = int v 240 @ r3 = int point 241 STMFD r13!,{r4-r11,r14} 242 243 MOV r4, r0 @ r4 = s 244 MOV r5, r1 @ r5 = b 245 MOV r6, r2 @ r6 = v 246 MOV r7, r3 @ r7 = point 247 BL decode_packed_entry_number 248 MOV r8, r0 249 250 MOV r0, r5 251 BL oggpack_eop 252 CMP r0, #0 253 BNE dm_duff 254 255 @ r4 = s 256 @ r5 = b 257 @ r6 = v 258 @ r7 = point 259 @ r8 = entry 260 261 LDR r1, [r4,#12] @ r1 = s->dec_type 262 LDR r2, [r4,#16] @ r2 = s->q_bits 263 LDR r3, [r4,#20] @ r3 = s->dim 264 LDR r5, [r4,#24] @ r5 = s->q_delp 265 LDR r11,[r4,#28] @ r11= s->q_minp 266 LDR r12,[r4,#32] @ r12= s->q_del = mul 267 LDR r14,[r4,#36] @ r14= s->q_min 268 SUBS r11,r7, r11 @ r11= add = point - s->q_minp 269 270 MOVGT r14,r14,ASR r11 @ r14= add = s->q_min >> add (if add >0) 271 RSBLT r11,r11,#0 272 MOVLT r14,r14,LSL r11 @ r14= add = s->q_min << -add (if add < 0) 273 274 SUBS r5, r7, r5 @ r5 = shiftM = point - s->q_delp 275 LDR r7, [r4,#40] @ r7 = s->q_seq 276 RSBLT r5, r5, #0 @ if (shiftM<0) r5 =-shiftM 277 MOVLT r12,r12,LSL r5 @ r12=mul<<-shiftM 278 MOVLT r5, #0 @ r5 =shiftM = 0 279 MOVGT r14,r14,LSL r5 @ add <<= shiftM 280 281 CMP r7,#0 @ seqMask = (s->q_seq?-1:0) 282 MVNNE r7,#0 283 284 CMP r1, #2 285 BEQ dm2 286 BGT dm3 287 CMP r1,#0 @ probably never happens 288 BLE dm_duff 289dm1: 290 @ r1 = s->dec_type 291 @ r2 = s->q_bits 292 @ r3 = s->dim 293 @ r5 = shiftM 294 @ r6 = v 295 @ r7 = seqMask 296 @ r8 = entry 297 @ r12= mul 298 @ r14= add 299 MOV r0, #1 300 RSB r0, r0, r0, LSL r2 @ r0 = mask = (1<<s->q_bits)-1 301 MOV r11,#0 @ r11= prev = 0 302dm1_loop: 303 AND r1, r8, r0 @ r1 = v = entry & mask 304 MLA r1, r12, r1, r14 @ r1 = (add + mul*v) 305 MOV r8, r8, LSR r2 @ r8 = entry>>s->q_bits 306 SUBS r3, r3, #1 307 ADD r1, r11,r1, ASR r5 @ r1 = v = prev+((add+mul*v)>>shiftM) 308 AND r11,r1, r7 @ r11= prev = seqMask & v 309 STR r1, [r6], #4 @ *v++ = v 310 BGT dm1_loop 311 312 MOV r0, #0 313 LDMFD r13!,{r4-r11,PC} 314dm2: 315 @ r1 = s->dec_type 316 @ r2 = s->q_bits 317 @ r3 = s->dim 318 @ r4 = s 319 @ r5 = shiftM 320 @ r6 = v 321 @ r7 = seqMask 322 @ r8 = entry 323 @ r12= mul 324 @ r14= add 325 LDR r1, [r4,#44] @ r1 = s->q_pack 326 LDR r4, [r4,#48] @ r4 = s->q_val 327 MOV r11,#0 @ r11= prev 328 MOV r0, #1 329 RSB r0, r0, r0, LSL r1 @ r8 = mask = (1<<s->q_pack)-1 330 CMP r2,#8 331 BGT dm2_hword 332dm2_loop: 333 AND r2, r8, r0 @ r2 = entry & mask 334 LDRB r2, [r4, r2] @ r2 = v = q->val[entry & mask] 335 MOV r8, r8, LSR r1 @ r8 = entry>>q_pack 336 MLA r2, r12,r2, r14 @ r2 = (add+mul*v) 337 SUBS r3, r3, #1 338 ADD r2, r11,r2, ASR r5 @ r2 = v = prev+(add+mul*v)>>shiftM 339 AND r11,r2, r7 @ r11= prev = seqMask & v 340 STR r2, [r6], #4 @ *v++ = v 341 BGT dm2_loop 342 MOV r0, #0 343 LDMFD r13!,{r4-r11,PC} 344 345dm2_hword: 346 AND r2, r8, r0 @ r2 = entry & mask 347 MOV r2, r2, LSL #1 @ r2 = 2*r2 348 LDRH r2, [r4, r2] @ r2 = v = q->val[entry & mask] 349 MOV r8, r8, LSR r1 @ r8 = entry>>q_pack 350 MLA r2, r12,r2, r14 @ r2 = (add+mul*v) 351 SUBS r3, r3, #1 352 ADD r2, r11,r2, ASR r5 @ r2 = v = prev+(add+mul*v)>>shiftM 353 AND r11,r2, r7 @ r11= prev = seqMask & v 354 STR r2, [r6], #4 @ *v++ = v 355 BGT dm2_hword 356 MOV r0, #0 357 LDMFD r13!,{r4-r11,PC} 358 359dm3: 360 @ r1 = s->dec_type 361 @ r2 = s->q_bits 362 @ r3 = s->dim 363 @ r4 = s 364 @ r5 = shiftM 365 @ r6 = v 366 @ r7 = seqMask 367 @ r8 = entry 368 @ r12= mul 369 @ r14= add 370 LDR r1, [r4,#44] @ r1 = s->q_pack 371 LDR r4, [r4,#48] @ r4 = s->q_val 372 CMP r2,#8 373 MOV r11,#0 @ r11= prev 374 MLA r4,r1,r8,r4 @ r4 = ptr = s->q_val+entry*s->q_pack 375 376 BGT dm3_hword 377dm3_loop: 378 LDRB r2, [r4], #1 @ r2 = v = *ptr++ 379 SUBS r3, r3, #1 380 MLA r2, r12,r2, r14 @ r2 = (add+mul*v) 381 ADD r2, r11,r2, ASR r5 @ r2 = v = prev+(add+mul*v)>>shiftM 382 AND r11,r2, r7 @ r11= prev = seqMask & v 383 STR r2, [r6], #4 @ *v++ = v 384 BGT dm3_loop 385 MOV r0, #0 386 LDMFD r13!,{r4-r11,PC} 387 388dm3_hword: 389 LDRH r2, [r4], #2 @ r2 = *ptr++ 390 SUBS r3, r3, #1 391 MLA r2, r12,r2, r14 @ r2 = (add+mul*v) 392 ADD r2, r11,r2, ASR r5 @ r2 = v = prev+(add+mul*v)>>shiftM 393 AND r11,r2, r7 @ r11= prev = seqMask & v 394 STR r2, [r6], #4 @ *v++ = v 395 BGT dm3_hword 396 MOV r0, #0 397 LDMFD r13!,{r4-r11,PC} 398 399dm_duff: 400 MVN r0,#0 401 LDMFD r13!,{r4-r11,PC} 402 403vorbis_book_decodevv_add: 404 @ r0 = codebook *book 405 @ r1 = ogg_int32_t **a 406 @ r2 = long offset 407 @ r3 = int ch 408 @ <> = b 409 @ <> = n 410 @ <> = point 411 STMFD r13!,{r4-r11,R14} 412 LDR r7, [r0, #13*4] @ r7 = used_entries 413 MOV r9, r0 @ r9 = book 414 MOV r10,r1 @ r10= 0xa[chptr] chptr=0 415 MOV r6, r3 @ r6 = ch 416 ADD r8, r10,r3, LSL #2 @ r8 = 0xa[ch] 417 MOV r11,r2 @ r11= offset 418 CMP r7, #0 @ if (used_entries <= 0) 419 BLE vbdvva_exit @ exit 420 LDR r5, [r13,#10*4] @ r5 = n 421vbdvva_loop1: 422 @ r5 = n 423 @ r6 = ch 424 @ r8 = 0xa[ch] 425 @ r9 = book 426 @ r10= 0xa[chptr] 427 @ r11= offset 428 MOV r0, r9 @ r0 = book 429 LDR r1, [r13,# 9*4] @ r1 = b 430 LDR r2, [r9, #14*4] @ r2 = v = dec_buf 431 LDR r3, [r13,#11*4] @ r3 = point 432 BL decode_map 433 CMP r0, #0 434 BNE vbdvva_fail 435 436 LDR r0, [r9, # 5*4] @ r0 = book->dim 437 LDR r1, [r9, #14*4] @ r1 = v = dec_buf 438vbdvva_loop2: 439 CMP r5,#0 440 BLE vbdvva_exit 441 LDR r2, [r10],#4 @ r2 = a[chptr++] 442 LDR r12,[r1], #4 @ r1 = v[j++] 443 CMP r10,r8 @ if (chptr == ch) 444 SUBEQ r10,r10,r6, LSL #2 @ chptr = 0 445 LDR r14,[r2, r11,LSL #2]! @ r2 = 0xa[chptr++][i] r14=[r12] 446 ADDEQ r11,r11,#1 @ i++ 447 SUBEQ r5, r5, #1 @ n-- 448 SUBS r0, r0, #1 @ r0-- 449 ADD r12,r12,r14 @ r12= a[chptr++][i]+ v[j] 450 STR r12,[r2] @ r12= a[chptr++][i]+=v[j] 451 BGT vbdvva_loop2 452 CMP r5,#0 453 BGT vbdvva_loop1 454vbdvva_exit: 455 MOV r0, #0 @ return 0 456 LDMFD r13!,{r4-r11,PC} 457vbdvva_fail: 458 MVN r0, #0 @ return -1 459 LDMFD r13!,{r4-r11,PC} 460 461_checksum: 462 @ r0 = ogg_reference *or 463 @ r1 = bytes 464 STMFD r13!,{r5-r6,r14} 465 466 ADR r6,.Lcrc_lookup 467 LDR r5,[r6] 468 ADD r5,r6 469 MOV r14,#0 @ r14= crc_reg = 0 470 MOVS r12,r0 471 BEQ _cs_end 472_cs_loop1: 473 LDMIA r12,{r0,r2,r3,r12} @ r0 = or->buffer 474 @ r2 = or->begin 475 @ r3 = or->length 476 @ r12= or->next 477 LDR r0,[r0] @ r0 = or->buffer->data 478 CMP r1,r3 @ r3 = post = (bytes < or->length ? 479 MOVLT r3,r1 @ bytes : or->length) 480 MOVS r6,r3 @ r6 = j = post 481 BEQ _cs_no_bytes 482 ADD r0,r0,r2 @ r0 = or->buffer->data + or->begin 483_cs_loop2: 484 LDRB r2, [r0],#1 @ r2 = data[j] 485 @ stall 486 @ stall Xscale 487 EOR r2, r2, r14,LSR #24 @ r2 = (crc_reg>>24)^data[j] 488 LDR r2, [r5, r2, LSL #2] @ r2 = crc_lkp[(crc_reg>>24)^data[j]] 489 SUBS r6, r6, #1 @ j-- 490 @ stall Xscale 491 EOR r14,r2, r14,LSL #8 @ r14= crc_reg = (crc_reg<<8)^r2 492 BGT _cs_loop2 493_cs_no_bytes: 494 SUBS r1, r1, r3 495 CMPNE r12,#0 496 BNE _cs_loop1 497_cs_end: 498 MOV r0,r14 499 LDMFD r13!,{r5-r6,PC} 500 501.Lcrc_lookup: 502 .WORD crc_lookup-.Lcrc_lookup 503 504 @ END 505