2
0

scale_msa.cc 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949
  1. /*
  2. * Copyright 2016 The LibYuv Project Authors. All rights reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #include <assert.h>
  11. #include "libyuv/scale_row.h"
  12. // This module is for GCC MSA
  13. #if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)
  14. #include "libyuv/macros_msa.h"
  15. #ifdef __cplusplus
  16. namespace libyuv {
  17. extern "C" {
  18. #endif
  19. #define LOAD_INDEXED_DATA(srcp, indx0, out0) \
  20. { \
  21. out0[0] = srcp[indx0[0]]; \
  22. out0[1] = srcp[indx0[1]]; \
  23. out0[2] = srcp[indx0[2]]; \
  24. out0[3] = srcp[indx0[3]]; \
  25. }
  26. void ScaleARGBRowDown2_MSA(const uint8_t* src_argb,
  27. ptrdiff_t src_stride,
  28. uint8_t* dst_argb,
  29. int dst_width) {
  30. int x;
  31. v16u8 src0, src1, dst0;
  32. (void)src_stride;
  33. for (x = 0; x < dst_width; x += 4) {
  34. src0 = (v16u8)__msa_ld_b((v16i8*)src_argb, 0);
  35. src1 = (v16u8)__msa_ld_b((v16i8*)src_argb, 16);
  36. dst0 = (v16u8)__msa_pckod_w((v4i32)src1, (v4i32)src0);
  37. ST_UB(dst0, dst_argb);
  38. src_argb += 32;
  39. dst_argb += 16;
  40. }
  41. }
  42. void ScaleARGBRowDown2Linear_MSA(const uint8_t* src_argb,
  43. ptrdiff_t src_stride,
  44. uint8_t* dst_argb,
  45. int dst_width) {
  46. int x;
  47. v16u8 src0, src1, vec0, vec1, dst0;
  48. (void)src_stride;
  49. for (x = 0; x < dst_width; x += 4) {
  50. src0 = (v16u8)__msa_ld_b((v16i8*)src_argb, 0);
  51. src1 = (v16u8)__msa_ld_b((v16i8*)src_argb, 16);
  52. vec0 = (v16u8)__msa_pckev_w((v4i32)src1, (v4i32)src0);
  53. vec1 = (v16u8)__msa_pckod_w((v4i32)src1, (v4i32)src0);
  54. dst0 = (v16u8)__msa_aver_u_b((v16u8)vec0, (v16u8)vec1);
  55. ST_UB(dst0, dst_argb);
  56. src_argb += 32;
  57. dst_argb += 16;
  58. }
  59. }
  60. void ScaleARGBRowDown2Box_MSA(const uint8_t* src_argb,
  61. ptrdiff_t src_stride,
  62. uint8_t* dst_argb,
  63. int dst_width) {
  64. int x;
  65. const uint8_t* s = src_argb;
  66. const uint8_t* t = src_argb + src_stride;
  67. v16u8 src0, src1, src2, src3, vec0, vec1, vec2, vec3, dst0;
  68. v8u16 reg0, reg1, reg2, reg3;
  69. v16i8 shuffler = {0, 4, 1, 5, 2, 6, 3, 7, 8, 12, 9, 13, 10, 14, 11, 15};
  70. for (x = 0; x < dst_width; x += 4) {
  71. src0 = (v16u8)__msa_ld_b((v16i8*)s, 0);
  72. src1 = (v16u8)__msa_ld_b((v16i8*)s, 16);
  73. src2 = (v16u8)__msa_ld_b((v16i8*)t, 0);
  74. src3 = (v16u8)__msa_ld_b((v16i8*)t, 16);
  75. vec0 = (v16u8)__msa_vshf_b(shuffler, (v16i8)src0, (v16i8)src0);
  76. vec1 = (v16u8)__msa_vshf_b(shuffler, (v16i8)src1, (v16i8)src1);
  77. vec2 = (v16u8)__msa_vshf_b(shuffler, (v16i8)src2, (v16i8)src2);
  78. vec3 = (v16u8)__msa_vshf_b(shuffler, (v16i8)src3, (v16i8)src3);
  79. reg0 = __msa_hadd_u_h(vec0, vec0);
  80. reg1 = __msa_hadd_u_h(vec1, vec1);
  81. reg2 = __msa_hadd_u_h(vec2, vec2);
  82. reg3 = __msa_hadd_u_h(vec3, vec3);
  83. reg0 += reg2;
  84. reg1 += reg3;
  85. reg0 = (v8u16)__msa_srari_h((v8i16)reg0, 2);
  86. reg1 = (v8u16)__msa_srari_h((v8i16)reg1, 2);
  87. dst0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0);
  88. ST_UB(dst0, dst_argb);
  89. s += 32;
  90. t += 32;
  91. dst_argb += 16;
  92. }
  93. }
  94. void ScaleARGBRowDownEven_MSA(const uint8_t* src_argb,
  95. ptrdiff_t src_stride,
  96. int32_t src_stepx,
  97. uint8_t* dst_argb,
  98. int dst_width) {
  99. int x;
  100. int32_t stepx = src_stepx * 4;
  101. int32_t data0, data1, data2, data3;
  102. (void)src_stride;
  103. for (x = 0; x < dst_width; x += 4) {
  104. data0 = LW(src_argb);
  105. data1 = LW(src_argb + stepx);
  106. data2 = LW(src_argb + stepx * 2);
  107. data3 = LW(src_argb + stepx * 3);
  108. SW(data0, dst_argb);
  109. SW(data1, dst_argb + 4);
  110. SW(data2, dst_argb + 8);
  111. SW(data3, dst_argb + 12);
  112. src_argb += stepx * 4;
  113. dst_argb += 16;
  114. }
  115. }
  116. void ScaleARGBRowDownEvenBox_MSA(const uint8_t* src_argb,
  117. ptrdiff_t src_stride,
  118. int src_stepx,
  119. uint8_t* dst_argb,
  120. int dst_width) {
  121. int x;
  122. const uint8_t* nxt_argb = src_argb + src_stride;
  123. int32_t stepx = src_stepx * 4;
  124. int64_t data0, data1, data2, data3;
  125. v16u8 src0 = {0}, src1 = {0}, src2 = {0}, src3 = {0};
  126. v16u8 vec0, vec1, vec2, vec3;
  127. v8u16 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7;
  128. v16u8 dst0;
  129. for (x = 0; x < dst_width; x += 4) {
  130. data0 = LD(src_argb);
  131. data1 = LD(src_argb + stepx);
  132. data2 = LD(src_argb + stepx * 2);
  133. data3 = LD(src_argb + stepx * 3);
  134. src0 = (v16u8)__msa_insert_d((v2i64)src0, 0, data0);
  135. src0 = (v16u8)__msa_insert_d((v2i64)src0, 1, data1);
  136. src1 = (v16u8)__msa_insert_d((v2i64)src1, 0, data2);
  137. src1 = (v16u8)__msa_insert_d((v2i64)src1, 1, data3);
  138. data0 = LD(nxt_argb);
  139. data1 = LD(nxt_argb + stepx);
  140. data2 = LD(nxt_argb + stepx * 2);
  141. data3 = LD(nxt_argb + stepx * 3);
  142. src2 = (v16u8)__msa_insert_d((v2i64)src2, 0, data0);
  143. src2 = (v16u8)__msa_insert_d((v2i64)src2, 1, data1);
  144. src3 = (v16u8)__msa_insert_d((v2i64)src3, 0, data2);
  145. src3 = (v16u8)__msa_insert_d((v2i64)src3, 1, data3);
  146. vec0 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src0);
  147. vec1 = (v16u8)__msa_ilvr_b((v16i8)src3, (v16i8)src1);
  148. vec2 = (v16u8)__msa_ilvl_b((v16i8)src2, (v16i8)src0);
  149. vec3 = (v16u8)__msa_ilvl_b((v16i8)src3, (v16i8)src1);
  150. reg0 = __msa_hadd_u_h(vec0, vec0);
  151. reg1 = __msa_hadd_u_h(vec1, vec1);
  152. reg2 = __msa_hadd_u_h(vec2, vec2);
  153. reg3 = __msa_hadd_u_h(vec3, vec3);
  154. reg4 = (v8u16)__msa_pckev_d((v2i64)reg2, (v2i64)reg0);
  155. reg5 = (v8u16)__msa_pckev_d((v2i64)reg3, (v2i64)reg1);
  156. reg6 = (v8u16)__msa_pckod_d((v2i64)reg2, (v2i64)reg0);
  157. reg7 = (v8u16)__msa_pckod_d((v2i64)reg3, (v2i64)reg1);
  158. reg4 += reg6;
  159. reg5 += reg7;
  160. reg4 = (v8u16)__msa_srari_h((v8i16)reg4, 2);
  161. reg5 = (v8u16)__msa_srari_h((v8i16)reg5, 2);
  162. dst0 = (v16u8)__msa_pckev_b((v16i8)reg5, (v16i8)reg4);
  163. ST_UB(dst0, dst_argb);
  164. src_argb += stepx * 4;
  165. nxt_argb += stepx * 4;
  166. dst_argb += 16;
  167. }
  168. }
  169. void ScaleRowDown2_MSA(const uint8_t* src_ptr,
  170. ptrdiff_t src_stride,
  171. uint8_t* dst,
  172. int dst_width) {
  173. int x;
  174. v16u8 src0, src1, src2, src3, dst0, dst1;
  175. (void)src_stride;
  176. for (x = 0; x < dst_width; x += 32) {
  177. src0 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 0);
  178. src1 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 16);
  179. src2 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 32);
  180. src3 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 48);
  181. dst0 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0);
  182. dst1 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2);
  183. ST_UB2(dst0, dst1, dst, 16);
  184. src_ptr += 64;
  185. dst += 32;
  186. }
  187. }
  188. void ScaleRowDown2Linear_MSA(const uint8_t* src_ptr,
  189. ptrdiff_t src_stride,
  190. uint8_t* dst,
  191. int dst_width) {
  192. int x;
  193. v16u8 src0, src1, src2, src3, vec0, vec1, vec2, vec3, dst0, dst1;
  194. (void)src_stride;
  195. for (x = 0; x < dst_width; x += 32) {
  196. src0 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 0);
  197. src1 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 16);
  198. src2 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 32);
  199. src3 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 48);
  200. vec0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0);
  201. vec2 = (v16u8)__msa_pckev_b((v16i8)src3, (v16i8)src2);
  202. vec1 = (v16u8)__msa_pckod_b((v16i8)src1, (v16i8)src0);
  203. vec3 = (v16u8)__msa_pckod_b((v16i8)src3, (v16i8)src2);
  204. dst0 = __msa_aver_u_b(vec1, vec0);
  205. dst1 = __msa_aver_u_b(vec3, vec2);
  206. ST_UB2(dst0, dst1, dst, 16);
  207. src_ptr += 64;
  208. dst += 32;
  209. }
  210. }
  211. void ScaleRowDown2Box_MSA(const uint8_t* src_ptr,
  212. ptrdiff_t src_stride,
  213. uint8_t* dst,
  214. int dst_width) {
  215. int x;
  216. const uint8_t* s = src_ptr;
  217. const uint8_t* t = src_ptr + src_stride;
  218. v16u8 src0, src1, src2, src3, src4, src5, src6, src7, dst0, dst1;
  219. v8u16 vec0, vec1, vec2, vec3;
  220. for (x = 0; x < dst_width; x += 32) {
  221. src0 = (v16u8)__msa_ld_b((v16i8*)s, 0);
  222. src1 = (v16u8)__msa_ld_b((v16i8*)s, 16);
  223. src2 = (v16u8)__msa_ld_b((v16i8*)s, 32);
  224. src3 = (v16u8)__msa_ld_b((v16i8*)s, 48);
  225. src4 = (v16u8)__msa_ld_b((v16i8*)t, 0);
  226. src5 = (v16u8)__msa_ld_b((v16i8*)t, 16);
  227. src6 = (v16u8)__msa_ld_b((v16i8*)t, 32);
  228. src7 = (v16u8)__msa_ld_b((v16i8*)t, 48);
  229. vec0 = __msa_hadd_u_h(src0, src0);
  230. vec1 = __msa_hadd_u_h(src1, src1);
  231. vec2 = __msa_hadd_u_h(src2, src2);
  232. vec3 = __msa_hadd_u_h(src3, src3);
  233. vec0 += __msa_hadd_u_h(src4, src4);
  234. vec1 += __msa_hadd_u_h(src5, src5);
  235. vec2 += __msa_hadd_u_h(src6, src6);
  236. vec3 += __msa_hadd_u_h(src7, src7);
  237. vec0 = (v8u16)__msa_srari_h((v8i16)vec0, 2);
  238. vec1 = (v8u16)__msa_srari_h((v8i16)vec1, 2);
  239. vec2 = (v8u16)__msa_srari_h((v8i16)vec2, 2);
  240. vec3 = (v8u16)__msa_srari_h((v8i16)vec3, 2);
  241. dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0);
  242. dst1 = (v16u8)__msa_pckev_b((v16i8)vec3, (v16i8)vec2);
  243. ST_UB2(dst0, dst1, dst, 16);
  244. s += 64;
  245. t += 64;
  246. dst += 32;
  247. }
  248. }
  249. void ScaleRowDown4_MSA(const uint8_t* src_ptr,
  250. ptrdiff_t src_stride,
  251. uint8_t* dst,
  252. int dst_width) {
  253. int x;
  254. v16u8 src0, src1, src2, src3, vec0, vec1, dst0;
  255. (void)src_stride;
  256. for (x = 0; x < dst_width; x += 16) {
  257. src0 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 0);
  258. src1 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 16);
  259. src2 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 32);
  260. src3 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 48);
  261. vec0 = (v16u8)__msa_pckev_b((v16i8)src1, (v16i8)src0);
  262. vec1 = (v16u8)__msa_pckev_b((v16i8)src3, (v16i8)src2);
  263. dst0 = (v16u8)__msa_pckod_b((v16i8)vec1, (v16i8)vec0);
  264. ST_UB(dst0, dst);
  265. src_ptr += 64;
  266. dst += 16;
  267. }
  268. }
  269. void ScaleRowDown4Box_MSA(const uint8_t* src_ptr,
  270. ptrdiff_t src_stride,
  271. uint8_t* dst,
  272. int dst_width) {
  273. int x;
  274. const uint8_t* s = src_ptr;
  275. const uint8_t* t0 = s + src_stride;
  276. const uint8_t* t1 = s + src_stride * 2;
  277. const uint8_t* t2 = s + src_stride * 3;
  278. v16u8 src0, src1, src2, src3, src4, src5, src6, src7, dst0;
  279. v8u16 vec0, vec1, vec2, vec3;
  280. v4u32 reg0, reg1, reg2, reg3;
  281. for (x = 0; x < dst_width; x += 16) {
  282. src0 = (v16u8)__msa_ld_b((v16i8*)s, 0);
  283. src1 = (v16u8)__msa_ld_b((v16i8*)s, 16);
  284. src2 = (v16u8)__msa_ld_b((v16i8*)s, 32);
  285. src3 = (v16u8)__msa_ld_b((v16i8*)s, 48);
  286. src4 = (v16u8)__msa_ld_b((v16i8*)t0, 0);
  287. src5 = (v16u8)__msa_ld_b((v16i8*)t0, 16);
  288. src6 = (v16u8)__msa_ld_b((v16i8*)t0, 32);
  289. src7 = (v16u8)__msa_ld_b((v16i8*)t0, 48);
  290. vec0 = __msa_hadd_u_h(src0, src0);
  291. vec1 = __msa_hadd_u_h(src1, src1);
  292. vec2 = __msa_hadd_u_h(src2, src2);
  293. vec3 = __msa_hadd_u_h(src3, src3);
  294. vec0 += __msa_hadd_u_h(src4, src4);
  295. vec1 += __msa_hadd_u_h(src5, src5);
  296. vec2 += __msa_hadd_u_h(src6, src6);
  297. vec3 += __msa_hadd_u_h(src7, src7);
  298. src0 = (v16u8)__msa_ld_b((v16i8*)t1, 0);
  299. src1 = (v16u8)__msa_ld_b((v16i8*)t1, 16);
  300. src2 = (v16u8)__msa_ld_b((v16i8*)t1, 32);
  301. src3 = (v16u8)__msa_ld_b((v16i8*)t1, 48);
  302. src4 = (v16u8)__msa_ld_b((v16i8*)t2, 0);
  303. src5 = (v16u8)__msa_ld_b((v16i8*)t2, 16);
  304. src6 = (v16u8)__msa_ld_b((v16i8*)t2, 32);
  305. src7 = (v16u8)__msa_ld_b((v16i8*)t2, 48);
  306. vec0 += __msa_hadd_u_h(src0, src0);
  307. vec1 += __msa_hadd_u_h(src1, src1);
  308. vec2 += __msa_hadd_u_h(src2, src2);
  309. vec3 += __msa_hadd_u_h(src3, src3);
  310. vec0 += __msa_hadd_u_h(src4, src4);
  311. vec1 += __msa_hadd_u_h(src5, src5);
  312. vec2 += __msa_hadd_u_h(src6, src6);
  313. vec3 += __msa_hadd_u_h(src7, src7);
  314. reg0 = __msa_hadd_u_w(vec0, vec0);
  315. reg1 = __msa_hadd_u_w(vec1, vec1);
  316. reg2 = __msa_hadd_u_w(vec2, vec2);
  317. reg3 = __msa_hadd_u_w(vec3, vec3);
  318. reg0 = (v4u32)__msa_srari_w((v4i32)reg0, 4);
  319. reg1 = (v4u32)__msa_srari_w((v4i32)reg1, 4);
  320. reg2 = (v4u32)__msa_srari_w((v4i32)reg2, 4);
  321. reg3 = (v4u32)__msa_srari_w((v4i32)reg3, 4);
  322. vec0 = (v8u16)__msa_pckev_h((v8i16)reg1, (v8i16)reg0);
  323. vec1 = (v8u16)__msa_pckev_h((v8i16)reg3, (v8i16)reg2);
  324. dst0 = (v16u8)__msa_pckev_b((v16i8)vec1, (v16i8)vec0);
  325. ST_UB(dst0, dst);
  326. s += 64;
  327. t0 += 64;
  328. t1 += 64;
  329. t2 += 64;
  330. dst += 16;
  331. }
  332. }
  333. void ScaleRowDown38_MSA(const uint8_t* src_ptr,
  334. ptrdiff_t src_stride,
  335. uint8_t* dst,
  336. int dst_width) {
  337. int x, width;
  338. uint64_t dst0;
  339. uint32_t dst1;
  340. v16u8 src0, src1, vec0;
  341. v16i8 mask = {0, 3, 6, 8, 11, 14, 16, 19, 22, 24, 27, 30, 0, 0, 0, 0};
  342. (void)src_stride;
  343. assert(dst_width % 3 == 0);
  344. width = dst_width / 3;
  345. for (x = 0; x < width; x += 4) {
  346. src0 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 0);
  347. src1 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 16);
  348. vec0 = (v16u8)__msa_vshf_b(mask, (v16i8)src1, (v16i8)src0);
  349. dst0 = __msa_copy_u_d((v2i64)vec0, 0);
  350. dst1 = __msa_copy_u_w((v4i32)vec0, 2);
  351. SD(dst0, dst);
  352. SW(dst1, dst + 8);
  353. src_ptr += 32;
  354. dst += 12;
  355. }
  356. }
  357. void ScaleRowDown38_2_Box_MSA(const uint8_t* src_ptr,
  358. ptrdiff_t src_stride,
  359. uint8_t* dst_ptr,
  360. int dst_width) {
  361. int x, width;
  362. const uint8_t* s = src_ptr;
  363. const uint8_t* t = src_ptr + src_stride;
  364. uint64_t dst0;
  365. uint32_t dst1;
  366. v16u8 src0, src1, src2, src3, out;
  367. v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7;
  368. v4u32 tmp0, tmp1, tmp2, tmp3, tmp4;
  369. v8i16 zero = {0};
  370. v8i16 mask = {0, 1, 2, 8, 3, 4, 5, 9};
  371. v16i8 dst_mask = {0, 2, 16, 4, 6, 18, 8, 10, 20, 12, 14, 22, 0, 0, 0, 0};
  372. v4u32 const_0x2AAA = (v4u32)__msa_fill_w(0x2AAA);
  373. v4u32 const_0x4000 = (v4u32)__msa_fill_w(0x4000);
  374. assert((dst_width % 3 == 0) && (dst_width > 0));
  375. width = dst_width / 3;
  376. for (x = 0; x < width; x += 4) {
  377. src0 = (v16u8)__msa_ld_b((v16i8*)s, 0);
  378. src1 = (v16u8)__msa_ld_b((v16i8*)s, 16);
  379. src2 = (v16u8)__msa_ld_b((v16i8*)t, 0);
  380. src3 = (v16u8)__msa_ld_b((v16i8*)t, 16);
  381. vec0 = (v8u16)__msa_ilvr_b((v16i8)src2, (v16i8)src0);
  382. vec1 = (v8u16)__msa_ilvl_b((v16i8)src2, (v16i8)src0);
  383. vec2 = (v8u16)__msa_ilvr_b((v16i8)src3, (v16i8)src1);
  384. vec3 = (v8u16)__msa_ilvl_b((v16i8)src3, (v16i8)src1);
  385. vec0 = __msa_hadd_u_h((v16u8)vec0, (v16u8)vec0);
  386. vec1 = __msa_hadd_u_h((v16u8)vec1, (v16u8)vec1);
  387. vec2 = __msa_hadd_u_h((v16u8)vec2, (v16u8)vec2);
  388. vec3 = __msa_hadd_u_h((v16u8)vec3, (v16u8)vec3);
  389. vec4 = (v8u16)__msa_vshf_h(mask, zero, (v8i16)vec0);
  390. vec5 = (v8u16)__msa_vshf_h(mask, zero, (v8i16)vec1);
  391. vec6 = (v8u16)__msa_vshf_h(mask, zero, (v8i16)vec2);
  392. vec7 = (v8u16)__msa_vshf_h(mask, zero, (v8i16)vec3);
  393. vec0 = (v8u16)__msa_pckod_w((v4i32)vec1, (v4i32)vec0);
  394. vec1 = (v8u16)__msa_pckod_w((v4i32)vec3, (v4i32)vec2);
  395. vec0 = (v8u16)__msa_pckod_w((v4i32)vec1, (v4i32)vec0);
  396. tmp0 = __msa_hadd_u_w(vec4, vec4);
  397. tmp1 = __msa_hadd_u_w(vec5, vec5);
  398. tmp2 = __msa_hadd_u_w(vec6, vec6);
  399. tmp3 = __msa_hadd_u_w(vec7, vec7);
  400. tmp4 = __msa_hadd_u_w(vec0, vec0);
  401. vec0 = (v8u16)__msa_pckev_h((v8i16)tmp1, (v8i16)tmp0);
  402. vec1 = (v8u16)__msa_pckev_h((v8i16)tmp3, (v8i16)tmp2);
  403. tmp0 = __msa_hadd_u_w(vec0, vec0);
  404. tmp1 = __msa_hadd_u_w(vec1, vec1);
  405. tmp0 *= const_0x2AAA;
  406. tmp1 *= const_0x2AAA;
  407. tmp4 *= const_0x4000;
  408. tmp0 = (v4u32)__msa_srai_w((v4i32)tmp0, 16);
  409. tmp1 = (v4u32)__msa_srai_w((v4i32)tmp1, 16);
  410. tmp4 = (v4u32)__msa_srai_w((v4i32)tmp4, 16);
  411. vec0 = (v8u16)__msa_pckev_h((v8i16)tmp1, (v8i16)tmp0);
  412. vec1 = (v8u16)__msa_pckev_h((v8i16)tmp4, (v8i16)tmp4);
  413. out = (v16u8)__msa_vshf_b(dst_mask, (v16i8)vec1, (v16i8)vec0);
  414. dst0 = __msa_copy_u_d((v2i64)out, 0);
  415. dst1 = __msa_copy_u_w((v4i32)out, 2);
  416. SD(dst0, dst_ptr);
  417. SW(dst1, dst_ptr + 8);
  418. s += 32;
  419. t += 32;
  420. dst_ptr += 12;
  421. }
  422. }
  423. void ScaleRowDown38_3_Box_MSA(const uint8_t* src_ptr,
  424. ptrdiff_t src_stride,
  425. uint8_t* dst_ptr,
  426. int dst_width) {
  427. int x, width;
  428. const uint8_t* s = src_ptr;
  429. const uint8_t* t0 = s + src_stride;
  430. const uint8_t* t1 = s + src_stride * 2;
  431. uint64_t dst0;
  432. uint32_t dst1;
  433. v16u8 src0, src1, src2, src3, src4, src5, out;
  434. v8u16 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7;
  435. v4u32 tmp0, tmp1, tmp2, tmp3, tmp4;
  436. v8u16 zero = {0};
  437. v8i16 mask = {0, 1, 2, 8, 3, 4, 5, 9};
  438. v16i8 dst_mask = {0, 2, 16, 4, 6, 18, 8, 10, 20, 12, 14, 22, 0, 0, 0, 0};
  439. v4u32 const_0x1C71 = (v4u32)__msa_fill_w(0x1C71);
  440. v4u32 const_0x2AAA = (v4u32)__msa_fill_w(0x2AAA);
  441. assert((dst_width % 3 == 0) && (dst_width > 0));
  442. width = dst_width / 3;
  443. for (x = 0; x < width; x += 4) {
  444. src0 = (v16u8)__msa_ld_b((v16i8*)s, 0);
  445. src1 = (v16u8)__msa_ld_b((v16i8*)s, 16);
  446. src2 = (v16u8)__msa_ld_b((v16i8*)t0, 0);
  447. src3 = (v16u8)__msa_ld_b((v16i8*)t0, 16);
  448. src4 = (v16u8)__msa_ld_b((v16i8*)t1, 0);
  449. src5 = (v16u8)__msa_ld_b((v16i8*)t1, 16);
  450. vec0 = (v8u16)__msa_ilvr_b((v16i8)src2, (v16i8)src0);
  451. vec1 = (v8u16)__msa_ilvl_b((v16i8)src2, (v16i8)src0);
  452. vec2 = (v8u16)__msa_ilvr_b((v16i8)src3, (v16i8)src1);
  453. vec3 = (v8u16)__msa_ilvl_b((v16i8)src3, (v16i8)src1);
  454. vec4 = (v8u16)__msa_ilvr_b((v16i8)zero, (v16i8)src4);
  455. vec5 = (v8u16)__msa_ilvl_b((v16i8)zero, (v16i8)src4);
  456. vec6 = (v8u16)__msa_ilvr_b((v16i8)zero, (v16i8)src5);
  457. vec7 = (v8u16)__msa_ilvl_b((v16i8)zero, (v16i8)src5);
  458. vec0 = __msa_hadd_u_h((v16u8)vec0, (v16u8)vec0);
  459. vec1 = __msa_hadd_u_h((v16u8)vec1, (v16u8)vec1);
  460. vec2 = __msa_hadd_u_h((v16u8)vec2, (v16u8)vec2);
  461. vec3 = __msa_hadd_u_h((v16u8)vec3, (v16u8)vec3);
  462. vec0 += __msa_hadd_u_h((v16u8)vec4, (v16u8)vec4);
  463. vec1 += __msa_hadd_u_h((v16u8)vec5, (v16u8)vec5);
  464. vec2 += __msa_hadd_u_h((v16u8)vec6, (v16u8)vec6);
  465. vec3 += __msa_hadd_u_h((v16u8)vec7, (v16u8)vec7);
  466. vec4 = (v8u16)__msa_vshf_h(mask, (v8i16)zero, (v8i16)vec0);
  467. vec5 = (v8u16)__msa_vshf_h(mask, (v8i16)zero, (v8i16)vec1);
  468. vec6 = (v8u16)__msa_vshf_h(mask, (v8i16)zero, (v8i16)vec2);
  469. vec7 = (v8u16)__msa_vshf_h(mask, (v8i16)zero, (v8i16)vec3);
  470. vec0 = (v8u16)__msa_pckod_w((v4i32)vec1, (v4i32)vec0);
  471. vec1 = (v8u16)__msa_pckod_w((v4i32)vec3, (v4i32)vec2);
  472. vec0 = (v8u16)__msa_pckod_w((v4i32)vec1, (v4i32)vec0);
  473. tmp0 = __msa_hadd_u_w(vec4, vec4);
  474. tmp1 = __msa_hadd_u_w(vec5, vec5);
  475. tmp2 = __msa_hadd_u_w(vec6, vec6);
  476. tmp3 = __msa_hadd_u_w(vec7, vec7);
  477. tmp4 = __msa_hadd_u_w(vec0, vec0);
  478. vec0 = (v8u16)__msa_pckev_h((v8i16)tmp1, (v8i16)tmp0);
  479. vec1 = (v8u16)__msa_pckev_h((v8i16)tmp3, (v8i16)tmp2);
  480. tmp0 = __msa_hadd_u_w(vec0, vec0);
  481. tmp1 = __msa_hadd_u_w(vec1, vec1);
  482. tmp0 *= const_0x1C71;
  483. tmp1 *= const_0x1C71;
  484. tmp4 *= const_0x2AAA;
  485. tmp0 = (v4u32)__msa_srai_w((v4i32)tmp0, 16);
  486. tmp1 = (v4u32)__msa_srai_w((v4i32)tmp1, 16);
  487. tmp4 = (v4u32)__msa_srai_w((v4i32)tmp4, 16);
  488. vec0 = (v8u16)__msa_pckev_h((v8i16)tmp1, (v8i16)tmp0);
  489. vec1 = (v8u16)__msa_pckev_h((v8i16)tmp4, (v8i16)tmp4);
  490. out = (v16u8)__msa_vshf_b(dst_mask, (v16i8)vec1, (v16i8)vec0);
  491. dst0 = __msa_copy_u_d((v2i64)out, 0);
  492. dst1 = __msa_copy_u_w((v4i32)out, 2);
  493. SD(dst0, dst_ptr);
  494. SW(dst1, dst_ptr + 8);
  495. s += 32;
  496. t0 += 32;
  497. t1 += 32;
  498. dst_ptr += 12;
  499. }
  500. }
  501. void ScaleAddRow_MSA(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width) {
  502. int x;
  503. v16u8 src0;
  504. v8u16 dst0, dst1;
  505. v16i8 zero = {0};
  506. assert(src_width > 0);
  507. for (x = 0; x < src_width; x += 16) {
  508. src0 = LD_UB(src_ptr);
  509. dst0 = (v8u16)__msa_ld_h((v8i16*)dst_ptr, 0);
  510. dst1 = (v8u16)__msa_ld_h((v8i16*)dst_ptr, 16);
  511. dst0 += (v8u16)__msa_ilvr_b(zero, (v16i8)src0);
  512. dst1 += (v8u16)__msa_ilvl_b(zero, (v16i8)src0);
  513. ST_UH2(dst0, dst1, dst_ptr, 8);
  514. src_ptr += 16;
  515. dst_ptr += 16;
  516. }
  517. }
  518. void ScaleFilterCols_MSA(uint8_t* dst_ptr,
  519. const uint8_t* src_ptr,
  520. int dst_width,
  521. int x,
  522. int dx) {
  523. int j;
  524. v4i32 vec_x = __msa_fill_w(x);
  525. v4i32 vec_dx = __msa_fill_w(dx);
  526. v4i32 vec_const = {0, 1, 2, 3};
  527. v4i32 vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, vec9;
  528. v4i32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
  529. v8u16 reg0, reg1;
  530. v16u8 dst0;
  531. v4i32 const_0xFFFF = __msa_fill_w(0xFFFF);
  532. v4i32 const_0x40 = __msa_fill_w(0x40);
  533. vec0 = vec_dx * vec_const;
  534. vec1 = vec_dx * 4;
  535. vec_x += vec0;
  536. for (j = 0; j < dst_width - 1; j += 16) {
  537. vec2 = vec_x >> 16;
  538. vec6 = vec_x & const_0xFFFF;
  539. vec_x += vec1;
  540. vec3 = vec_x >> 16;
  541. vec7 = vec_x & const_0xFFFF;
  542. vec_x += vec1;
  543. vec4 = vec_x >> 16;
  544. vec8 = vec_x & const_0xFFFF;
  545. vec_x += vec1;
  546. vec5 = vec_x >> 16;
  547. vec9 = vec_x & const_0xFFFF;
  548. vec_x += vec1;
  549. vec6 >>= 9;
  550. vec7 >>= 9;
  551. vec8 >>= 9;
  552. vec9 >>= 9;
  553. LOAD_INDEXED_DATA(src_ptr, vec2, tmp0);
  554. LOAD_INDEXED_DATA(src_ptr, vec3, tmp1);
  555. LOAD_INDEXED_DATA(src_ptr, vec4, tmp2);
  556. LOAD_INDEXED_DATA(src_ptr, vec5, tmp3);
  557. vec2 += 1;
  558. vec3 += 1;
  559. vec4 += 1;
  560. vec5 += 1;
  561. LOAD_INDEXED_DATA(src_ptr, vec2, tmp4);
  562. LOAD_INDEXED_DATA(src_ptr, vec3, tmp5);
  563. LOAD_INDEXED_DATA(src_ptr, vec4, tmp6);
  564. LOAD_INDEXED_DATA(src_ptr, vec5, tmp7);
  565. tmp4 -= tmp0;
  566. tmp5 -= tmp1;
  567. tmp6 -= tmp2;
  568. tmp7 -= tmp3;
  569. tmp4 *= vec6;
  570. tmp5 *= vec7;
  571. tmp6 *= vec8;
  572. tmp7 *= vec9;
  573. tmp4 += const_0x40;
  574. tmp5 += const_0x40;
  575. tmp6 += const_0x40;
  576. tmp7 += const_0x40;
  577. tmp4 >>= 7;
  578. tmp5 >>= 7;
  579. tmp6 >>= 7;
  580. tmp7 >>= 7;
  581. tmp0 += tmp4;
  582. tmp1 += tmp5;
  583. tmp2 += tmp6;
  584. tmp3 += tmp7;
  585. reg0 = (v8u16)__msa_pckev_h((v8i16)tmp1, (v8i16)tmp0);
  586. reg1 = (v8u16)__msa_pckev_h((v8i16)tmp3, (v8i16)tmp2);
  587. dst0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0);
  588. __msa_st_b(dst0, dst_ptr, 0);
  589. dst_ptr += 16;
  590. }
  591. }
  592. void ScaleARGBCols_MSA(uint8_t* dst_argb,
  593. const uint8_t* src_argb,
  594. int dst_width,
  595. int x,
  596. int dx) {
  597. const uint32_t* src = (const uint32_t*)(src_argb);
  598. uint32_t* dst = (uint32_t*)(dst_argb);
  599. int j;
  600. v4i32 x_vec = __msa_fill_w(x);
  601. v4i32 dx_vec = __msa_fill_w(dx);
  602. v4i32 const_vec = {0, 1, 2, 3};
  603. v4i32 vec0, vec1, vec2;
  604. v4i32 dst0;
  605. vec0 = dx_vec * const_vec;
  606. vec1 = dx_vec * 4;
  607. x_vec += vec0;
  608. for (j = 0; j < dst_width; j += 4) {
  609. vec2 = x_vec >> 16;
  610. x_vec += vec1;
  611. LOAD_INDEXED_DATA(src, vec2, dst0);
  612. __msa_st_w(dst0, dst, 0);
  613. dst += 4;
  614. }
  615. }
  616. void ScaleARGBFilterCols_MSA(uint8_t* dst_argb,
  617. const uint8_t* src_argb,
  618. int dst_width,
  619. int x,
  620. int dx) {
  621. const uint32_t* src = (const uint32_t*)(src_argb);
  622. int j;
  623. v4u32 src0, src1, src2, src3;
  624. v4u32 vec0, vec1, vec2, vec3;
  625. v16u8 reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7;
  626. v16u8 mult0, mult1, mult2, mult3;
  627. v8u16 tmp0, tmp1, tmp2, tmp3;
  628. v16u8 dst0, dst1;
  629. v4u32 vec_x = (v4u32)__msa_fill_w(x);
  630. v4u32 vec_dx = (v4u32)__msa_fill_w(dx);
  631. v4u32 vec_const = {0, 1, 2, 3};
  632. v16u8 const_0x7f = (v16u8)__msa_fill_b(0x7f);
  633. vec0 = vec_dx * vec_const;
  634. vec1 = vec_dx * 4;
  635. vec_x += vec0;
  636. for (j = 0; j < dst_width - 1; j += 8) {
  637. vec2 = vec_x >> 16;
  638. reg0 = (v16u8)(vec_x >> 9);
  639. vec_x += vec1;
  640. vec3 = vec_x >> 16;
  641. reg1 = (v16u8)(vec_x >> 9);
  642. vec_x += vec1;
  643. reg0 = reg0 & const_0x7f;
  644. reg1 = reg1 & const_0x7f;
  645. reg0 = (v16u8)__msa_shf_b((v16i8)reg0, 0);
  646. reg1 = (v16u8)__msa_shf_b((v16i8)reg1, 0);
  647. reg2 = reg0 ^ const_0x7f;
  648. reg3 = reg1 ^ const_0x7f;
  649. mult0 = (v16u8)__msa_ilvr_b((v16i8)reg0, (v16i8)reg2);
  650. mult1 = (v16u8)__msa_ilvl_b((v16i8)reg0, (v16i8)reg2);
  651. mult2 = (v16u8)__msa_ilvr_b((v16i8)reg1, (v16i8)reg3);
  652. mult3 = (v16u8)__msa_ilvl_b((v16i8)reg1, (v16i8)reg3);
  653. LOAD_INDEXED_DATA(src, vec2, src0);
  654. LOAD_INDEXED_DATA(src, vec3, src1);
  655. vec2 += 1;
  656. vec3 += 1;
  657. LOAD_INDEXED_DATA(src, vec2, src2);
  658. LOAD_INDEXED_DATA(src, vec3, src3);
  659. reg4 = (v16u8)__msa_ilvr_b((v16i8)src2, (v16i8)src0);
  660. reg5 = (v16u8)__msa_ilvl_b((v16i8)src2, (v16i8)src0);
  661. reg6 = (v16u8)__msa_ilvr_b((v16i8)src3, (v16i8)src1);
  662. reg7 = (v16u8)__msa_ilvl_b((v16i8)src3, (v16i8)src1);
  663. tmp0 = __msa_dotp_u_h(reg4, mult0);
  664. tmp1 = __msa_dotp_u_h(reg5, mult1);
  665. tmp2 = __msa_dotp_u_h(reg6, mult2);
  666. tmp3 = __msa_dotp_u_h(reg7, mult3);
  667. tmp0 >>= 7;
  668. tmp1 >>= 7;
  669. tmp2 >>= 7;
  670. tmp3 >>= 7;
  671. dst0 = (v16u8)__msa_pckev_b((v16i8)tmp1, (v16i8)tmp0);
  672. dst1 = (v16u8)__msa_pckev_b((v16i8)tmp3, (v16i8)tmp2);
  673. __msa_st_b(dst0, dst_argb, 0);
  674. __msa_st_b(dst1, dst_argb, 16);
  675. dst_argb += 32;
  676. }
  677. }
  678. void ScaleRowDown34_MSA(const uint8_t* src_ptr,
  679. ptrdiff_t src_stride,
  680. uint8_t* dst,
  681. int dst_width) {
  682. int x;
  683. (void)src_stride;
  684. v16u8 src0, src1, src2, src3;
  685. v16u8 vec0, vec1, vec2;
  686. v16i8 mask0 = {0, 1, 3, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19, 20};
  687. v16i8 mask1 = {5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19, 20, 21, 23, 24, 25};
  688. v16i8 mask2 = {11, 12, 13, 15, 16, 17, 19, 20,
  689. 21, 23, 24, 25, 27, 28, 29, 31};
  690. assert((dst_width % 3 == 0) && (dst_width > 0));
  691. for (x = 0; x < dst_width; x += 48) {
  692. src0 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 0);
  693. src1 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 16);
  694. src2 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 32);
  695. src3 = (v16u8)__msa_ld_b((v16i8*)src_ptr, 48);
  696. vec0 = (v16u8)__msa_vshf_b(mask0, (v16i8)src1, (v16i8)src0);
  697. vec1 = (v16u8)__msa_vshf_b(mask1, (v16i8)src2, (v16i8)src1);
  698. vec2 = (v16u8)__msa_vshf_b(mask2, (v16i8)src3, (v16i8)src2);
  699. __msa_st_b((v16i8)vec0, dst, 0);
  700. __msa_st_b((v16i8)vec1, dst, 16);
  701. __msa_st_b((v16i8)vec2, dst, 32);
  702. src_ptr += 64;
  703. dst += 48;
  704. }
  705. }
  706. void ScaleRowDown34_0_Box_MSA(const uint8_t* src_ptr,
  707. ptrdiff_t src_stride,
  708. uint8_t* d,
  709. int dst_width) {
  710. const uint8_t* s = src_ptr;
  711. const uint8_t* t = src_ptr + src_stride;
  712. int x;
  713. v16u8 src0, src1, src2, src3, src4, src5, src6, src7, dst0, dst1, dst2;
  714. v16u8 vec0, vec1, vec2, vec3, vec4, vec5;
  715. v16u8 vec6, vec7, vec8, vec9, vec10, vec11;
  716. v8i16 reg0, reg1, reg2, reg3, reg4, reg5;
  717. v8i16 reg6, reg7, reg8, reg9, reg10, reg11;
  718. v16u8 const0 = {3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1};
  719. v16u8 const1 = {1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1};
  720. v16u8 const2 = {1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3};
  721. v16i8 mask0 = {0, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10};
  722. v16i8 mask1 = {10, 11, 12, 13, 13, 14, 14, 15,
  723. 16, 17, 17, 18, 18, 19, 20, 21};
  724. v16i8 mask2 = {5, 6, 6, 7, 8, 9, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15};
  725. v8i16 shft0 = {2, 1, 2, 2, 1, 2, 2, 1};
  726. v8i16 shft1 = {2, 2, 1, 2, 2, 1, 2, 2};
  727. v8i16 shft2 = {1, 2, 2, 1, 2, 2, 1, 2};
  728. assert((dst_width % 3 == 0) && (dst_width > 0));
  729. for (x = 0; x < dst_width; x += 48) {
  730. src0 = (v16u8)__msa_ld_b((v16i8*)s, 0);
  731. src1 = (v16u8)__msa_ld_b((v16i8*)s, 16);
  732. src2 = (v16u8)__msa_ld_b((v16i8*)s, 32);
  733. src3 = (v16u8)__msa_ld_b((v16i8*)s, 48);
  734. src4 = (v16u8)__msa_ld_b((v16i8*)t, 0);
  735. src5 = (v16u8)__msa_ld_b((v16i8*)t, 16);
  736. src6 = (v16u8)__msa_ld_b((v16i8*)t, 32);
  737. src7 = (v16u8)__msa_ld_b((v16i8*)t, 48);
  738. vec0 = (v16u8)__msa_vshf_b(mask0, (v16i8)src0, (v16i8)src0);
  739. vec1 = (v16u8)__msa_vshf_b(mask1, (v16i8)src1, (v16i8)src0);
  740. vec2 = (v16u8)__msa_vshf_b(mask2, (v16i8)src1, (v16i8)src1);
  741. vec3 = (v16u8)__msa_vshf_b(mask0, (v16i8)src2, (v16i8)src2);
  742. vec4 = (v16u8)__msa_vshf_b(mask1, (v16i8)src3, (v16i8)src2);
  743. vec5 = (v16u8)__msa_vshf_b(mask2, (v16i8)src3, (v16i8)src3);
  744. vec6 = (v16u8)__msa_vshf_b(mask0, (v16i8)src4, (v16i8)src4);
  745. vec7 = (v16u8)__msa_vshf_b(mask1, (v16i8)src5, (v16i8)src4);
  746. vec8 = (v16u8)__msa_vshf_b(mask2, (v16i8)src5, (v16i8)src5);
  747. vec9 = (v16u8)__msa_vshf_b(mask0, (v16i8)src6, (v16i8)src6);
  748. vec10 = (v16u8)__msa_vshf_b(mask1, (v16i8)src7, (v16i8)src6);
  749. vec11 = (v16u8)__msa_vshf_b(mask2, (v16i8)src7, (v16i8)src7);
  750. reg0 = (v8i16)__msa_dotp_u_h(vec0, const0);
  751. reg1 = (v8i16)__msa_dotp_u_h(vec1, const1);
  752. reg2 = (v8i16)__msa_dotp_u_h(vec2, const2);
  753. reg3 = (v8i16)__msa_dotp_u_h(vec3, const0);
  754. reg4 = (v8i16)__msa_dotp_u_h(vec4, const1);
  755. reg5 = (v8i16)__msa_dotp_u_h(vec5, const2);
  756. reg6 = (v8i16)__msa_dotp_u_h(vec6, const0);
  757. reg7 = (v8i16)__msa_dotp_u_h(vec7, const1);
  758. reg8 = (v8i16)__msa_dotp_u_h(vec8, const2);
  759. reg9 = (v8i16)__msa_dotp_u_h(vec9, const0);
  760. reg10 = (v8i16)__msa_dotp_u_h(vec10, const1);
  761. reg11 = (v8i16)__msa_dotp_u_h(vec11, const2);
  762. reg0 = __msa_srar_h(reg0, shft0);
  763. reg1 = __msa_srar_h(reg1, shft1);
  764. reg2 = __msa_srar_h(reg2, shft2);
  765. reg3 = __msa_srar_h(reg3, shft0);
  766. reg4 = __msa_srar_h(reg4, shft1);
  767. reg5 = __msa_srar_h(reg5, shft2);
  768. reg6 = __msa_srar_h(reg6, shft0);
  769. reg7 = __msa_srar_h(reg7, shft1);
  770. reg8 = __msa_srar_h(reg8, shft2);
  771. reg9 = __msa_srar_h(reg9, shft0);
  772. reg10 = __msa_srar_h(reg10, shft1);
  773. reg11 = __msa_srar_h(reg11, shft2);
  774. reg0 = reg0 * 3 + reg6;
  775. reg1 = reg1 * 3 + reg7;
  776. reg2 = reg2 * 3 + reg8;
  777. reg3 = reg3 * 3 + reg9;
  778. reg4 = reg4 * 3 + reg10;
  779. reg5 = reg5 * 3 + reg11;
  780. reg0 = __msa_srari_h(reg0, 2);
  781. reg1 = __msa_srari_h(reg1, 2);
  782. reg2 = __msa_srari_h(reg2, 2);
  783. reg3 = __msa_srari_h(reg3, 2);
  784. reg4 = __msa_srari_h(reg4, 2);
  785. reg5 = __msa_srari_h(reg5, 2);
  786. dst0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0);
  787. dst1 = (v16u8)__msa_pckev_b((v16i8)reg3, (v16i8)reg2);
  788. dst2 = (v16u8)__msa_pckev_b((v16i8)reg5, (v16i8)reg4);
  789. __msa_st_b((v16i8)dst0, d, 0);
  790. __msa_st_b((v16i8)dst1, d, 16);
  791. __msa_st_b((v16i8)dst2, d, 32);
  792. s += 64;
  793. t += 64;
  794. d += 48;
  795. }
  796. }
  797. void ScaleRowDown34_1_Box_MSA(const uint8_t* src_ptr,
  798. ptrdiff_t src_stride,
  799. uint8_t* d,
  800. int dst_width) {
  801. const uint8_t* s = src_ptr;
  802. const uint8_t* t = src_ptr + src_stride;
  803. int x;
  804. v16u8 src0, src1, src2, src3, src4, src5, src6, src7, dst0, dst1, dst2;
  805. v16u8 vec0, vec1, vec2, vec3, vec4, vec5;
  806. v16u8 vec6, vec7, vec8, vec9, vec10, vec11;
  807. v8i16 reg0, reg1, reg2, reg3, reg4, reg5;
  808. v8i16 reg6, reg7, reg8, reg9, reg10, reg11;
  809. v16u8 const0 = {3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1};
  810. v16u8 const1 = {1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1};
  811. v16u8 const2 = {1, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 3};
  812. v16i8 mask0 = {0, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10};
  813. v16i8 mask1 = {10, 11, 12, 13, 13, 14, 14, 15,
  814. 16, 17, 17, 18, 18, 19, 20, 21};
  815. v16i8 mask2 = {5, 6, 6, 7, 8, 9, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15};
  816. v8i16 shft0 = {2, 1, 2, 2, 1, 2, 2, 1};
  817. v8i16 shft1 = {2, 2, 1, 2, 2, 1, 2, 2};
  818. v8i16 shft2 = {1, 2, 2, 1, 2, 2, 1, 2};
  819. assert((dst_width % 3 == 0) && (dst_width > 0));
  820. for (x = 0; x < dst_width; x += 48) {
  821. src0 = (v16u8)__msa_ld_b((v16i8*)s, 0);
  822. src1 = (v16u8)__msa_ld_b((v16i8*)s, 16);
  823. src2 = (v16u8)__msa_ld_b((v16i8*)s, 32);
  824. src3 = (v16u8)__msa_ld_b((v16i8*)s, 48);
  825. src4 = (v16u8)__msa_ld_b((v16i8*)t, 0);
  826. src5 = (v16u8)__msa_ld_b((v16i8*)t, 16);
  827. src6 = (v16u8)__msa_ld_b((v16i8*)t, 32);
  828. src7 = (v16u8)__msa_ld_b((v16i8*)t, 48);
  829. vec0 = (v16u8)__msa_vshf_b(mask0, (v16i8)src0, (v16i8)src0);
  830. vec1 = (v16u8)__msa_vshf_b(mask1, (v16i8)src1, (v16i8)src0);
  831. vec2 = (v16u8)__msa_vshf_b(mask2, (v16i8)src1, (v16i8)src1);
  832. vec3 = (v16u8)__msa_vshf_b(mask0, (v16i8)src2, (v16i8)src2);
  833. vec4 = (v16u8)__msa_vshf_b(mask1, (v16i8)src3, (v16i8)src2);
  834. vec5 = (v16u8)__msa_vshf_b(mask2, (v16i8)src3, (v16i8)src3);
  835. vec6 = (v16u8)__msa_vshf_b(mask0, (v16i8)src4, (v16i8)src4);
  836. vec7 = (v16u8)__msa_vshf_b(mask1, (v16i8)src5, (v16i8)src4);
  837. vec8 = (v16u8)__msa_vshf_b(mask2, (v16i8)src5, (v16i8)src5);
  838. vec9 = (v16u8)__msa_vshf_b(mask0, (v16i8)src6, (v16i8)src6);
  839. vec10 = (v16u8)__msa_vshf_b(mask1, (v16i8)src7, (v16i8)src6);
  840. vec11 = (v16u8)__msa_vshf_b(mask2, (v16i8)src7, (v16i8)src7);
  841. reg0 = (v8i16)__msa_dotp_u_h(vec0, const0);
  842. reg1 = (v8i16)__msa_dotp_u_h(vec1, const1);
  843. reg2 = (v8i16)__msa_dotp_u_h(vec2, const2);
  844. reg3 = (v8i16)__msa_dotp_u_h(vec3, const0);
  845. reg4 = (v8i16)__msa_dotp_u_h(vec4, const1);
  846. reg5 = (v8i16)__msa_dotp_u_h(vec5, const2);
  847. reg6 = (v8i16)__msa_dotp_u_h(vec6, const0);
  848. reg7 = (v8i16)__msa_dotp_u_h(vec7, const1);
  849. reg8 = (v8i16)__msa_dotp_u_h(vec8, const2);
  850. reg9 = (v8i16)__msa_dotp_u_h(vec9, const0);
  851. reg10 = (v8i16)__msa_dotp_u_h(vec10, const1);
  852. reg11 = (v8i16)__msa_dotp_u_h(vec11, const2);
  853. reg0 = __msa_srar_h(reg0, shft0);
  854. reg1 = __msa_srar_h(reg1, shft1);
  855. reg2 = __msa_srar_h(reg2, shft2);
  856. reg3 = __msa_srar_h(reg3, shft0);
  857. reg4 = __msa_srar_h(reg4, shft1);
  858. reg5 = __msa_srar_h(reg5, shft2);
  859. reg6 = __msa_srar_h(reg6, shft0);
  860. reg7 = __msa_srar_h(reg7, shft1);
  861. reg8 = __msa_srar_h(reg8, shft2);
  862. reg9 = __msa_srar_h(reg9, shft0);
  863. reg10 = __msa_srar_h(reg10, shft1);
  864. reg11 = __msa_srar_h(reg11, shft2);
  865. reg0 += reg6;
  866. reg1 += reg7;
  867. reg2 += reg8;
  868. reg3 += reg9;
  869. reg4 += reg10;
  870. reg5 += reg11;
  871. reg0 = __msa_srari_h(reg0, 1);
  872. reg1 = __msa_srari_h(reg1, 1);
  873. reg2 = __msa_srari_h(reg2, 1);
  874. reg3 = __msa_srari_h(reg3, 1);
  875. reg4 = __msa_srari_h(reg4, 1);
  876. reg5 = __msa_srari_h(reg5, 1);
  877. dst0 = (v16u8)__msa_pckev_b((v16i8)reg1, (v16i8)reg0);
  878. dst1 = (v16u8)__msa_pckev_b((v16i8)reg3, (v16i8)reg2);
  879. dst2 = (v16u8)__msa_pckev_b((v16i8)reg5, (v16i8)reg4);
  880. __msa_st_b((v16i8)dst0, d, 0);
  881. __msa_st_b((v16i8)dst1, d, 16);
  882. __msa_st_b((v16i8)dst2, d, 32);
  883. s += 64;
  884. t += 64;
  885. d += 48;
  886. }
  887. }
  888. #ifdef __cplusplus
  889. } // extern "C"
  890. } // namespace libyuv
  891. #endif
  892. #endif // !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)