idct_mmi.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:11k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.   Originally provided by Intel at AP-922
  3.   http://developer.intel.com/vtune/cbts/strmsimd/922down.htm
  4.   (See more app notes at http://developer.intel.com/vtune/cbts/strmsimd/appnotes.htm)
  5.   but in a limited edition.
  6.   column code adapted from peter gubanov
  7.   Copyright (c) 2000-2001 Peter Gubanov <peter@elecard.net.ru>
  8.   http://www.elecard.com/peter/idct.shtml
  9.   Rounding trick Copyright (c) 2000 Michel Lespinasse <walken@zoy.org>
  10.   MMI port by Leon van Stuivenberg
  11. */  
  12. #include "../common.h"
  13. #include "../dsputil.h"
  14. #include "mmi.h"
  15. #define BITS_INV_ACC 5 // 4 or 5 for IEEE
  16. #define SHIFT_INV_ROW (16 - BITS_INV_ACC)
  17. #define SHIFT_INV_COL   (1 + BITS_INV_ACC)
  18. #define TG1 6518
  19. #define TG2 13573
  20. #define TG3 21895
  21. #define CS4 23170
  22. #define ROUNDER_0 0
  23. #define ROUNDER_1 16
  24. #define TAB_i_04 (32+0)
  25. #define TAB_i_17 (32+64)
  26. #define TAB_i_26 (32+128)
  27. #define TAB_i_35 (32+192)
  28. #define TG_1_16 (32+256+0)
  29. #define TG_2_16 (32+256+16)
  30. #define TG_3_16 (32+256+32)
  31. #define COS_4_16 (32+256+48)
  32. #define CLIPMAX (32+256+64+0)
  33. static short consttable[] align16 = {
  34. /* rounder 0*/ // assume SHIFT_INV_ROW == 11
  35.  0x3ff, 1, 0x3ff, 1, 0x3ff, 1, 0x3ff, 1,
  36. /* rounder 1*/
  37.  0x3ff, 0, 0x3ff, 0, 0x3ff, 0, 0x3ff, 0,
  38. /* row 0/4*/
  39.  16384,  21407, -16384, -21407,  22725,  19266, -22725, -12873, 
  40.   8867,  16384,   8867,  16384,   4520,  12873,  -4520,  19266, 
  41.  16384,  -8867,  16384,  -8867,  12873, -22725,  19266, -22725, 
  42.  21407, -16384, -21407,  16384,  19266,   4520, -12873,   4520, 
  43. /* row 1/7*/
  44.  22725,  29692, -22725, -29692,  31521,  26722, -31521, -17855, 
  45.  12299,  22725,  12299,  22725,   6270,  17855,  -6270,  26722, 
  46.  22725, -12299,  22725, -12299,  17855, -31521,  26722, -31521, 
  47.  29692, -22725, -29692,  22725,  26722,   6270, -17855,   6270, 
  48. /* row 2/6*/
  49.  21407,  27969, -21407, -27969,  29692,  25172, -29692, -16819, 
  50.  11585,  21407,  11585,  21407,   5906,  16819,  -5906,  25172, 
  51.  21407, -11585,  21407, -11585,  16819, -29692,  25172, -29692, 
  52.  27969, -21407, -27969,  21407,  25172,   5906, -16819,   5906, 
  53. /*row 3/5*/
  54.  19266,  25172, -19266, -25172,  26722,  22654, -26722, -15137, 
  55.  10426,  19266,  10426,  19266,   5315,  15137,  -5315,  22654, 
  56.  19266, -10426,  19266, -10426,  15137, -26722,  22654, -26722, 
  57.  25172, -19266, -25172,  19266,  22654,   5315, -15137,   5315,
  58. /*column constants*/
  59.  TG1, TG1, TG1, TG1, TG1, TG1, TG1, TG1,
  60.  TG2, TG2, TG2, TG2, TG2, TG2, TG2, TG2,
  61.  TG3, TG3, TG3, TG3, TG3, TG3, TG3, TG3,
  62.  CS4, CS4, CS4, CS4, CS4, CS4, CS4, CS4,
  63. /* clamp */
  64.  255, 255, 255, 255, 255, 255, 255, 255
  65. };
  66. #define DCT_8_INV_ROW1(blk, rowoff, taboff, rnd, outreg) { 
  67. lq(blk, rowoff, $16); /* r16 = x7  x5  x3  x1  x6  x4  x2  x0 */ 
  68. /*slot*/ 
  69. lq($24, 0+taboff, $17); /* r17 = w */ 
  70. /*delay slot $16*/ 
  71. lq($24, 16+taboff, $18);/* r18 = w */ 
  72. prevh($16, $2); /* r2  = x1  x3  x5  x7  x0  x2  x4  x6 */ 
  73. lq($24, 32+taboff, $19);/* r19 = w */ 
  74. phmadh($17, $16, $17); /* r17 = b1"b0'a1"a0' */ 
  75. lq($24, 48+taboff, $20);/* r20 = w */ 
  76. phmadh($18, $2, $18); /* r18 = b1'b0"a1'a0" */ 
  77. phmadh($19, $16, $19); /* r19 = b3"b2'a3"a2' */ 
  78. phmadh($20, $2, $20); /* r20 = b3'b2"a3'a2" */ 
  79. paddw($17, $18, $17); /* r17 = (b1)(b0)(a1)(a0) */ 
  80. paddw($19, $20, $19); /* r19 = (b3)(b2)(a3)(a2) */ 
  81. pcpyld($19, $17, $18); /* r18 = (a3)(a2)(a1)(a0) */ 
  82. pcpyud($17, $19, $20); /* r20 = (b3)(b2)(b1)(b0) */ 
  83. paddw($18, rnd, $18); /* r18 = (a3)(a2)(a1)(a0) */
  84. paddw($18, $20, $17); /* r17 = ()()()(a0+b0) */ 
  85. psubw($18, $20, $20); /* r20 = ()()()(a0-b0) */ 
  86. psraw($17, SHIFT_INV_ROW, $17); /* r17 = (y3 y2 y1 y0) */ 
  87. psraw($20, SHIFT_INV_ROW, $20); /* r20 = (y4 y5 y6 y7) */ 
  88. ppach($20, $17, outreg);/* out = y4 y5 y6 y7 y3 y2 y1 y0  Note order */ 
  89. prevh(outreg, $2);
  90. pcpyud($2, $2, $2);
  91. pcpyld($2, outreg, outreg);
  92. }
  93. #define DCT_8_INV_COL8() 
  94. lq($24, TG_3_16, $2); /* r2  = tn3 */
  95. pmulth($11, $2, $17); /* r17 = x3 * tn3 (6420) */ 
  96. psraw($17, 15, $17);
  97. pmfhl_uw($3); /* r3  = 7531 */
  98. psraw($3, 15, $3);
  99. pinteh($3, $17, $17); /* r17 = x3 * tn3 */ 
  100. psubh($17, $13, $17); /* r17 = tm35 */
  101. pmulth($13, $2, $18); /* r18 = x5 * tn3 (6420) */ 
  102. psraw($18, 15, $18);
  103. pmfhl_uw($3); /* r3  = 7531 */
  104. psraw($3, 15, $3);
  105. pinteh($3, $18, $18); /* r18 = x5 * tn3 */ 
  106. paddh($18, $11, $18); /* r18 = tp35 */
  107. lq($24, TG_1_16, $2); /* r2  = tn1 */
  108. pmulth($15, $2, $19); /* r19 = x7 * tn1 (6420) */ 
  109. psraw($19, 15, $19);
  110. pmfhl_uw($3); /* r3  = 7531 */
  111. psraw($3, 15, $3);
  112. pinteh($3, $19, $19); /* r19 = x7 * tn1 */ 
  113. paddh($19, $9, $19); /* r19 = tp17 */
  114. pmulth($9, $2, $20); /* r20 = x1 * tn1 (6420) */ 
  115. psraw($20, 15, $20);
  116. pmfhl_uw($3); /* r3  = 7531 */
  117. psraw($3, 15, $3);
  118. pinteh($3, $20, $20); /* r20 = x1 * tn1 */ 
  119. psubh($20, $15, $20); /* r20 = tm17 */
  120. psubh($19, $18, $3); /* r3  = t1 */
  121. paddh($20, $17, $16); /* r16 = t2 */
  122. psubh($20, $17, $23); /* r23 = b3 */
  123. paddh($19, $18, $20); /* r20 = b0 */
  124. lq($24, COS_4_16, $2); /* r2  = cs4 */
  125. paddh($3, $16, $21); /* r21 = t1+t2 */
  126. psubh($3, $16, $22); /* r22 = t1-t2 */
  127. pmulth($21, $2, $21); /* r21 = cs4 * (t1+t2) 6420 */ 
  128. psraw($21, 15, $21);
  129. pmfhl_uw($3); /* r3  = 7531 */
  130. psraw($3, 15, $3);
  131. pinteh($3, $21, $21); /* r21 = b1 */
  132. pmulth($22, $2, $22); /* r22 = cs4 * (t1-t2) 6420 */ 
  133. psraw($22, 15, $22);
  134. pmfhl_uw($3); /* r3  = 7531 */
  135. psraw($3, 15, $3);
  136. pinteh($3, $22, $22); /* r22 = b2 */
  137. lq($24, TG_2_16, $2); /* r2  = tn2 */
  138. pmulth($10, $2, $17); /* r17 = x2 * tn2 (6420) */ 
  139. psraw($17, 15, $17);
  140. pmfhl_uw($3); /* r3  = 7531 */
  141. psraw($3, 15, $3);
  142. pinteh($3, $17, $17); /* r17 = x3 * tn3 */ 
  143. psubh($17, $14, $17); /* r17 = tm26 */
  144. pmulth($14, $2, $18); /* r18 = x6 * tn2 (6420) */ 
  145. psraw($18, 15, $18);
  146. pmfhl_uw($3); /* r3  = 7531 */
  147. psraw($3, 15, $3);
  148. pinteh($3, $18, $18); /* r18 = x6 * tn2 */ 
  149. paddh($18, $10, $18); /* r18 = tp26 */
  150. paddh($8, $12, $2); /* r2  = tp04 */
  151. psubh($8, $12, $3); /* r3  = tm04 */
  152. paddh($2, $18, $16); /* r16 = a0 */
  153. psubh($2, $18, $19); /* r19 = a3 */
  154. psubh($3, $17, $18); /* r18 = a2 */
  155. paddh($3, $17, $17); /* r17 = a1 */
  156. #define DCT_8_INV_COL8_STORE(blk) 
  157. paddh($16, $20, $2); /* y0  a0+b0 */
  158. psubh($16, $20, $16); /* y7  a0-b0 */
  159. psrah($2, SHIFT_INV_COL, $2);
  160. psrah($16, SHIFT_INV_COL, $16);
  161. sq($2, 0, blk); 
  162. sq($16, 112, blk); 
  163. paddh($17, $21, $3); /* y1  a1+b1 */
  164. psubh($17, $21, $17); /* y6  a1-b1 */
  165. psrah($3, SHIFT_INV_COL, $3);
  166. psrah($17, SHIFT_INV_COL, $17);
  167. sq($3, 16, blk);
  168. sq($17, 96, blk);
  169. paddh($18, $22, $2); /* y2  a2+b2 */
  170. psubh($18, $22, $18); /* y5  a2-b2 */
  171. psrah($2, SHIFT_INV_COL, $2);
  172. psrah($18, SHIFT_INV_COL, $18);
  173. sq($2, 32, blk);
  174. sq($18, 80, blk);
  175. paddh($19, $23, $3); /* y3  a3+b3 */
  176. psubh($19, $23, $19); /* y4  a3-b3 */
  177. psrah($3, SHIFT_INV_COL, $3);
  178. psrah($19, SHIFT_INV_COL, $19);
  179. sq($3, 48, blk);
  180. sq($19, 64, blk);
  181. #define DCT_8_INV_COL8_PMS() 
  182. paddh($16, $20, $2); /* y0  a0+b0 */
  183. psubh($16, $20, $20); /* y7  a0-b0 */
  184. psrah($2, SHIFT_INV_COL, $16);
  185. psrah($20, SHIFT_INV_COL, $20);
  186. paddh($17, $21, $3); /* y1  a1+b1 */
  187. psubh($17, $21, $21); /* y6  a1-b1 */
  188. psrah($3, SHIFT_INV_COL, $17);
  189. psrah($21, SHIFT_INV_COL, $21);
  190. paddh($18, $22, $2); /* y2  a2+b2 */
  191. psubh($18, $22, $22); /* y5  a2-b2 */
  192. psrah($2, SHIFT_INV_COL, $18);
  193. psrah($22, SHIFT_INV_COL, $22);
  194. paddh($19, $23, $3); /* y3  a3+b3 */
  195. psubh($19, $23, $23); /* y4  a3-b3 */
  196. psrah($3, SHIFT_INV_COL, $19);
  197. psrah($23, SHIFT_INV_COL, $23);
  198. #define PUT(rs) 
  199. pminh(rs, $11, $2);
  200.      pmaxh($2, $0, $2);
  201. ppacb($0, $2, $2); 
  202. sd3(2, 0, 4); 
  203. __asm__ __volatile__ ("add $4, $5, $4");
  204. #define DCT_8_INV_COL8_PUT() 
  205.      PUT($16);
  206.      PUT($17);
  207.      PUT($18);
  208.      PUT($19);
  209.      PUT($23);
  210.      PUT($22);
  211.      PUT($21);
  212.      PUT($20);
  213. #define ADD(rs) 
  214.     ld3(4, 0, 2); 
  215.     pextlb($0, $2, $2); 
  216.     paddh($2, rs, $2); 
  217.     pminh($2, $11, $2);
  218.     pmaxh($2, $0, $2);
  219.     ppacb($0, $2, $2); 
  220.     sd3(2, 0, 4); 
  221.     __asm__ __volatile__ ("add $4, $5, $4");
  222. /*fixme: schedule*/
  223. #define DCT_8_INV_COL8_ADD() 
  224.      ADD($16);
  225.      ADD($17);
  226.      ADD($18);
  227.      ADD($19);
  228.      ADD($23);
  229.      ADD($22);
  230.      ADD($21);
  231.      ADD($20);
  232. void ff_mmi_idct(int16_t * block)
  233. {
  234.     /* $4 = block */
  235.     __asm__ __volatile__("la $24, %0"::"m"(consttable[0]));
  236.     lq($24, ROUNDER_0, $8);
  237.     lq($24, ROUNDER_1, $7);
  238.     DCT_8_INV_ROW1($4, 0, TAB_i_04, $8, $8);
  239.     DCT_8_INV_ROW1($4, 16, TAB_i_17, $7, $9);
  240.     DCT_8_INV_ROW1($4, 32, TAB_i_26, $7, $10);
  241.     DCT_8_INV_ROW1($4, 48, TAB_i_35, $7, $11);
  242.     DCT_8_INV_ROW1($4, 64, TAB_i_04, $7, $12);
  243.     DCT_8_INV_ROW1($4, 80, TAB_i_35, $7, $13);
  244.     DCT_8_INV_ROW1($4, 96, TAB_i_26, $7, $14);
  245.     DCT_8_INV_ROW1($4, 112, TAB_i_17, $7, $15);
  246.     DCT_8_INV_COL8();
  247.     DCT_8_INV_COL8_STORE($4);
  248.  
  249.     //let savedtemp regs be saved
  250.     __asm__ __volatile__(" ":::"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23");
  251. }
  252. void ff_mmi_idct_put(uint8_t *dest, int line_size, DCTELEM *block)
  253. {
  254.     /* $4 = dest, $5 = line_size, $6 = block */
  255.     __asm__ __volatile__("la $24, %0"::"m"(consttable[0]));
  256.     lq($24, ROUNDER_0, $8);
  257.     lq($24, ROUNDER_1, $7);
  258.     DCT_8_INV_ROW1($6, 0, TAB_i_04, $8, $8);
  259.     DCT_8_INV_ROW1($6, 16, TAB_i_17, $7, $9);
  260.     DCT_8_INV_ROW1($6, 32, TAB_i_26, $7, $10);
  261.     DCT_8_INV_ROW1($6, 48, TAB_i_35, $7, $11);
  262.     DCT_8_INV_ROW1($6, 64, TAB_i_04, $7, $12);
  263.     DCT_8_INV_ROW1($6, 80, TAB_i_35, $7, $13);
  264.     DCT_8_INV_ROW1($6, 96, TAB_i_26, $7, $14);
  265.     DCT_8_INV_ROW1($6, 112, TAB_i_17, $7, $15);
  266.     DCT_8_INV_COL8();
  267.     lq($24, CLIPMAX, $11);
  268.     DCT_8_INV_COL8_PMS();
  269.     DCT_8_INV_COL8_PUT();
  270.     //let savedtemp regs be saved
  271.     __asm__ __volatile__(" ":::"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23");
  272. }
  273. void ff_mmi_idct_add(uint8_t *dest, int line_size, DCTELEM *block)
  274. {
  275.     /* $4 = dest, $5 = line_size, $6 = block */
  276.     __asm__ __volatile__("la $24, %0"::"m"(consttable[0]));
  277.     lq($24, ROUNDER_0, $8);
  278.     lq($24, ROUNDER_1, $7);
  279.     DCT_8_INV_ROW1($6, 0, TAB_i_04, $8, $8);
  280.     DCT_8_INV_ROW1($6, 16, TAB_i_17, $7, $9);
  281.     DCT_8_INV_ROW1($6, 32, TAB_i_26, $7, $10);
  282.     DCT_8_INV_ROW1($6, 48, TAB_i_35, $7, $11);
  283.     DCT_8_INV_ROW1($6, 64, TAB_i_04, $7, $12);
  284.     DCT_8_INV_ROW1($6, 80, TAB_i_35, $7, $13);
  285.     DCT_8_INV_ROW1($6, 96, TAB_i_26, $7, $14);
  286.     DCT_8_INV_ROW1($6, 112, TAB_i_17, $7, $15);
  287.     DCT_8_INV_COL8();
  288.     lq($24, CLIPMAX, $11);
  289.     DCT_8_INV_COL8_PMS();
  290.     DCT_8_INV_COL8_ADD();
  291.     //let savedtemp regs be saved
  292.     __asm__ __volatile__(" ":::"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23");
  293. }