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.

290 lines
9.8KB

  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. int stride, int h, int x, int y) {
  70. DECLARE_ALIGNED(16, signed int, ABCD)[4] =
  71. {((8 - x) * (8 - y)),
  72. (( x) * (8 - y)),
  73. ((8 - x) * ( y)),
  74. (( x) * ( y))};
  75. register int i;
  76. vec_u8 fperm;
  77. const vec_s32 vABCD = vec_ld(0, ABCD);
  78. const vec_s16 vA = vec_splat((vec_s16)vABCD, 1);
  79. const vec_s16 vB = vec_splat((vec_s16)vABCD, 3);
  80. const vec_s16 vC = vec_splat((vec_s16)vABCD, 5);
  81. const vec_s16 vD = vec_splat((vec_s16)vABCD, 7);
  82. LOAD_ZERO;
  83. const vec_s16 v32ss = vec_sl(vec_splat_s16(1),vec_splat_u16(5));
  84. const vec_u16 v6us = vec_splat_u16(6);
  85. register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
  86. register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
  87. vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1;
  88. vec_u8 vsrc0uc, vsrc1uc;
  89. vec_s16 vsrc0ssH, vsrc1ssH;
  90. vec_u8 vsrcCuc, vsrc2uc, vsrc3uc;
  91. vec_s16 vsrc2ssH, vsrc3ssH, psum;
  92. vec_u8 vdst, ppsum, vfdst, fsum;
  93. if (((unsigned long)dst) % 16 == 0) {
  94. fperm = (vec_u8){0x10, 0x11, 0x12, 0x13,
  95. 0x14, 0x15, 0x16, 0x17,
  96. 0x08, 0x09, 0x0A, 0x0B,
  97. 0x0C, 0x0D, 0x0E, 0x0F};
  98. } else {
  99. fperm = (vec_u8){0x00, 0x01, 0x02, 0x03,
  100. 0x04, 0x05, 0x06, 0x07,
  101. 0x18, 0x19, 0x1A, 0x1B,
  102. 0x1C, 0x1D, 0x1E, 0x1F};
  103. }
  104. vsrcAuc = vec_ld(0, src);
  105. if (loadSecond)
  106. vsrcBuc = vec_ld(16, src);
  107. vsrcperm0 = vec_lvsl(0, src);
  108. vsrcperm1 = vec_lvsl(1, src);
  109. vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0);
  110. if (reallyBadAlign)
  111. vsrc1uc = vsrcBuc;
  112. else
  113. vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1);
  114. vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc);
  115. vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc);
  116. if (ABCD[3]) {
  117. if (!loadSecond) {// -> !reallyBadAlign
  118. for (i = 0 ; i < h ; i++) {
  119. vsrcCuc = vec_ld(stride + 0, src);
  120. vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
  121. vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
  122. CHROMA_MC8_ALTIVEC_CORE(v32ss, noop)
  123. }
  124. } else {
  125. vec_u8 vsrcDuc;
  126. for (i = 0 ; i < h ; i++) {
  127. vsrcCuc = vec_ld(stride + 0, src);
  128. vsrcDuc = vec_ld(stride + 16, src);
  129. vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
  130. if (reallyBadAlign)
  131. vsrc3uc = vsrcDuc;
  132. else
  133. vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
  134. CHROMA_MC8_ALTIVEC_CORE(v32ss, noop)
  135. }
  136. }
  137. } else {
  138. const vec_s16 vE = vec_add(vB, vC);
  139. if (ABCD[2]) { // x == 0 B == 0
  140. if (!loadSecond) {// -> !reallyBadAlign
  141. for (i = 0 ; i < h ; i++) {
  142. vsrcCuc = vec_ld(stride + 0, src);
  143. vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
  144. CHROMA_MC8_ALTIVEC_CORE_SIMPLE
  145. vsrc0uc = vsrc1uc;
  146. }
  147. } else {
  148. vec_u8 vsrcDuc;
  149. for (i = 0 ; i < h ; i++) {
  150. vsrcCuc = vec_ld(stride + 0, src);
  151. vsrcDuc = vec_ld(stride + 15, src);
  152. vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
  153. CHROMA_MC8_ALTIVEC_CORE_SIMPLE
  154. vsrc0uc = vsrc1uc;
  155. }
  156. }
  157. } else { // y == 0 C == 0
  158. if (!loadSecond) {// -> !reallyBadAlign
  159. for (i = 0 ; i < h ; i++) {
  160. vsrcCuc = vec_ld(0, src);
  161. vsrc0uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
  162. vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
  163. CHROMA_MC8_ALTIVEC_CORE_SIMPLE
  164. }
  165. } else {
  166. vec_u8 vsrcDuc;
  167. for (i = 0 ; i < h ; i++) {
  168. vsrcCuc = vec_ld(0, src);
  169. vsrcDuc = vec_ld(15, src);
  170. vsrc0uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
  171. if (reallyBadAlign)
  172. vsrc1uc = vsrcDuc;
  173. else
  174. vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
  175. CHROMA_MC8_ALTIVEC_CORE_SIMPLE
  176. }
  177. }
  178. }
  179. }
  180. }
  181. #endif
  182. /* this code assume that stride % 16 == 0 */
  183. #ifdef PREFIX_no_rnd_vc1_chroma_mc8_altivec
  184. static void PREFIX_no_rnd_vc1_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, int stride, int h, int x, int y) {
  185. DECLARE_ALIGNED(16, signed int, ABCD)[4] =
  186. {((8 - x) * (8 - y)),
  187. (( x) * (8 - y)),
  188. ((8 - x) * ( y)),
  189. (( x) * ( y))};
  190. register int i;
  191. vec_u8 fperm;
  192. const vec_s32 vABCD = vec_ld(0, ABCD);
  193. const vec_s16 vA = vec_splat((vec_s16)vABCD, 1);
  194. const vec_s16 vB = vec_splat((vec_s16)vABCD, 3);
  195. const vec_s16 vC = vec_splat((vec_s16)vABCD, 5);
  196. const vec_s16 vD = vec_splat((vec_s16)vABCD, 7);
  197. LOAD_ZERO;
  198. const vec_s16 v28ss = vec_sub(vec_sl(vec_splat_s16(1),vec_splat_u16(5)),vec_splat_s16(4));
  199. const vec_u16 v6us = vec_splat_u16(6);
  200. register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
  201. register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
  202. vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1;
  203. vec_u8 vsrc0uc, vsrc1uc;
  204. vec_s16 vsrc0ssH, vsrc1ssH;
  205. vec_u8 vsrcCuc, vsrc2uc, vsrc3uc;
  206. vec_s16 vsrc2ssH, vsrc3ssH, psum;
  207. vec_u8 vdst, ppsum, vfdst, fsum;
  208. if (((unsigned long)dst) % 16 == 0) {
  209. fperm = (vec_u8){0x10, 0x11, 0x12, 0x13,
  210. 0x14, 0x15, 0x16, 0x17,
  211. 0x08, 0x09, 0x0A, 0x0B,
  212. 0x0C, 0x0D, 0x0E, 0x0F};
  213. } else {
  214. fperm = (vec_u8){0x00, 0x01, 0x02, 0x03,
  215. 0x04, 0x05, 0x06, 0x07,
  216. 0x18, 0x19, 0x1A, 0x1B,
  217. 0x1C, 0x1D, 0x1E, 0x1F};
  218. }
  219. vsrcAuc = vec_ld(0, src);
  220. if (loadSecond)
  221. vsrcBuc = vec_ld(16, src);
  222. vsrcperm0 = vec_lvsl(0, src);
  223. vsrcperm1 = vec_lvsl(1, src);
  224. vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0);
  225. if (reallyBadAlign)
  226. vsrc1uc = vsrcBuc;
  227. else
  228. vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1);
  229. vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc0uc);
  230. vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc1uc);
  231. if (!loadSecond) {// -> !reallyBadAlign
  232. for (i = 0 ; i < h ; i++) {
  233. vsrcCuc = vec_ld(stride + 0, src);
  234. vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
  235. vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
  236. CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28)
  237. }
  238. } else {
  239. vec_u8 vsrcDuc;
  240. for (i = 0 ; i < h ; i++) {
  241. vsrcCuc = vec_ld(stride + 0, src);
  242. vsrcDuc = vec_ld(stride + 16, src);
  243. vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
  244. if (reallyBadAlign)
  245. vsrc3uc = vsrcDuc;
  246. else
  247. vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
  248. CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28)
  249. }
  250. }
  251. }
  252. #endif
  253. #undef noop
  254. #undef add28
  255. #undef CHROMA_MC8_ALTIVEC_CORE