You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

295 lines
10.0KB

  1. /*
  2. * Copyright (c) 2004 Romain Dolbeau <romain@dolbeau.org>
  3. *
  4. * This file is part of Libav.
  5. *
  6. * Libav 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. * Libav 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 Libav; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "libavutil/mem.h"
  21. /* this code assume that stride % 16 == 0 */
  22. #define CHROMA_MC8_ALTIVEC_CORE(BIAS1, BIAS2) \
  23. vsrc2ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc2uc);\
  24. vsrc3ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc3uc);\
  25. \
  26. psum = vec_mladd(vA, vsrc0ssH, BIAS1);\
  27. psum = vec_mladd(vB, vsrc1ssH, psum);\
  28. psum = vec_mladd(vC, vsrc2ssH, psum);\
  29. psum = vec_mladd(vD, vsrc3ssH, psum);\
  30. psum = BIAS2(psum);\
  31. psum = vec_sr(psum, v6us);\
  32. \
  33. vdst = vec_ld(0, dst);\
  34. ppsum = (vec_u8)vec_pack(psum, psum);\
  35. vfdst = vec_perm(vdst, ppsum, fperm);\
  36. \
  37. OP_U8_ALTIVEC(fsum, vfdst, vdst);\
  38. \
  39. vec_st(fsum, 0, dst);\
  40. \
  41. vsrc0ssH = vsrc2ssH;\
  42. vsrc1ssH = vsrc3ssH;\
  43. \
  44. dst += stride;\
  45. src += stride;
  46. #define CHROMA_MC8_ALTIVEC_CORE_SIMPLE \
  47. \
  48. vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc);\
  49. vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc);\
  50. \
  51. psum = vec_mladd(vA, vsrc0ssH, v32ss);\
  52. psum = vec_mladd(vE, vsrc1ssH, psum);\
  53. psum = vec_sr(psum, v6us);\
  54. \
  55. vdst = vec_ld(0, dst);\
  56. ppsum = (vec_u8)vec_pack(psum, psum);\
  57. vfdst = vec_perm(vdst, ppsum, fperm);\
  58. \
  59. OP_U8_ALTIVEC(fsum, vfdst, vdst);\
  60. \
  61. vec_st(fsum, 0, dst);\
  62. \
  63. dst += stride;\
  64. src += stride;
  65. #define noop(a) a
  66. #define add28(a) vec_add(v28ss, a)
  67. #ifdef PREFIX_h264_chroma_mc8_altivec
  68. static void PREFIX_h264_chroma_mc8_altivec(uint8_t * dst, uint8_t * src,
  69. ptrdiff_t stride, int h,
  70. int x, int y)
  71. {
  72. DECLARE_ALIGNED(16, signed int, ABCD)[4] =
  73. {((8 - x) * (8 - y)),
  74. (( x) * (8 - y)),
  75. ((8 - x) * ( y)),
  76. (( x) * ( y))};
  77. register int i;
  78. vec_u8 fperm;
  79. const vec_s32 vABCD = vec_ld(0, ABCD);
  80. const vec_s16 vA = vec_splat((vec_s16)vABCD, 1);
  81. const vec_s16 vB = vec_splat((vec_s16)vABCD, 3);
  82. const vec_s16 vC = vec_splat((vec_s16)vABCD, 5);
  83. const vec_s16 vD = vec_splat((vec_s16)vABCD, 7);
  84. LOAD_ZERO;
  85. const vec_s16 v32ss = vec_sl(vec_splat_s16(1),vec_splat_u16(5));
  86. const vec_u16 v6us = vec_splat_u16(6);
  87. register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
  88. register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
  89. vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1;
  90. vec_u8 vsrc0uc, vsrc1uc;
  91. vec_s16 vsrc0ssH, vsrc1ssH;
  92. vec_u8 vsrcCuc, vsrc2uc, vsrc3uc;
  93. vec_s16 vsrc2ssH, vsrc3ssH, psum;
  94. vec_u8 vdst, ppsum, vfdst, fsum;
  95. if (((unsigned long)dst) % 16 == 0) {
  96. fperm = (vec_u8){0x10, 0x11, 0x12, 0x13,
  97. 0x14, 0x15, 0x16, 0x17,
  98. 0x08, 0x09, 0x0A, 0x0B,
  99. 0x0C, 0x0D, 0x0E, 0x0F};
  100. } else {
  101. fperm = (vec_u8){0x00, 0x01, 0x02, 0x03,
  102. 0x04, 0x05, 0x06, 0x07,
  103. 0x18, 0x19, 0x1A, 0x1B,
  104. 0x1C, 0x1D, 0x1E, 0x1F};
  105. }
  106. vsrcAuc = vec_ld(0, src);
  107. if (loadSecond)
  108. vsrcBuc = vec_ld(16, src);
  109. vsrcperm0 = vec_lvsl(0, src);
  110. vsrcperm1 = vec_lvsl(1, src);
  111. vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0);
  112. if (reallyBadAlign)
  113. vsrc1uc = vsrcBuc;
  114. else
  115. vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1);
  116. vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc);
  117. vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc);
  118. if (ABCD[3]) {
  119. if (!loadSecond) {// -> !reallyBadAlign
  120. for (i = 0 ; i < h ; i++) {
  121. vsrcCuc = vec_ld(stride + 0, src);
  122. vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
  123. vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
  124. CHROMA_MC8_ALTIVEC_CORE(v32ss, noop)
  125. }
  126. } else {
  127. vec_u8 vsrcDuc;
  128. for (i = 0 ; i < h ; i++) {
  129. vsrcCuc = vec_ld(stride + 0, src);
  130. vsrcDuc = vec_ld(stride + 16, src);
  131. vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
  132. if (reallyBadAlign)
  133. vsrc3uc = vsrcDuc;
  134. else
  135. vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
  136. CHROMA_MC8_ALTIVEC_CORE(v32ss, noop)
  137. }
  138. }
  139. } else {
  140. const vec_s16 vE = vec_add(vB, vC);
  141. if (ABCD[2]) { // x == 0 B == 0
  142. if (!loadSecond) {// -> !reallyBadAlign
  143. for (i = 0 ; i < h ; i++) {
  144. vsrcCuc = vec_ld(stride + 0, src);
  145. vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
  146. CHROMA_MC8_ALTIVEC_CORE_SIMPLE
  147. vsrc0uc = vsrc1uc;
  148. }
  149. } else {
  150. vec_u8 vsrcDuc;
  151. for (i = 0 ; i < h ; i++) {
  152. vsrcCuc = vec_ld(stride + 0, src);
  153. vsrcDuc = vec_ld(stride + 15, src);
  154. vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
  155. CHROMA_MC8_ALTIVEC_CORE_SIMPLE
  156. vsrc0uc = vsrc1uc;
  157. }
  158. }
  159. } else { // y == 0 C == 0
  160. if (!loadSecond) {// -> !reallyBadAlign
  161. for (i = 0 ; i < h ; i++) {
  162. vsrcCuc = vec_ld(0, src);
  163. vsrc0uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
  164. vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
  165. CHROMA_MC8_ALTIVEC_CORE_SIMPLE
  166. }
  167. } else {
  168. vec_u8 vsrcDuc;
  169. for (i = 0 ; i < h ; i++) {
  170. vsrcCuc = vec_ld(0, src);
  171. vsrcDuc = vec_ld(15, src);
  172. vsrc0uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
  173. if (reallyBadAlign)
  174. vsrc1uc = vsrcDuc;
  175. else
  176. vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
  177. CHROMA_MC8_ALTIVEC_CORE_SIMPLE
  178. }
  179. }
  180. }
  181. }
  182. }
  183. #endif
  184. /* this code assume that stride % 16 == 0 */
  185. #ifdef PREFIX_no_rnd_vc1_chroma_mc8_altivec
  186. static void PREFIX_no_rnd_vc1_chroma_mc8_altivec(uint8_t *dst, uint8_t *src,
  187. ptrdiff_t stride, int h,
  188. int x, int y)
  189. {
  190. DECLARE_ALIGNED(16, signed int, ABCD)[4] =
  191. {((8 - x) * (8 - y)),
  192. (( x) * (8 - y)),
  193. ((8 - x) * ( y)),
  194. (( x) * ( y))};
  195. register int i;
  196. vec_u8 fperm;
  197. const vec_s32 vABCD = vec_ld(0, ABCD);
  198. const vec_s16 vA = vec_splat((vec_s16)vABCD, 1);
  199. const vec_s16 vB = vec_splat((vec_s16)vABCD, 3);
  200. const vec_s16 vC = vec_splat((vec_s16)vABCD, 5);
  201. const vec_s16 vD = vec_splat((vec_s16)vABCD, 7);
  202. LOAD_ZERO;
  203. const vec_s16 v28ss = vec_sub(vec_sl(vec_splat_s16(1),vec_splat_u16(5)),vec_splat_s16(4));
  204. const vec_u16 v6us = vec_splat_u16(6);
  205. register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
  206. register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
  207. vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1;
  208. vec_u8 vsrc0uc, vsrc1uc;
  209. vec_s16 vsrc0ssH, vsrc1ssH;
  210. vec_u8 vsrcCuc, vsrc2uc, vsrc3uc;
  211. vec_s16 vsrc2ssH, vsrc3ssH, psum;
  212. vec_u8 vdst, ppsum, vfdst, fsum;
  213. if (((unsigned long)dst) % 16 == 0) {
  214. fperm = (vec_u8){0x10, 0x11, 0x12, 0x13,
  215. 0x14, 0x15, 0x16, 0x17,
  216. 0x08, 0x09, 0x0A, 0x0B,
  217. 0x0C, 0x0D, 0x0E, 0x0F};
  218. } else {
  219. fperm = (vec_u8){0x00, 0x01, 0x02, 0x03,
  220. 0x04, 0x05, 0x06, 0x07,
  221. 0x18, 0x19, 0x1A, 0x1B,
  222. 0x1C, 0x1D, 0x1E, 0x1F};
  223. }
  224. vsrcAuc = vec_ld(0, src);
  225. if (loadSecond)
  226. vsrcBuc = vec_ld(16, src);
  227. vsrcperm0 = vec_lvsl(0, src);
  228. vsrcperm1 = vec_lvsl(1, src);
  229. vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0);
  230. if (reallyBadAlign)
  231. vsrc1uc = vsrcBuc;
  232. else
  233. vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1);
  234. vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc0uc);
  235. vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc1uc);
  236. if (!loadSecond) {// -> !reallyBadAlign
  237. for (i = 0 ; i < h ; i++) {
  238. vsrcCuc = vec_ld(stride + 0, src);
  239. vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
  240. vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
  241. CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28)
  242. }
  243. } else {
  244. vec_u8 vsrcDuc;
  245. for (i = 0 ; i < h ; i++) {
  246. vsrcCuc = vec_ld(stride + 0, src);
  247. vsrcDuc = vec_ld(stride + 16, src);
  248. vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
  249. if (reallyBadAlign)
  250. vsrc3uc = vsrcDuc;
  251. else
  252. vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
  253. CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28)
  254. }
  255. }
  256. }
  257. #endif
  258. #undef noop
  259. #undef add28
  260. #undef CHROMA_MC8_ALTIVEC_CORE