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