063d0527bd01df7bfe3a8d8e04bb4704f4b0f6d1
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ARDroneLib / VLIB / Platform / arm9_P6 / UVLC / uvlc_p6.S
1 #include "../video_utils_p6.h"
2
3 #ifdef HAS_UVLC_ENCODE
4
5         .text
6         .align  4
7
8
9         .global uvlc_encode
10         .type   uvlc_encode, %function
11
12 /*
13   Registers usage
14     r0 : stream
15     r1 : value_code
16     r2 : value_length
17     r3 : not_last (do not modify)
18     ip : run
19     lr : level
20 */
21 uvlc_encode:
22         stmdb   sp!, {r4, r5, lr}         /* save regiter on the stack */
23
24         mov     ip, r2                    /* ip = run */
25         clz     r4, ip                    /* r4 = clz(run) */
26
27         movs    lr, r1                    /* lr = level */
28         rsbmi   lr, lr, #0                /* lr = |level| */
29         movmi   r5, #1
30         movpl   r5, #0                    /* save sign value */
31         mov     r1, #1                    /* value_code = 1 */
32
33   /* Serialize run */
34
35         rsbs    r4, r4, #31               /* length = 31 - clz(run) */
36         subgt   ip, ip, r1, lsl r4        /* run = run - (1 << length) */
37         add     r4, r4, #1
38         add     r2, r4, #1                /* value_length = length + 1 */
39         subgt   r4, r4, #1
40         orrgt   r1, ip, r1, lsl r4
41         addgt   r2, r2, r4
42
43   /* Serialize level */
44         mov     ip, #1
45         clz     r4, lr
46         rsbs    r4, r4, #31               /* r4 = 31 - clz(level) number of bits used in level */
47         subgt   lr, ip, lsl r4            /* code -= (1 << length) */
48         addgt   r4, r4, #1
49         add     r4, r4, #1
50         add     r2, r2, r4                /* value_length += length */
51         orr     r1, ip, r1, lsl r4        /* value_code = 1 | (value_code << length) */
52         subs    r4, r4, #2
53         addgt   r2, r2, r4                /* value_length += length */
54         orrgt   r1, lr, r1, lsl r4        /* value_code = code | (value_code << length) */
55         add     r2, r2, #1
56         orr     r1, r5, r1, lsl #1
57
58   /* Serialize not_last if needed */
59         ldmia   sp!, {r4, r5, lr}         /* restore saved registers */
60
61         cmp     r3, #0
62         addeq   r2, r2, #3                /* value_length += 3 */
63         moveq   ip, #5
64         orreq   r1, ip, r1, lsl #3        /* value_code = 0x5 | (value_code << 3) */
65
66         b       video_write_data          /* jump to video_write_data to serialize data */
67
68 #endif