armbits-gnu.S 8.8 KB

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