hevc_idct_msa.c 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025
  1. /*
  2. * Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * FFmpeg is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with FFmpeg; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "libavutil/mips/generic_macros_msa.h"
  21. #include "libavcodec/mips/hevcdsp_mips.h"
  22. static const int16_t gt8x8_cnst[16] __attribute__ ((aligned (64))) = {
  23. 64, 64, 83, 36, 89, 50, 18, 75, 64, -64, 36, -83, 75, -89, -50, -18
  24. };
  25. static const int16_t gt16x16_cnst[64] __attribute__ ((aligned (64))) = {
  26. 64, 83, 64, 36, 89, 75, 50, 18, 90, 80, 57, 25, 70, 87, 9, 43,
  27. 64, 36, -64, -83, 75, -18, -89, -50, 87, 9, -80, -70, -43, 57, -25, -90,
  28. 64, -36, -64, 83, 50, -89, 18, 75, 80, -70, -25, 90, -87, 9, 43, 57,
  29. 64, -83, 64, -36, 18, -50, 75, -89, 70, -87, 90, -80, 9, -43, -57, 25
  30. };
  31. static const int16_t gt32x32_cnst0[256] __attribute__ ((aligned (64))) = {
  32. 90, 90, 88, 85, 82, 78, 73, 67, 61, 54, 46, 38, 31, 22, 13, 4,
  33. 90, 82, 67, 46, 22, -4, -31, -54, -73, -85, -90, -88, -78, -61, -38, -13,
  34. 88, 67, 31, -13, -54, -82, -90, -78, -46, -4, 38, 73, 90, 85, 61, 22,
  35. 85, 46, -13, -67, -90, -73, -22, 38, 82, 88, 54, -4, -61, -90, -78, -31,
  36. 82, 22, -54, -90, -61, 13, 78, 85, 31, -46, -90, -67, 4, 73, 88, 38,
  37. 78, -4, -82, -73, 13, 85, 67, -22, -88, -61, 31, 90, 54, -38, -90, -46,
  38. 73, -31, -90, -22, 78, 67, -38, -90, -13, 82, 61, -46, -88, -4, 85, 54,
  39. 67, -54, -78, 38, 85, -22, -90, 4, 90, 13, -88, -31, 82, 46, -73, -61,
  40. 61, -73, -46, 82, 31, -88, -13, 90, -4, -90, 22, 85, -38, -78, 54, 67,
  41. 54, -85, -4, 88, -46, -61, 82, 13, -90, 38, 67, -78, -22, 90, -31, -73,
  42. 46, -90, 38, 54, -90, 31, 61, -88, 22, 67, -85, 13, 73, -82, 4, 78,
  43. 38, -88, 73, -4, -67, 90, -46, -31, 85, -78, 13, 61, -90, 54, 22, -82,
  44. 31, -78, 90, -61, 4, 54, -88, 82, -38, -22, 73, -90, 67, -13, -46, 85,
  45. 22, -61, 85, -90, 73, -38, -4, 46, -78, 90, -82, 54, -13, -31, 67, -88,
  46. 13, -38, 61, -78, 88, -90, 85, -73, 54, -31, 4, 22, -46, 67, -82, 90,
  47. 4, -13, 22, -31, 38, -46, 54, -61, 67, -73, 78, -82, 85, -88, 90, -90
  48. };
  49. static const int16_t gt32x32_cnst1[64] __attribute__ ((aligned (64))) = {
  50. 90, 87, 80, 70, 57, 43, 25, 9, 87, 57, 9, -43, -80, -90, -70, -25,
  51. 80, 9, -70, -87, -25, 57, 90, 43, 70, -43, -87, 9, 90, 25, -80, -57,
  52. 57, -80, -25, 90, -9, -87, 43, 70, 43, -90, 57, 25, -87, 70, 9, -80,
  53. 25, -70, 90, -80, 43, 9, -57, 87, 9, -25, 43, -57, 70, -80, 87, -90
  54. };
  55. static const int16_t gt32x32_cnst2[16] __attribute__ ((aligned (64))) = {
  56. 89, 75, 50, 18, 75, -18, -89, -50, 50, -89, 18, 75, 18, -50, 75, -89
  57. };
  58. #define HEVC_IDCT4x4_COL(in_r0, in_l0, in_r1, in_l1, \
  59. sum0, sum1, sum2, sum3, shift) \
  60. { \
  61. v4i32 vec0, vec1, vec2, vec3, vec4, vec5; \
  62. v4i32 cnst64 = __msa_ldi_w(64); \
  63. v4i32 cnst83 = __msa_ldi_w(83); \
  64. v4i32 cnst36 = __msa_ldi_w(36); \
  65. \
  66. DOTP_SH4_SW(in_r0, in_r1, in_l0, in_l1, cnst64, cnst64, \
  67. cnst83, cnst36, vec0, vec2, vec1, vec3); \
  68. DOTP_SH2_SW(in_l0, in_l1, cnst36, cnst83, vec4, vec5); \
  69. \
  70. sum0 = vec0 + vec2; \
  71. sum1 = vec0 - vec2; \
  72. sum3 = sum0; \
  73. sum2 = sum1; \
  74. \
  75. vec1 += vec3; \
  76. vec4 -= vec5; \
  77. \
  78. sum0 += vec1; \
  79. sum1 += vec4; \
  80. sum2 -= vec4; \
  81. sum3 -= vec1; \
  82. \
  83. SRARI_W4_SW(sum0, sum1, sum2, sum3, shift); \
  84. SAT_SW4_SW(sum0, sum1, sum2, sum3, 15); \
  85. }
  86. #define HEVC_IDCT8x8_COL(in0, in1, in2, in3, in4, in5, in6, in7, shift) \
  87. { \
  88. v8i16 src0_r, src1_r, src2_r, src3_r; \
  89. v8i16 src0_l, src1_l, src2_l, src3_l; \
  90. v8i16 filt0, filter0, filter1, filter2, filter3; \
  91. v4i32 temp0_r, temp1_r, temp2_r, temp3_r, temp4_r, temp5_r; \
  92. v4i32 temp0_l, temp1_l, temp2_l, temp3_l, temp4_l, temp5_l; \
  93. v4i32 sum0_r, sum1_r, sum2_r, sum3_r; \
  94. v4i32 sum0_l, sum1_l, sum2_l, sum3_l; \
  95. \
  96. ILVR_H4_SH(in4, in0, in6, in2, in5, in1, in3, in7, \
  97. src0_r, src1_r, src2_r, src3_r); \
  98. ILVL_H4_SH(in4, in0, in6, in2, in5, in1, in3, in7, \
  99. src0_l, src1_l, src2_l, src3_l); \
  100. \
  101. filt0 = LD_SH(filter); \
  102. SPLATI_W4_SH(filt0, filter0, filter1, filter2, filter3); \
  103. DOTP_SH4_SW(src0_r, src0_l, src1_r, src1_l, filter0, filter0, \
  104. filter1, filter1, temp0_r, temp0_l, temp1_r, temp1_l); \
  105. \
  106. BUTTERFLY_4(temp0_r, temp0_l, temp1_l, temp1_r, sum0_r, sum0_l, \
  107. sum1_l, sum1_r); \
  108. sum2_r = sum1_r; \
  109. sum2_l = sum1_l; \
  110. sum3_r = sum0_r; \
  111. sum3_l = sum0_l; \
  112. \
  113. DOTP_SH4_SW(src2_r, src2_l, src3_r, src3_l, filter2, filter2, \
  114. filter3, filter3, temp2_r, temp2_l, temp3_r, temp3_l); \
  115. \
  116. temp2_r += temp3_r; \
  117. temp2_l += temp3_l; \
  118. sum0_r += temp2_r; \
  119. sum0_l += temp2_l; \
  120. sum3_r -= temp2_r; \
  121. sum3_l -= temp2_l; \
  122. \
  123. SRARI_W4_SW(sum0_r, sum0_l, sum3_r, sum3_l, shift); \
  124. SAT_SW4_SW(sum0_r, sum0_l, sum3_r, sum3_l, 15); \
  125. PCKEV_H2_SH(sum0_l, sum0_r, sum3_l, sum3_r, in0, in7); \
  126. DOTP_SH4_SW(src2_r, src2_l, src3_r, src3_l, filter3, filter3, \
  127. filter2, filter2, temp4_r, temp4_l, temp5_r, temp5_l); \
  128. \
  129. temp4_r -= temp5_r; \
  130. temp4_l -= temp5_l; \
  131. sum1_r += temp4_r; \
  132. sum1_l += temp4_l; \
  133. sum2_r -= temp4_r; \
  134. sum2_l -= temp4_l; \
  135. \
  136. SRARI_W4_SW(sum1_r, sum1_l, sum2_r, sum2_l, shift); \
  137. SAT_SW4_SW(sum1_r, sum1_l, sum2_r, sum2_l, 15); \
  138. PCKEV_H2_SH(sum1_l, sum1_r, sum2_l, sum2_r, in3, in4); \
  139. \
  140. filt0 = LD_SH(filter + 8); \
  141. SPLATI_W4_SH(filt0, filter0, filter1, filter2, filter3); \
  142. DOTP_SH4_SW(src0_r, src0_l, src1_r, src1_l, filter0, filter0, \
  143. filter1, filter1, temp0_r, temp0_l, temp1_r, temp1_l); \
  144. \
  145. BUTTERFLY_4(temp0_r, temp0_l, temp1_l, temp1_r, sum0_r, sum0_l, \
  146. sum1_l, sum1_r); \
  147. sum2_r = sum1_r; \
  148. sum2_l = sum1_l; \
  149. sum3_r = sum0_r; \
  150. sum3_l = sum0_l; \
  151. \
  152. DOTP_SH4_SW(src2_r, src2_l, src3_r, src3_l, filter2, filter2, \
  153. filter3, filter3, temp2_r, temp2_l, temp3_r, temp3_l); \
  154. \
  155. temp2_r += temp3_r; \
  156. temp2_l += temp3_l; \
  157. sum0_r += temp2_r; \
  158. sum0_l += temp2_l; \
  159. sum3_r -= temp2_r; \
  160. sum3_l -= temp2_l; \
  161. \
  162. SRARI_W4_SW(sum0_r, sum0_l, sum3_r, sum3_l, shift); \
  163. SAT_SW4_SW(sum0_r, sum0_l, sum3_r, sum3_l, 15); \
  164. PCKEV_H2_SH(sum0_l, sum0_r, sum3_l, sum3_r, in1, in6); \
  165. DOTP_SH4_SW(src2_r, src2_l, src3_r, src3_l, filter3, filter3, \
  166. filter2, filter2, temp4_r, temp4_l, temp5_r, temp5_l); \
  167. \
  168. temp4_r -= temp5_r; \
  169. temp4_l -= temp5_l; \
  170. sum1_r -= temp4_r; \
  171. sum1_l -= temp4_l; \
  172. sum2_r += temp4_r; \
  173. sum2_l += temp4_l; \
  174. \
  175. SRARI_W4_SW(sum1_r, sum1_l, sum2_r, sum2_l, shift); \
  176. SAT_SW4_SW(sum1_r, sum1_l, sum2_r, sum2_l, 15); \
  177. PCKEV_H2_SH(sum1_l, sum1_r, sum2_l, sum2_r, in2, in5); \
  178. }
  179. #define HEVC_IDCT16x16_COL(src0_r, src1_r, src2_r, src3_r, \
  180. src4_r, src5_r, src6_r, src7_r, \
  181. src0_l, src1_l, src2_l, src3_l, \
  182. src4_l, src5_l, src6_l, src7_l, shift) \
  183. { \
  184. int16_t *ptr0, *ptr1; \
  185. v8i16 filt0, filt1, dst0, dst1; \
  186. v8i16 filter0, filter1, filter2, filter3; \
  187. v4i32 temp0_r, temp1_r, temp0_l, temp1_l; \
  188. v4i32 sum0_r, sum1_r, sum2_r, sum3_r, sum0_l, sum1_l, sum2_l; \
  189. v4i32 sum3_l, res0_r, res1_r, res0_l, res1_l; \
  190. \
  191. ptr0 = (buf_ptr + 112); \
  192. ptr1 = (buf_ptr + 128); \
  193. k = -1; \
  194. \
  195. for (j = 0; j < 4; j++) \
  196. { \
  197. LD_SH2(filter, 8, filt0, filt1) \
  198. filter += 16; \
  199. SPLATI_W2_SH(filt0, 0, filter0, filter1); \
  200. SPLATI_W2_SH(filt1, 0, filter2, filter3); \
  201. DOTP_SH4_SW(src0_r, src0_l, src4_r, src4_l, filter0, filter0, \
  202. filter2, filter2, sum0_r, sum0_l, sum2_r, sum2_l); \
  203. DOTP_SH2_SW(src7_r, src7_l, filter2, filter2, sum3_r, sum3_l); \
  204. DPADD_SH4_SW(src1_r, src1_l, src5_r, src5_l, filter1, filter1, \
  205. filter3, filter3, sum0_r, sum0_l, sum2_r, sum2_l); \
  206. DPADD_SH2_SW(src6_r, src6_l, filter3, filter3, sum3_r, sum3_l); \
  207. \
  208. sum1_r = sum0_r; \
  209. sum1_l = sum0_l; \
  210. \
  211. SPLATI_W2_SH(filt0, 2, filter0, filter1); \
  212. SPLATI_W2_SH(filt1, 2, filter2, filter3); \
  213. DOTP_SH2_SW(src2_r, src2_l, filter0, filter0, temp0_r, temp0_l); \
  214. DPADD_SH2_SW(src6_r, src6_l, filter2, filter2, sum2_r, sum2_l); \
  215. DOTP_SH2_SW(src5_r, src5_l, filter2, filter2, temp1_r, temp1_l); \
  216. \
  217. sum0_r += temp0_r; \
  218. sum0_l += temp0_l; \
  219. sum1_r -= temp0_r; \
  220. sum1_l -= temp0_l; \
  221. \
  222. sum3_r = temp1_r - sum3_r; \
  223. sum3_l = temp1_l - sum3_l; \
  224. \
  225. DOTP_SH2_SW(src3_r, src3_l, filter1, filter1, temp0_r, temp0_l); \
  226. DPADD_SH4_SW(src7_r, src7_l, src4_r, src4_l, filter3, filter3, \
  227. filter3, filter3, sum2_r, sum2_l, sum3_r, sum3_l); \
  228. \
  229. sum0_r += temp0_r; \
  230. sum0_l += temp0_l; \
  231. sum1_r -= temp0_r; \
  232. sum1_l -= temp0_l; \
  233. \
  234. BUTTERFLY_4(sum0_r, sum0_l, sum2_l, sum2_r, res0_r, res0_l, \
  235. res1_l, res1_r); \
  236. SRARI_W4_SW(res0_r, res0_l, res1_r, res1_l, shift); \
  237. SAT_SW4_SW(res0_r, res0_l, res1_r, res1_l, 15); \
  238. PCKEV_H2_SH(res0_l, res0_r, res1_l, res1_r, dst0, dst1); \
  239. ST_SH(dst0, buf_ptr); \
  240. ST_SH(dst1, (buf_ptr + ((15 - (j * 2)) * 16))); \
  241. \
  242. BUTTERFLY_4(sum1_r, sum1_l, sum3_l, sum3_r, res0_r, res0_l, \
  243. res1_l, res1_r); \
  244. SRARI_W4_SW(res0_r, res0_l, res1_r, res1_l, shift); \
  245. SAT_SW4_SW(res0_r, res0_l, res1_r, res1_l, 15); \
  246. PCKEV_H2_SH(res0_l, res0_r, res1_l, res1_r, dst0, dst1); \
  247. ST_SH(dst0, (ptr0 + (((j / 2 + j % 2) * 2 * k) * 16))); \
  248. ST_SH(dst1, (ptr1 - (((j / 2 + j % 2) * 2 * k) * 16))); \
  249. \
  250. k *= -1; \
  251. buf_ptr += 16; \
  252. } \
  253. }
  254. #define HEVC_EVEN16_CALC(input, sum0_r, sum0_l, load_idx, store_idx) \
  255. { \
  256. LD_SW2(input + load_idx * 8, 4, tmp0_r, tmp0_l); \
  257. tmp1_r = sum0_r; \
  258. tmp1_l = sum0_l; \
  259. sum0_r += tmp0_r; \
  260. sum0_l += tmp0_l; \
  261. ST_SW2(sum0_r, sum0_l, (input + load_idx * 8), 4); \
  262. tmp1_r -= tmp0_r; \
  263. tmp1_l -= tmp0_l; \
  264. ST_SW2(tmp1_r, tmp1_l, (input + store_idx * 8), 4); \
  265. }
  266. #define HEVC_IDCT_LUMA4x4_COL(in_r0, in_l0, in_r1, in_l1, \
  267. res0, res1, res2, res3, shift) \
  268. { \
  269. v4i32 vec0, vec1, vec2, vec3; \
  270. v4i32 cnst74 = __msa_ldi_w(74); \
  271. v4i32 cnst55 = __msa_ldi_w(55); \
  272. v4i32 cnst29 = __msa_ldi_w(29); \
  273. \
  274. vec0 = in_r0 + in_r1; \
  275. vec2 = in_r0 - in_l1; \
  276. res0 = vec0 * cnst29; \
  277. res1 = vec2 * cnst55; \
  278. res2 = in_r0 - in_r1; \
  279. vec1 = in_r1 + in_l1; \
  280. res2 += in_l1; \
  281. vec3 = in_l0 * cnst74; \
  282. res3 = vec0 * cnst55; \
  283. \
  284. res0 += vec1 * cnst55; \
  285. res1 -= vec1 * cnst29; \
  286. res2 *= cnst74; \
  287. res3 += vec2 * cnst29; \
  288. \
  289. res0 += vec3; \
  290. res1 += vec3; \
  291. res3 -= vec3; \
  292. \
  293. SRARI_W4_SW(res0, res1, res2, res3, shift); \
  294. SAT_SW4_SW(res0, res1, res2, res3, 15); \
  295. }
  296. static void hevc_idct_4x4_msa(int16_t *coeffs)
  297. {
  298. v8i16 in0, in1;
  299. v4i32 in_r0, in_l0, in_r1, in_l1;
  300. v4i32 sum0, sum1, sum2, sum3;
  301. v8i16 zeros = { 0 };
  302. LD_SH2(coeffs, 8, in0, in1);
  303. ILVRL_H2_SW(zeros, in0, in_r0, in_l0);
  304. ILVRL_H2_SW(zeros, in1, in_r1, in_l1);
  305. HEVC_IDCT4x4_COL(in_r0, in_l0, in_r1, in_l1, sum0, sum1, sum2, sum3, 7);
  306. TRANSPOSE4x4_SW_SW(sum0, sum1, sum2, sum3, in_r0, in_l0, in_r1, in_l1);
  307. HEVC_IDCT4x4_COL(in_r0, in_l0, in_r1, in_l1, sum0, sum1, sum2, sum3, 12);
  308. /* Pack and transpose */
  309. PCKEV_H2_SH(sum2, sum0, sum3, sum1, in0, in1);
  310. ILVRL_H2_SW(in1, in0, sum0, sum1);
  311. ILVRL_W2_SH(sum1, sum0, in0, in1);
  312. ST_SH2(in0, in1, coeffs, 8);
  313. }
  314. static void hevc_idct_8x8_msa(int16_t *coeffs)
  315. {
  316. const int16_t *filter = &gt8x8_cnst[0];
  317. v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
  318. LD_SH8(coeffs, 8, in0, in1, in2, in3, in4, in5, in6, in7);
  319. HEVC_IDCT8x8_COL(in0, in1, in2, in3, in4, in5, in6, in7, 7);
  320. TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7,
  321. in0, in1, in2, in3, in4, in5, in6, in7);
  322. HEVC_IDCT8x8_COL(in0, in1, in2, in3, in4, in5, in6, in7, 12);
  323. TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7,
  324. in0, in1, in2, in3, in4, in5, in6, in7);
  325. ST_SH8(in0, in1, in2, in3, in4, in5, in6, in7, coeffs, 8);
  326. }
  327. static void hevc_idct_16x16_msa(int16_t *coeffs)
  328. {
  329. int16_t i, j, k;
  330. int16_t buf[256];
  331. int16_t *buf_ptr = &buf[0];
  332. int16_t *src = coeffs;
  333. const int16_t *filter = &gt16x16_cnst[0];
  334. v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
  335. v8i16 in8, in9, in10, in11, in12, in13, in14, in15;
  336. v8i16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7;
  337. v8i16 src0_r, src1_r, src2_r, src3_r, src4_r, src5_r, src6_r, src7_r;
  338. v8i16 src0_l, src1_l, src2_l, src3_l, src4_l, src5_l, src6_l, src7_l;
  339. for (i = 2; i--;) {
  340. LD_SH16(src, 16, in0, in1, in2, in3, in4, in5, in6, in7,
  341. in8, in9, in10, in11, in12, in13, in14, in15);
  342. ILVR_H4_SH(in4, in0, in12, in8, in6, in2, in14, in10,
  343. src0_r, src1_r, src2_r, src3_r);
  344. ILVR_H4_SH(in5, in1, in13, in9, in3, in7, in11, in15,
  345. src4_r, src5_r, src6_r, src7_r);
  346. ILVL_H4_SH(in4, in0, in12, in8, in6, in2, in14, in10,
  347. src0_l, src1_l, src2_l, src3_l);
  348. ILVL_H4_SH(in5, in1, in13, in9, in3, in7, in11, in15,
  349. src4_l, src5_l, src6_l, src7_l);
  350. HEVC_IDCT16x16_COL(src0_r, src1_r, src2_r, src3_r, src4_r, src5_r,
  351. src6_r, src7_r, src0_l, src1_l, src2_l, src3_l,
  352. src4_l, src5_l, src6_l, src7_l, 7);
  353. src += 8;
  354. buf_ptr = (&buf[0] + 8);
  355. filter = &gt16x16_cnst[0];
  356. }
  357. src = &buf[0];
  358. buf_ptr = coeffs;
  359. filter = &gt16x16_cnst[0];
  360. for (i = 2; i--;) {
  361. LD_SH16(src, 8, in0, in8, in1, in9, in2, in10, in3, in11,
  362. in4, in12, in5, in13, in6, in14, in7, in15);
  363. TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7,
  364. in0, in1, in2, in3, in4, in5, in6, in7);
  365. TRANSPOSE8x8_SH_SH(in8, in9, in10, in11, in12, in13, in14, in15,
  366. in8, in9, in10, in11, in12, in13, in14, in15);
  367. ILVR_H4_SH(in4, in0, in12, in8, in6, in2, in14, in10,
  368. src0_r, src1_r, src2_r, src3_r);
  369. ILVR_H4_SH(in5, in1, in13, in9, in3, in7, in11, in15,
  370. src4_r, src5_r, src6_r, src7_r);
  371. ILVL_H4_SH(in4, in0, in12, in8, in6, in2, in14, in10,
  372. src0_l, src1_l, src2_l, src3_l);
  373. ILVL_H4_SH(in5, in1, in13, in9, in3, in7, in11, in15,
  374. src4_l, src5_l, src6_l, src7_l);
  375. HEVC_IDCT16x16_COL(src0_r, src1_r, src2_r, src3_r, src4_r, src5_r,
  376. src6_r, src7_r, src0_l, src1_l, src2_l, src3_l,
  377. src4_l, src5_l, src6_l, src7_l, 12);
  378. src += 128;
  379. buf_ptr = coeffs + 8;
  380. filter = &gt16x16_cnst[0];
  381. }
  382. LD_SH8(coeffs, 16, in0, in1, in2, in3, in4, in5, in6, in7);
  383. TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7,
  384. vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7);
  385. ST_SH8(vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, coeffs, 16);
  386. LD_SH8((coeffs + 8), 16, in0, in1, in2, in3, in4, in5, in6, in7);
  387. TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7,
  388. vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7);
  389. LD_SH8((coeffs + 128), 16, in8, in9, in10, in11, in12, in13, in14, in15);
  390. ST_SH8(vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, (coeffs + 128), 16);
  391. TRANSPOSE8x8_SH_SH(in8, in9, in10, in11, in12, in13, in14, in15,
  392. vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7);
  393. ST_SH8(vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, (coeffs + 8), 16);
  394. LD_SH8((coeffs + 136), 16, in0, in1, in2, in3, in4, in5, in6, in7);
  395. TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7,
  396. vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7);
  397. ST_SH8(vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, (coeffs + 136), 16);
  398. }
  399. static void hevc_idct_8x32_column_msa(int16_t *coeffs, uint8_t buf_pitch,
  400. uint8_t round)
  401. {
  402. uint8_t i;
  403. const int16_t *filter_ptr0 = &gt32x32_cnst0[0];
  404. const int16_t *filter_ptr1 = &gt32x32_cnst1[0];
  405. const int16_t *filter_ptr2 = &gt32x32_cnst2[0];
  406. const int16_t *filter_ptr3 = &gt8x8_cnst[0];
  407. int16_t *src0 = (coeffs + buf_pitch);
  408. int16_t *src1 = (coeffs + 2 * buf_pitch);
  409. int16_t *src2 = (coeffs + 4 * buf_pitch);
  410. int16_t *src3 = (coeffs);
  411. int32_t cnst0, cnst1;
  412. int32_t tmp_buf[8 * 32 + 15];
  413. int32_t *tmp_buf_ptr = tmp_buf + 15;
  414. v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
  415. v8i16 src0_r, src1_r, src2_r, src3_r, src4_r, src5_r, src6_r, src7_r;
  416. v8i16 src0_l, src1_l, src2_l, src3_l, src4_l, src5_l, src6_l, src7_l;
  417. v8i16 filt0, filter0, filter1, filter2, filter3;
  418. v4i32 sum0_r, sum0_l, sum1_r, sum1_l, tmp0_r, tmp0_l, tmp1_r, tmp1_l;
  419. /* Align pointer to 64 byte boundary */
  420. tmp_buf_ptr = (int32_t *)(((uintptr_t) tmp_buf_ptr) & ~(uintptr_t) 63);
  421. /* process coeff 4, 12, 20, 28 */
  422. LD_SH4(src2, 8 * buf_pitch, in0, in1, in2, in3);
  423. ILVR_H2_SH(in1, in0, in3, in2, src0_r, src1_r);
  424. ILVL_H2_SH(in1, in0, in3, in2, src0_l, src1_l);
  425. LD_SH2(src3, 16 * buf_pitch, in4, in6);
  426. LD_SH2((src3 + 8 * buf_pitch), 16 * buf_pitch, in5, in7);
  427. ILVR_H2_SH(in6, in4, in7, in5, src2_r, src3_r);
  428. ILVL_H2_SH(in6, in4, in7, in5, src2_l, src3_l);
  429. /* loop for all columns of constants */
  430. for (i = 0; i < 2; i++) {
  431. /* processing single column of constants */
  432. cnst0 = LW(filter_ptr2);
  433. cnst1 = LW(filter_ptr2 + 2);
  434. filter0 = (v8i16) __msa_fill_w(cnst0);
  435. filter1 = (v8i16) __msa_fill_w(cnst1);
  436. DOTP_SH2_SW(src0_r, src0_l, filter0, filter0, sum0_r, sum0_l);
  437. DPADD_SH2_SW(src1_r, src1_l, filter1, filter1, sum0_r, sum0_l);
  438. ST_SW2(sum0_r, sum0_l, (tmp_buf_ptr + 2 * i * 8), 4);
  439. /* processing single column of constants */
  440. cnst0 = LW(filter_ptr2 + 4);
  441. cnst1 = LW(filter_ptr2 + 6);
  442. filter0 = (v8i16) __msa_fill_w(cnst0);
  443. filter1 = (v8i16) __msa_fill_w(cnst1);
  444. DOTP_SH2_SW(src0_r, src0_l, filter0, filter0, sum0_r, sum0_l);
  445. DPADD_SH2_SW(src1_r, src1_l, filter1, filter1, sum0_r, sum0_l);
  446. ST_SW2(sum0_r, sum0_l, (tmp_buf_ptr + (2 * i + 1) * 8), 4);
  447. filter_ptr2 += 8;
  448. }
  449. /* process coeff 0, 8, 16, 24 */
  450. /* loop for all columns of constants */
  451. for (i = 0; i < 2; i++) {
  452. /* processing first column of filter constants */
  453. cnst0 = LW(filter_ptr3);
  454. cnst1 = LW(filter_ptr3 + 2);
  455. filter0 = (v8i16) __msa_fill_w(cnst0);
  456. filter1 = (v8i16) __msa_fill_w(cnst1);
  457. DOTP_SH4_SW(src2_r, src2_l, src3_r, src3_l, filter0, filter0, filter1,
  458. filter1, sum0_r, sum0_l, tmp1_r, tmp1_l);
  459. sum1_r = sum0_r - tmp1_r;
  460. sum1_l = sum0_l - tmp1_l;
  461. sum0_r = sum0_r + tmp1_r;
  462. sum0_l = sum0_l + tmp1_l;
  463. HEVC_EVEN16_CALC(tmp_buf_ptr, sum0_r, sum0_l, i, (7 - i));
  464. HEVC_EVEN16_CALC(tmp_buf_ptr, sum1_r, sum1_l, (3 - i), (4 + i));
  465. filter_ptr3 += 8;
  466. }
  467. /* process coeff 2 6 10 14 18 22 26 30 */
  468. LD_SH8(src1, 4 * buf_pitch, in0, in1, in2, in3, in4, in5, in6, in7);
  469. ILVR_H4_SH(in1, in0, in3, in2, in5, in4, in7, in6,
  470. src0_r, src1_r, src2_r, src3_r);
  471. ILVL_H4_SH(in1, in0, in3, in2, in5, in4, in7, in6,
  472. src0_l, src1_l, src2_l, src3_l);
  473. /* loop for all columns of constants */
  474. for (i = 0; i < 8; i++) {
  475. /* processing single column of constants */
  476. filt0 = LD_SH(filter_ptr1);
  477. SPLATI_W4_SH(filt0, filter0, filter1, filter2, filter3);
  478. DOTP_SH2_SW(src0_r, src0_l, filter0, filter0, sum0_r, sum0_l);
  479. DPADD_SH4_SW(src1_r, src1_l, src2_r, src2_l, filter1, filter1, filter2,
  480. filter2, sum0_r, sum0_l, sum0_r, sum0_l);
  481. DPADD_SH2_SW(src3_r, src3_l, filter3, filter3, sum0_r, sum0_l);
  482. LD_SW2(tmp_buf_ptr + i * 8, 4, tmp0_r, tmp0_l);
  483. tmp1_r = tmp0_r;
  484. tmp1_l = tmp0_l;
  485. tmp0_r += sum0_r;
  486. tmp0_l += sum0_l;
  487. ST_SW2(tmp0_r, tmp0_l, (tmp_buf_ptr + i * 8), 4);
  488. tmp1_r -= sum0_r;
  489. tmp1_l -= sum0_l;
  490. ST_SW2(tmp1_r, tmp1_l, (tmp_buf_ptr + (15 - i) * 8), 4);
  491. filter_ptr1 += 8;
  492. }
  493. /* process coeff 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 */
  494. LD_SH8(src0, 2 * buf_pitch, in0, in1, in2, in3, in4, in5, in6, in7);
  495. src0 += 16 * buf_pitch;
  496. ILVR_H4_SH(in1, in0, in3, in2, in5, in4, in7, in6,
  497. src0_r, src1_r, src2_r, src3_r);
  498. ILVL_H4_SH(in1, in0, in3, in2, in5, in4, in7, in6,
  499. src0_l, src1_l, src2_l, src3_l);
  500. LD_SH8(src0, 2 * buf_pitch, in0, in1, in2, in3, in4, in5, in6, in7);
  501. ILVR_H4_SH(in1, in0, in3, in2, in5, in4, in7, in6,
  502. src4_r, src5_r, src6_r, src7_r);
  503. ILVL_H4_SH(in1, in0, in3, in2, in5, in4, in7, in6,
  504. src4_l, src5_l, src6_l, src7_l);
  505. /* loop for all columns of filter constants */
  506. for (i = 0; i < 16; i++) {
  507. /* processing single column of constants */
  508. filt0 = LD_SH(filter_ptr0);
  509. SPLATI_W4_SH(filt0, filter0, filter1, filter2, filter3);
  510. DOTP_SH2_SW(src0_r, src0_l, filter0, filter0, sum0_r, sum0_l);
  511. DPADD_SH4_SW(src1_r, src1_l, src2_r, src2_l, filter1, filter1, filter2,
  512. filter2, sum0_r, sum0_l, sum0_r, sum0_l);
  513. DPADD_SH2_SW(src3_r, src3_l, filter3, filter3, sum0_r, sum0_l);
  514. tmp1_r = sum0_r;
  515. tmp1_l = sum0_l;
  516. filt0 = LD_SH(filter_ptr0 + 8);
  517. SPLATI_W4_SH(filt0, filter0, filter1, filter2, filter3);
  518. DOTP_SH2_SW(src4_r, src4_l, filter0, filter0, sum0_r, sum0_l);
  519. DPADD_SH4_SW(src5_r, src5_l, src6_r, src6_l, filter1, filter1, filter2,
  520. filter2, sum0_r, sum0_l, sum0_r, sum0_l);
  521. DPADD_SH2_SW(src7_r, src7_l, filter3, filter3, sum0_r, sum0_l);
  522. sum0_r += tmp1_r;
  523. sum0_l += tmp1_l;
  524. LD_SW2(tmp_buf_ptr + i * 8, 4, tmp0_r, tmp0_l);
  525. tmp1_r = tmp0_r;
  526. tmp1_l = tmp0_l;
  527. tmp0_r += sum0_r;
  528. tmp0_l += sum0_l;
  529. sum1_r = __msa_fill_w(round);
  530. SRAR_W2_SW(tmp0_r, tmp0_l, sum1_r);
  531. SAT_SW2_SW(tmp0_r, tmp0_l, 15);
  532. in0 = __msa_pckev_h((v8i16) tmp0_l, (v8i16) tmp0_r);
  533. ST_SH(in0, (coeffs + i * buf_pitch));
  534. tmp1_r -= sum0_r;
  535. tmp1_l -= sum0_l;
  536. SRAR_W2_SW(tmp1_r, tmp1_l, sum1_r);
  537. SAT_SW2_SW(tmp1_r, tmp1_l, 15);
  538. in0 = __msa_pckev_h((v8i16) tmp1_l, (v8i16) tmp1_r);
  539. ST_SH(in0, (coeffs + (31 - i) * buf_pitch));
  540. filter_ptr0 += 16;
  541. }
  542. }
  543. static void hevc_idct_transpose_32x8_to_8x32(int16_t *coeffs, int16_t *tmp_buf)
  544. {
  545. uint8_t i;
  546. v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
  547. for (i = 0; i < 4; i++) {
  548. LD_SH8(coeffs + i * 8, 32, in0, in1, in2, in3, in4, in5, in6, in7);
  549. TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7,
  550. in0, in1, in2, in3, in4, in5, in6, in7);
  551. ST_SH8(in0, in1, in2, in3, in4, in5, in6, in7, tmp_buf + i * 8 * 8, 8);
  552. }
  553. }
  554. static void hevc_idct_transpose_8x32_to_32x8(int16_t *tmp_buf, int16_t *coeffs)
  555. {
  556. uint8_t i;
  557. v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
  558. for (i = 0; i < 4; i++) {
  559. LD_SH8(tmp_buf + i * 8 * 8, 8, in0, in1, in2, in3, in4, in5, in6, in7);
  560. TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7,
  561. in0, in1, in2, in3, in4, in5, in6, in7);
  562. ST_SH8(in0, in1, in2, in3, in4, in5, in6, in7, coeffs + i * 8, 32);
  563. }
  564. }
  565. static void hevc_idct_32x32_msa(int16_t *coeffs)
  566. {
  567. uint8_t row_cnt, col_cnt;
  568. int16_t *src = coeffs;
  569. int16_t tmp_buf[8 * 32 + 31];
  570. int16_t *tmp_buf_ptr = tmp_buf + 31;
  571. uint8_t round;
  572. uint8_t buf_pitch;
  573. /* Align pointer to 64 byte boundary */
  574. tmp_buf_ptr = (int16_t *)(((uintptr_t) tmp_buf_ptr) & ~(uintptr_t) 63);
  575. /* column transform */
  576. round = 7;
  577. buf_pitch = 32;
  578. for (col_cnt = 0; col_cnt < 4; col_cnt++) {
  579. /* process 8x32 blocks */
  580. hevc_idct_8x32_column_msa((coeffs + col_cnt * 8), buf_pitch, round);
  581. }
  582. /* row transform */
  583. round = 12;
  584. buf_pitch = 8;
  585. for (row_cnt = 0; row_cnt < 4; row_cnt++) {
  586. /* process 32x8 blocks */
  587. src = (coeffs + 32 * 8 * row_cnt);
  588. hevc_idct_transpose_32x8_to_8x32(src, tmp_buf_ptr);
  589. hevc_idct_8x32_column_msa(tmp_buf_ptr, buf_pitch, round);
  590. hevc_idct_transpose_8x32_to_32x8(tmp_buf_ptr, src);
  591. }
  592. }
  593. static void hevc_idct_dc_4x4_msa(int16_t *coeffs)
  594. {
  595. int32_t val;
  596. v8i16 dst;
  597. val = (coeffs[0] + 1) >> 1;
  598. val = (val + 32) >> 6;
  599. dst = __msa_fill_h(val);
  600. ST_SH2(dst, dst, coeffs, 8);
  601. }
  602. static void hevc_idct_dc_8x8_msa(int16_t *coeffs)
  603. {
  604. int32_t val;
  605. v8i16 dst;
  606. val = (coeffs[0] + 1) >> 1;
  607. val = (val + 32) >> 6;
  608. dst = __msa_fill_h(val);
  609. ST_SH8(dst, dst, dst, dst, dst, dst, dst, dst, coeffs, 8);
  610. }
  611. static void hevc_idct_dc_16x16_msa(int16_t *coeffs)
  612. {
  613. uint8_t loop;
  614. int32_t val;
  615. v8i16 dst;
  616. val = (coeffs[0] + 1) >> 1;
  617. val = (val + 32) >> 6;
  618. dst = __msa_fill_h(val);
  619. for (loop = 4; loop--;) {
  620. ST_SH8(dst, dst, dst, dst, dst, dst, dst, dst, coeffs, 8);
  621. coeffs += 8 * 8;
  622. }
  623. }
  624. static void hevc_idct_dc_32x32_msa(int16_t *coeffs)
  625. {
  626. uint8_t loop;
  627. int32_t val;
  628. v8i16 dst;
  629. val = (coeffs[0] + 1) >> 1;
  630. val = (val + 32) >> 6;
  631. dst = __msa_fill_h(val);
  632. for (loop = 16; loop--;) {
  633. ST_SH8(dst, dst, dst, dst, dst, dst, dst, dst, coeffs, 8);
  634. coeffs += 8 * 8;
  635. }
  636. }
  637. static void hevc_addblk_4x4_msa(int16_t *coeffs, uint8_t *dst, int32_t stride)
  638. {
  639. uint32_t dst0, dst1, dst2, dst3;
  640. v8i16 dst_r0, dst_l0, in0, in1;
  641. v4i32 dst_vec = { 0 };
  642. v16u8 zeros = { 0 };
  643. LD_SH2(coeffs, 8, in0, in1);
  644. LW4(dst, stride, dst0, dst1, dst2, dst3);
  645. INSERT_W4_SW(dst0, dst1, dst2, dst3, dst_vec);
  646. ILVRL_B2_SH(zeros, dst_vec, dst_r0, dst_l0);
  647. ADD2(dst_r0, in0, dst_l0, in1, dst_r0, dst_l0);
  648. CLIP_SH2_0_255(dst_r0, dst_l0);
  649. dst_vec = (v4i32) __msa_pckev_b((v16i8) dst_l0, (v16i8) dst_r0);
  650. ST_W4(dst_vec, 0, 1, 2, 3, dst, stride);
  651. }
  652. static void hevc_addblk_8x8_msa(int16_t *coeffs, uint8_t *dst, int32_t stride)
  653. {
  654. uint8_t *temp_dst = dst;
  655. uint64_t dst0, dst1, dst2, dst3;
  656. v2i64 dst_vec0 = { 0 };
  657. v2i64 dst_vec1 = { 0 };
  658. v8i16 dst_r0, dst_l0, dst_r1, dst_l1;
  659. v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
  660. v16u8 zeros = { 0 };
  661. LD_SH8(coeffs, 8, in0, in1, in2, in3, in4, in5, in6, in7);
  662. LD4(temp_dst, stride, dst0, dst1, dst2, dst3);
  663. temp_dst += (4 * stride);
  664. INSERT_D2_SD(dst0, dst1, dst_vec0);
  665. INSERT_D2_SD(dst2, dst3, dst_vec1);
  666. ILVRL_B2_SH(zeros, dst_vec0, dst_r0, dst_l0);
  667. ILVRL_B2_SH(zeros, dst_vec1, dst_r1, dst_l1);
  668. ADD4(dst_r0, in0, dst_l0, in1, dst_r1, in2, dst_l1, in3,
  669. dst_r0, dst_l0, dst_r1, dst_l1);
  670. CLIP_SH4_0_255(dst_r0, dst_l0, dst_r1, dst_l1);
  671. PCKEV_B2_SH(dst_l0, dst_r0, dst_l1, dst_r1, dst_r0, dst_r1);
  672. ST_D4(dst_r0, dst_r1, 0, 1, 0, 1, dst, stride);
  673. LD4(temp_dst, stride, dst0, dst1, dst2, dst3);
  674. INSERT_D2_SD(dst0, dst1, dst_vec0);
  675. INSERT_D2_SD(dst2, dst3, dst_vec1);
  676. UNPCK_UB_SH(dst_vec0, dst_r0, dst_l0);
  677. UNPCK_UB_SH(dst_vec1, dst_r1, dst_l1);
  678. ADD4(dst_r0, in4, dst_l0, in5, dst_r1, in6, dst_l1, in7,
  679. dst_r0, dst_l0, dst_r1, dst_l1);
  680. CLIP_SH4_0_255(dst_r0, dst_l0, dst_r1, dst_l1);
  681. PCKEV_B2_SH(dst_l0, dst_r0, dst_l1, dst_r1, dst_r0, dst_r1);
  682. ST_D4(dst_r0, dst_r1, 0, 1, 0, 1, dst + 4 * stride, stride);
  683. }
  684. static void hevc_addblk_16x16_msa(int16_t *coeffs, uint8_t *dst, int32_t stride)
  685. {
  686. uint8_t loop_cnt;
  687. uint8_t *temp_dst = dst;
  688. v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
  689. v8i16 dst_r0, dst_l0, dst_r1, dst_l1, dst_r2, dst_l2, dst_r3, dst_l3;
  690. v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
  691. /* Pre-load for next iteration */
  692. LD_UB4(temp_dst, stride, dst4, dst5, dst6, dst7);
  693. temp_dst += (4 * stride);
  694. LD_SH4(coeffs, 16, in0, in2, in4, in6);
  695. LD_SH4((coeffs + 8), 16, in1, in3, in5, in7);
  696. coeffs += 64;
  697. for (loop_cnt = 3; loop_cnt--;) {
  698. UNPCK_UB_SH(dst4, dst_r0, dst_l0);
  699. UNPCK_UB_SH(dst5, dst_r1, dst_l1);
  700. UNPCK_UB_SH(dst6, dst_r2, dst_l2);
  701. UNPCK_UB_SH(dst7, dst_r3, dst_l3);
  702. dst_r0 += in0;
  703. dst_l0 += in1;
  704. dst_r1 += in2;
  705. dst_l1 += in3;
  706. dst_r2 += in4;
  707. dst_l2 += in5;
  708. dst_r3 += in6;
  709. dst_l3 += in7;
  710. /* Pre-load for next iteration */
  711. LD_UB4(temp_dst, stride, dst4, dst5, dst6, dst7);
  712. temp_dst += (4 * stride);
  713. LD_SH4(coeffs, 16, in0, in2, in4, in6);
  714. LD_SH4((coeffs + 8), 16, in1, in3, in5, in7);
  715. coeffs += 64;
  716. CLIP_SH4_0_255(dst_r0, dst_l0, dst_r1, dst_l1);
  717. CLIP_SH4_0_255(dst_r2, dst_l2, dst_r3, dst_l3);
  718. PCKEV_B4_UB(dst_l0, dst_r0, dst_l1, dst_r1, dst_l2, dst_r2, dst_l3,
  719. dst_r3, dst0, dst1, dst2, dst3);
  720. ST_UB4(dst0, dst1, dst2, dst3, dst, stride);
  721. dst += (4 * stride);
  722. }
  723. UNPCK_UB_SH(dst4, dst_r0, dst_l0);
  724. UNPCK_UB_SH(dst5, dst_r1, dst_l1);
  725. UNPCK_UB_SH(dst6, dst_r2, dst_l2);
  726. UNPCK_UB_SH(dst7, dst_r3, dst_l3);
  727. dst_r0 += in0;
  728. dst_l0 += in1;
  729. dst_r1 += in2;
  730. dst_l1 += in3;
  731. dst_r2 += in4;
  732. dst_l2 += in5;
  733. dst_r3 += in6;
  734. dst_l3 += in7;
  735. CLIP_SH4_0_255(dst_r0, dst_l0, dst_r1, dst_l1);
  736. CLIP_SH4_0_255(dst_r2, dst_l2, dst_r3, dst_l3);
  737. PCKEV_B4_UB(dst_l0, dst_r0, dst_l1, dst_r1, dst_l2, dst_r2, dst_l3,
  738. dst_r3, dst0, dst1, dst2, dst3);
  739. ST_UB4(dst0, dst1, dst2, dst3, dst, stride);
  740. }
  741. static void hevc_addblk_32x32_msa(int16_t *coeffs, uint8_t *dst, int32_t stride)
  742. {
  743. uint8_t loop_cnt;
  744. uint8_t *temp_dst = dst;
  745. v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
  746. v8i16 dst_r0, dst_l0, dst_r1, dst_l1, dst_r2, dst_l2, dst_r3, dst_l3;
  747. v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
  748. /* Pre-load for next iteration */
  749. LD_UB2(temp_dst, 16, dst4, dst5);
  750. temp_dst += stride;
  751. LD_UB2(temp_dst, 16, dst6, dst7);
  752. temp_dst += stride;
  753. LD_SH4(coeffs, 16, in0, in2, in4, in6);
  754. LD_SH4((coeffs + 8), 16, in1, in3, in5, in7);
  755. coeffs += 64;
  756. for (loop_cnt = 14; loop_cnt--;) {
  757. UNPCK_UB_SH(dst4, dst_r0, dst_l0);
  758. UNPCK_UB_SH(dst5, dst_r1, dst_l1);
  759. UNPCK_UB_SH(dst6, dst_r2, dst_l2);
  760. UNPCK_UB_SH(dst7, dst_r3, dst_l3);
  761. dst_r0 += in0;
  762. dst_l0 += in1;
  763. dst_r1 += in2;
  764. dst_l1 += in3;
  765. dst_r2 += in4;
  766. dst_l2 += in5;
  767. dst_r3 += in6;
  768. dst_l3 += in7;
  769. /* Pre-load for next iteration */
  770. LD_UB2(temp_dst, 16, dst4, dst5);
  771. temp_dst += stride;
  772. LD_UB2(temp_dst, 16, dst6, dst7);
  773. temp_dst += stride;
  774. LD_SH4(coeffs, 16, in0, in2, in4, in6);
  775. LD_SH4((coeffs + 8), 16, in1, in3, in5, in7);
  776. coeffs += 64;
  777. CLIP_SH4_0_255(dst_r0, dst_l0, dst_r1, dst_l1);
  778. CLIP_SH4_0_255(dst_r2, dst_l2, dst_r3, dst_l3);
  779. PCKEV_B4_UB(dst_l0, dst_r0, dst_l1, dst_r1, dst_l2, dst_r2, dst_l3,
  780. dst_r3, dst0, dst1, dst2, dst3);
  781. ST_UB2(dst0, dst1, dst, 16);
  782. dst += stride;
  783. ST_UB2(dst2, dst3, dst, 16);
  784. dst += stride;
  785. }
  786. UNPCK_UB_SH(dst4, dst_r0, dst_l0);
  787. UNPCK_UB_SH(dst5, dst_r1, dst_l1);
  788. UNPCK_UB_SH(dst6, dst_r2, dst_l2);
  789. UNPCK_UB_SH(dst7, dst_r3, dst_l3);
  790. dst_r0 += in0;
  791. dst_l0 += in1;
  792. dst_r1 += in2;
  793. dst_l1 += in3;
  794. dst_r2 += in4;
  795. dst_l2 += in5;
  796. dst_r3 += in6;
  797. dst_l3 += in7;
  798. /* Pre-load for next iteration */
  799. LD_UB2(temp_dst, 16, dst4, dst5);
  800. temp_dst += stride;
  801. LD_UB2(temp_dst, 16, dst6, dst7);
  802. temp_dst += stride;
  803. LD_SH4(coeffs, 16, in0, in2, in4, in6);
  804. LD_SH4((coeffs + 8), 16, in1, in3, in5, in7);
  805. CLIP_SH4_0_255(dst_r0, dst_l0, dst_r1, dst_l1);
  806. CLIP_SH4_0_255(dst_r2, dst_l2, dst_r3, dst_l3);
  807. PCKEV_B4_UB(dst_l0, dst_r0, dst_l1, dst_r1, dst_l2, dst_r2, dst_l3,
  808. dst_r3, dst0, dst1, dst2, dst3);
  809. ST_UB2(dst0, dst1, dst, 16);
  810. dst += stride;
  811. ST_UB2(dst2, dst3, dst, 16);
  812. dst += stride;
  813. UNPCK_UB_SH(dst4, dst_r0, dst_l0);
  814. UNPCK_UB_SH(dst5, dst_r1, dst_l1);
  815. UNPCK_UB_SH(dst6, dst_r2, dst_l2);
  816. UNPCK_UB_SH(dst7, dst_r3, dst_l3);
  817. dst_r0 += in0;
  818. dst_l0 += in1;
  819. dst_r1 += in2;
  820. dst_l1 += in3;
  821. dst_r2 += in4;
  822. dst_l2 += in5;
  823. dst_r3 += in6;
  824. dst_l3 += in7;
  825. CLIP_SH4_0_255(dst_r0, dst_l0, dst_r1, dst_l1);
  826. CLIP_SH4_0_255(dst_r2, dst_l2, dst_r3, dst_l3);
  827. PCKEV_B4_UB(dst_l0, dst_r0, dst_l1, dst_r1, dst_l2, dst_r2, dst_l3,
  828. dst_r3, dst0, dst1, dst2, dst3);
  829. ST_UB2(dst0, dst1, dst, 16);
  830. dst += stride;
  831. ST_UB2(dst2, dst3, dst, 16);
  832. }
  833. static void hevc_idct_luma_4x4_msa(int16_t *coeffs)
  834. {
  835. v8i16 in0, in1, dst0, dst1;
  836. v4i32 in_r0, in_l0, in_r1, in_l1, res0, res1, res2, res3;
  837. LD_SH2(coeffs, 8, in0, in1);
  838. UNPCK_SH_SW(in0, in_r0, in_l0);
  839. UNPCK_SH_SW(in1, in_r1, in_l1);
  840. HEVC_IDCT_LUMA4x4_COL(in_r0, in_l0, in_r1, in_l1, res0, res1, res2, res3,
  841. 7);
  842. TRANSPOSE4x4_SW_SW(res0, res1, res2, res3, in_r0, in_l0, in_r1, in_l1);
  843. HEVC_IDCT_LUMA4x4_COL(in_r0, in_l0, in_r1, in_l1, res0, res1, res2, res3,
  844. 12);
  845. /* Pack and transpose */
  846. PCKEV_H2_SH(res2, res0, res3, res1, dst0, dst1);
  847. ILVRL_H2_SW(dst1, dst0, res0, res1);
  848. ILVRL_W2_SH(res1, res0, dst0, dst1);
  849. ST_SH2(dst0, dst1, coeffs, 8);
  850. }
  851. void ff_hevc_idct_4x4_msa(int16_t *coeffs, int col_limit)
  852. {
  853. hevc_idct_4x4_msa(coeffs);
  854. }
  855. void ff_hevc_idct_8x8_msa(int16_t *coeffs, int col_limit)
  856. {
  857. hevc_idct_8x8_msa(coeffs);
  858. }
  859. void ff_hevc_idct_16x16_msa(int16_t *coeffs, int col_limit)
  860. {
  861. hevc_idct_16x16_msa(coeffs);
  862. }
  863. void ff_hevc_idct_32x32_msa(int16_t *coeffs, int col_limit)
  864. {
  865. hevc_idct_32x32_msa(coeffs);
  866. }
  867. void ff_hevc_addblk_4x4_msa(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
  868. {
  869. hevc_addblk_4x4_msa(coeffs, dst, stride);
  870. }
  871. void ff_hevc_addblk_8x8_msa(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
  872. {
  873. hevc_addblk_8x8_msa(coeffs, dst, stride);
  874. }
  875. void ff_hevc_addblk_16x16_msa(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
  876. {
  877. hevc_addblk_16x16_msa(coeffs, dst, stride);
  878. }
  879. void ff_hevc_addblk_32x32_msa(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
  880. {
  881. hevc_addblk_32x32_msa(coeffs, dst, stride);
  882. }
  883. void ff_hevc_idct_dc_4x4_msa(int16_t *coeffs)
  884. {
  885. hevc_idct_dc_4x4_msa(coeffs);
  886. }
  887. void ff_hevc_idct_dc_8x8_msa(int16_t *coeffs)
  888. {
  889. hevc_idct_dc_8x8_msa(coeffs);
  890. }
  891. void ff_hevc_idct_dc_16x16_msa(int16_t *coeffs)
  892. {
  893. hevc_idct_dc_16x16_msa(coeffs);
  894. }
  895. void ff_hevc_idct_dc_32x32_msa(int16_t *coeffs)
  896. {
  897. hevc_idct_dc_32x32_msa(coeffs);
  898. }
  899. void ff_hevc_idct_luma_4x4_msa(int16_t *coeffs)
  900. {
  901. hevc_idct_luma_4x4_msa(coeffs);
  902. }