Rough merge of master into experimental
[platform/upstream/libvpx.git] / vp9 / encoder / arm / armv5te / boolhuff_armv5te.asm
1 ;
2 ;  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 ;
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.
9 ;
10
11
12     EXPORT |vp8_start_encode|
13     EXPORT |vp9_encode_bool|
14     EXPORT |vp8_stop_encode|
15     EXPORT |vp8_encode_value|
16
17     INCLUDE vp9_asm_enc_offsets.asm
18
19     ARM
20     REQUIRE8
21     PRESERVE8
22
23     AREA    |.text|, CODE, READONLY
24
25 ; r0 BOOL_CODER *br
26 ; r1 unsigned char *source
27
28 |vp8_start_encode| PROC
29     mov     r12, #0
30     mov     r3,  #255
31     mvn     r2,  #23
32     str     r12, [r0, #vp9_writer_lowvalue]
33     str     r3,  [r0, #vp9_writer_range]
34     str     r12, [r0, #vp9_writer_value]
35     str     r2,  [r0, #vp9_writer_count]
36     str     r12, [r0, #vp9_writer_pos]
37     str     r1,  [r0, #vp9_writer_buffer]
38     bx      lr
39     ENDP
40
41 ; r0 BOOL_CODER *br
42 ; r1 int bit
43 ; r2 int probability
44 |vp9_encode_bool| PROC
45     push    {r4-r9, lr}
46
47     mov     r4, r2
48
49     ldr     r2, [r0, #vp9_writer_lowvalue]
50     ldr     r5, [r0, #vp9_writer_range]
51     ldr     r3, [r0, #vp9_writer_count]
52
53     sub     r7, r5, #1                  ; range-1
54
55     cmp     r1, #0
56     mul     r6, r4, r7                  ; ((range-1) * probability)
57
58     mov     r7, #1
59     add     r4, r7, r6, lsr #8          ; 1 + (((range-1) * probability) >> 8)
60
61     addne   r2, r2, r4                  ; if  (bit) lowvalue += split
62     subne   r4, r5, r4                  ; if  (bit) range = range-split
63
64     ; Counting the leading zeros is used to normalize range.
65     clz     r6, r4
66     sub     r6, r6, #24                 ; shift
67
68     ; Flag is set on the sum of count.  This flag is used later
69     ; to determine if count >= 0
70     adds    r3, r3, r6                  ; count += shift
71     lsl     r5, r4, r6                  ; range <<= shift
72     bmi     token_count_lt_zero         ; if(count >= 0)
73
74     sub     r6, r6, r3                  ; offset = shift - count
75     sub     r4, r6, #1                  ; offset-1
76     lsls    r4, r2, r4                  ; if((lowvalue<<(offset-1)) & 0x80000000 )
77     bpl     token_high_bit_not_set
78
79     ldr     r4, [r0, #vp9_writer_pos]   ; x
80     sub     r4, r4, #1                  ; x = w->pos-1
81     b       token_zero_while_start
82 token_zero_while_loop
83     mov     r9, #0
84     strb    r9, [r7, r4]                ; w->buffer[x] =(unsigned char)0
85     sub     r4, r4, #1                  ; x--
86 token_zero_while_start
87     cmp     r4, #0
88     ldrge   r7, [r0, #vp9_writer_buffer]
89     ldrb    r1, [r7, r4]
90     cmpge   r1, #0xff
91     beq     token_zero_while_loop
92
93     ldr     r7, [r0, #vp9_writer_buffer]
94     ldrb    r9, [r7, r4]                ; w->buffer[x]
95     add     r9, r9, #1
96     strb    r9, [r7, r4]                ; w->buffer[x] + 1
97 token_high_bit_not_set
98     rsb     r4, r6, #24                 ; 24-offset
99     ldr     r9, [r0, #vp9_writer_buffer]
100     lsr     r7, r2, r4                  ; lowvalue >> (24-offset)
101     ldr     r4, [r0, #vp9_writer_pos]   ; w->pos
102     lsl     r2, r2, r6                  ; lowvalue <<= offset
103     mov     r6, r3                      ; shift = count
104     add     r1, r4, #1                  ; w->pos++
105     bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
106     str     r1, [r0, #vp9_writer_pos]
107     sub     r3, r3, #8                  ; count -= 8
108     strb    r7, [r9, r4]                ; w->buffer[w->pos++]
109
110 token_count_lt_zero
111     lsl     r2, r2, r6                  ; lowvalue <<= shift
112
113     str     r2, [r0, #vp9_writer_lowvalue]
114     str     r5, [r0, #vp9_writer_range]
115     str     r3, [r0, #vp9_writer_count]
116     pop     {r4-r9, pc}
117     ENDP
118
119 ; r0 BOOL_CODER *br
120 |vp8_stop_encode| PROC
121     push    {r4-r10, lr}
122
123     ldr     r2, [r0, #vp9_writer_lowvalue]
124     ldr     r5, [r0, #vp9_writer_range]
125     ldr     r3, [r0, #vp9_writer_count]
126
127     mov     r10, #32
128
129 stop_encode_loop
130     sub     r7, r5, #1                  ; range-1
131
132     mov     r4, r7, lsl #7              ; ((range-1) * 128)
133
134     mov     r7, #1
135     add     r4, r7, r4, lsr #8          ; 1 + (((range-1) * 128) >> 8)
136
137     ; Counting the leading zeros is used to normalize range.
138     clz     r6, r4
139     sub     r6, r6, #24                 ; shift
140
141     ; Flag is set on the sum of count.  This flag is used later
142     ; to determine if count >= 0
143     adds    r3, r3, r6                  ; count += shift
144     lsl     r5, r4, r6                  ; range <<= shift
145     bmi     token_count_lt_zero_se      ; if(count >= 0)
146
147     sub     r6, r6, r3                  ; offset = shift - count
148     sub     r4, r6, #1                  ; offset-1
149     lsls    r4, r2, r4                  ; if((lowvalue<<(offset-1)) & 0x80000000 )
150     bpl     token_high_bit_not_set_se
151
152     ldr     r4, [r0, #vp9_writer_pos]   ; x
153     sub     r4, r4, #1                  ; x = w->pos-1
154     b       token_zero_while_start_se
155 token_zero_while_loop_se
156     mov     r9, #0
157     strb    r9, [r7, r4]                ; w->buffer[x] =(unsigned char)0
158     sub     r4, r4, #1                  ; x--
159 token_zero_while_start_se
160     cmp     r4, #0
161     ldrge   r7, [r0, #vp9_writer_buffer]
162     ldrb    r1, [r7, r4]
163     cmpge   r1, #0xff
164     beq     token_zero_while_loop_se
165
166     ldr     r7, [r0, #vp9_writer_buffer]
167     ldrb    r9, [r7, r4]                ; w->buffer[x]
168     add     r9, r9, #1
169     strb    r9, [r7, r4]                ; w->buffer[x] + 1
170 token_high_bit_not_set_se
171     rsb     r4, r6, #24                 ; 24-offset
172     ldr     r9, [r0, #vp9_writer_buffer]
173     lsr     r7, r2, r4                  ; lowvalue >> (24-offset)
174     ldr     r4, [r0, #vp9_writer_pos]   ; w->pos
175     lsl     r2, r2, r6                  ; lowvalue <<= offset
176     mov     r6, r3                      ; shift = count
177     add     r1, r4, #1                  ; w->pos++
178     bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
179     str     r1, [r0, #vp9_writer_pos]
180     sub     r3, r3, #8                  ; count -= 8
181     strb    r7, [r9, r4]                ; w->buffer[w->pos++]
182
183 token_count_lt_zero_se
184     lsl     r2, r2, r6                  ; lowvalue <<= shift
185
186     subs    r10, r10, #1
187     bne     stop_encode_loop
188
189     str     r2, [r0, #vp9_writer_lowvalue]
190     str     r5, [r0, #vp9_writer_range]
191     str     r3, [r0, #vp9_writer_count]
192     pop     {r4-r10, pc}
193
194     ENDP
195
196 ; r0 BOOL_CODER *br
197 ; r1 int data
198 ; r2 int bits
199 |vp8_encode_value| PROC
200     push    {r4-r11, lr}
201
202     mov     r10, r2
203
204     ldr     r2, [r0, #vp9_writer_lowvalue]
205     ldr     r5, [r0, #vp9_writer_range]
206     ldr     r3, [r0, #vp9_writer_count]
207
208     rsb     r4, r10, #32                 ; 32-n
209
210     ; v is kept in r1 during the token pack loop
211     lsl     r1, r1, r4                  ; r1 = v << 32 - n
212
213 encode_value_loop
214     sub     r7, r5, #1                  ; range-1
215
216     ; Decisions are made based on the bit value shifted
217     ; off of v, so set a flag here based on this.
218     ; This value is refered to as "bb"
219     lsls    r1, r1, #1                  ; bit = v >> n
220     mov     r4, r7, lsl #7              ; ((range-1) * 128)
221
222     mov     r7, #1
223     add     r4, r7, r4, lsr #8          ; 1 + (((range-1) * 128) >> 8)
224
225     addcs   r2, r2, r4                  ; if  (bit) lowvalue += split
226     subcs   r4, r5, r4                  ; if  (bit) range = range-split
227
228     ; Counting the leading zeros is used to normalize range.
229     clz     r6, r4
230     sub     r6, r6, #24                 ; shift
231
232     ; Flag is set on the sum of count.  This flag is used later
233     ; to determine if count >= 0
234     adds    r3, r3, r6                  ; count += shift
235     lsl     r5, r4, r6                  ; range <<= shift
236     bmi     token_count_lt_zero_ev      ; if(count >= 0)
237
238     sub     r6, r6, r3                  ; offset = shift - count
239     sub     r4, r6, #1                  ; offset-1
240     lsls    r4, r2, r4                  ; if((lowvalue<<(offset-1)) & 0x80000000 )
241     bpl     token_high_bit_not_set_ev
242
243     ldr     r4, [r0, #vp9_writer_pos]   ; x
244     sub     r4, r4, #1                  ; x = w->pos-1
245     b       token_zero_while_start_ev
246 token_zero_while_loop_ev
247     mov     r9, #0
248     strb    r9, [r7, r4]                ; w->buffer[x] =(unsigned char)0
249     sub     r4, r4, #1                  ; x--
250 token_zero_while_start_ev
251     cmp     r4, #0
252     ldrge   r7, [r0, #vp9_writer_buffer]
253     ldrb    r11, [r7, r4]
254     cmpge   r11, #0xff
255     beq     token_zero_while_loop_ev
256
257     ldr     r7, [r0, #vp9_writer_buffer]
258     ldrb    r9, [r7, r4]                ; w->buffer[x]
259     add     r9, r9, #1
260     strb    r9, [r7, r4]                ; w->buffer[x] + 1
261 token_high_bit_not_set_ev
262     rsb     r4, r6, #24                 ; 24-offset
263     ldr     r9, [r0, #vp9_writer_buffer]
264     lsr     r7, r2, r4                  ; lowvalue >> (24-offset)
265     ldr     r4, [r0, #vp9_writer_pos]   ; w->pos
266     lsl     r2, r2, r6                  ; lowvalue <<= offset
267     mov     r6, r3                      ; shift = count
268     add     r11, r4, #1                 ; w->pos++
269     bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
270     str     r11, [r0, #vp9_writer_pos]
271     sub     r3, r3, #8                  ; count -= 8
272     strb    r7, [r9, r4]                ; w->buffer[w->pos++]
273
274 token_count_lt_zero_ev
275     lsl     r2, r2, r6                  ; lowvalue <<= shift
276
277     subs    r10, r10, #1
278     bne     encode_value_loop
279
280     str     r2, [r0, #vp9_writer_lowvalue]
281     str     r5, [r0, #vp9_writer_range]
282     str     r3, [r0, #vp9_writer_count]
283     pop     {r4-r11, pc}
284     ENDP
285
286     END