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 |vp8cx_pack_tokens_armv5|
     13 
     14     INCLUDE asm_enc_offsets.asm
     15 
     16     ARM
     17     REQUIRE8
     18     PRESERVE8
     19 
     20     AREA    |.text|, CODE, READONLY
     21 
     22 ; r0 vp8_writer *w
     23 ; r1 const TOKENEXTRA *p
     24 ; r2 int xcount
     25 ; r3 vp8_coef_encodings
     26 ; s0 vp8_extra_bits
     27 ; s1 vp8_coef_tree
     28 |vp8cx_pack_tokens_armv5| PROC
     29     push    {r4-r11, lr}
     30 
     31     ; Add size of xcount * sizeof (TOKENEXTRA) to get stop
     32     ;  sizeof (TOKENEXTRA) is 8
     33     sub     sp, sp, #12
     34     add     r2, r1, r2, lsl #3          ; stop = p + xcount*sizeof(TOKENEXTRA)
     35     str     r2, [sp, #0]
     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]
     40     b       check_p_lt_stop
     41 
     42 while_p_lt_stop
     43     ldrb    r6, [r1, #tokenextra_token] ; t
     44     ldr     r4, [sp, #8]                ; vp8_coef_encodings
     45     mov     lr, #0
     46     add     r4, r4, r6, lsl #3          ; a = vp8_coef_encodings + t
     47     ldr     r9, [r1, #tokenextra_context_tree]   ; pp
     48 
     49     ldrb    r7, [r1, #tokenextra_skip_eob_node]
     50 
     51     ldr     r6, [r4, #vp8_token_value]  ; v
     52     ldr     r8, [r4, #vp8_token_len]    ; n
     53 
     54     ; vp8 specific skip_eob_node
     55     cmp     r7, #0
     56     movne   lr, #2                      ; i = 2
     57     subne   r8, r8, #1                  ; --n
     58 
     59     rsb     r4, r8, #32                 ; 32-n
     60     ldr     r10, [sp, #52]              ; vp8_coef_tree
     61 
     62     ; v is kept in r12 during the token pack loop
     63     lsl     r12, r6, r4                ; r12 = v << 32 - n
     64 
     65 ; loop start
     66 token_loop
     67     ldrb    r4, [r9, lr, asr #1]        ; pp [i>>1]
     68     sub     r7, r5, #1                  ; range-1
     69 
     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]))
     75 
     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
     79 
     80     mov     r7, #1
     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)
     83 
     84     addcs   r2, r2, r4                  ; if  (bb) lowvalue += split
     85     subcs   r4, r5, r4                  ; if  (bb) range = range-split
     86 
     87     ; Counting the leading zeros is used to normalize range.
     88     clz     r6, r4
     89     sub     r6, r6, #24                 ; shift
     90 
     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)
     96 
     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
    101 
    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
    106     mov     r10, #0
    107     strb    r10, [r7, r4]               ; w->buffer[x] =(unsigned char)0
    108     sub     r4, r4, #1                  ; x--
    109 token_zero_while_start
    110     cmp     r4, #0
    111     ldrge   r7, [r0, #vp8_writer_buffer]
    112     ldrb    r11, [r7, r4]
    113     cmpge   r11, #0xff
    114     beq     token_zero_while_loop
    115 
    116     ldr     r7, [r0, #vp8_writer_buffer]
    117     ldrb    r10, [r7, r4]               ; w->buffer[x]
    118     add     r10, r10, #1
    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++]
    132 
    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
    137 
    138 token_count_lt_zero
    139     lsl     r2, r2, r6                  ; lowvalue <<= shift
    140 
    141     subs    r8, r8, #1                  ; --n
    142     bne     token_loop
    143 
    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
    149 
    150     ldr     r4, [r12, #vp8_extra_bit_struct_base_val]
    151     cmp     r4, #0
    152     beq     skip_extra_bits
    153 
    154 ;   if( b->base_val)
    155     ldr     r8, [r12, #vp8_extra_bit_struct_len] ; L
    156     ldrsh   lr, [r1, #tokenextra_extra] ; e = p->Extra
    157     cmp     r8, #0                      ; if( L)
    158     beq     no_extra_bits
    159 
    160     ldr     r9, [r12, #vp8_extra_bit_struct_prob]
    161     asr     r7, lr, #1                  ; v=e>>1
    162 
    163     ldr     r10, [r12, #vp8_extra_bit_struct_tree]
    164     str     r10, [sp, #4]               ; b->tree
    165 
    166     rsb     r4, r8, #32
    167     lsl     r12, r7, r4
    168 
    169     mov     lr, #0                      ; i = 0
    170 
    171 extra_bits_loop
    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
    177 
    178     mov     r7, #1
    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)
    181 
    182     addcs   r2, r2, r4                  ; if  (bb) lowvalue += split
    183     subcs   r4, r5, r4                  ; if  (bb) range = range-split
    184 
    185     clz     r6, r4
    186     sub     r6, r6, #24
    187 
    188     adds    r3, r3, r6                  ; count += shift
    189     lsl     r5, r4, r6                  ; range <<= shift
    190     bmi     extra_count_lt_zero         ; if(count >= 0)
    191 
    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
    196 
    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
    201     mov     r10, #0
    202     strb    r10, [r7, r4]               ; w->buffer[x] =(unsigned char)0
    203     sub     r4, r4, #1                  ; x--
    204 extra_zero_while_start
    205     cmp     r4, #0
    206     ldrge   r7, [r0, #vp8_writer_buffer]
    207     ldrb    r11, [r7, r4]
    208     cmpge   r11, #0xff
    209     beq     extra_zero_while_loop
    210 
    211     ldr     r7, [r0, #vp8_writer_buffer]
    212     ldrb    r10, [r7, r4]
    213     add     r10, r10, #1
    214     strb    r10, [r7, r4]
    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
    228 extra_count_lt_zero
    229     lsl     r2, r2, r6
    230 
    231     subs    r8, r8, #1                  ; --n
    232     bne     extra_bits_loop             ; while (n)
    233 
    234 no_extra_bits
    235     ldr     lr, [r1, #4]                ; e = p->Extra
    236     add     r4, r5, #1                  ; range + 1
    237     tst     lr, #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
    244 
    245     ldr     r4, [r0, #vp8_writer_pos]
    246     mov     r7, #0
    247     sub     r4, r4, #1
    248     b       end_zero_while_start
    249 end_zero_while_loop
    250     strb    r7, [r6, r4]
    251     sub     r4, r4, #1                  ; x--
    252 end_zero_while_start
    253     cmp     r4, #0
    254     ldrge   r6, [r0, #vp8_writer_buffer]
    255     ldrb    r12, [r6, r4]
    256     cmpge   r12, #0xff
    257     beq     end_zero_while_loop
    258 
    259     ldr     r6, [r0, #vp8_writer_buffer]
    260     ldrb    r7, [r6, r4]
    261     add     r7, r7, #1
    262     strb    r7, [r6, r4]
    263 end_high_bit_not_set
    264     adds    r3, r3, #1                  ; ++count
    265     lsl     r2, r2, #1                  ; lowvalue  <<= 1
    266     bne     end_count_zero
    267 
    268     ldr     r4, [r0, #vp8_writer_pos]
    269     mvn     r3, #7
    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
    274     str     r12, [r0, #0x10]
    275     strb    r6, [r7, r4]
    276 end_count_zero
    277 skip_extra_bits
    278     add     r1, r1, #TOKENEXTRA_SZ      ; ++p
    279 check_p_lt_stop
    280     ldr     r4, [sp, #0]                ; stop
    281     cmp     r1, r4                      ; while( p < stop)
    282     bcc     while_p_lt_stop
    283 
    284     str     r2, [r0, #vp8_writer_lowvalue]
    285     str     r5, [r0, #vp8_writer_range]
    286     str     r3, [r0, #vp8_writer_count]
    287     add     sp, sp, #12
    288     pop     {r4-r11, pc}
    289     ENDP
    290 
    291     END
    292