media/libtheora/lib/arm/armbits.s

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 ;********************************************************************
michael@0 2 ;* *
michael@0 3 ;* THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
michael@0 4 ;* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
michael@0 5 ;* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
michael@0 6 ;* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
michael@0 7 ;* *
michael@0 8 ;* THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2010 *
michael@0 9 ;* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
michael@0 10 ;* *
michael@0 11 ;********************************************************************
michael@0 12 ;
michael@0 13 ; function:
michael@0 14 ; last mod: $Id: armbits.s 17481 2010-10-03 22:49:42Z tterribe $
michael@0 15 ;
michael@0 16 ;********************************************************************
michael@0 17
michael@0 18 AREA |.text|, CODE, READONLY
michael@0 19
michael@0 20 ; Explicitly specifying alignment here because some versions of
michael@0 21 ; gas don't align code correctly. See
michael@0 22 ; http://lists.gnu.org/archive/html/bug-binutils/2011-06/msg00199.html
michael@0 23 ; https://bugzilla.mozilla.org/show_bug.cgi?id=920992
michael@0 24 ALIGN
michael@0 25
michael@0 26 EXPORT oc_pack_read_arm
michael@0 27 EXPORT oc_pack_read1_arm
michael@0 28 EXPORT oc_huff_token_decode_arm
michael@0 29
michael@0 30 oc_pack_read1_arm PROC
michael@0 31 ; r0 = oc_pack_buf *_b
michael@0 32 ADD r12,r0,#8
michael@0 33 LDMIA r12,{r2,r3} ; r2 = window
michael@0 34 ; Stall... ; r3 = available
michael@0 35 ; Stall...
michael@0 36 SUBS r3,r3,#1 ; r3 = available-1, available<1 => LT
michael@0 37 BLT oc_pack_read1_refill
michael@0 38 MOV r0,r2,LSR #31 ; r0 = window>>31
michael@0 39 MOV r2,r2,LSL #1 ; r2 = window<<=1
michael@0 40 STMIA r12,{r2,r3} ; window = r2
michael@0 41 ; available = r3
michael@0 42 MOV PC,r14
michael@0 43 ENDP
michael@0 44
michael@0 45 oc_pack_read_arm PROC
michael@0 46 ; r0 = oc_pack_buf *_b
michael@0 47 ; r1 = int _bits
michael@0 48 ADD r12,r0,#8
michael@0 49 LDMIA r12,{r2,r3} ; r2 = window
michael@0 50 ; Stall... ; r3 = available
michael@0 51 ; Stall...
michael@0 52 SUBS r3,r3,r1 ; r3 = available-_bits, available<_bits => LT
michael@0 53 BLT oc_pack_read_refill
michael@0 54 RSB r0,r1,#32 ; r0 = 32-_bits
michael@0 55 MOV r0,r2,LSR r0 ; r0 = window>>32-_bits
michael@0 56 MOV r2,r2,LSL r1 ; r2 = window<<=_bits
michael@0 57 STMIA r12,{r2,r3} ; window = r2
michael@0 58 ; available = r3
michael@0 59 MOV PC,r14
michael@0 60
michael@0 61 ; We need to refill window.
michael@0 62 oc_pack_read1_refill
michael@0 63 MOV r1,#1
michael@0 64 oc_pack_read_refill
michael@0 65 STMFD r13!,{r10,r11,r14}
michael@0 66 LDMIA r0,{r10,r11} ; r10 = stop
michael@0 67 ; r11 = ptr
michael@0 68 RSB r0,r1,#32 ; r0 = 32-_bits
michael@0 69 RSB r3,r3,r0 ; r3 = 32-available
michael@0 70 ; We can use unsigned compares for both the pointers and for available
michael@0 71 ; (allowing us to chain condition codes) because available will never be
michael@0 72 ; larger than 32 (or we wouldn't be here), and thus 32-available will never be
michael@0 73 ; negative.
michael@0 74 CMP r10,r11 ; ptr<stop => HI
michael@0 75 CMPHI r3,#7 ; available<=24 => HI
michael@0 76 LDRHIB r14,[r11],#1 ; r14 = *ptr++
michael@0 77 SUBHI r3,#8 ; available += 8
michael@0 78 ; (HI) Stall...
michael@0 79 ORRHI r2,r14,LSL r3 ; r2 = window|=r14<<32-available
michael@0 80 CMPHI r10,r11 ; ptr<stop => HI
michael@0 81 CMPHI r3,#7 ; available<=24 => HI
michael@0 82 LDRHIB r14,[r11],#1 ; r14 = *ptr++
michael@0 83 SUBHI r3,#8 ; available += 8
michael@0 84 ; (HI) Stall...
michael@0 85 ORRHI r2,r14,LSL r3 ; r2 = window|=r14<<32-available
michael@0 86 CMPHI r10,r11 ; ptr<stop => HI
michael@0 87 CMPHI r3,#7 ; available<=24 => HI
michael@0 88 LDRHIB r14,[r11],#1 ; r14 = *ptr++
michael@0 89 SUBHI r3,#8 ; available += 8
michael@0 90 ; (HI) Stall...
michael@0 91 ORRHI r2,r14,LSL r3 ; r2 = window|=r14<<32-available
michael@0 92 CMPHI r10,r11 ; ptr<stop => HI
michael@0 93 CMPHI r3,#7 ; available<=24 => HI
michael@0 94 LDRHIB r14,[r11],#1 ; r14 = *ptr++
michael@0 95 SUBHI r3,#8 ; available += 8
michael@0 96 ; (HI) Stall...
michael@0 97 ORRHI r2,r14,LSL r3 ; r2 = window|=r14<<32-available
michael@0 98 SUBS r3,r0,r3 ; r3 = available-=_bits, available<bits => GT
michael@0 99 BLT oc_pack_read_refill_last
michael@0 100 MOV r0,r2,LSR r0 ; r0 = window>>32-_bits
michael@0 101 MOV r2,r2,LSL r1 ; r2 = window<<=_bits
michael@0 102 STR r11,[r12,#-4] ; ptr = r11
michael@0 103 STMIA r12,{r2,r3} ; window = r2
michael@0 104 ; available = r3
michael@0 105 LDMFD r13!,{r10,r11,PC}
michael@0 106
michael@0 107 ; Either we wanted to read more than 24 bits and didn't have enough room to
michael@0 108 ; stuff the last byte into the window, or we hit the end of the packet.
michael@0 109 oc_pack_read_refill_last
michael@0 110 CMP r11,r10 ; ptr<stop => LO
michael@0 111 ; If we didn't hit the end of the packet, then pull enough of the next byte to
michael@0 112 ; to fill up the window.
michael@0 113 LDRLOB r14,[r11] ; (LO) r14 = *ptr
michael@0 114 ; Otherwise, set the EOF flag and pretend we have lots of available bits.
michael@0 115 MOVHS r14,#1 ; (HS) r14 = 1
michael@0 116 ADDLO r10,r3,r1 ; (LO) r10 = available
michael@0 117 STRHS r14,[r12,#8] ; (HS) eof = 1
michael@0 118 ANDLO r10,r10,#7 ; (LO) r10 = available&7
michael@0 119 MOVHS r3,#1<<30 ; (HS) available = OC_LOTS_OF_BITS
michael@0 120 ORRLO r2,r14,LSL r10 ; (LO) r2 = window|=*ptr>>(available&7)
michael@0 121 MOV r0,r2,LSR r0 ; r0 = window>>32-_bits
michael@0 122 MOV r2,r2,LSL r1 ; r2 = window<<=_bits
michael@0 123 STR r11,[r12,#-4] ; ptr = r11
michael@0 124 STMIA r12,{r2,r3} ; window = r2
michael@0 125 ; available = r3
michael@0 126 LDMFD r13!,{r10,r11,PC}
michael@0 127 ENDP
michael@0 128
michael@0 129
michael@0 130
michael@0 131 oc_huff_token_decode_arm PROC
michael@0 132 ; r0 = oc_pack_buf *_b
michael@0 133 ; r1 = const ogg_int16_t *_tree
michael@0 134 STMFD r13!,{r4,r5,r10,r14}
michael@0 135 LDRSH r10,[r1] ; r10 = n=_tree[0]
michael@0 136 LDMIA r0,{r2-r5} ; r2 = stop
michael@0 137 ; Stall... ; r3 = ptr
michael@0 138 ; Stall... ; r4 = window
michael@0 139 ; r5 = available
michael@0 140 CMP r10,r5 ; n>available => GT
michael@0 141 BGT oc_huff_token_decode_refill0
michael@0 142 RSB r14,r10,#32 ; r14 = 32-n
michael@0 143 MOV r14,r4,LSR r14 ; r14 = bits=window>>32-n
michael@0 144 ADD r14,r1,r14,LSL #1 ; r14 = _tree+bits
michael@0 145 LDRSH r12,[r14,#2] ; r12 = node=_tree[1+bits]
michael@0 146 ; Stall...
michael@0 147 ; Stall...
michael@0 148 RSBS r14,r12,#0 ; r14 = -node, node>0 => MI
michael@0 149 BMI oc_huff_token_decode_continue
michael@0 150 MOV r10,r14,LSR #8 ; r10 = n=node>>8
michael@0 151 MOV r4,r4,LSL r10 ; r4 = window<<=n
michael@0 152 SUB r5,r10 ; r5 = available-=n
michael@0 153 STMIB r0,{r3-r5} ; ptr = r3
michael@0 154 ; window = r4
michael@0 155 ; available = r5
michael@0 156 AND r0,r14,#255 ; r0 = node&255
michael@0 157 LDMFD r13!,{r4,r5,r10,pc}
michael@0 158
michael@0 159 ; The first tree node wasn't enough to reach a leaf, read another
michael@0 160 oc_huff_token_decode_continue
michael@0 161 ADD r12,r1,r12,LSL #1 ; r12 = _tree+node
michael@0 162 MOV r4,r4,LSL r10 ; r4 = window<<=n
michael@0 163 SUB r5,r5,r10 ; r5 = available-=n
michael@0 164 LDRSH r10,[r12],#2 ; r10 = n=_tree[node]
michael@0 165 ; Stall... ; r12 = _tree+node+1
michael@0 166 ; Stall...
michael@0 167 CMP r10,r5 ; n>available => GT
michael@0 168 BGT oc_huff_token_decode_refill
michael@0 169 RSB r14,r10,#32 ; r14 = 32-n
michael@0 170 MOV r14,r4,LSR r14 ; r14 = bits=window>>32-n
michael@0 171 ADD r12,r12,r14 ;
michael@0 172 LDRSH r12,[r12,r14] ; r12 = node=_tree[node+1+bits]
michael@0 173 ; Stall...
michael@0 174 ; Stall...
michael@0 175 RSBS r14,r12,#0 ; r14 = -node, node>0 => MI
michael@0 176 BMI oc_huff_token_decode_continue
michael@0 177 MOV r10,r14,LSR #8 ; r10 = n=node>>8
michael@0 178 MOV r4,r4,LSL r10 ; r4 = window<<=n
michael@0 179 SUB r5,r10 ; r5 = available-=n
michael@0 180 STMIB r0,{r3-r5} ; ptr = r3
michael@0 181 ; window = r4
michael@0 182 ; available = r5
michael@0 183 AND r0,r14,#255 ; r0 = node&255
michael@0 184 LDMFD r13!,{r4,r5,r10,pc}
michael@0 185
michael@0 186 oc_huff_token_decode_refill0
michael@0 187 ADD r12,r1,#2 ; r12 = _tree+1
michael@0 188 oc_huff_token_decode_refill
michael@0 189 ; We can't possibly need more than 15 bits, so available must be <= 15.
michael@0 190 ; Therefore we can load at least two bytes without checking it.
michael@0 191 CMP r2,r3 ; ptr<stop => HI
michael@0 192 LDRHIB r14,[r3],#1 ; r14 = *ptr++
michael@0 193 RSBHI r5,r5,#24 ; (HI) available = 32-(available+=8)
michael@0 194 RSBLS r5,r5,#32 ; (LS) r5 = 32-available
michael@0 195 ORRHI r4,r14,LSL r5 ; r4 = window|=r14<<32-available
michael@0 196 CMPHI r2,r3 ; ptr<stop => HI
michael@0 197 LDRHIB r14,[r3],#1 ; r14 = *ptr++
michael@0 198 SUBHI r5,#8 ; available += 8
michael@0 199 ; (HI) Stall...
michael@0 200 ORRHI r4,r14,LSL r5 ; r4 = window|=r14<<32-available
michael@0 201 ; We can use unsigned compares for both the pointers and for available
michael@0 202 ; (allowing us to chain condition codes) because available will never be
michael@0 203 ; larger than 32 (or we wouldn't be here), and thus 32-available will never be
michael@0 204 ; negative.
michael@0 205 CMPHI r2,r3 ; ptr<stop => HI
michael@0 206 CMPHI r5,#7 ; available<=24 => HI
michael@0 207 LDRHIB r14,[r3],#1 ; r14 = *ptr++
michael@0 208 SUBHI r5,#8 ; available += 8
michael@0 209 ; (HI) Stall...
michael@0 210 ORRHI r4,r14,LSL r5 ; r4 = window|=r14<<32-available
michael@0 211 CMP r2,r3 ; ptr<stop => HI
michael@0 212 MOVLS r5,#-1<<30 ; (LS) available = OC_LOTS_OF_BITS+32
michael@0 213 CMPHI r5,#7 ; (HI) available<=24 => HI
michael@0 214 LDRHIB r14,[r3],#1 ; (HI) r14 = *ptr++
michael@0 215 SUBHI r5,#8 ; (HI) available += 8
michael@0 216 ; (HI) Stall...
michael@0 217 ORRHI r4,r14,LSL r5 ; (HI) r4 = window|=r14<<32-available
michael@0 218 RSB r14,r10,#32 ; r14 = 32-n
michael@0 219 MOV r14,r4,LSR r14 ; r14 = bits=window>>32-n
michael@0 220 ADD r12,r12,r14 ;
michael@0 221 LDRSH r12,[r12,r14] ; r12 = node=_tree[node+1+bits]
michael@0 222 RSB r5,r5,#32 ; r5 = available
michael@0 223 ; Stall...
michael@0 224 RSBS r14,r12,#0 ; r14 = -node, node>0 => MI
michael@0 225 BMI oc_huff_token_decode_continue
michael@0 226 MOV r10,r14,LSR #8 ; r10 = n=node>>8
michael@0 227 MOV r4,r4,LSL r10 ; r4 = window<<=n
michael@0 228 SUB r5,r10 ; r5 = available-=n
michael@0 229 STMIB r0,{r3-r5} ; ptr = r3
michael@0 230 ; window = r4
michael@0 231 ; available = r5
michael@0 232 AND r0,r14,#255 ; r0 = node&255
michael@0 233 LDMFD r13!,{r4,r5,r10,pc}
michael@0 234 ENDP
michael@0 235
michael@0 236 END

mercurial