| ; |
| ; Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
| ; |
| ; Use of this source code is governed by a BSD-style license |
| ; that can be found in the LICENSE file in the root of the source |
| ; tree. An additional intellectual property rights grant can be found |
| ; in the file PATENTS. All contributing project authors may |
| ; be found in the AUTHORS file in the root of the source tree. |
| ; |
| |
| |
| EXPORT |vp8_start_encode| |
| EXPORT |vp8_encode_bool| |
| EXPORT |vp8_stop_encode| |
| EXPORT |vp8_encode_value| |
| |
| INCLUDE vpx_vp8_enc_asm_offsets.asm |
| |
| ARM |
| REQUIRE8 |
| PRESERVE8 |
| |
| AREA |.text|, CODE, READONLY |
| |
| ; r0 BOOL_CODER *br |
| ; r1 unsigned char *source |
| |
| |vp8_start_encode| PROC |
| mov r12, #0 |
| mov r3, #255 |
| mvn r2, #23 |
| str r12, [r0, #vp8_writer_lowvalue] |
| str r3, [r0, #vp8_writer_range] |
| str r12, [r0, #vp8_writer_value] |
| str r2, [r0, #vp8_writer_count] |
| str r12, [r0, #vp8_writer_pos] |
| str r1, [r0, #vp8_writer_buffer] |
| bx lr |
| ENDP |
| |
| ; r0 BOOL_CODER *br |
| ; r1 int bit |
| ; r2 int probability |
| |vp8_encode_bool| PROC |
| push {r4-r9, lr} |
| |
| mov r4, r2 |
| |
| ldr r2, [r0, #vp8_writer_lowvalue] |
| ldr r5, [r0, #vp8_writer_range] |
| ldr r3, [r0, #vp8_writer_count] |
| |
| sub r7, r5, #1 ; range-1 |
| |
| cmp r1, #0 |
| mul r4, r4, r7 ; ((range-1) * probability) |
| |
| mov r7, #1 |
| add r4, r7, r4, lsr #8 ; 1 + (((range-1) * probability) >> 8) |
| |
| addne r2, r2, r4 ; if (bit) lowvalue += split |
| subne r4, r5, r4 ; if (bit) range = range-split |
| |
| ; Counting the leading zeros is used to normalize range. |
| clz r6, r4 |
| sub r6, r6, #24 ; shift |
| |
| ; Flag is set on the sum of count. This flag is used later |
| ; to determine if count >= 0 |
| adds r3, r3, r6 ; count += shift |
| lsl r5, r4, r6 ; range <<= shift |
| bmi token_count_lt_zero ; if(count >= 0) |
| |
| sub r6, r6, r3 ; offset = shift - count |
| sub r4, r6, #1 ; offset-1 |
| lsls r4, r2, r4 ; if((lowvalue<<(offset-1)) & 0x80000000 ) |
| bpl token_high_bit_not_set |
| |
| ldr r4, [r0, #vp8_writer_pos] ; x |
| sub r4, r4, #1 ; x = w->pos-1 |
| b token_zero_while_start |
| token_zero_while_loop |
| mov r9, #0 |
| strb r9, [r7, r4] ; w->buffer[x] =(unsigned char)0 |
| sub r4, r4, #1 ; x-- |
| token_zero_while_start |
| cmp r4, #0 |
| ldrge r7, [r0, #vp8_writer_buffer] |
| ldrb r1, [r7, r4] |
| cmpge r1, #0xff |
| beq token_zero_while_loop |
| |
| ldr r7, [r0, #vp8_writer_buffer] |
| ldrb r9, [r7, r4] ; w->buffer[x] |
| add r9, r9, #1 |
| strb r9, [r7, r4] ; w->buffer[x] + 1 |
| token_high_bit_not_set |
| rsb r4, r6, #24 ; 24-offset |
| ldr r9, [r0, #vp8_writer_buffer] |
| lsr r7, r2, r4 ; lowvalue >> (24-offset) |
| ldr r4, [r0, #vp8_writer_pos] ; w->pos |
| lsl r2, r2, r6 ; lowvalue <<= offset |
| mov r6, r3 ; shift = count |
| add r1, r4, #1 ; w->pos++ |
| bic r2, r2, #0xff000000 ; lowvalue &= 0xffffff |
| str r1, [r0, #vp8_writer_pos] |
| sub r3, r3, #8 ; count -= 8 |
| strb r7, [r9, r4] ; w->buffer[w->pos++] |
| |
| token_count_lt_zero |
| lsl r2, r2, r6 ; lowvalue <<= shift |
| |
| str r2, [r0, #vp8_writer_lowvalue] |
| str r5, [r0, #vp8_writer_range] |
| str r3, [r0, #vp8_writer_count] |
| pop {r4-r9, pc} |
| ENDP |
| |
| ; r0 BOOL_CODER *br |
| |vp8_stop_encode| PROC |
| push {r4-r10, lr} |
| |
| ldr r2, [r0, #vp8_writer_lowvalue] |
| ldr r5, [r0, #vp8_writer_range] |
| ldr r3, [r0, #vp8_writer_count] |
| |
| mov r10, #32 |
| |
| stop_encode_loop |
| sub r7, r5, #1 ; range-1 |
| |
| mov r4, r7, lsl #7 ; ((range-1) * 128) |
| |
| mov r7, #1 |
| add r4, r7, r4, lsr #8 ; 1 + (((range-1) * 128) >> 8) |
| |
| ; Counting the leading zeros is used to normalize range. |
| clz r6, r4 |
| sub r6, r6, #24 ; shift |
| |
| ; Flag is set on the sum of count. This flag is used later |
| ; to determine if count >= 0 |
| adds r3, r3, r6 ; count += shift |
| lsl r5, r4, r6 ; range <<= shift |
| bmi token_count_lt_zero_se ; if(count >= 0) |
| |
| sub r6, r6, r3 ; offset = shift - count |
| sub r4, r6, #1 ; offset-1 |
| lsls r4, r2, r4 ; if((lowvalue<<(offset-1)) & 0x80000000 ) |
| bpl token_high_bit_not_set_se |
| |
| ldr r4, [r0, #vp8_writer_pos] ; x |
| sub r4, r4, #1 ; x = w->pos-1 |
| b token_zero_while_start_se |
| token_zero_while_loop_se |
| mov r9, #0 |
| strb r9, [r7, r4] ; w->buffer[x] =(unsigned char)0 |
| sub r4, r4, #1 ; x-- |
| token_zero_while_start_se |
| cmp r4, #0 |
| ldrge r7, [r0, #vp8_writer_buffer] |
| ldrb r1, [r7, r4] |
| cmpge r1, #0xff |
| beq token_zero_while_loop_se |
| |
| ldr r7, [r0, #vp8_writer_buffer] |
| ldrb r9, [r7, r4] ; w->buffer[x] |
| add r9, r9, #1 |
| strb r9, [r7, r4] ; w->buffer[x] + 1 |
| token_high_bit_not_set_se |
| rsb r4, r6, #24 ; 24-offset |
| ldr r9, [r0, #vp8_writer_buffer] |
| lsr r7, r2, r4 ; lowvalue >> (24-offset) |
| ldr r4, [r0, #vp8_writer_pos] ; w->pos |
| lsl r2, r2, r6 ; lowvalue <<= offset |
| mov r6, r3 ; shift = count |
| add r1, r4, #1 ; w->pos++ |
| bic r2, r2, #0xff000000 ; lowvalue &= 0xffffff |
| str r1, [r0, #vp8_writer_pos] |
| sub r3, r3, #8 ; count -= 8 |
| strb r7, [r9, r4] ; w->buffer[w->pos++] |
| |
| token_count_lt_zero_se |
| lsl r2, r2, r6 ; lowvalue <<= shift |
| |
| subs r10, r10, #1 |
| bne stop_encode_loop |
| |
| str r2, [r0, #vp8_writer_lowvalue] |
| str r5, [r0, #vp8_writer_range] |
| str r3, [r0, #vp8_writer_count] |
| pop {r4-r10, pc} |
| |
| ENDP |
| |
| ; r0 BOOL_CODER *br |
| ; r1 int data |
| ; r2 int bits |
| |vp8_encode_value| PROC |
| push {r4-r11, lr} |
| |
| mov r10, r2 |
| |
| ldr r2, [r0, #vp8_writer_lowvalue] |
| ldr r5, [r0, #vp8_writer_range] |
| ldr r3, [r0, #vp8_writer_count] |
| |
| ; reverse the stream of bits to be packed. Normally |
| ; the most significant bit is peeled off and compared |
| ; in the form of (v >> --n) & 1. ARM architecture has |
| ; the ability to set a flag based on the value of the |
| ; bit shifted off the bottom of the register. To make |
| ; that happen the bitstream is reversed. |
| rbit r11, r1 |
| rsb r4, r10, #32 ; 32-n |
| |
| ; v is kept in r1 during the token pack loop |
| lsr r1, r11, r4 ; v >>= 32 - n |
| |
| encode_value_loop |
| sub r7, r5, #1 ; range-1 |
| |
| ; Decisions are made based on the bit value shifted |
| ; off of v, so set a flag here based on this. |
| ; This value is refered to as "bb" |
| lsrs r1, r1, #1 ; bit = v >> n |
| mov r4, r7, lsl #7 ; ((range-1) * 128) |
| |
| mov r7, #1 |
| add r4, r7, r4, lsr #8 ; 1 + (((range-1) * 128) >> 8) |
| |
| addcs r2, r2, r4 ; if (bit) lowvalue += split |
| subcs r4, r5, r4 ; if (bit) range = range-split |
| |
| ; Counting the leading zeros is used to normalize range. |
| clz r6, r4 |
| sub r6, r6, #24 ; shift |
| |
| ; Flag is set on the sum of count. This flag is used later |
| ; to determine if count >= 0 |
| adds r3, r3, r6 ; count += shift |
| lsl r5, r4, r6 ; range <<= shift |
| bmi token_count_lt_zero_ev ; if(count >= 0) |
| |
| sub r6, r6, r3 ; offset = shift - count |
| sub r4, r6, #1 ; offset-1 |
| lsls r4, r2, r4 ; if((lowvalue<<(offset-1)) & 0x80000000 ) |
| bpl token_high_bit_not_set_ev |
| |
| ldr r4, [r0, #vp8_writer_pos] ; x |
| sub r4, r4, #1 ; x = w->pos-1 |
| b token_zero_while_start_ev |
| token_zero_while_loop_ev |
| mov r9, #0 |
| strb r9, [r7, r4] ; w->buffer[x] =(unsigned char)0 |
| sub r4, r4, #1 ; x-- |
| token_zero_while_start_ev |
| cmp r4, #0 |
| ldrge r7, [r0, #vp8_writer_buffer] |
| ldrb r11, [r7, r4] |
| cmpge r11, #0xff |
| beq token_zero_while_loop_ev |
| |
| ldr r7, [r0, #vp8_writer_buffer] |
| ldrb r9, [r7, r4] ; w->buffer[x] |
| add r9, r9, #1 |
| strb r9, [r7, r4] ; w->buffer[x] + 1 |
| token_high_bit_not_set_ev |
| rsb r4, r6, #24 ; 24-offset |
| ldr r9, [r0, #vp8_writer_buffer] |
| lsr r7, r2, r4 ; lowvalue >> (24-offset) |
| ldr r4, [r0, #vp8_writer_pos] ; w->pos |
| lsl r2, r2, r6 ; lowvalue <<= offset |
| mov r6, r3 ; shift = count |
| add r11, r4, #1 ; w->pos++ |
| bic r2, r2, #0xff000000 ; lowvalue &= 0xffffff |
| str r11, [r0, #vp8_writer_pos] |
| sub r3, r3, #8 ; count -= 8 |
| strb r7, [r9, r4] ; w->buffer[w->pos++] |
| |
| token_count_lt_zero_ev |
| lsl r2, r2, r6 ; lowvalue <<= shift |
| |
| subs r10, r10, #1 |
| bne encode_value_loop |
| |
| str r2, [r0, #vp8_writer_lowvalue] |
| str r5, [r0, #vp8_writer_range] |
| str r3, [r0, #vp8_writer_count] |
| pop {r4-r11, pc} |
| ENDP |
| |
| END |