17913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang@ Tremolo library 22da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@----------------------------------------------------------------------- 32da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ Copyright (C) 2002-2009, Xiph.org Foundation 42da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ Copyright (C) 2010, Robin Watts for Pinknoise Productions Ltd 52da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ All rights reserved. 62da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang 72da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ Redistribution and use in source and binary forms, with or without 82da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ modification, are permitted provided that the following conditions 92da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ are met: 102da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang 112da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ * Redistributions of source code must retain the above copyright 122da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ notice, this list of conditions and the following disclaimer. 132da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ * Redistributions in binary form must reproduce the above 142da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ copyright notice, this list of conditions and the following disclaimer 152da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ in the documentation and/or other materials provided with the 162da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ distribution. 172da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ * Neither the names of the Xiph.org Foundation nor Pinknoise 182da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ Productions Ltd nor the names of its contributors may be used to 192da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ endorse or promote products derived from this software without 202da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ specific prior written permission. 212da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ 222da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 232da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 242da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 252da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 262da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 272da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 282da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 292da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 302da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 312da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 322da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 332da723a953a18e3c7fec194cec1216cf31130c86Gloria Wang@ ---------------------------------------------------------------------- 347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang .text 367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang .global oggpack_look 387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang .global oggpack_adv 397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang .global oggpack_readinit 407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang .global oggpack_read 417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangoggpack_look: 437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r0 = oggpack_buffer *b 447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r1 = int bits 457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STMFD r13!,{r10,r11,r14} 467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMIA r0,{r2,r3,r12} 477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r2 = bitsLeftInSegment 487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r3 = ptr 497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r12= bitsLeftInWord 507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang SUBS r2,r2,r1 @ bitsLeftinSegment -= bits 517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BLT look_slow @ Not enough bits in this segment for 527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ this request. Do it slowly. 537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r10,[r3] @ r10= ptr[0] 547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r14,r12,#32 @ r14= 32-bitsLeftInWord 557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang SUBS r12,r12,r1 @ r12= bitsLeftInWord -= bits 567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDRLT r11,[r3,#4]! @ r11= ptr[1] 577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r10,r10,LSR r14 @ r10= ptr[0]>>(32-bitsLeftInWord) 587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDLE r12,r12,#32 @ r12= bitsLeftInWord += 32 597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r14,r14,#32 @ r14= 32-bitsLeftInWord 607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ORRLT r10,r10,r11,LSL r14 @ r10= Next 32 bits. 617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r14,#1 627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r14,r14,r14,LSL r1 637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang AND r0,r10,r14 647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMFD r13!,{r10,r11,PC} 657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglook_slow: 677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STMFD r13!,{r5,r6} 687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDS r10,r2,r1 @ r10= bitsLeftInSegment + bits (i.e. 697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ the initial value of bitsLeftInSeg) 707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r10 = bitsLeftInSegment (initial) 717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r12 = bitsLeftInWord 727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r14,r12,#32 @ r14= 32-bitsLeftInWord 737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r5,r10 @ r5 = bitsLeftInSegment (initial) 747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BLT look_overrun 757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BEQ look_next_segment @ r10= r12 = 0, if we branch 767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang CMP r12,r10 @ If bitsLeftInWord < bitsLeftInSeg 777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ there must be more in the next word 787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r10,[r3],#4 @ r10= ptr[0] 797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDRLT r6,[r3] @ r6 = ptr[1] 807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r11,#1 817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r10,r10,LSR r14 @ r10= first bitsLeftInWord bits 827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ORRLT r10,r10,r6,LSL r12 @ r10= first bitsLeftInSeg bits+crap 837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r11,r11,r11,LSL r5 @ r11= mask 847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang AND r10,r10,r11 @ r10= first r5 bits 857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ Load the next segments data 867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglook_next_segment: 877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ At this point, r10 contains the first r5 bits of the result 887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r11,[r0,#12] @ r11= head = b->head 897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ Stall 907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ Stall 917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglook_next_segment_2: 927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r11,[r11,#12] @ r11= head = head->next 937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ Stall 947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ Stall 957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang CMP r11,#0 967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BEQ look_out_of_data 977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMIA r11,{r6,r12,r14} @ r6 = buffer 987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r12= begin 997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r14= length 1007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r6,[r6] @ r6 = buffer->data 1017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang CMP r14,#0 1027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BEQ look_next_segment_2 1037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r6,r6,r12 @ r6 = buffer->data+begin 1047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglook_slow_loop: 1057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDRB r12,[r6],#1 @ r12= *buffer 1067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang SUBS r14,r14,#1 @ r14= length 1077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ Stall 1087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ORR r10,r10,r12,LSL r5 @ r10= first r5+8 bits 1097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r5,r5,#8 1107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BLE look_really_slow 1117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang CMP r5,r1 1127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BLT look_slow_loop 1137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r14,#1 1147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r14,r14,r14,LSL r1 1157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang AND r0,r10,r14 1167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMFD r13!,{r5,r6,r10,r11,PC} 1177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglook_really_slow: 1207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang CMP r5,r1 1217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BLT look_next_segment_2 1227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r14,#1 1237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r14,r14,r14,LSL r1 1247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang AND r0,r10,r14 1257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMFD r13!,{r5,r6,r10,r11,PC} 1267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglook_out_of_data: 1287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @MVN r0,#0 ; return -1 1297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r0,#0 1307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMFD r13!,{r5,r6,r10,r11,PC} 1317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglook_overrun: 1337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ We had overrun when we started, so we need to skip -r10 bits. 1347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r11,[r0,#12] @ r11 = head = b->head 1357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 1367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 1377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wanglook_overrun_next_segment: 1387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r11,[r11,#12] @ r11 = head->next 1397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 1407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 1417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang CMP r11,#0 1427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BEQ look_out_of_data 1437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMIA r11,{r6,r7,r14} @ r6 = buffer 1447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r7 = begin 1457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r14= length 1467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r6,[r6] @ r6 = buffer->data 1477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 1487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 1497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r6,r6,r7 @ r6 = buffer->data+begin 1507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r14,r14,LSL #3 @ r14= length in bits 1517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDS r14,r14,r10 @ r14= length in bits-bits to skip 1527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOVLE r10,r14 1537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BLE look_overrun_next_segment 1547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r10,r10,#0 @ r10= bits to skip 1557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r6,r10,r10,LSR #3 @ r6 = pointer to data 1567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r10,#0 1577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang B look_slow_loop 1587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangoggpack_adv: 1607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r0 = oggpack_buffer *b 1617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r1 = bits 1627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMIA r0,{r2,r3,r12} 1637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r2 = bitsLeftInSegment 1647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r3 = ptr 1657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r12= bitsLeftInWord 1667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang SUBS r2,r2,r1 @ Does this run us out of bits in the 1677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BLE adv_slow @ segment? If so, do it slowly 1687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang SUBS r12,r12,r1 1697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDLE r12,r12,#32 1707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDLE r3,r3,#4 1717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STMIA r0,{r2,r3,r12} 1729a688754461ebfc91769b5d3c8ba5aba9fe1f376Andreas Huber BX LR 1737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangadv_slow: 1747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STMFD r13!,{r10,r14} 1757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 1767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r14,[r0,#12] @ r14= head 1777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 1787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangadv_slow_loop: 1797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r1,[r0,#20] @ r1 = count 1807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r10,[r14,#8] @ r10= head->length 1817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r14,[r14,#12] @ r14= head->next 1827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 1837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r1,r1,r10 @ r1 = count += head->length 1847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang CMP r14,#0 1857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BEQ adv_end 1867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STR r1,[r0,#20] @ b->count = count 1877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STR r14,[r0,#12] @ b->head = head 1887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMIA r14,{r3,r10,r12} @ r3 = buffer 1897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r10= begin 1907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r12= length 1917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r3,[r3] @ r3 = buffer->data 1927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r3,r3,r10 @ r3 = Pointer to start (byte) 1937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang AND r10,r3,#3 @ r10= bytes to backtrk to word align 1947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r10,r10,LSL #3 @ r10= bits to backtrk to word align 1957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r10,r10,#32 @ r10= bits left in word 1967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDS r10,r10,r2 @ r10= bits left in word after skip 1977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDLE r10,r10,#32 1987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDLE r3,r3,#4 1997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BIC r3,r3,#3 @ r3 = Pointer to start (word) 2007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDS r2,r2,r12,LSL #3 @ r2 = length in bits after advance 2017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BLE adv_slow_loop 2027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STMIA r0,{r2,r3,r10} 2037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMFD r13!,{r10,PC} 2057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangadv_end: 2067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r2, #0 2077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r12,#0 2087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STMIA r0,{r2,r3,r12} 2097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMFD r13!,{r10,PC} 2117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangoggpack_readinit: 2137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r0 = oggpack_buffer *b 2147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r1 = oggreference *r 2157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STR r1,[r0,#12] @ b->head = r1 2167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STR r1,[r0,#16] @ b->tail = r1 2177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMIA r1,{r2,r3,r12} @ r2 = b->head->buffer 2187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r3 = b->head->begin 2197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r12= b->head->length 2207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r2,[r2] @ r2 = b->head->buffer->data 2217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r1,r12,LSL #3 @ r1 = BitsInSegment 2227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r12,#0 2237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r3,r2,r3 @ r3 = r2+b->head->begin 2247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BIC r2,r3,#3 @ r2 = b->headptr (word) 2257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang AND r3,r3,#3 2267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r3,r3,LSL #3 2277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r3,r3,#32 @ r3 = BitsInWord 2287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STMIA r0,{r1,r2,r3} 2297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STR r12,[r0,#20] 2309a688754461ebfc91769b5d3c8ba5aba9fe1f376Andreas Huber BX LR 2317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangoggpack_read: 2337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r0 = oggpack_buffer *b 2347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r1 = int bits 2357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STMFD r13!,{r10,r11,r14} 2367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMIA r0,{r2,r3,r12} 2377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r2 = bitsLeftInSegment 2387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r3 = ptr 2397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r12= bitsLeftInWord 2407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang SUBS r2,r2,r1 @ bitsLeftinSegment -= bits 2417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BLT read_slow @ Not enough bits in this segment for 2427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ this request. Do it slowly. 2437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r10,[r3] @ r10= ptr[0] 2447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r14,r12,#32 @ r14= 32-bitsLeftInWord 2457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang SUBS r12,r12,r1 @ r12= bitsLeftInWord -= bits 2467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDLE r3,r3,#4 2477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDRLT r11,[r3] @ r11= ptr[1] 2487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r10,r10,LSR r14 @ r10= ptr[0]>>(32-bitsLeftInWord) 2497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDLE r12,r12,#32 @ r12= bitsLeftInWord += 32 2507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r14,r14,#32 @ r14= 32-bitsLeftInWord 2517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ORRLT r10,r10,r11,LSL r14 @ r10= Next 32 bits. 2527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STMIA r0,{r2,r3,r12} 2537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r14,#1 2547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r14,r14,r14,LSL r1 2557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang AND r0,r10,r14 2567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMFD r13!,{r10,r11,PC} 2577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 2587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangread_slow: 2597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STMFD r13!,{r5,r6} 2607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDS r10,r2,r1 @ r10= bitsLeftInSegment + bits (i.e. 2617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ the initial value of bitsLeftInSeg) 2627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r10 = bitsLeftInSegment (initial) 2637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r12 = bitsLeftInWord 2647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r14,r12,#32 @ r14= 32-bitsLeftInWord 2657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r5,r10 @ r5 = bitsLeftInSegment (initial) 2667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BLT read_overrun 2677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BEQ read_next_segment @ r10= r12 = 0, if we branch 2687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang CMP r12,r10 @ If bitsLeftInWord < bitsLeftInSeg 2697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ there must be more in the next word 2707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r10,[r3],#4 @ r10= ptr[0] 2717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDRLT r6,[r3] @ r6 = ptr[1] 2727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r11,#1 2737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r10,r10,LSR r14 @ r10= first bitsLeftInWord bits 2747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ORRLT r10,r10,r6,LSL r12 @ r10= first bitsLeftInSeg bits+crap 2757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r11,r11,r11,LSL r5 @ r11= mask 2767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang AND r10,r10,r11 @ r10= first r5 bits 2777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ Load the next segments data 2787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangread_next_segment: 2797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ At this point, r10 contains the first r5 bits of the result 2807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r11,[r0,#12] @ r11= head = b->head 2817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ Stall 2827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangread_next_segment_2: 2837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r11 = head 2847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r6,[r0,#20] @ r6 = count 2857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r12,[r11,#8] @ r12= length 2867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r11,[r11,#12] @ r11= head = head->next 2877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ Stall 2887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r6,r6,r12 @ count += length 2897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang CMP r11,#0 2907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BEQ read_out_of_data 2917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STR r11,[r0,#12] 2927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STR r6,[r0,#20] @ b->count = count 2937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMIA r11,{r6,r12,r14} @ r6 = buffer 2947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r12= begin 2957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r14= length 2967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r6,[r6] @ r6 = buffer->data 2977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang CMP r14,#0 2987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BEQ read_next_segment_2 2997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r6,r6,r12 @ r6 = buffer->data+begin 3007913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangread_slow_loop: 3017913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDRB r12,[r6],#1 @ r12= *buffer 3027913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang SUBS r14,r14,#1 @ r14= length 3037913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ Stall 3047913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ORR r10,r10,r12,LSL r5 @ r10= first r5+8 bits 3057913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r5,r5,#8 3067913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BLE read_really_slow 3077913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang CMP r5,r1 3087913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BLT read_slow_loop 3097913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangread_end: 3107913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r12,#1 3117913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r12,r12,r12,LSL r1 3127913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3137913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ Store back the new position 3147913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r2 = -number of bits to go from this segment 3157913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r6 = ptr 3167913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r14= bytesLeftInSegment 3177913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r11= New head value 3187913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMIA r11,{r3,r6,r14} @ r3 = buffer 3197913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r6 = begin 3207913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r14= length 3217913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r3,[r3] @ r3 = buffer->data 3227913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r1,r2,r14,LSL #3 @ r1 = bitsLeftInSegment 3237913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 3247913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r6,r3,r6 @ r6 = pointer 3257913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang AND r3,r6,#3 @ r3 = bytes used in first word 3267913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r3,r2,r3,LSL #3 @ r3 = bits used in first word 3277913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BIC r2,r6,#3 @ r2 = word ptr 3287913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSBS r3,r3,#32 @ r3 = bitsLeftInWord 3297913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDLE r3,r3,#32 3307913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDLE r2,r2,#4 3317913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STMIA r0,{r1,r2,r3} 3327913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3337913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang AND r0,r10,r12 3347913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMFD r13!,{r5,r6,r10,r11,PC} 3357913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3367913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3377913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangread_really_slow: 3387913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang CMP r5,r1 3397913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BGE read_end 3407913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r14,[r11,#8] @ r14= length of segment just done 3417913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 3427913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 3437913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r2,r2,r14,LSL #3 @ r2 = -bits to use from next seg 3447913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang B read_next_segment_2 3457913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3467913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangread_out_of_data: 3477913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ Store back the new position 3487913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r2 = -number of bits to go from this segment 3497913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r6 = ptr 3507913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r14= bytesLeftInSegment 3517913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ RJW: This may be overkill - we leave the buffer empty, with -1 3527913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ bits left in it. We might get away with just storing the 3537913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ bitsLeftInSegment as -1. 3547913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r11,[r0,#12] @ r11=head 3557913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3567913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMIA r11,{r3,r6,r14} @ r3 = buffer 3577913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r6 = begin 3587913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r14= length 3597913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r3,[r3] @ r3 = buffer->data 3607913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r6,r3,r6 @ r6 = pointer 3617913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r6,r6,r14 3627913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang AND r3,r6,#3 @ r3 = bytes used in first word 3637913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r3,r3,LSL #3 @ r3 = bits used in first word 3647913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BIC r2,r6,#3 @ r2 = word ptr 3657913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSBS r3,r3,#32 @ r3 = bitsLeftInWord 3667913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MVN r1,#0 @ r1 = -1 = bitsLeftInSegment 3677913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang STMIA r0,{r1,r2,r3} 3687913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @MVN r0,#0 ; return -1 3697913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r0,#0 3707913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMFD r13!,{r5,r6,r10,r11,PC} 3717913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3727913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangread_overrun: 3737913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ We had overrun when we started, so we need to skip -r10 bits. 3747913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r11,[r0,#12] @ r11 = head = b->head 3757913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 3767913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 3777913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wangread_overrun_next_segment: 3787913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r11,[r11,#12] @ r11 = head->next 3797913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 3807913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 3817913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang CMP r11,#0 3827913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BEQ read_out_of_data 3837913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDMIA r11,{r6,r7,r14} @ r6 = buffer 3847913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r7 = begin 3857913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ r14= length 3867913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang LDR r6,[r6] @ r6 = buffer->data 3877913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 3887913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ stall 3897913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r6,r6,r7 @ r6 = buffer->data+begin 3907913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r14,r14,LSL #3 @ r14= length in bits 3917913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADDS r14,r14,r10 @ r14= length in bits-bits to skip 3927913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOVLE r10,r14 3937913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang BLE read_overrun_next_segment 3947913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang RSB r10,r10,#0 @ r10= bits to skip 3957913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang ADD r6,r10,r10,LSR #3 @ r6 = pointer to data 3967913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang MOV r10,#0 3977913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang B read_slow_loop 3987913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang 3997913073ddf11ca3dd7b0439998e1b17d443bb0baGloria Wang @ END 400