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 .hidden crc_lookup 48 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 365 LDR r4, [r4,#52] @ r4 = s->q_val 366 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: 433 LDR r2, [r10],#4 @ r2 = a[chptr++] 434 LDR r12,[r1], #4 @ r1 = v[j++] 435 CMP r10,r8 @ if (chptr == ch) 436 SUBEQ r10,r10,r6, LSL #2 @ chptr = 0 437 LDR r14,[r2, r11,LSL #2]! @ r2 = 0xa[chptr++][i] r14=[r12] 438 ADDEQ r11,r11,#1 @ i++ 439 SUBEQ r5, r5, #1 @ n-- 440 SUBS r0, r0, #1 @ r0-- 441 ADD r12,r12,r14 @ r12= a[chptr++][i]+ v[j] 442 STR r12,[r2] @ r12= a[chptr++][i]+=v[j] 443 BGT vbdvva_loop2 444 CMP r5,#0 445 BGT vbdvva_loop1 446vbdvva_exit: 447 MOV r0, #0 @ return 0 448 LDMFD r13!,{r4-r11,PC} 449vbdvva_fail: 450 MVN r0, #0 @ return -1 451 LDMFD r13!,{r4-r11,PC} 452 453_checksum: 454 @ r0 = ogg_reference *or 455 @ r1 = bytes 456 STMFD r13!,{r5-r6,r14} 457 458 ADR r6,.Lcrc_lookup 459 LDR r5,[r6] 460 ADD r5,r6 461 MOV r14,#0 @ r14= crc_reg = 0 462 MOVS r12,r0 463 BEQ _cs_end 464_cs_loop1: 465 LDMIA r12,{r0,r2,r3,r12} @ r0 = or->buffer 466 @ r2 = or->begin 467 @ r3 = or->length 468 @ r12= or->next 469 LDR r0,[r0] @ r0 = or->buffer->data 470 CMP r1,r3 @ r3 = post = (bytes < or->length ? 471 MOVLT r3,r1 @ bytes : or->length) 472 MOVS r6,r3 @ r6 = j = post 473 BEQ _cs_no_bytes 474 ADD r0,r0,r2 @ r0 = or->buffer->data + or->begin 475_cs_loop2: 476 LDRB r2, [r0],#1 @ r2 = data[j] 477 @ stall 478 @ stall Xscale 479 EOR r2, r2, r14,LSR #24 @ r2 = (crc_reg>>24)^data[j] 480 LDR r2, [r5, r2, LSL #2] @ r2 = crc_lkp[(crc_reg>>24)^data[j]] 481 SUBS r6, r6, #1 @ j-- 482 @ stall Xscale 483 EOR r14,r2, r14,LSL #8 @ r14= crc_reg = (crc_reg<<8)^r2 484 BGT _cs_loop2 485_cs_no_bytes: 486 SUBS r1, r1, r3 487 CMPNE r12,#0 488 BNE _cs_loop1 489_cs_end: 490 MOV r0,r14 491 LDMFD r13!,{r5-r6,PC} 492 493.Lcrc_lookup: 494 .WORD crc_lookup-.Lcrc_lookup 495 496 @ END 497