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