2 ; Copyright (c) 2010 The WebM project authors. All Rights Reserved.
4 ; Use of this source code is governed by a BSD-style license
5 ; that can be found in the LICENSE file in the root of the source
6 ; tree. An additional intellectual property rights grant can be found
7 ; in the file PATENTS. All contributing project authors may
8 ; be found in the AUTHORS file in the root of the source tree.
12 EXPORT |vp8cx_pack_tokens_armv5|
14 INCLUDE asm_enc_offsets.asm
20 AREA |.text|
, CODE
, READONLY
23 ; r1 const TOKENEXTRA *p
25 ; r3 vp8_coef_encodings
28 |vp8cx_pack_tokens_armv5|
PROC
31 ; Add size of xcount * sizeof (TOKENEXTRA) to get stop
32 ; sizeof (TOKENEXTRA) is 8
34 add r2
, r1
, r2
, lsl #
3 ; stop = p + xcount*sizeof(TOKENEXTRA)
36 str r3
, [sp, #
8] ; save vp8_coef_encodings
37 ldr r2
, [r0
, #vp8_writer_lowvalue
]
38 ldr r5
, [r0
, #vp8_writer_range
]
39 ldr r3
, [r0
, #vp8_writer_count
]
43 ldrb r6
, [r1
, #tokenextra_token
] ; t
44 ldr r4
, [sp, #
8] ; vp8_coef_encodings
46 add r4
, r4
, r6
, lsl #
3 ; a = vp8_coef_encodings + t
47 ldr r9
, [r1
, #tokenextra_context_tree
] ; pp
49 ldrb r7
, [r1
, #tokenextra_skip_eob_node
]
51 ldr r6
, [r4
, #vp8_token_value
] ; v
52 ldr r8
, [r4
, #vp8_token_len
] ; n
54 ; vp8 specific skip_eob_node
57 subne r8
, r8
, #
1 ; --n
59 rsb r4
, r8
, #
32 ; 32-n
60 ldr r10
, [sp, #
52] ; vp8_coef_tree
62 ; v is kept in r12 during the token pack loop
63 lsl r12
, r6
, r4
; r12 = v << 32 - n
67 ldrb r4
, [r9
, lr
, asr #
1] ; pp [i>>1]
68 sub r7
, r5
, #
1 ; range-1
70 ; Decisions are made based on the bit value shifted
71 ; off of v, so set a flag here based on this.
72 ; This value is refered to as "bb"
73 lsls r12
, r12
, #
1 ; bb = v >> n
74 mul r4
, r4
, r7
; ((range-1) * pp[i>>1]))
76 ; bb can only be 0 or 1. So only execute this statement
77 ; if bb == 1, otherwise it will act like i + 0
78 addcs lr
, lr
, #
1 ; i + bb
81 ldrsb lr
, [r10
, lr
] ; i = vp8_coef_tree[i+bb]
82 add r4
, r7
, r4
, lsr #
8 ; 1 + (((range-1) * pp[i>>1]) >> 8)
84 addcs r2
, r2
, r4
; if (bb) lowvalue += split
85 subcs r4
, r5
, r4
; if (bb) range = range-split
87 ; Counting the leading zeros is used to normalize range.
89 sub r6
, r6
, #
24 ; shift
91 ; Flag is set on the sum of count. This flag is used later
92 ; to determine if count >= 0
93 adds r3
, r3
, r6
; count += shift
94 lsl r5
, r4
, r6
; range <<= shift
95 bmi token_count_lt_zero
; if(count >= 0)
97 sub r6
, r6
, r3
; offset = shift - count
98 sub r4
, r6
, #
1 ; offset-1
99 lsls r4
, r2
, r4
; if((lowvalue<<(offset-1)) & 0x80000000 )
100 bpl token_high_bit_not_set
102 ldr r4
, [r0
, #vp8_writer_pos
] ; x
103 sub r4
, r4
, #
1 ; x = w->pos-1
104 b token_zero_while_start
105 token_zero_while_loop
107 strb r10
, [r7
, r4
] ; w->buffer[x] =(unsigned char)0
109 token_zero_while_start
111 ldrge r7
, [r0
, #vp8_writer_buffer
]
114 beq token_zero_while_loop
116 ldr r7
, [r0
, #vp8_writer_buffer
]
117 ldrb r10
, [r7
, r4
] ; w->buffer[x]
119 strb r10
, [r7
, r4
] ; w->buffer[x] + 1
120 token_high_bit_not_set
121 rsb r4
, r6
, #
24 ; 24-offset
122 ldr r10
, [r0
, #vp8_writer_buffer
]
123 lsr r7
, r2
, r4
; lowvalue >> (24-offset)
124 ldr r4
, [r0
, #vp8_writer_pos
] ; w->pos
125 lsl r2
, r2
, r6
; lowvalue <<= offset
126 mov r6
, r3
; shift = count
127 add r11
, r4
, #
1 ; w->pos++
128 bic r2
, r2
, #
0xff000000 ; lowvalue &= 0xffffff
129 str r11
, [r0
, #vp8_writer_pos
]
130 sub r3
, r3
, #
8 ; count -= 8
131 strb r7
, [r10
, r4
] ; w->buffer[w->pos++]
133 ; r10 is used earlier in the loop, but r10 is used as
134 ; temp variable here. So after r10 is used, reload
135 ; vp8_coef_tree_dcd into r10
136 ldr r10
, [sp, #
52] ; vp8_coef_tree
139 lsl r2
, r2
, r6
; lowvalue <<= shift
141 subs r8
, r8
, #
1 ; --n
144 ldrb r6
, [r1
, #tokenextra_token
] ; t
145 ldr r7
, [sp, #
48] ; vp8_extra_bits
146 ; Add t * sizeof (vp8_extra_bit_struct) to get the desired
147 ; element. Here vp8_extra_bit_struct == 16
148 add r12
, r7
, r6
, lsl #
4 ; b = vp8_extra_bits + t
150 ldr r4
, [r12
, #vp8_extra_bit_struct_base_val
]
155 ldr r8
, [r12
, #vp8_extra_bit_struct_len
] ; L
156 ldrsh lr
, [r1
, #tokenextra_extra
] ; e = p->Extra
160 ldr r9
, [r12
, #vp8_extra_bit_struct_prob
]
161 asr r7
, lr
, #
1 ; v=e>>1
163 ldr r10
, [r12
, #vp8_extra_bit_struct_tree
]
164 str r10
, [sp, #
4] ; b->tree
172 ldrb r4
, [r9
, lr
, asr #
1] ; pp[i>>1]
173 sub r7
, r5
, #
1 ; range-1
174 lsls r12
, r12
, #
1 ; v >> n
175 mul r4
, r4
, r7
; (range-1) * pp[i>>1]
176 addcs lr
, lr
, #
1 ; i + bb
179 ldrsb lr
, [r10
, lr
] ; i = b->tree[i+bb]
180 add r4
, r7
, r4
, lsr #
8 ; split = 1 + (((range-1) * pp[i>>1]) >> 8)
182 addcs r2
, r2
, r4
; if (bb) lowvalue += split
183 subcs r4
, r5
, r4
; if (bb) range = range-split
188 adds r3
, r3
, r6
; count += shift
189 lsl r5
, r4
, r6
; range <<= shift
190 bmi extra_count_lt_zero
; if(count >= 0)
192 sub r6
, r6
, r3
; offset= shift - count
193 sub r4
, r6
, #
1 ; offset-1
194 lsls r4
, r2
, r4
; if((lowvalue<<(offset-1)) & 0x80000000 )
195 bpl extra_high_bit_not_set
197 ldr r4
, [r0
, #vp8_writer_pos
] ; x
198 sub r4
, r4
, #
1 ; x = w->pos - 1
199 b extra_zero_while_start
200 extra_zero_while_loop
202 strb r10
, [r7
, r4
] ; w->buffer[x] =(unsigned char)0
204 extra_zero_while_start
206 ldrge r7
, [r0
, #vp8_writer_buffer
]
209 beq extra_zero_while_loop
211 ldr r7
, [r0
, #vp8_writer_buffer
]
215 extra_high_bit_not_set
216 rsb r4
, r6
, #
24 ; 24-offset
217 ldr r10
, [r0
, #vp8_writer_buffer
]
218 lsr r7
, r2
, r4
; lowvalue >> (24-offset)
219 ldr r4
, [r0
, #vp8_writer_pos
]
220 lsl r2
, r2
, r6
; lowvalue <<= offset
221 mov r6
, r3
; shift = count
222 add r11
, r4
, #
1 ; w->pos++
223 bic r2
, r2
, #
0xff000000 ; lowvalue &= 0xffffff
224 str r11
, [r0
, #vp8_writer_pos
]
225 sub r3
, r3
, #
8 ; count -= 8
226 strb r7
, [r10
, r4
] ; w->buffer[w->pos++]=(lowvalue >> (24-offset))
227 ldr r10
, [sp, #
4] ; b->tree
231 subs r8
, r8
, #
1 ; --n
232 bne extra_bits_loop
; while (n)
235 ldr lr
, [r1
, #
4] ; e = p->Extra
236 add r4
, r5
, #
1 ; range + 1
238 lsr r4
, r4
, #
1 ; split = (range + 1) >> 1
239 addne r2
, r2
, r4
; lowvalue += split
240 subne r4
, r5
, r4
; range = range-split
241 tst r2
, #
0x80000000 ; lowvalue & 0x80000000
242 lsl r5
, r4
, #
1 ; range <<= 1
243 beq end_high_bit_not_set
245 ldr r4
, [r0
, #vp8_writer_pos
]
248 b end_zero_while_start
254 ldrge r6
, [r0
, #vp8_writer_buffer
]
257 beq end_zero_while_loop
259 ldr r6
, [r0
, #vp8_writer_buffer
]
264 adds r3
, r3
, #
1 ; ++count
265 lsl r2
, r2
, #
1 ; lowvalue <<= 1
268 ldr r4
, [r0
, #vp8_writer_pos
]
270 ldr r7
, [r0
, #vp8_writer_buffer
]
271 lsr r6
, r2
, #
24 ; lowvalue >> 24
272 add r12
, r4
, #
1 ; w->pos++
273 bic r2
, r2
, #
0xff000000 ; lowvalue &= 0xffffff
278 add r1
, r1
, #TOKENEXTRA_SZ
; ++p
280 ldr r4
, [sp, #
0] ; stop
281 cmp r1
, r4
; while( p < stop)
284 str r2
, [r0
, #vp8_writer_lowvalue
]
285 str r5
, [r0
, #vp8_writer_range
]
286 str r3
, [r0
, #vp8_writer_count
]