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