; Tremolo library ; Copyright (C) 2009 Robin Watts for Pinknoise Productions Ltd AREA |.text|, CODE, READONLY EXPORT decode_packed_entry_number EXPORT decode_packed_entry_number_REALSTART EXPORT decode_map EXPORT vorbis_book_decodevv_add EXPORT _checksum IMPORT oggpack_adv IMPORT oggpack_look IMPORT oggpack_eop IMPORT crc_lookup decode_packed_entry_number_REALSTART dpen_nobits MOV r0,r5 ; r0 = b MOV r1,#1 ; r1 = 1 BL oggpack_adv ; oggpack_adv(b,1) /* Force eop */ duff MVN r0,#0 ; return -1 LDMFD r13!,{r4-r8,r10,PC} dpen_readfailed SUBS r4,r4,#1 ; r4 = --read BEQ dpen_nobits MOV r0,r5 ; r0 = b MOV r1,r4 ; r1 = read ADR r14,dpen_read_return B oggpack_look decode_packed_entry_number ; r0 = codebook *book ; r1 = oggpack_buffer *b STMFD r13!,{r4-r8,r10,r14} LDMIA r0,{r4,r6,r7} ; r4 = read = book->max_length ; r6 = book->dec_table ; r7 = book->dec_method MOV r5,r1 ; r5 = b MOV r0,r5 ; r0 = b MOV r1,r4 ; r1 = read BL oggpack_look dpen_read_return CMP r0,#0 BLT dpen_readfailed ; r0 = lok ; r4 = read ; r5 = b ; r6 = dec_table ; r7 = dec_method CMP r7, #3 BGT meth4 BEQ meth3 CMP r7, #1 BGT meth2 BEQ meth1 meth0 RSB r1, r4, #0 ; r1 = i-read = 0-read MOV r7, #0 ; r7 = chase m0_loop MOVS r0, r0, LSR #1 ; r0 = lok>>1 C = bottom bit ADC r2, r6, r7, LSL #1 ; r8 = &t[chase*2+C] LDRB r7, [r2] ADDS r1, r1, #1 ; r1 = i-read++ (i-read<0 => i= 0) === (i >= read) MVNGT r7, #0 ; if (i >= read) value to return = -1 ADD r1, r1, r4 ; r1 = i-read+read+1 = i +1 MOV r0, r5 ; r0 = b BL oggpack_adv ; oggpack_adv(b, i+1); MOV r0, r7 ; return chase LDMFD r13!,{r4-r8,r10,PC} meth1 ; r0 = lok ; r4 = read ; r5 = b ; r6 = dec_table RSB r1, r4, #0 ; r1 = i = -read MOV r10,#0 ; r10= next = 0 m1_loop MOV r7, r10 ; r7 = chase=next MOVS r0, r0, LSR #1 ; r0 = lok>>1 C = bottom bit ADC r8, r6, r7 ; r8 = t+chase+bit LDRB r10,[r8], -r6 ; r10= next=t[chase+bit] r8=chase+bit ADDS r1, r1, #1 ; r1 = i++ ; stall Xscale CMPLT r10,#0x80 ; if (next & 0x80) == 0 BLT m1_loop ADD r1, r1, r4 ; r1 = i+read MOV r0, r5 ; r0 = b BL oggpack_adv ; oggpack_adv(b, i) CMP r10,#0x80 BLT duff CMP r8, r7 ; if bit==0 (chase+bit==chase) (sets C) LDRNEB r14,[r6, r7] ; r14= t[chase] MOVEQ r14,#128 ADC r12,r8, r6 ; r12= chase+bit+1+t LDRB r14,[r12,r14,LSR #7] ; r14= t[chase+bit+1+(!bit || t[chase]&0x80)] BIC r10,r10,#0x80 ; r3 = next &= ~0x80 ; stall Xscale ORR r0, r14,r10,LSL #8 ; r7 = chase = (next<<8) | r14 LDMFD r13!,{r4-r8,r10,PC} meth2 RSB r1, r4, #0 ; r1 = i-read = 0-read MOV r7, #0 ; r7 = chase MOV r6, r6, LSR #1 m2_loop MOVS r0, r0, LSR #1 ; r0 = lok>>1 C = bottom bit ADC r2, r6, r7, LSL #1 ; r8 = &t[chase*2+C] LDRH r7, [r2, r2] ADDS r1, r1, #1 ; r1 = i-read++ (i-read<0 => i= 0) === (i >= read) MVNGT r7, #0 ; if (i >= read) value to return = -1 ADD r1, r1, r4 ; r1 = i-read+read+1 = i +1 MOV r0, r5 ; r0 = b BL oggpack_adv ; oggpack_adv(b, i+1); MOV r0, r7 ; return chase LDMFD r13!,{r4-r8,r10,PC} meth3 ; r0 = lok ; r4 = read ; r5 = b ; r6 = dec_table RSB r1, r4, #0 ; r1 = i = -read MOV r10,#0 ; r10= next = 0 m3_loop MOV r7, r10 ; r7 = chase=next MOVS r0, r0, LSR #1 ; r0 = lok>>1 C = bottom bit ADC r8, r7, #0 ; r8 = chase+bit MOV r8, r8, LSL #1 ; r8 = (chase+bit)<<1 LDRH r10,[r6, r8] ; r10= next=t[chase+bit] ADDS r1, r1, #1 ; r1 = i++ ; stall Xscale CMPLT r10,#0x8000 ; if (next & 0x8000) == 0 BLT m3_loop ADD r1, r1, r4 ; r1 = i+read MOV r0, r5 ; r0 = b BL oggpack_adv ; oggpack_adv(b, i) CMP r10,#0x8000 BLT duff MOV r7, r7, LSL #1 CMP r8, r7 ; if bit==0 (chase+bit==chase) sets C LDRNEH r14,[r6, r7] ; r14= t[chase] MOVEQ r14,#0x8000 ADC r12,r8, r14,LSR #15 ; r12= 1+((chase+bit)<<1)+(!bit || t[chase]&0x8000) ADC r12,r12,r14,LSR #15 ; r12= t + (1+chase+bit+(!bit || t[chase]&0x8000))<<1 LDRH r14,[r6, r12] ; r14= t[chase+bit+1 BIC r10,r10,#0x8000 ; r3 = next &= ~0x8000 ; stall Xscale ORR r0, r14,r10,LSL #16 ; r7 = chase = (next<<16) | r14 LDMFD r13!,{r4-r8,r10,PC} meth4 RSB r1, r4, #0 ; r1 = i-read = 0-read MOV r7, #0 ; r7 = chase m4_loop MOVS r0, r0, LSR #1 ; r0 = lok>>1 C = bottom bit ADC r2, r7, r7 ; r8 = chase*2+C LDR r7, [r6, r2, LSL #2] ADDS r1, r1, #1 ; r1 = i-read++ (i-read<0 => i= 0) === (i >= read) MVNGT r7, #0 ; if (i >= read) value to return = -1 ADD r1, r1, r4 ; r1 = i-read+read+1 = i +1 MOV r0, r5 ; r0 = b BL oggpack_adv ; oggpack_adv(b, i+1); MOV r0, r7 ; return chase LDMFD r13!,{r4-r8,r10,PC} decode_map ; r0 = codebook *s ; r1 = oggpack_buffer *b ; r2 = int v ; r3 = int point STMFD r13!,{r4-r11,r14} MOV r4, r0 ; r4 = s MOV r5, r1 ; r5 = b MOV r6, r2 ; r6 = v MOV r7, r3 ; r7 = point BL decode_packed_entry_number MOV r8, r0 MOV r0, r5 BL oggpack_eop CMP r0, #0 BNE dm_duff ; r4 = s ; r5 = b ; r6 = v ; r7 = point ; r8 = entry LDR r1, [r4,#12] ; r1 = s->dec_type LDR r2, [r4,#16] ; r2 = s->q_bits LDR r3, [r4,#20] ; r3 = s->dim LDR r5, [r4,#24] ; r5 = s->q_delp LDR r11,[r4,#28] ; r11= s->q_minp LDR r12,[r4,#32] ; r12= s->q_del = mul LDR r14,[r4,#36] ; r14= s->q_min SUBS r11,r7, r11 ; r11= add = point - s->q_minp MOVGT r14,r14,ASR r11 ; r14= add = s->q_min >> add (if add >0) RSBLT r11,r11,#0 MOVLT r14,r14,LSL r11 ; r14= add = s->q_min << -add (if add < 0) SUBS r5, r7, r5 ; r5 = shiftM = point - s->q_delp LDR r7, [r4,#40] ; r7 = s->q_seq RSBLT r5, r5, #0 ; if (shiftM<0) r5 =-shiftM MOVLT r12,r12,LSL r5 ; r12=mul<<-shiftM MOVLT r5, #0 ; r5 =shiftM = 0 MOVGT r14,r14,LSL r5 ; add <<= shiftM CMP r7,#0 ; seqMask = (s->q_seq?-1:0) MVNNE r7,#0 CMP r1, #2 BEQ dm2 BGT dm3 CMP r1,#0 ; probably never happens BLE dm_duff dm1 ; r1 = s->dec_type ; r2 = s->q_bits ; r3 = s->dim ; r5 = shiftM ; r6 = v ; r7 = seqMask ; r8 = entry ; r12= mul ; r14= add MOV r0, #1 RSB r0, r0, r0, LSL r2 ; r0 = mask = (1<q_bits)-1 MOV r11,#0 ; r11= prev = 0 dm1_loop AND r1, r8, r0 ; r1 = v = entry & mask MLA r1, r12, r1, r14 ; r1 = (add + mul*v) MOV r8, r8, LSR r2 ; r8 = entry>>s->q_bits SUBS r3, r3, #1 ADD r1, r11,r1, ASR r5 ; r1 = v = prev+((add+mul*v)>>shiftM) AND r11,r1, r7 ; r11= prev = seqMask & v STR r1, [r6], #4 ; *v++ = v BGT dm1_loop MOV r0, #0 LDMFD r13!,{r4-r11,PC} dm2 ; r1 = s->dec_type ; r2 = s->q_bits ; r3 = s->dim ; r4 = s ; r5 = shiftM ; r6 = v ; r7 = seqMask ; r8 = entry ; r12= mul ; r14= add LDR r1, [r4,#44] ; r1 = s->q_pack LDR r4, [r4,#48] ; r4 = s->q_val MOV r11,#0 ; r11= prev MOV r0, #1 RSB r0, r0, r0, LSL r1 ; r8 = mask = (1<q_pack)-1 CMP r2,#8 BGT dm2_hword dm2_loop AND r2, r8, r0 ; r2 = entry & mask LDRB r2, [r4, r2] ; r2 = v = q->val[entry & mask] MOV r8, r8, LSR r1 ; r8 = entry>>q_pack MLA r2, r12,r2, r14 ; r2 = (add+mul*v) SUBS r3, r3, #1 ADD r2, r11,r2, ASR r5 ; r2 = v = prev+(add+mul*v)>>shiftM AND r11,r2, r7 ; r11= prev = seqMask & v STR r2, [r6], #4 ; *v++ = v BGT dm2_loop MOV r0, #0 LDMFD r13!,{r4-r11,PC} dm2_hword AND r2, r8, r0 ; r2 = entry & mask MOV r2, r2, LSL #1 ; r2 = 2*r2 LDRH r2, [r4, r2] ; r2 = v = q->val[entry & mask] MOV r8, r8, LSR r1 ; r8 = entry>>q_pack MLA r2, r12,r2, r14 ; r2 = (add+mul*v) SUBS r3, r3, #1 ADD r2, r11,r2, ASR r5 ; r2 = v = prev+(add+mul*v)>>shiftM AND r11,r2, r7 ; r11= prev = seqMask & v STR r2, [r6], #4 ; *v++ = v BGT dm2_hword MOV r0, #0 LDMFD r13!,{r4-r11,PC} dm3 ; r1 = s->dec_type ; r2 = s->q_bits ; r3 = s->dim ; r4 = s ; r5 = shiftM ; r6 = v ; r7 = seqMask ; r8 = entry ; r12= mul ; r14= add LDR r1, [r4,#44] ; r1 = s->q_pack LDR r4, [r4,#52] ; r4 = s->q_val CMP r2,#8 MOV r11,#0 ; r11= prev MLA r4,r1,r8,r4 ; r4 = ptr = s->q_val+entry*s->q_pack BGT dm3_hword dm3_loop LDRB r2, [r4], #1 ; r2 = v = *ptr++ SUBS r3, r3, #1 MLA r2, r12,r2, r14 ; r2 = (add+mul*v) ADD r2, r11,r2, ASR r5 ; r2 = v = prev+(add+mul*v)>>shiftM AND r11,r2, r7 ; r11= prev = seqMask & v STR r2, [r6], #4 ; *v++ = v BGT dm3_loop MOV r0, #0 LDMFD r13!,{r4-r11,PC} dm3_hword LDRH r2, [r4], #2 ; r2 = *ptr++ SUBS r3, r3, #1 MLA r2, r12,r2, r14 ; r2 = (add+mul*v) ADD r2, r11,r2, ASR r5 ; r2 = v = prev+(add+mul*v)>>shiftM AND r11,r2, r7 ; r11= prev = seqMask & v STR r2, [r6], #4 ; *v++ = v BGT dm3_hword MOV r0, #0 LDMFD r13!,{r4-r11,PC} dm_duff MVN r0,#0 LDMFD r13!,{r4-r11,PC} vorbis_book_decodevv_add ; r0 = codebook *book ; r1 = ogg_int32_t **a ; r2 = long offset ; r3 = int ch ; <> = b ; <> = n ; <> = point STMFD r13!,{r4-r11,R14} LDR r7, [r0, #13*4] ; r7 = used_entries MOV r9, r0 ; r9 = book MOV r10,r1 ; r10= &a[chptr] chptr=0 MOV r6, r3 ; r6 = ch ADD r8, r10,r3, LSL #2 ; r8 = &a[ch] MOV r11,r2 ; r11= offset CMP r7, #0 ; if (used_entries <= 0) BLE vbdvva_exit ; exit LDR r5, [r13,#10*4] ; r5 = n vbdvva_loop1 ; r5 = n ; r6 = ch ; r8 = &a[ch] ; r9 = book ; r10= &a[chptr] ; r11= offset MOV r0, r9 ; r0 = book LDR r1, [r13,# 9*4] ; r1 = b LDR r2, [r9, #14*4] ; r2 = v = dec_buf LDR r3, [r13,#11*4] ; r3 = point BL decode_map CMP r0, #0 BNE vbdvva_fail LDR r0, [r9, # 5*4] ; r0 = book->dim LDR r1, [r9, #14*4] ; r1 = v = dec_buf vbdvva_loop2 LDR r2, [r10],#4 ; r2 = a[chptr++] LDR r12,[r1], #4 ; r1 = v[j++] CMP r10,r8 ; if (chptr == ch) SUBEQ r10,r10,r6, LSL #2 ; chptr = 0 LDR r14,[r2, r11,LSL #2]! ; r2 = &a[chptr++][i] r14=[r12] ADDEQ r11,r11,#1 ; i++ SUBEQ r5, r5, #1 ; n-- SUBS r0, r0, #1 ; r0-- ADD r12,r12,r14 ; r12= a[chptr++][i]+ v[j] STR r12,[r2] ; r12= a[chptr++][i]+=v[j] BGT vbdvva_loop2 CMP r5,#0 BGT vbdvva_loop1 vbdvva_exit MOV r0, #0 ; return 0 LDMFD r13!,{r4-r11,PC} vbdvva_fail MVN r0, #0 ; return -1 LDMFD r13!,{r4-r11,PC} _checksum ; r0 = ogg_reference *or ; r1 = bytes STMFD r13!,{r5-r6,r14} LDR r5,=crc_lookup MOV r14,#0 ; r14= crc_reg = 0 MOVS r12,r0 BEQ _cs_end _cs_loop1 LDMIA r12,{r0,r2,r3,r12} ; r0 = or->buffer ; r2 = or->begin ; r3 = or->length ; r12= or->next LDR r0,[r0] ; r0 = or->buffer->data CMP r1,r3 ; r3 = post = (bytes < or->length ? MOVLT r3,r1 ; bytes : or->length) MOVS r6,r3 ; r6 = j = post BEQ _cs_no_bytes ADD r0,r0,r2 ; r0 = or->buffer->data + or->begin _cs_loop2 LDRB r2, [r0],#1 ; r2 = data[j] ; stall ; stall Xscale EOR r2, r2, r14,LSR #24 ; r2 = (crc_reg>>24)^data[j] LDR r2, [r5, r2, LSL #2] ; r2 = crc_lkp[(crc_reg>>24)^data[j]] SUBS r6, r6, #1 ; j-- ; stall Xscale EOR r14,r2, r14,LSL #8 ; r14= crc_reg = (crc_reg<<8)^r2 BGT _cs_loop2 _cs_no_bytes SUBS r1, r1, r3 CMPNE r12,#0 BNE _cs_loop1 _cs_end MOV r0,r14 LDMFD r13!,{r5-r6,PC} END