www.pudn.com > ccs_encoder.rar > idct.sa
.global _idct_int32
_idct_int32: .cproc blockp
.reg temp0, temp1, temp2, temp3,temp4,blockptr,sumh,sumv
.reg block,dcval,zo,if,m3,m1,blockptr1,blockptr2
.reg temp10,temp11,temp12,temp13
.reg z1,z2,z3,z4,z5,s0,s1,s2,s3
.reg y0,y1,y2,y3,y4,y5,y6,y7
.reg r10,r17 ,r1 ,r4 ;存放1左移后的结果,以便饱和,防止溢出
.reg FIX_1,FIX_2,FIX_3,FIX_I,FIX_A,FIX_B,FIX_C,FIX_D,FIX_E,FIX_F,FIX_G,FIX_H
MV blockp,blockptr
ZERO FIX_1
ZERO FIX_2
ZERO FIX_3
ZERO FIX_I
ZERO FIX_A
ZERO FIX_B
ZERO FIX_C
ZERO FIX_D
ZERO FIX_E
ZERO FIX_F
ZERO FIX_G
ZERO FIX_H
MVK 8,sumh ;行数
MVK 8,sumv ;列数
MVK 4433, FIX_1
MVK 6270, FIX_2
MVK -15137,FIX_3
MVK 9633, FIX_I ;sqrt(2)*c3
MVK 2446, FIX_A ;(-c1+c3+c5-c7)*sqrt(2)
MVK 16819, FIX_B ;(c1+c3-c5+c7)*sqrt(2)
MVK 25172, FIX_C ;(c1+c3+c5-c7)*sqrt(2)
MVK 12299, FIX_D ;(c1+c3-c5-c7)*sqrt(2)
MVK -7373, FIX_E ;(-c3+c7)*sqrt(2)
MVK -20995,FIX_F ;(-c1-c3)*sqrt(2)
MVK -16069,FIX_G ;(-c3-c5)*sqrt(2)
MVK -3196, FIX_H ;(-c3+c5)*sqrt(2)
loop0: OR z1, z2,zo ;首先判断AC系数是否全为零,如果为零就执行DC系数的赋值
LDH *blockptr[1],z1
LDH *blockptr[2],z2
LDH *blockptr[3],z1
OR zo,z1,zo
LDH *blockptr[4],z1
OR zo,z1,zo
LDH *blockptr[5],z1
OR zo,z1,zo
LDH *blockptr[6],z1
OR zo,z1,zo
LDH *blockptr[7],z1
OR zo,z1,zo
CMPEQ zo,0,if
[!if]B loop2
[if] B loop1
loop1: LDH *blockptr[0], dcval ;如果某一行的AC系数全为0,则将其全部赋值为DC系数的值
SSHL dcval,2,dcval
STH dcval, *blockptr[0]
STH dcval, *blockptr[1]
STH dcval, *blockptr[2]
STH dcval, *blockptr[3]
STH dcval, *blockptr[4]
STH dcval, *blockptr[5]
STH dcval, *blockptr[6]
STH dcval, *blockptr[7]
[sumh]SUB sumh,1,sumh
[sumh]LDH *blockptr++[8],m3 ;继续判断下一行
[sumh]B loop0
[!sumh]B loop3 ;进行列计算
loop2: LDH *blockptr[2],z2 ;如果AC系数不全为零,就要根据公式进行idct变换
LDH *blockptr[6],z3
ADD z2,z3,temp4
MPY temp4,FIX_1,z1
MPY z3,FIX_3,z3
ADD z1,z3,temp2
MPY z2,FIX_2,z2
ADD z1,z2,temp3
;ADD blockptr[0],blockptr[4],temp0
LDH *blockptr[0],z2
LDH *blockptr[4],z3
ADD z2,z3,temp0
SSHL temp0,13,temp0
;SUB blockptr[0],blockptr[4],temp1
SUB z2,z3,temp1
SSHL temp1,13,temp1
ADD temp0,temp3,temp10
SUB temp0,temp3,temp13
ADD temp1,temp2,temp11
SUB temp1,temp2,temp12
LDH *blockptr[7],temp0
LDH *blockptr[5],temp1
LDH *blockptr[3],temp2
LDH *blockptr[1],temp3
ADD temp0,temp3,z1
ADD temp1,temp2,z2
ADD temp0,temp2,z3
ADD temp1,temp3,z4
ADD z3,z4,z5
MPY z5,FIX_I,z5 ;sqrt)(2)*c3
MPY temp0,FIX_A,temp0 ;a
MPY temp1,FIX_B,temp1 ;b
MPY temp2,FIX_C,temp2 ;c
MPY temp3,FIX_D,temp2 ;d
MPY z1,FIX_E,z1
MPY z2,FIX_F,z2
MPY z3,FIX_G,z3
MPY z4,FIX_H,z4 ;h
ADD z3,z5,z3
ADD z4,z5,z4
ADD z1,z3,s0
ADD s0,temp0,temp0
ADD z2,z4,s1
ADD s1,temp1,temp1
ADD z2,z3,s2
ADD s2,temp2,temp2
ADD z1,z4,s3
ADD s3,temp3,temp3
ADD temp10,temp3,y0
MVK 1,r1
SSHL r1,10,r10
ADD y0,r10,y0
SHR y0,11,y0
STH y0,*blockptr[0]
SUB temp10,temp3,y7
ADD y7,r10,y7
SHR y7,11,y7
STH y7,*blockptr[7]
ADD temp11,temp2,y1
ADD y1,r10,y1
SHR y1,11,y1
STH y1,*blockptr[1]
SUB temp11,temp2,y6
ADD y6,r10,y6
SHR y6,11,y6
STH y6,*blockptr[6]
ADD temp12,temp1,y2
ADD y2,r10,y2
SHR y2,11,y2
STH y2,*blockptr[2]
SUB temp12,temp1,y5
ADD y5,r10,y5
SHR y5,11,y5
STH y5,*blockptr[5]
ADD temp13,temp0,y3
ADD y3,r10,y3
SHR y3,11,y3
STH y3,*blockptr[3]
SUB temp13,temp0,y4
ADD y4,r10,y4
SHR y4,11,y4
STH y4,*blockptr[4] ;计算出输出的系数
[sumh]SUB sumh,1,sumh
[sumh]LDH *blockptr++[8],m3 ;继续判断下一行
[sumh]B loop0
;计算完所有的行,重新给指针赋值,开始计算列
loop3: MV blockp,blockptr1
MV blockp,blockptr2
LDH *blockptr2++[31],m1
LDH *blockptr2++,m1
loop4:
LDH *blockptr1[8],z1
LDH *blockptr1[16],z2
OR z1, z2,zo
LDH *blockptr1[24],z1
OR zo,z1,zo
LDH *blockptr2[0],z1
OR zo,z1,zo
LDH *blockptr2[8],z1
OR zo,z1,zo
LDH *blockptr2[16],z1
OR zo,z1,zo
LDH *blockptr2[24],z1
OR zo,z1,zo
CMPEQ zo,0,if
[!if]B loop6
[if] B loop5
loop5:
LDH *blockptr1[0], dcval ;如果某一列的AC系数全为0,则将其全部赋值为DC系数的值
MVK 1,r1
SSHL r1,4,r4
ADD dcval,r4,dcval
SHR dcval,5,dcval
STH dcval, *blockptr1[0]
STH dcval, *blockptr1[8]
STH dcval, *blockptr1[16]
STH dcval, *blockptr1[24]
STH dcval, *blockptr2[0]
STH dcval, *blockptr2[8]
STH dcval, *blockptr2[16]
STH dcval, *blockptr2[24]
[sumv]SUB sumv,1,sumv
[sumv]LDH *blockptr1++,m3 ;继续判断下一列
[sumv]LDH *blockptr2++,m3
[sumv]B loop4
[!sumv]B loop7
loop6: LDH *blockptr1[16],z2 ;如果AC系数不全为零,就要根据公式进行idct变换
LDH *blockptr2[16],z3
ADD z2,z3,temp4
MPY temp4,FIX_1,z1
MPY z3,FIX_3,z3
ADD z1,z3,temp2
MPY z2,FIX_2,z2
ADD z1,z2,temp3
;ADD blockptr[0],blockptr[32],temp0
LDH *blockptr1[0],z1
LDH *blockptr2[0],z2
ADD z1,z2,temp0
SSHL temp0,13,temp0
;SUB blockptr[0],blockptr[32],temp1
SUB z1,z2,temp1
SSHL temp1,13,temp1
ADD temp0,temp3,temp10
SUB temp0,temp3,temp13
ADD temp1,temp2,temp11
SUB temp1,temp2,temp12
LDH *blockptr2[24],temp0
LDH *blockptr2[8],temp1
LDH *blockptr1[24],temp2
LDH *blockptr1[8], temp3
ADD temp0,temp3,z1
ADD temp1,temp2,z2
ADD temp0,temp2,z3
ADD temp1,temp3,z4
ADD z3,z4,z5
MPY z5,FIX_I,z5 ;sqrt)(2)*c3
MPY temp0,FIX_A,temp0 ;a
MPY temp1,FIX_B,temp1 ;b
MPY temp2,FIX_C,temp2 ;c
MPY temp3,FIX_D,temp2 ;d
MPY z1,FIX_E,z1
MPY z2,FIX_F,z2
MPY z3,FIX_G,z3
MPY z4,FIX_H,z4 ;h
ADD z3,z5,z3
ADD z4,z5,z4
ADD z1,z3,s0
ADD s0,temp0,temp0
ADD z2,z4,s1
ADD s1,temp1,temp1
ADD z2,z3,s2
ADD s2,temp2,temp2
ADD z1,z4,s3
ADD s3,temp3,temp3
ADD temp10,temp3,y0
SSHL r1,17,r17
ADD y0,r17,y0
SHR y0,18,y0
STH y0,*blockptr1[0]
SUB temp10,temp3,y7
ADD y7,r17,y7
SHR y7,18,y7
STH y7,*blockptr2[24]
ADD temp11,temp2,y1
ADD y1,r17,y1
SHR y1,18,y1
STH y1,*blockptr1[8]
SUB temp11,temp2,y6
ADD y6,r17,y6
SHR y6,18,y6
STH y6,*blockptr2[16]
ADD temp12,temp1,y2
ADD y2,r17,y2
SHR y2,18,y2
STH y2,*blockptr1[16]
SUB temp12,temp1,y5
ADD y5,r17,y5
SHR y5,18,y5
STH y5,*blockptr2[8]
ADD temp13,temp0,y3
ADD y3,r17,y3
SHR y3,18,y3
STH y3,*blockptr1[24]
SUB temp13,temp0,y4
ADD y4,r17,y4
SHR y4,18,y4
STH y4,*blockptr2[0] ;计算出输出的系数
[sumv]SUB sumv,1,sumv
[sumv]LDH *blockptr1++,m3 ;继续判断下一列
[sumv]LDH *blockptr2++,m3
[sumv]B loop5
[!sumv]B loop7
loop7:
; LDH *blockptr--[8],m3
.endproc