📄 arith_encoder_mpeg4.asm
字号:
decremented by 0x40000000. Whenever renormalization is done, value of both
coder->L and coder-R is doubled. This procedure is repeated till range value
(coder->R)is greater than 0x40000000.
Registers used : R0-R3, R6, R7, P0, P5.
*******************************************************************************/
.section program;
.global __arith_encode_renormalise;
.align 8;
__arith_encode_renormalise:
P0 = R0; // Address of coder
[--SP] = (R7:6,P5:5); // Push R7:6,P5
P5 = R0; // Duplicate the address of coder
R7 = R1-R1(NS)||R0 = [P0++];
// fetch coder->L
R6 = R0-R0(NS)||R1 = [P0--];
// fetch coder->R
BITSET(R7,31); // set r7 == 0x80000000
BITSET(R6,30); // set r6 == 0x40000000
CHK_WHILE:
CC = R1<R6(IU);
// check if code->R <0x40000000
IF !CC JUMP NORME_END; // if false jump to NORME_END
CC = R7<R0(IU); // check if coder->L >0x80000000
IF !CC JUMP CHK_ELSE_IF;
R0 = R0-R7; // coder->L -= 0x80000000
[P0] = R0; // store coder->L value
R0 = 1; // arguments to arith_bitplusfollow function
R1 = P5;
[--SP] = RETS;
CALL __arith_bitplusfollow;
RETS = [SP++];
P0 = P5;
JUMP END_WHILE;
CHK_ELSE_IF: R2 = R0+R1;
CC = R2 <= R7(IU); // check if coder->L+coder->R <= 0x80000000
IF !CC JUMP CHK_ELSE; // if true call arith_bitplusfollow with bit == 0
R0 = 0;
R1 = P5;
[--SP] = RETS;
CALL __arith_bitplusfollow;
RETS = [SP++];
P0 = P5;
JUMP END_WHILE;
CHK_ELSE:
R2 = 1; // else increment bits_to_follow
R0 = R0-R6(NS)||R1 = [P0+16];
// decrement coder->L by 0x40000000
R1 = R1+R2(NS)||[P0] = R0;
// store modified coder->L value
[P0+16] = R1; // store incremented bits_to_follow value
END_WHILE:
R0 = [P0++];
R0 = R0<<1||R1 = [P0--];// double coder->L
R1 = R1<<1||[P0++] = R0;// double coder->R
[P0--] = R1; // store updated values
JUMP CHK_WHILE; // repeat the procedure till coder->R < 0x40000000
NOP; // to remove stalls on the silicon
NORME_END:
(R7:6,P5:5) = [SP++];
RTS;
NOP;
__arith_encode_renormalise.end:
/*******************************************************************************
Prototype : void arith_bitplusfollow(int bit, ArCoder *coder);
This function writes a bit to bit-stream. In order to avoid start code emulation
1's are stuffed whenever there are too many successive '0's. If the first
3(MAX_HEADING) bits are '0' then '1' is stuffed. If 10(MAX_MIDDLE) or more
zeros are sent then '1' is inserted after MAX_MIDDLE th '0'.
Registers used : R0-R3, R7, P0, P1.
******************************************************************************/
.section program;
.global __arith_bitplusfollow;
.align 8;
__arith_bitplusfollow:
P0 = R1; // Address of coder
[--SP] = R7; // Push R7 register
R1 = 1;
R7 = R0 <<0 || P1 = [P0+52];
// fetch address of output buffer
R2 = R1-R1(NS) || R3 = [P0+20];
// fetch value of first_bit flag.
CC = R3 == 0; // check if first_bit flag == 0
IF !CC JUMP CLR_FIRST_BIT;
// if false jump to CLR_FIRST_BIT
B[P1++] = R0; // store bit value to output buffer
CC = R0 == 0; // check if bit value == 0
IF !CC JUMP CHK_ELSE_COND;
R2 = [P0+24]; // get value of nzeros
R2 += -1; // decrement the value of nzeros
CC = R2 == 0; // if nzeros == 0, stuff '1'.
IF CC JUMP CHK_ELSE_1;
[P0+24] = R2;
JUMP CHK_WHILE_LOOP;
CHK_ELSE_1:
B[P1++] = R1;
// stuff '1' to output buffer
CHK_ELSE_COND:
[P0+28] = R1;
R3 = [P0+44]; // set coder->nzeros to MAX_MIDDLE(i.e 10)
[P0+24] = R3;
JUMP CHK_WHILE_LOOP;
CLR_FIRST_BIT:
[P0+20] = R2;
// clear first bit
// if coder->bits-to-follow is non zero value then !bit value is added to
// bitstream and coder->bits-to-follow is decremented. this process is continued
// till coder->bits-to-follow becomes to zero.
CHK_WHILE_LOOP:
BITTGL(R7,0);
R2 = [P0+16]; // get value of coder->bits_to_follow
TEST_BACK:
CC = R2 <= 0;
// check if coder->bits_to_follow <= 0
IF CC JUMP END_WHILE_LOOP1(bp);
R2 = R2-R1(ns)||B[P1++] = R7;
// if false !bit is stored as output
CC = R7 == 0; // stored bit is checked for zero
IF !CC JUMP CHK_ELSE2; // if true decrement the nzero counter
R0 = [P0+24];
R0 += -1;
[P0+24] = R0;
CC = R0 == 0;
IF !CC JUMP TEST_BACK;
B[P1++] = R1;
CHK_ELSE2:
[P0+28] = R1;
R3 = [P0+44];
[P0+24] = R3; // set coder->nzeros to MAX_MIDDLE (i.e 10)
JUMP TEST_BACK;
END_WHILE_LOOP1:
[P0+16] = R2;
END_WHILE_LOOP:
[P0+52] = P1;
// store the present pointer of output address
R7 = [SP++]; // Pop R7 register
RTS;
NOP;
__arith_bitplusfollow.end:
/*******************************************************************************
Prototype : void arith_StopArCoder(ArCoder *coder);
In this procedure additional bits are copied to output bit stream which is
required for proper decoding. If 2(MAX_TRAIL) or more zeroes are sent then '1'
is inserted after MAX_TRAIL th '0'.
Registers used : R0-R3, R5-R7, P0, P5.
*******************************************************************************/
.section program;
.global __arith_StopArCoder;
.align 8;
__arith_StopArCoder:
P0 = R0;
// Address of coder
[--SP] = (R7:5,P5:5); // Push R7:5,P5 and RETS register
[--SP] = RETS;
P5 = R0; // store the address in P5
R0 = [P0]; // get value of coder->L
R3 = 8;
R7 = R0>>29||R2 = [P0+4];
// fetch value of coder->R
R6 = R0+R2;
R6 = R6>>29;
CC = R6 == 0;
IF CC R6 = R3;
R3 = R6-R7;
CC = R3 <= 3;
IF !CC JUMP BIT_EQ_2;
CC = BITTST(R7,0); // conditional check to find how many
// bits are left
//r1 = cycles;
R0 = CC;
CC = R3 == 3;
R3 = CC;
R6 = 3;
//r2 = cycles;
R3 = R3&R0;
CC = R3 == 1;
IF CC JUMP BIT_EQ_2;
R7 += 1;
JUMP FOR_LOOP;
BIT_EQ_2:
R7 >>= 1;
R7 += 1;
R6 = 2;
FOR_LOOP:
R5 = -R6;
R5 += 1;
JUMP_BACK:
CC = R6 == 0;
IF CC JUMP END_FORLOOP;
R0 = LSHIFT R7 BY R5.L;
R2 = 1;
R0 = R0&R2;
R1 = P5; // call arith_bitplusfollow to write bits to
//bit-stream
CALL __arith_bitplusfollow;
R6 += -1; // decrement the counter
R5 += 1;
JUMP JUMP_BACK;
END_FORLOOP:
R0 = [P5+28];
// get value of coder->nzeros
CC = R0 == 0;
IF CC JUMP CALL_BITPLUS;
R1 = [P5+44];
R2 = [P5+48];
R1 = R1-R2(NS)||R0 = [P5+24];
CC = R0<R1;
IF !CC JUMP NO_CALL;
CALL_BITPLUS:
R0 = 1;
R1 = P5;
CALL __arith_bitplusfollow;
// Do stuffing of '1' if necessary
NO_CALL:
RETS = [SP++];
(R7:5,P5:5) = [SP++];
RTS;
NOP; //to avoid one stall if LINK or UNLINK happens to be
//the next instruction after RTS in the memory.
__arith_StopArCoder.end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -