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.

1689 lines
61KB

  1. /*
  2. * Copyright (c) 2016 Google Inc.
  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/arm/asm.S"
  21. #include "neon.S"
  22. const itxfm4_coeffs, align=4
  23. .short 11585, 0, 6270, 15137
  24. iadst4_coeffs:
  25. .short 5283, 15212, 9929, 13377
  26. endconst
  27. const iadst8_coeffs, align=4
  28. .short 16305, 1606, 14449, 7723, 10394, 12665, 4756, 15679
  29. idct_coeffs:
  30. .short 11585, 0, 6270, 15137, 3196, 16069, 13623, 9102
  31. .short 1606, 16305, 12665, 10394, 7723, 14449, 15679, 4756
  32. .short 804, 16364, 12140, 11003, 7005, 14811, 15426, 5520
  33. .short 3981, 15893, 14053, 8423, 9760, 13160, 16207, 2404
  34. endconst
  35. const iadst16_coeffs, align=4
  36. .short 16364, 804, 15893, 3981, 11003, 12140, 8423, 14053
  37. .short 14811, 7005, 13160, 9760, 5520, 15426, 2404, 16207
  38. endconst
  39. @ Do four 4x4 transposes, using q registers for the subtransposes that don't
  40. @ need to address the individual d registers.
  41. @ r0,r1 == rq1, r2,r3 == rq1, etc
  42. .macro transpose16_q_4x_4x4 rq0, rq1, rq2, rq3, rq4, rq5, rq6, rq7, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15
  43. vtrn.32 \rq0, \rq1
  44. vtrn.32 \rq2, \rq3
  45. vtrn.32 \rq4, \rq5
  46. vtrn.32 \rq6, \rq7
  47. vtrn.16 \r0, \r1
  48. vtrn.16 \r2, \r3
  49. vtrn.16 \r4, \r5
  50. vtrn.16 \r6, \r7
  51. vtrn.16 \r8, \r9
  52. vtrn.16 \r10, \r11
  53. vtrn.16 \r12, \r13
  54. vtrn.16 \r14, \r15
  55. .endm
  56. @ out1 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14
  57. @ out2 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14
  58. @ in/out are d registers
  59. .macro mbutterfly0 out1, out2, in1, in2, tmpd1, tmpd2, tmpq3, tmpq4, neg=0
  60. vadd.s16 \tmpd1, \in1, \in2
  61. vsub.s16 \tmpd2, \in1, \in2
  62. vmull.s16 \tmpq3, \tmpd1, d0[0]
  63. vmull.s16 \tmpq4, \tmpd2, d0[0]
  64. .if \neg > 0
  65. vneg.s32 \tmpq3, \tmpq3
  66. .endif
  67. vrshrn.s32 \out1, \tmpq3, #14
  68. vrshrn.s32 \out2, \tmpq4, #14
  69. .endm
  70. @ Same as mbutterfly0 above, but treating the input in in2 as zero,
  71. @ writing the same output into both out1 and out2.
  72. .macro mbutterfly0_h out1, out2, in1, in2, tmpd1, tmpd2, tmpq3, tmpq4
  73. vmull.s16 \tmpq3, \in1, d0[0]
  74. vrshrn.s32 \out1, \tmpq3, #14
  75. vrshrn.s32 \out2, \tmpq3, #14
  76. .endm
  77. @ out1,out2 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14
  78. @ out3,out4 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14
  79. @ Same as mbutterfly0, but with input being 2 q registers, output
  80. @ being 4 d registers.
  81. @ This can do with either 4 or 6 temporary q registers.
  82. .macro dmbutterfly0 out1, out2, out3, out4, in1, in2, tmpq1, tmpq2, tmpd11, tmpd12, tmpd21, tmpd22, tmpq3, tmpq4, tmpq5, tmpq6
  83. vadd.s16 \tmpq1, \in1, \in2
  84. vsub.s16 \tmpq2, \in1, \in2
  85. vmull.s16 \tmpq3, \tmpd11, d0[0]
  86. vmull.s16 \tmpq4, \tmpd12, d0[0]
  87. .ifb \tmpq5
  88. vrshrn.s32 \out1, \tmpq3, #14
  89. vrshrn.s32 \out2, \tmpq4, #14
  90. vmull.s16 \tmpq3, \tmpd21, d0[0]
  91. vmull.s16 \tmpq4, \tmpd22, d0[0]
  92. vrshrn.s32 \out3, \tmpq3, #14
  93. vrshrn.s32 \out4, \tmpq4, #14
  94. .else
  95. vmull.s16 \tmpq5, \tmpd21, d0[0]
  96. vmull.s16 \tmpq6, \tmpd22, d0[0]
  97. vrshrn.s32 \out1, \tmpq3, #14
  98. vrshrn.s32 \out2, \tmpq4, #14
  99. vrshrn.s32 \out3, \tmpq5, #14
  100. vrshrn.s32 \out4, \tmpq6, #14
  101. .endif
  102. .endm
  103. @ out1 = in1 * coef1 - in2 * coef2
  104. @ out2 = in1 * coef2 + in2 * coef1
  105. @ out are 2 q registers, in are 2 d registers
  106. .macro mbutterfly_l out1, out2, in1, in2, coef1, coef2
  107. vmull.s16 \out1, \in1, \coef1
  108. vmlsl.s16 \out1, \in2, \coef2
  109. vmull.s16 \out2, \in1, \coef2
  110. vmlal.s16 \out2, \in2, \coef1
  111. .endm
  112. @ out1,out2 = in1,in2 * coef1 - in3,in4 * coef2
  113. @ out3,out4 = in1,in2 * coef2 + in3,in4 * coef1
  114. @ out are 4 q registers, in are 4 d registers
  115. .macro dmbutterfly_l out1, out2, out3, out4, in1, in2, in3, in4, coef1, coef2
  116. vmull.s16 \out1, \in1, \coef1
  117. vmull.s16 \out2, \in2, \coef1
  118. vmull.s16 \out3, \in1, \coef2
  119. vmull.s16 \out4, \in2, \coef2
  120. vmlsl.s16 \out1, \in3, \coef2
  121. vmlsl.s16 \out2, \in4, \coef2
  122. vmlal.s16 \out3, \in3, \coef1
  123. vmlal.s16 \out4, \in4, \coef1
  124. .endm
  125. @ inout1 = (inout1 * coef1 - inout2 * coef2 + (1 << 13)) >> 14
  126. @ inout2 = (inout1 * coef2 + inout2 * coef1 + (1 << 13)) >> 14
  127. @ inout are 2 d registers, tmp are 2 q registers
  128. .macro mbutterfly inout1, inout2, coef1, coef2, tmp1, tmp2, neg=0
  129. mbutterfly_l \tmp1, \tmp2, \inout1, \inout2, \coef1, \coef2
  130. .if \neg > 0
  131. vneg.s32 \tmp2, \tmp2
  132. .endif
  133. vrshrn.s32 \inout1, \tmp1, #14
  134. vrshrn.s32 \inout2, \tmp2, #14
  135. .endm
  136. @ Same as mbutterfly above, but treating the input in inout2 as zero
  137. .macro mbutterfly_h1 inout1, inout2, coef1, coef2, tmp1, tmp2
  138. vmull.s16 \tmp1, \inout1, \coef1
  139. vmull.s16 \tmp2, \inout1, \coef2
  140. vrshrn.s32 \inout1, \tmp1, #14
  141. vrshrn.s32 \inout2, \tmp2, #14
  142. .endm
  143. @ Same as mbutterfly above, but treating the input in inout1 as zero
  144. .macro mbutterfly_h2 inout1, inout2, coef1, coef2, tmp1, tmp2
  145. vmull.s16 \tmp1, \inout2, \coef2
  146. vmull.s16 \tmp2, \inout2, \coef1
  147. vneg.s32 \tmp1, \tmp1
  148. vrshrn.s32 \inout2, \tmp2, #14
  149. vrshrn.s32 \inout1, \tmp1, #14
  150. .endm
  151. @ inout1,inout2 = (inout1,inout2 * coef1 - inout3,inout4 * coef2 + (1 << 13)) >> 14
  152. @ inout3,inout4 = (inout1,inout2 * coef2 + inout3,inout4 * coef1 + (1 << 13)) >> 14
  153. @ inout are 4 d registers, tmp are 4 q registers
  154. .macro dmbutterfly inout1, inout2, inout3, inout4, coef1, coef2, tmp1, tmp2, tmp3, tmp4
  155. dmbutterfly_l \tmp1, \tmp2, \tmp3, \tmp4, \inout1, \inout2, \inout3, \inout4, \coef1, \coef2
  156. vrshrn.s32 \inout1, \tmp1, #14
  157. vrshrn.s32 \inout2, \tmp2, #14
  158. vrshrn.s32 \inout3, \tmp3, #14
  159. vrshrn.s32 \inout4, \tmp4, #14
  160. .endm
  161. @ out1 = in1 + in2
  162. @ out2 = in1 - in2
  163. .macro butterfly out1, out2, in1, in2
  164. vadd.s16 \out1, \in1, \in2
  165. vsub.s16 \out2, \in1, \in2
  166. .endm
  167. @ out1 = in1 - in2
  168. @ out2 = in1 + in2
  169. .macro butterfly_r out1, out2, in1, in2
  170. vsub.s16 \out1, \in1, \in2
  171. vadd.s16 \out2, \in1, \in2
  172. .endm
  173. @ out1 = (in1 + in2 + (1 << 13)) >> 14
  174. @ out2 = (in1 - in2 + (1 << 13)) >> 14
  175. @ out are 2 d registers, in are 2 q registers, tmp are 2 q registers
  176. .macro butterfly_n out1, out2, in1, in2, tmp1, tmp2
  177. vadd.s32 \tmp1, \in1, \in2
  178. vsub.s32 \tmp2, \in1, \in2
  179. vrshrn.s32 \out1, \tmp1, #14
  180. vrshrn.s32 \out2, \tmp2, #14
  181. .endm
  182. @ out1,out2 = (in1,in2 + in3,in4 + (1 << 13)) >> 14
  183. @ out3,out4 = (in1,in2 - in3,in4 + (1 << 13)) >> 14
  184. @ out are 4 d registers, in are 4 q registers, tmp are 4 q registers
  185. .macro dbutterfly_n out1, out2, out3, out4, in1, in2, in3, in4, tmp1, tmp2, tmp3, tmp4
  186. vadd.s32 \tmp1, \in1, \in3
  187. vadd.s32 \tmp2, \in2, \in4
  188. vsub.s32 \tmp3, \in1, \in3
  189. vsub.s32 \tmp4, \in2, \in4
  190. vrshrn.s32 \out1, \tmp1, #14
  191. vrshrn.s32 \out2, \tmp2, #14
  192. vrshrn.s32 \out3, \tmp3, #14
  193. vrshrn.s32 \out4, \tmp4, #14
  194. .endm
  195. .macro iwht4 c0, c1, c2, c3
  196. vadd.i16 \c0, \c0, \c1
  197. vsub.i16 d17, \c2, \c3
  198. vsub.i16 d16, \c0, d17
  199. vshr.s16 d16, d16, #1
  200. vsub.i16 \c2, d16, \c1
  201. vsub.i16 \c1, d16, \c3
  202. vadd.i16 \c3, d17, \c2
  203. vsub.i16 \c0, \c0, \c1
  204. .endm
  205. .macro idct4 c0, c1, c2, c3
  206. vmull.s16 q13, \c1, d0[3]
  207. vmull.s16 q11, \c1, d0[2]
  208. vadd.i16 d16, \c0, \c2
  209. vsub.i16 d17, \c0, \c2
  210. vmlal.s16 q13, \c3, d0[2]
  211. vmull.s16 q9, d16, d0[0]
  212. vmull.s16 q10, d17, d0[0]
  213. vmlsl.s16 q11, \c3, d0[3]
  214. vrshrn.s32 d26, q13, #14
  215. vrshrn.s32 d18, q9, #14
  216. vrshrn.s32 d20, q10, #14
  217. vrshrn.s32 d22, q11, #14
  218. vadd.i16 \c0, d18, d26
  219. vsub.i16 \c3, d18, d26
  220. vadd.i16 \c1, d20, d22
  221. vsub.i16 \c2, d20, d22
  222. .endm
  223. .macro iadst4 c0, c1, c2, c3
  224. vmull.s16 q10, \c0, d1[0]
  225. vmlal.s16 q10, \c2, d1[1]
  226. vmlal.s16 q10, \c3, d1[2]
  227. vmull.s16 q11, \c0, d1[2]
  228. vmlsl.s16 q11, \c2, d1[0]
  229. vsub.s16 \c0, \c0, \c2
  230. vmlsl.s16 q11, \c3, d1[1]
  231. vadd.s16 \c0, \c0, \c3
  232. vmull.s16 q13, \c1, d1[3]
  233. vmull.s16 q12, \c0, d1[3]
  234. vadd.s32 q14, q10, q13
  235. vadd.s32 q1, q11, q13
  236. vrshrn.s32 \c0, q14, #14
  237. vadd.s32 q10, q10, q11
  238. vrshrn.s32 \c1, q1, #14
  239. vsub.s32 q10, q10, q13
  240. vrshrn.s32 \c2, q12, #14
  241. vrshrn.s32 \c3, q10, #14
  242. .endm
  243. @ The public functions in this file have got the following signature:
  244. @ void itxfm_add(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
  245. .macro itxfm_func4x4 txfm1, txfm2
  246. function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_neon, export=1
  247. .ifc \txfm1,\txfm2
  248. .ifc \txfm1,idct
  249. movrel r12, itxfm4_coeffs
  250. vld1.16 {d0}, [r12,:64]
  251. .endif
  252. .ifc \txfm1,iadst
  253. movrel r12, iadst4_coeffs
  254. vld1.16 {d1}, [r12,:64]
  255. .endif
  256. .else
  257. movrel r12, itxfm4_coeffs
  258. vld1.16 {q0}, [r12,:128]
  259. .endif
  260. vmov.i16 q15, #0
  261. .ifc \txfm1\()_\txfm2,idct_idct
  262. cmp r3, #1
  263. bne 1f
  264. @ DC-only for idct/idct
  265. vld1.16 {d4[]}, [r2,:16]
  266. vmull.s16 q2, d4, d0[0]
  267. vrshrn.s32 d4, q2, #14
  268. vmull.s16 q2, d4, d0[0]
  269. vrshrn.s32 d4, q2, #14
  270. vst1.16 {d30[0]}, [r2,:16]
  271. vdup.16 q2, d4[0]
  272. vmov q3, q2
  273. b 2f
  274. .endif
  275. 1:
  276. vld1.16 {d4-d7}, [r2,:128]
  277. vst1.16 {q15}, [r2,:128]!
  278. .ifc \txfm1,iwht
  279. vshr.s16 q2, q2, #2
  280. vshr.s16 q3, q3, #2
  281. .endif
  282. \txfm1\()4 d4, d5, d6, d7
  283. vst1.16 {q15}, [r2,:128]!
  284. @ Transpose 4x4 with 16 bit elements
  285. vtrn.16 d4, d5
  286. vtrn.16 d6, d7
  287. vtrn.32 q2, q3
  288. \txfm2\()4 d4, d5, d6, d7
  289. 2:
  290. vld1.32 {d0[]}, [r0,:32], r1
  291. vld1.32 {d0[1]}, [r0,:32], r1
  292. .ifnc \txfm1,iwht
  293. vrshr.s16 q2, q2, #4
  294. vrshr.s16 q3, q3, #4
  295. .endif
  296. vaddw.u8 q2, q2, d0
  297. vld1.32 {d1[]}, [r0,:32], r1
  298. vld1.32 {d1[1]}, [r0,:32], r1
  299. vqmovun.s16 d0, q2
  300. sub r0, r0, r1, lsl #2
  301. vaddw.u8 q3, q3, d1
  302. vst1.32 {d0[0]}, [r0,:32], r1
  303. vqmovun.s16 d1, q3
  304. vst1.32 {d0[1]}, [r0,:32], r1
  305. vst1.32 {d1[0]}, [r0,:32], r1
  306. vst1.32 {d1[1]}, [r0,:32], r1
  307. bx lr
  308. endfunc
  309. .endm
  310. itxfm_func4x4 idct, idct
  311. itxfm_func4x4 iadst, idct
  312. itxfm_func4x4 idct, iadst
  313. itxfm_func4x4 iadst, iadst
  314. itxfm_func4x4 iwht, iwht
  315. .macro idct8
  316. dmbutterfly0 d16, d17, d24, d25, q8, q12, q2, q4, d4, d5, d8, d9, q3, q2, q5, q4 @ q8 = t0a, q12 = t1a
  317. dmbutterfly d20, d21, d28, d29, d0[2], d0[3], q2, q3, q4, q5 @ q10 = t2a, q14 = t3a
  318. dmbutterfly d18, d19, d30, d31, d1[0], d1[1], q2, q3, q4, q5 @ q9 = t4a, q15 = t7a
  319. dmbutterfly d26, d27, d22, d23, d1[2], d1[3], q2, q3, q4, q5 @ q13 = t5a, q11 = t6a
  320. butterfly q2, q14, q8, q14 @ q2 = t0, q14 = t3
  321. butterfly q3, q10, q12, q10 @ q3 = t1, q10 = t2
  322. butterfly q4, q13, q9, q13 @ q4 = t4, q13 = t5a
  323. butterfly q5, q11, q15, q11 @ q5 = t7, q11 = t6a
  324. butterfly q8, q15, q2, q5 @ q8 = out[0], q15 = out[7]
  325. dmbutterfly0 d4, d5, d10, d11, q11, q13, q9, q13, d18, d19, d26, d27, q2, q5, q11, q12 @ q2 = t6, q5 = t5
  326. butterfly q11, q12, q14, q4 @ q11 = out[3], q12 = out[4]
  327. butterfly q9, q14, q3, q2 @ q9 = out[1], q14 = out[6]
  328. butterfly_r q13, q10, q10, q5 @ q13 = out[5], q10 = out[2]
  329. .endm
  330. .macro iadst8
  331. dmbutterfly_l q4, q5, q2, q3, d30, d31, d16, d17, d2[1], d2[0] @ q4,q5 = t1a, q2,q3 = t0a
  332. dmbutterfly_l q8, q15, q6, q7, d22, d23, d24, d25, d3[1], d3[0] @ q8,q15 = t5a, q6,q7 = t4a
  333. dbutterfly_n d22, d23, d4, d5, q2, q3, q6, q7, q11, q12, q2, q3 @ q11 = t0, q2 = t4
  334. dbutterfly_n d24, d25, d6, d7, q4, q5, q8, q15, q12, q3, q6, q7 @ q12 = t1, q3 = t5
  335. dmbutterfly_l q6, q7, q4, q5, d26, d27, d20, d21, d2[3], d2[2] @ q6,q7 = t3a, q4,q5 = t2a
  336. dmbutterfly_l q10, q13, q8, q15, d18, d19, d28, d29, d3[3], d3[2] @ q10,q13 = t7a, q8,q15 = t6a
  337. dbutterfly_n d18, d19, d8, d9, q4, q5, q8, q15, q9, q14, q4, q5 @ q9 = t2, q4 = t6
  338. dbutterfly_n d16, d17, d12, d13, q6, q7, q10, q13, q8, q15, q6, q7 @ q8 = t3, q6 = t7
  339. butterfly q15, q12, q12, q8 @ q15 = -out[7], q12 = t3
  340. vneg.s16 q15, q15 @ q15 = out[7]
  341. butterfly q8, q9, q11, q9 @ q8 = out[0], q9 = t2
  342. dmbutterfly_l q10, q11, q5, q7, d4, d5, d6, d7, d0[2], d0[3] @ q10,q11 = t5a, q5,q7 = t4a
  343. dmbutterfly_l q2, q3, q13, q14, d12, d13, d8, d9, d0[3], d0[2] @ q2,q3 = t6a, q13,q14 = t7a
  344. dbutterfly_n d28, d29, d8, d9, q10, q11, q13, q14, q4, q6, q10, q11 @ q14 = out[6], q4 = t7
  345. dmbutterfly0 d22, d23, d24, d25, q9, q12, q6, q13, d12, d13, d26, d27, q9, q10 @ q11 = -out[3], q12 = out[4]
  346. vneg.s16 q11, q11 @ q11 = out[3]
  347. dbutterfly_n d18, d19, d4, d5, q5, q7, q2, q3, q9, q10, q2, q3 @ q9 = -out[1], q2 = t6
  348. vneg.s16 q9, q9 @ q9 = out[1]
  349. dmbutterfly0 d20, d21, d26, d27, q2, q4, q3, q5, d6, d7, d10, d11, q6, q7 @ q10 = out[2], q13 = -out[5]
  350. vneg.s16 q13, q13 @ q13 = out[5]
  351. .endm
  352. .macro itxfm_func8x8 txfm1, txfm2
  353. function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_neon, export=1
  354. @ Push q4-q7 if iadst is used, idct requires
  355. @ a few scratch registers less, so only push q4-q5
  356. @ if only idct is involved.
  357. @ The iadst also uses a few coefficients from
  358. @ idct, so those always need to be loaded.
  359. .ifc \txfm1\()_\txfm2,idct_idct
  360. movrel r12, idct_coeffs
  361. vpush {q4-q5}
  362. .else
  363. movrel r12, iadst8_coeffs
  364. vld1.16 {q1}, [r12,:128]!
  365. vpush {q4-q7}
  366. .endif
  367. vld1.16 {q0}, [r12,:128]
  368. vmov.i16 q2, #0
  369. vmov.i16 q3, #0
  370. .ifc \txfm1\()_\txfm2,idct_idct
  371. cmp r3, #1
  372. bne 1f
  373. @ DC-only for idct/idct
  374. vld1.16 {d16[]}, [r2,:16]
  375. vmull.s16 q8, d16, d0[0]
  376. vrshrn.s32 d16, q8, #14
  377. vmull.s16 q8, d16, d0[0]
  378. vrshrn.s32 d16, q8, #14
  379. vdup.16 q8, d16[0]
  380. vmov q9, q8
  381. vmov q10, q8
  382. vmov q11, q8
  383. vmov q12, q8
  384. vmov q13, q8
  385. vmov q14, q8
  386. vmov q15, q8
  387. vst1.16 {d4[0]}, [r2,:16]
  388. b 2f
  389. .endif
  390. 1:
  391. vld1.16 {q8-q9}, [r2,:128]!
  392. vld1.16 {q10-q11}, [r2,:128]!
  393. vld1.16 {q12-q13}, [r2,:128]!
  394. vld1.16 {q14-q15}, [r2,:128]!
  395. sub r2, r2, #128
  396. vst1.16 {q2-q3}, [r2,:128]!
  397. vst1.16 {q2-q3}, [r2,:128]!
  398. vst1.16 {q2-q3}, [r2,:128]!
  399. vst1.16 {q2-q3}, [r2,:128]!
  400. \txfm1\()8
  401. @ Transpose 8x8 with 16 bit elements
  402. vswp d17, d24
  403. vswp d19, d26
  404. vswp d21, d28
  405. vswp d23, d30
  406. transpose16_4x4 q8, q9, q10, q11, q12, q13, q14, q15
  407. \txfm2\()8
  408. 2:
  409. mov r3, r0
  410. @ Add into the destination
  411. vld1.8 {d4}, [r0,:64], r1
  412. vrshr.s16 q8, q8, #5
  413. vld1.8 {d5}, [r0,:64], r1
  414. vrshr.s16 q9, q9, #5
  415. vld1.8 {d6}, [r0,:64], r1
  416. vrshr.s16 q10, q10, #5
  417. vaddw.u8 q8, q8, d4
  418. vld1.8 {d7}, [r0,:64], r1
  419. vrshr.s16 q11, q11, #5
  420. vaddw.u8 q9, q9, d5
  421. vld1.8 {d8}, [r0,:64], r1
  422. vrshr.s16 q12, q12, #5
  423. vaddw.u8 q10, q10, d6
  424. vqmovun.s16 d4, q8
  425. vld1.8 {d9}, [r0,:64], r1
  426. vrshr.s16 q13, q13, #5
  427. vaddw.u8 q11, q11, d7
  428. vqmovun.s16 d5, q9
  429. vld1.8 {d10}, [r0,:64], r1
  430. vrshr.s16 q14, q14, #5
  431. vaddw.u8 q12, q12, d8
  432. vqmovun.s16 d6, q10
  433. vld1.8 {d11}, [r0,:64], r1
  434. vrshr.s16 q15, q15, #5
  435. vaddw.u8 q13, q13, d9
  436. vqmovun.s16 d7, q11
  437. vst1.8 {d4}, [r3,:64], r1
  438. vaddw.u8 q14, q14, d10
  439. vst1.8 {d5}, [r3,:64], r1
  440. vqmovun.s16 d8, q12
  441. vst1.8 {d6}, [r3,:64], r1
  442. vaddw.u8 q15, q15, d11
  443. vst1.8 {d7}, [r3,:64], r1
  444. vqmovun.s16 d9, q13
  445. vst1.8 {d8}, [r3,:64], r1
  446. vqmovun.s16 d10, q14
  447. vst1.8 {d9}, [r3,:64], r1
  448. vqmovun.s16 d11, q15
  449. vst1.8 {d10}, [r3,:64], r1
  450. vst1.8 {d11}, [r3,:64], r1
  451. .ifc \txfm1\()_\txfm2,idct_idct
  452. vpop {q4-q5}
  453. .else
  454. vpop {q4-q7}
  455. .endif
  456. bx lr
  457. endfunc
  458. .endm
  459. itxfm_func8x8 idct, idct
  460. itxfm_func8x8 iadst, idct
  461. .ltorg
  462. itxfm_func8x8 idct, iadst
  463. itxfm_func8x8 iadst, iadst
  464. function idct16x16_dc_add_neon
  465. movrel r12, idct_coeffs
  466. vld1.16 {d0}, [r12,:64]
  467. vmov.i16 q2, #0
  468. vld1.16 {d16[]}, [r2,:16]
  469. vmull.s16 q8, d16, d0[0]
  470. vrshrn.s32 d16, q8, #14
  471. vmull.s16 q8, d16, d0[0]
  472. vrshrn.s32 d16, q8, #14
  473. vdup.16 q8, d16[0]
  474. vst1.16 {d4[0]}, [r2,:16]
  475. vrshr.s16 q8, q8, #6
  476. mov r3, r0
  477. mov r12, #16
  478. 1:
  479. @ Loop to add the constant from q8 into all 16x16 outputs
  480. subs r12, r12, #2
  481. vld1.8 {q2}, [r0,:128], r1
  482. vaddw.u8 q10, q8, d4
  483. vld1.8 {q3}, [r0,:128], r1
  484. vaddw.u8 q11, q8, d5
  485. vaddw.u8 q12, q8, d6
  486. vaddw.u8 q13, q8, d7
  487. vqmovun.s16 d4, q10
  488. vqmovun.s16 d5, q11
  489. vqmovun.s16 d6, q12
  490. vst1.8 {q2}, [r3,:128], r1
  491. vqmovun.s16 d7, q13
  492. vst1.8 {q3}, [r3,:128], r1
  493. bne 1b
  494. bx lr
  495. endfunc
  496. .ltorg
  497. .macro idct16_end
  498. butterfly d18, d7, d4, d7 @ d18 = t0a, d7 = t7a
  499. butterfly d19, d22, d5, d22 @ d19 = t1a, d22 = t6
  500. butterfly d4, d26, d20, d26 @ d4 = t2a, d26 = t5
  501. butterfly d5, d6, d28, d6 @ d5 = t3a, d6 = t4
  502. butterfly d20, d28, d16, d24 @ d20 = t8a, d28 = t11a
  503. butterfly d24, d21, d23, d21 @ d24 = t9, d21 = t10
  504. butterfly d23, d27, d25, d27 @ d23 = t14, d27 = t13
  505. butterfly d25, d29, d29, d17 @ d25 = t15a, d29 = t12a
  506. mbutterfly0 d27, d21, d27, d21, d16, d30, q8, q15 @ d27 = t13a, d21 = t10a
  507. mbutterfly0 d29, d28, d29, d28, d16, d30, q8, q15 @ d29 = t12, d28 = t11
  508. vswp d27, d29 @ d27 = t12, d29 = t13a
  509. vswp d28, d27 @ d28 = t12, d27 = t11
  510. butterfly d16, d31, d18, d25 @ d16 = out[0], d31 = out[15]
  511. butterfly d17, d30, d19, d23 @ d17 = out[1], d30 = out[14]
  512. butterfly_r d25, d22, d22, d24 @ d25 = out[9], d22 = out[6]
  513. butterfly d23, d24, d7, d20 @ d23 = out[7], d24 = out[8]
  514. butterfly d18, d29, d4, d29 @ d18 = out[2], d29 = out[13]
  515. butterfly d19, d28, d5, d28 @ d19 = out[3], d28 = out[12]
  516. vmov d4, d21 @ d4 = t10a
  517. butterfly d20, d27, d6, d27 @ d20 = out[4], d27 = out[11]
  518. butterfly d21, d26, d26, d4 @ d21 = out[5], d26 = out[10]
  519. bx lr
  520. .endm
  521. function idct16
  522. mbutterfly0 d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a
  523. mbutterfly d20, d28, d0[2], d0[3], q2, q3 @ d20 = t2a, d28 = t3a
  524. mbutterfly d18, d30, d1[0], d1[1], q2, q3 @ d18 = t4a, d30 = t7a
  525. mbutterfly d26, d22, d1[2], d1[3], q2, q3 @ d26 = t5a, d22 = t6a
  526. mbutterfly d17, d31, d2[0], d2[1], q2, q3 @ d17 = t8a, d31 = t15a
  527. mbutterfly d25, d23, d2[2], d2[3], q2, q3 @ d25 = t9a, d23 = t14a
  528. mbutterfly d21, d27, d3[0], d3[1], q2, q3 @ d21 = t10a, d27 = t13a
  529. mbutterfly d29, d19, d3[2], d3[3], q2, q3 @ d29 = t11a, d19 = t12a
  530. butterfly d4, d28, d16, d28 @ d4 = t0, d28 = t3
  531. butterfly d5, d20, d24, d20 @ d5 = t1, d20 = t2
  532. butterfly d6, d26, d18, d26 @ d6 = t4, d26 = t5
  533. butterfly d7, d22, d30, d22 @ d7 = t7, d22 = t6
  534. butterfly d16, d25, d17, d25 @ d16 = t8, d25 = t9
  535. butterfly d24, d21, d29, d21 @ d24 = t11, d21 = t10
  536. butterfly d17, d27, d19, d27 @ d17 = t12, d27 = t13
  537. butterfly d29, d23, d31, d23 @ d29 = t15, d23 = t14
  538. mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a
  539. mbutterfly d23, d25, d0[2], d0[3], q9, q15 @ d23 = t9a, d25 = t14a
  540. mbutterfly d27, d21, d0[2], d0[3], q9, q15, neg=1 @ d27 = t13a, d21 = t10a
  541. idct16_end
  542. endfunc
  543. function idct16_half
  544. mbutterfly0_h d16, d24, d16, d24, d4, d6, q2, q3 @ d16 = t0a, d24 = t1a
  545. mbutterfly_h1 d20, d28, d0[2], d0[3], q2, q3 @ d20 = t2a, d28 = t3a
  546. mbutterfly_h1 d18, d30, d1[0], d1[1], q2, q3 @ d18 = t4a, d30 = t7a
  547. mbutterfly_h2 d26, d22, d1[2], d1[3], q2, q3 @ d26 = t5a, d22 = t6a
  548. mbutterfly_h1 d17, d31, d2[0], d2[1], q2, q3 @ d17 = t8a, d31 = t15a
  549. mbutterfly_h2 d25, d23, d2[2], d2[3], q2, q3 @ d25 = t9a, d23 = t14a
  550. mbutterfly_h1 d21, d27, d3[0], d3[1], q2, q3 @ d21 = t10a, d27 = t13a
  551. mbutterfly_h2 d29, d19, d3[2], d3[3], q2, q3 @ d29 = t11a, d19 = t12a
  552. butterfly d4, d28, d16, d28 @ d4 = t0, d28 = t3
  553. butterfly d5, d20, d24, d20 @ d5 = t1, d20 = t2
  554. butterfly d6, d26, d18, d26 @ d6 = t4, d26 = t5
  555. butterfly d7, d22, d30, d22 @ d7 = t7, d22 = t6
  556. butterfly d16, d25, d17, d25 @ d16 = t8, d25 = t9
  557. butterfly d24, d21, d29, d21 @ d24 = t11, d21 = t10
  558. butterfly d17, d27, d19, d27 @ d17 = t12, d27 = t13
  559. butterfly d29, d23, d31, d23 @ d29 = t15, d23 = t14
  560. mbutterfly0 d22, d26, d22, d26, d18, d30, q9, q15 @ d22 = t6a, d26 = t5a
  561. mbutterfly d23, d25, d0[2], d0[3], q9, q15 @ d23 = t9a, d25 = t14a
  562. mbutterfly d27, d21, d0[2], d0[3], q9, q15, neg=1 @ d27 = t13a, d21 = t10a
  563. idct16_end
  564. endfunc
  565. function idct16_quarter
  566. vmull.s16 q12, d19, d3[3]
  567. vmull.s16 q2, d17, d2[0]
  568. vmull.s16 q3, d18, d1[1]
  569. vmull.s16 q15, d18, d1[0]
  570. vneg.s32 q12, q12
  571. vmull.s16 q14, d17, d2[1]
  572. vmull.s16 q13, d19, d3[2]
  573. vmull.s16 q11, d16, d0[0]
  574. vrshrn.s32 d24, q12, #14
  575. vrshrn.s32 d16, q2, #14
  576. vrshrn.s32 d7, q3, #14
  577. vrshrn.s32 d6, q15, #14
  578. vrshrn.s32 d29, q14, #14
  579. vrshrn.s32 d17, q13, #14
  580. vrshrn.s32 d28, q11, #14
  581. mbutterfly_l q10, q11, d17, d24, d0[2], d0[3]
  582. mbutterfly_l q9, q15, d29, d16, d0[2], d0[3]
  583. vneg.s32 q11, q11
  584. vrshrn.s32 d27, q10, #14
  585. vrshrn.s32 d21, q11, #14
  586. vrshrn.s32 d23, q9, #14
  587. vrshrn.s32 d25, q15, #14
  588. vmov d4, d28
  589. vmov d5, d28
  590. mbutterfly0 d22, d26, d7, d6, d18, d30, q9, q15
  591. vmov d20, d28
  592. idct16_end
  593. endfunc
  594. function iadst16
  595. movrel r12, iadst16_coeffs
  596. vld1.16 {q0-q1}, [r12,:128]
  597. mbutterfly_l q3, q2, d31, d16, d0[1], d0[0] @ q3 = t1, q2 = t0
  598. mbutterfly_l q5, q4, d23, d24, d1[1], d1[0] @ q5 = t9, q4 = t8
  599. butterfly_n d31, d24, q3, q5, q6, q5 @ d31 = t1a, d24 = t9a
  600. mbutterfly_l q7, q6, d29, d18, d0[3], d0[2] @ q7 = t3, q6 = t2
  601. butterfly_n d16, d23, q2, q4, q3, q4 @ d16 = t0a, d23 = t8a
  602. mbutterfly_l q3, q2, d21, d26, d1[3], d1[2] @ q3 = t11, q2 = t10
  603. butterfly_n d29, d26, q7, q3, q4, q3 @ d29 = t3a, d26 = t11a
  604. mbutterfly_l q5, q4, d27, d20, d2[1], d2[0] @ q5 = t5, q4 = t4
  605. butterfly_n d18, d21, q6, q2, q3, q2 @ d18 = t2a, d21 = t10a
  606. mbutterfly_l q7, q6, d19, d28, d3[1], d3[0] @ q7 = t13, q6 = t12
  607. butterfly_n d20, d28, q5, q7, q2, q7 @ d20 = t5a, d28 = t13a
  608. mbutterfly_l q3, q2, d25, d22, d2[3], d2[2] @ q3 = t7, q2 = t6
  609. butterfly_n d27, d19, q4, q6, q5, q6 @ d27 = t4a, d19 = t12a
  610. mbutterfly_l q5, q4, d17, d30, d3[3], d3[2] @ q5 = t15, q4 = t14
  611. movrel r12, idct_coeffs
  612. vld1.16 {q0}, [r12,:128]
  613. butterfly_n d22, d30, q3, q5, q6, q5 @ d22 = t7a, d30 = t15a
  614. mbutterfly_l q7, q6, d23, d24, d1[0], d1[1] @ q7 = t9, q6 = t8
  615. butterfly_n d25, d17, q2, q4, q3, q4 @ d25 = t6a, d17 = t14a
  616. mbutterfly_l q2, q3, d28, d19, d1[1], d1[0] @ q2 = t12, q3 = t13
  617. butterfly_n d23, d19, q6, q2, q4, q2 @ d23 = t8a, d19 = t12a
  618. mbutterfly_l q5, q4, d21, d26, d1[2], d1[3] @ q5 = t11, q4 = t10
  619. butterfly_r d4, d27, d16, d27 @ d4 = t4, d27 = t0
  620. butterfly_n d24, d28, q7, q3, q6, q3 @ d24 = t9a, d28 = t13a
  621. mbutterfly_l q6, q7, d30, d17, d1[3], d1[2] @ q6 = t14, q7 = t15
  622. butterfly_r d5, d20, d31, d20 @ d5 = t5, d20 = t1
  623. butterfly_n d21, d17, q4, q6, q3, q6 @ d21 = t10a, d17 = t14a
  624. butterfly_n d26, d30, q5, q7, q4, q7 @ d26 = t11a, d30 = t15a
  625. butterfly_r d6, d25, d18, d25 @ d6 = t6, d25 = t2
  626. butterfly_r d7, d22, d29, d22 @ d7 = t7, d22 = t3
  627. mbutterfly_l q5, q4, d19, d28, d0[2], d0[3] @ q5 = t13, q4 = t12
  628. mbutterfly_l q6, q7, d30, d17, d0[3], d0[2] @ q6 = t14, q7 = t15
  629. butterfly_n d18, d30, q4, q6, q8, q6 @ d18 = out[2], d30 = t14a
  630. butterfly_n d29, d17, q5, q7, q6, q7 @ d29 = -out[13], d17 = t15a
  631. vneg.s16 d29, d29 @ d29 = out[13]
  632. mbutterfly_l q5, q4, d4, d5, d0[2], d0[3] @ q5 = t5a, q4 = t4a
  633. mbutterfly_l q6, q7, d7, d6, d0[3], d0[2] @ q6 = t6a, q7 = t7a
  634. butterfly d2, d6, d27, d25 @ d2 = out[0], d6 = t2a
  635. butterfly d3, d7, d23, d21 @ d3 =-out[1], d7 = t10
  636. butterfly_n d19, d31, q4, q6, q2, q4 @ d19 = -out[3], d31 = t6
  637. vneg.s16 d19, d19 @ d19 = out[3]
  638. butterfly_n d28, d16, q5, q7, q2, q5 @ d28 = out[12], d16 = t7
  639. butterfly d5, d8, d20, d22 @ d5 =-out[15],d8 = t3a
  640. butterfly d4, d9, d24, d26 @ d4 = out[14],d9 = t11
  641. mbutterfly0 d23, d24, d6, d8, d10, d11, q6, q7, 1 @ d23 = out[7], d24 = out[8]
  642. mbutterfly0 d20, d27, d16, d31, d10, d11, q6, q7 @ d20 = out[4], d27 = out[11]
  643. mbutterfly0 d22, d25, d9, d7, d10, d11, q6, q7 @ d22 = out[6], d25 = out[9]
  644. mbutterfly0 d21, d26, d30, d17, d10, d11, q6, q7, 1 @ d21 = out[5], d26 = out[10]
  645. vneg.s16 d31, d5 @ d31 = out[15]
  646. vneg.s16 d17, d3 @ d17 = out[1]
  647. vmov d16, d2
  648. vmov d30, d4
  649. bx lr
  650. endfunc
  651. .macro load_add_store coef0, coef1, coef2, coef3
  652. vrshr.s16 \coef0, \coef0, #6
  653. vrshr.s16 \coef1, \coef1, #6
  654. vld1.32 {d4[]}, [r0,:32], r1
  655. vld1.32 {d4[1]}, [r3,:32], r1
  656. vrshr.s16 \coef2, \coef2, #6
  657. vrshr.s16 \coef3, \coef3, #6
  658. vld1.32 {d5[]}, [r0,:32], r1
  659. vld1.32 {d5[1]}, [r3,:32], r1
  660. vaddw.u8 \coef0, \coef0, d4
  661. vld1.32 {d6[]}, [r0,:32], r1
  662. vld1.32 {d6[1]}, [r3,:32], r1
  663. vaddw.u8 \coef1, \coef1, d5
  664. vld1.32 {d7[]}, [r0,:32], r1
  665. vld1.32 {d7[1]}, [r3,:32], r1
  666. vqmovun.s16 d4, \coef0
  667. vqmovun.s16 d5, \coef1
  668. sub r0, r0, r1, lsl #2
  669. sub r3, r3, r1, lsl #2
  670. vaddw.u8 \coef2, \coef2, d6
  671. vaddw.u8 \coef3, \coef3, d7
  672. vst1.32 {d4[0]}, [r0,:32], r1
  673. vst1.32 {d4[1]}, [r3,:32], r1
  674. vqmovun.s16 d6, \coef2
  675. vst1.32 {d5[0]}, [r0,:32], r1
  676. vst1.32 {d5[1]}, [r3,:32], r1
  677. vqmovun.s16 d7, \coef3
  678. vst1.32 {d6[0]}, [r0,:32], r1
  679. vst1.32 {d6[1]}, [r3,:32], r1
  680. vst1.32 {d7[0]}, [r0,:32], r1
  681. vst1.32 {d7[1]}, [r3,:32], r1
  682. .endm
  683. .macro itxfm16_1d_funcs txfm
  684. @ Read a vertical 4x16 slice out of a 16x16 matrix, do a transform on it,
  685. @ transpose into a horizontal 16x4 slice and store.
  686. @ r0 = dst (temp buffer)
  687. @ r1 = slice offset
  688. @ r2 = src
  689. function \txfm\()16_1d_4x16_pass1_neon
  690. push {lr}
  691. mov r12, #32
  692. vmov.s16 q2, #0
  693. .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
  694. vld1.16 {d\i}, [r2,:64]
  695. vst1.16 {d4}, [r2,:64], r12
  696. .endr
  697. bl \txfm\()16
  698. @ Do four 4x4 transposes. Originally, d16-d31 contain the
  699. @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31
  700. @ contain the transposed 4x4 blocks.
  701. transpose16_q_4x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
  702. @ Store the transposed 4x4 blocks horizontally.
  703. cmp r1, #12
  704. beq 1f
  705. .irp i, 16, 20, 24, 28, 17, 21, 25, 29, 18, 22, 26, 30, 19, 23, 27, 31
  706. vst1.16 {d\i}, [r0,:64]!
  707. .endr
  708. pop {pc}
  709. 1:
  710. @ Special case: For the last input column (r1 == 12),
  711. @ which would be stored as the last row in the temp buffer,
  712. @ don't store the first 4x4 block, but keep it in registers
  713. @ for the first slice of the second pass (where it is the
  714. @ last 4x4 block).
  715. add r0, r0, #8
  716. vst1.16 {d20}, [r0,:64]!
  717. vst1.16 {d24}, [r0,:64]!
  718. vst1.16 {d28}, [r0,:64]!
  719. add r0, r0, #8
  720. vst1.16 {d21}, [r0,:64]!
  721. vst1.16 {d25}, [r0,:64]!
  722. vst1.16 {d29}, [r0,:64]!
  723. add r0, r0, #8
  724. vst1.16 {d22}, [r0,:64]!
  725. vst1.16 {d26}, [r0,:64]!
  726. vst1.16 {d30}, [r0,:64]!
  727. add r0, r0, #8
  728. vst1.16 {d23}, [r0,:64]!
  729. vst1.16 {d27}, [r0,:64]!
  730. vst1.16 {d31}, [r0,:64]!
  731. vmov d28, d16
  732. vmov d29, d17
  733. vmov d30, d18
  734. vmov d31, d19
  735. pop {pc}
  736. endfunc
  737. @ Read a vertical 4x16 slice out of a 16x16 matrix, do a transform on it,
  738. @ load the destination pixels (from a similar 4x16 slice), add and store back.
  739. @ r0 = dst
  740. @ r1 = dst stride
  741. @ r2 = src (temp buffer)
  742. @ r3 = slice offset
  743. function \txfm\()16_1d_4x16_pass2_neon
  744. push {lr}
  745. mov r12, #32
  746. .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27
  747. vld1.16 {d\i}, [r2,:64], r12
  748. .endr
  749. cmp r3, #0
  750. beq 1f
  751. .irp i, 28, 29, 30, 31
  752. vld1.16 {d\i}, [r2,:64], r12
  753. .endr
  754. 1:
  755. add r3, r0, r1
  756. lsl r1, r1, #1
  757. bl \txfm\()16
  758. load_add_store q8, q9, q10, q11
  759. load_add_store q12, q13, q14, q15
  760. pop {pc}
  761. endfunc
  762. .endm
  763. itxfm16_1d_funcs idct
  764. itxfm16_1d_funcs iadst
  765. @ This is the minimum eob value for each subpartition, in increments of 4
  766. const min_eob_idct_idct_16, align=4
  767. .short 0, 10, 38, 89
  768. endconst
  769. .macro itxfm_func16x16 txfm1, txfm2
  770. function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_neon, export=1
  771. .ifc \txfm1\()_\txfm2,idct_idct
  772. cmp r3, #1
  773. beq idct16x16_dc_add_neon
  774. .endif
  775. push {r4-r8,lr}
  776. .ifnc \txfm1\()_\txfm2,idct_idct
  777. vpush {q4-q7}
  778. .endif
  779. @ Align the stack, allocate a temp buffer
  780. T mov r7, sp
  781. T and r7, r7, #15
  782. A and r7, sp, #15
  783. add r7, r7, #512
  784. sub sp, sp, r7
  785. mov r4, r0
  786. mov r5, r1
  787. mov r6, r2
  788. .ifc \txfm1,idct
  789. movrel r12, idct_coeffs
  790. vld1.16 {q0-q1}, [r12,:128]
  791. .endif
  792. .ifc \txfm1\()_\txfm2,idct_idct
  793. cmp r3, #10
  794. ble idct16x16_quarter_add_neon
  795. cmp r3, #38
  796. ble idct16x16_half_add_neon
  797. movrel r8, min_eob_idct_idct_16 + 2
  798. .endif
  799. .irp i, 0, 4, 8, 12
  800. add r0, sp, #(\i*32)
  801. .ifc \txfm1\()_\txfm2,idct_idct
  802. .if \i > 0
  803. ldrh_post r1, r8, #2
  804. cmp r3, r1
  805. it le
  806. movle r1, #(16 - \i)/4
  807. ble 1f
  808. .endif
  809. .endif
  810. mov r1, #\i
  811. add r2, r6, #(\i*2)
  812. bl \txfm1\()16_1d_4x16_pass1_neon
  813. .endr
  814. .ifc \txfm1\()_\txfm2,idct_idct
  815. b 3f
  816. 1:
  817. @ For all-zero slices in pass 1, set d28-d31 to zero, for the in-register
  818. @ passthrough of coefficients to pass 2 and clear the end of the temp buffer
  819. vmov.i16 q14, #0
  820. vmov.i16 q15, #0
  821. 2:
  822. subs r1, r1, #1
  823. .rept 4
  824. vst1.16 {q14-q15}, [r0,:128]!
  825. .endr
  826. bne 2b
  827. 3:
  828. .endif
  829. .ifc \txfm1\()_\txfm2,iadst_idct
  830. movrel r12, idct_coeffs
  831. vld1.16 {q0-q1}, [r12,:128]
  832. .endif
  833. .irp i, 0, 4, 8, 12
  834. add r0, r4, #(\i)
  835. mov r1, r5
  836. add r2, sp, #(\i*2)
  837. mov r3, #\i
  838. bl \txfm2\()16_1d_4x16_pass2_neon
  839. .endr
  840. add sp, sp, r7
  841. .ifnc \txfm1\()_\txfm2,idct_idct
  842. vpop {q4-q7}
  843. .endif
  844. pop {r4-r8,pc}
  845. endfunc
  846. .endm
  847. itxfm_func16x16 idct, idct
  848. itxfm_func16x16 iadst, idct
  849. itxfm_func16x16 idct, iadst
  850. itxfm_func16x16 iadst, iadst
  851. .ltorg
  852. function idct16_1d_4x16_pass1_quarter_neon
  853. push {lr}
  854. mov r12, #32
  855. vmov.s16 q2, #0
  856. .irp i, 16, 17, 18, 19
  857. vld1.16 {d\i}, [r2,:64]
  858. vst1.16 {d4}, [r2,:64], r12
  859. .endr
  860. bl idct16_quarter
  861. @ Do four 4x4 transposes. Originally, d16-d31 contain the
  862. @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31
  863. @ contain the transposed 4x4 blocks.
  864. transpose16_q_4x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
  865. @ Store the transposed 4x4 blocks horizontally.
  866. @ The first 4x4 block is kept in registers for the second pass,
  867. @ store the rest in the temp buffer.
  868. add r0, r0, #8
  869. vst1.16 {d20}, [r0,:64]!
  870. vst1.16 {d24}, [r0,:64]!
  871. vst1.16 {d28}, [r0,:64]!
  872. add r0, r0, #8
  873. vst1.16 {d21}, [r0,:64]!
  874. vst1.16 {d25}, [r0,:64]!
  875. vst1.16 {d29}, [r0,:64]!
  876. add r0, r0, #8
  877. vst1.16 {d22}, [r0,:64]!
  878. vst1.16 {d26}, [r0,:64]!
  879. vst1.16 {d30}, [r0,:64]!
  880. add r0, r0, #8
  881. vst1.16 {d23}, [r0,:64]!
  882. vst1.16 {d27}, [r0,:64]!
  883. vst1.16 {d31}, [r0,:64]!
  884. pop {pc}
  885. endfunc
  886. function idct16_1d_4x16_pass2_quarter_neon
  887. push {lr}
  888. @ Only load the top 4 lines, and only do it for the later slices.
  889. @ For the first slice, d16-d19 is kept in registers from the first pass.
  890. cmp r3, #0
  891. beq 1f
  892. mov r12, #32
  893. .irp i, 16, 17, 18, 19
  894. vld1.16 {d\i}, [r2,:64], r12
  895. .endr
  896. 1:
  897. add r3, r0, r1
  898. lsl r1, r1, #1
  899. bl idct16_quarter
  900. load_add_store q8, q9, q10, q11
  901. load_add_store q12, q13, q14, q15
  902. pop {pc}
  903. endfunc
  904. function idct16_1d_4x16_pass1_half_neon
  905. push {lr}
  906. mov r12, #32
  907. vmov.s16 q2, #0
  908. .irp i, 16, 17, 18, 19, 20, 21, 22, 23
  909. vld1.16 {d\i}, [r2,:64]
  910. vst1.16 {d4}, [r2,:64], r12
  911. .endr
  912. bl idct16_half
  913. @ Do four 4x4 transposes. Originally, d16-d31 contain the
  914. @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31
  915. @ contain the transposed 4x4 blocks.
  916. transpose16_q_4x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
  917. @ Store the transposed 4x4 blocks horizontally.
  918. cmp r1, #4
  919. beq 1f
  920. .irp i, 16, 20, 24, 28, 17, 21, 25, 29, 18, 22, 26, 30, 19, 23, 27, 31
  921. vst1.16 {d\i}, [r0,:64]!
  922. .endr
  923. pop {pc}
  924. 1:
  925. @ Special case: For the second input column (r1 == 4),
  926. @ which would be stored as the second row in the temp buffer,
  927. @ don't store the first 4x4 block, but keep it in registers
  928. @ for the first slice of the second pass (where it is the
  929. @ second 4x4 block).
  930. add r0, r0, #8
  931. vst1.16 {d20}, [r0,:64]!
  932. vst1.16 {d24}, [r0,:64]!
  933. vst1.16 {d28}, [r0,:64]!
  934. add r0, r0, #8
  935. vst1.16 {d21}, [r0,:64]!
  936. vst1.16 {d25}, [r0,:64]!
  937. vst1.16 {d29}, [r0,:64]!
  938. add r0, r0, #8
  939. vst1.16 {d22}, [r0,:64]!
  940. vst1.16 {d26}, [r0,:64]!
  941. vst1.16 {d30}, [r0,:64]!
  942. add r0, r0, #8
  943. vst1.16 {d23}, [r0,:64]!
  944. vst1.16 {d27}, [r0,:64]!
  945. vst1.16 {d31}, [r0,:64]!
  946. vmov d20, d16
  947. vmov d21, d17
  948. vmov d22, d18
  949. vmov d23, d19
  950. pop {pc}
  951. endfunc
  952. function idct16_1d_4x16_pass2_half_neon
  953. push {lr}
  954. mov r12, #32
  955. cmp r3, #0
  956. .irp i, 16, 17, 18, 19
  957. vld1.16 {d\i}, [r2,:64], r12
  958. .endr
  959. beq 1f
  960. .irp i, 20, 21, 22, 23
  961. vld1.16 {d\i}, [r2,:64], r12
  962. .endr
  963. 1:
  964. add r3, r0, r1
  965. lsl r1, r1, #1
  966. bl idct16_half
  967. load_add_store q8, q9, q10, q11
  968. load_add_store q12, q13, q14, q15
  969. pop {pc}
  970. endfunc
  971. .purgem load_add_store
  972. .macro idct16_partial size
  973. function idct16x16_\size\()_add_neon
  974. add r0, sp, #(0*32)
  975. mov r1, #0
  976. add r2, r6, #(0*2)
  977. bl idct16_1d_4x16_pass1_\size\()_neon
  978. .ifc \size,half
  979. add r0, sp, #(4*32)
  980. mov r1, #4
  981. add r2, r6, #(4*2)
  982. bl idct16_1d_4x16_pass1_\size\()_neon
  983. .endif
  984. .irp i, 0, 4, 8, 12
  985. add r0, r4, #(\i)
  986. mov r1, r5
  987. add r2, sp, #(\i*2)
  988. mov r3, #\i
  989. bl idct16_1d_4x16_pass2_\size\()_neon
  990. .endr
  991. add sp, sp, r7
  992. pop {r4-r8,pc}
  993. endfunc
  994. .endm
  995. idct16_partial quarter
  996. idct16_partial half
  997. function idct32x32_dc_add_neon
  998. movrel r12, idct_coeffs
  999. vld1.16 {d0}, [r12,:64]
  1000. vmov.i16 q2, #0
  1001. vld1.16 {d16[]}, [r2,:16]
  1002. vmull.s16 q8, d16, d0[0]
  1003. vrshrn.s32 d16, q8, #14
  1004. vmull.s16 q8, d16, d0[0]
  1005. vrshrn.s32 d16, q8, #14
  1006. vdup.16 q8, d16[0]
  1007. vst1.16 {d4[0]}, [r2,:16]
  1008. vrshr.s16 q8, q8, #6
  1009. mov r3, r0
  1010. mov r12, #32
  1011. 1:
  1012. @ Loop to add the constant from q8 into all 32x32 outputs
  1013. subs r12, r12, #2
  1014. vld1.8 {q0-q1}, [r0,:128], r1
  1015. vaddw.u8 q9, q8, d0
  1016. vaddw.u8 q10, q8, d1
  1017. vld1.8 {q2-q3}, [r0,:128], r1
  1018. vaddw.u8 q11, q8, d2
  1019. vaddw.u8 q12, q8, d3
  1020. vaddw.u8 q13, q8, d4
  1021. vaddw.u8 q14, q8, d5
  1022. vaddw.u8 q15, q8, d6
  1023. vqmovun.s16 d0, q9
  1024. vaddw.u8 q9, q8, d7
  1025. vqmovun.s16 d1, q10
  1026. vqmovun.s16 d2, q11
  1027. vqmovun.s16 d3, q12
  1028. vqmovun.s16 d4, q13
  1029. vqmovun.s16 d5, q14
  1030. vst1.8 {q0-q1}, [r3,:128], r1
  1031. vqmovun.s16 d6, q15
  1032. vqmovun.s16 d7, q9
  1033. vst1.8 {q2-q3}, [r3,:128], r1
  1034. bne 1b
  1035. bx lr
  1036. endfunc
  1037. .macro idct32_end
  1038. butterfly d16, d9, d8, d9 @ d16 = t16a, d9 = t19a
  1039. butterfly d17, d20, d23, d20 @ d17 = t17, d20 = t18
  1040. butterfly d18, d10, d11, d10 @ d18 = t23a, d10 = t20a
  1041. butterfly d19, d21, d22, d21 @ d19 = t22, d21 = t21
  1042. butterfly d8, d28, d28, d30 @ d8 = t24a, d28 = t27a
  1043. butterfly d23, d26, d25, d26 @ d23 = t25, d26 = t26
  1044. butterfly d11, d29, d29, d31 @ d11 = t31a, d29 = t28a
  1045. butterfly d22, d27, d24, d27 @ d22 = t30, d27 = t29
  1046. mbutterfly d27, d20, d0[2], d0[3], q12, q15 @ d27 = t18a, d20 = t29a
  1047. mbutterfly d29, d9, d0[2], d0[3], q12, q15 @ d29 = t19, d5 = t28
  1048. mbutterfly d28, d10, d0[2], d0[3], q12, q15, neg=1 @ d28 = t27, d6 = t20
  1049. mbutterfly d26, d21, d0[2], d0[3], q12, q15, neg=1 @ d26 = t26a, d21 = t21a
  1050. butterfly d31, d24, d11, d8 @ d31 = t31, d24 = t24
  1051. butterfly d30, d25, d22, d23 @ d30 = t30a, d25 = t25a
  1052. butterfly_r d23, d16, d16, d18 @ d23 = t23, d16 = t16
  1053. butterfly_r d22, d17, d17, d19 @ d22 = t22a, d17 = t17a
  1054. butterfly d18, d21, d27, d21 @ d18 = t18, d21 = t21
  1055. butterfly_r d27, d28, d9, d28 @ d27 = t27a, d28 = t28a
  1056. butterfly d8, d26, d20, d26 @ d8 = t29, d26 = t26
  1057. butterfly d19, d20, d29, d10 @ d19 = t19a, d20 = t20
  1058. vmov d29, d8 @ d29 = t29
  1059. mbutterfly0 d27, d20, d27, d20, d8, d10, q4, q5 @ d27 = t27, d20 = t20
  1060. mbutterfly0 d26, d21, d26, d21, d8, d10, q4, q5 @ d26 = t26a, d21 = t21a
  1061. mbutterfly0 d25, d22, d25, d22, d8, d10, q4, q5 @ d25 = t25, d22 = t22
  1062. mbutterfly0 d24, d23, d24, d23, d8, d10, q4, q5 @ d24 = t24a, d23 = t23a
  1063. bx lr
  1064. .endm
  1065. function idct32_odd
  1066. mbutterfly d16, d31, d4[0], d4[1], q4, q5 @ d16 = t16a, d31 = t31a
  1067. mbutterfly d24, d23, d4[2], d4[3], q4, q5 @ d24 = t17a, d23 = t30a
  1068. mbutterfly d20, d27, d5[0], d5[1], q4, q5 @ d20 = t18a, d27 = t29a
  1069. mbutterfly d28, d19, d5[2], d5[3], q4, q5 @ d28 = t19a, d19 = t28a
  1070. mbutterfly d18, d29, d6[0], d6[1], q4, q5 @ d18 = t20a, d29 = t27a
  1071. mbutterfly d26, d21, d6[2], d6[3], q4, q5 @ d26 = t21a, d21 = t26a
  1072. mbutterfly d22, d25, d7[0], d7[1], q4, q5 @ d22 = t22a, d25 = t25a
  1073. mbutterfly d30, d17, d7[2], d7[3], q4, q5 @ d30 = t23a, d17 = t24a
  1074. butterfly d8, d24, d16, d24 @ d8 = t16, d24 = t17
  1075. butterfly d9, d20, d28, d20 @ d9 = t19, d20 = t18
  1076. butterfly d10, d26, d18, d26 @ d10 = t20, d26 = t21
  1077. butterfly d11, d22, d30, d22 @ d11 = t23, d22 = t22
  1078. butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25
  1079. butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26
  1080. butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30
  1081. butterfly d31, d27, d19, d27 @ d31 = t28, d27 = t29
  1082. mbutterfly d23, d24, d1[0], d1[1], q8, q9 @ d23 = t17a, d24 = t30a
  1083. mbutterfly d27, d20, d1[0], d1[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a
  1084. mbutterfly d21, d26, d1[2], d1[3], q8, q9 @ d21 = t21a, d26 = t26a
  1085. mbutterfly d25, d22, d1[2], d1[3], q8, q9, neg=1 @ d25 = t25a, d22 = t22a
  1086. idct32_end
  1087. endfunc
  1088. function idct32_odd_half
  1089. mbutterfly_h1 d16, d31, d4[0], d4[1], q4, q5 @ d16 = t16a, d31 = t31a
  1090. mbutterfly_h2 d24, d23, d4[2], d4[3], q4, q5 @ d24 = t17a, d23 = t30a
  1091. mbutterfly_h1 d20, d27, d5[0], d5[1], q4, q5 @ d20 = t18a, d27 = t29a
  1092. mbutterfly_h2 d28, d19, d5[2], d5[3], q4, q5 @ d28 = t19a, d19 = t28a
  1093. mbutterfly_h1 d18, d29, d6[0], d6[1], q4, q5 @ d18 = t20a, d29 = t27a
  1094. mbutterfly_h2 d26, d21, d6[2], d6[3], q4, q5 @ d26 = t21a, d21 = t26a
  1095. mbutterfly_h1 d22, d25, d7[0], d7[1], q4, q5 @ d22 = t22a, d25 = t25a
  1096. mbutterfly_h2 d30, d17, d7[2], d7[3], q4, q5 @ d30 = t23a, d17 = t24a
  1097. butterfly d8, d24, d16, d24 @ d8 = t16, d24 = t17
  1098. butterfly d9, d20, d28, d20 @ d9 = t19, d20 = t18
  1099. butterfly d10, d26, d18, d26 @ d10 = t20, d26 = t21
  1100. butterfly d11, d22, d30, d22 @ d11 = t23, d22 = t22
  1101. butterfly d28, d25, d17, d25 @ d28 = t24, d25 = t25
  1102. butterfly d30, d21, d29, d21 @ d30 = t27, d21 = t26
  1103. butterfly d29, d23, d31, d23 @ d29 = t31, d23 = t30
  1104. butterfly d31, d27, d19, d27 @ d31 = t28, d27 = t29
  1105. mbutterfly d23, d24, d1[0], d1[1], q8, q9 @ d23 = t17a, d24 = t30a
  1106. mbutterfly d27, d20, d1[0], d1[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a
  1107. mbutterfly d21, d26, d1[2], d1[3], q8, q9 @ d21 = t21a, d26 = t26a
  1108. mbutterfly d25, d22, d1[2], d1[3], q8, q9, neg=1 @ d25 = t25a, d22 = t22a
  1109. idct32_end
  1110. endfunc
  1111. function idct32_odd_quarter
  1112. vmull.s16 q4, d16, d4[0]
  1113. vmull.s16 q14, d19, d5[3]
  1114. vmull.s16 q15, d16, d4[1]
  1115. vmull.s16 q11, d17, d7[2]
  1116. vmull.s16 q5, d17, d7[3]
  1117. vmull.s16 q13, d19, d5[2]
  1118. vmull.s16 q10, d18, d6[0]
  1119. vmull.s16 q12, d18, d6[1]
  1120. vneg.s32 q14, q14
  1121. vneg.s32 q5, q5
  1122. vrshrn.s32 d8, q4, #14
  1123. vrshrn.s32 d9, q14, #14
  1124. vrshrn.s32 d29, q15, #14
  1125. vrshrn.s32 d28, q11, #14
  1126. vrshrn.s32 d11, q5, #14
  1127. vrshrn.s32 d31, q13, #14
  1128. vrshrn.s32 d10, q10, #14
  1129. vrshrn.s32 d30, q12, #14
  1130. mbutterfly_l q8, q9, d29, d8, d1[0], d1[1]
  1131. mbutterfly_l q13, q10, d31, d9, d1[0], d1[1]
  1132. vrshrn.s32 d23, q8, #14
  1133. vrshrn.s32 d24, q9, #14
  1134. vneg.s32 q10, q10
  1135. vrshrn.s32 d27, q13, #14
  1136. vrshrn.s32 d20, q10, #14
  1137. mbutterfly_l q8, q9, d30, d10, d1[2], d1[3]
  1138. vrshrn.s32 d21, q8, #14
  1139. vrshrn.s32 d26, q9, #14
  1140. mbutterfly_l q8, q9, d28, d11, d1[2], d1[3]
  1141. vrshrn.s32 d25, q8, #14
  1142. vneg.s32 q9, q9
  1143. vrshrn.s32 d22, q9, #14
  1144. idct32_end
  1145. endfunc
  1146. .macro idct32_funcs suffix
  1147. @ Do an 32-point IDCT of a 4x32 slice out of a 32x32 matrix.
  1148. @ We don't have register space to do a single pass IDCT of 4x32 though,
  1149. @ but the 32-point IDCT can be decomposed into two 16-point IDCTs;
  1150. @ a normal IDCT16 with every other input component (the even ones, with
  1151. @ each output written twice), followed by a separate 16-point IDCT
  1152. @ of the odd inputs, added/subtracted onto the outputs of the first idct16.
  1153. @ r0 = dst (temp buffer)
  1154. @ r1 = unused
  1155. @ r2 = src
  1156. function idct32_1d_4x32_pass1\suffix\()_neon
  1157. push {lr}
  1158. @ idct16 clobbers q2-q3 (since it doesn't clobber q4-q7 at all
  1159. @ when doing the normal 16x16 idct), so move the idct32_odd coeffs
  1160. @ to q4-q5
  1161. vmov q4, q2
  1162. vmov q5, q3
  1163. @ Double stride of the input, since we only read every other line
  1164. mov r12, #128
  1165. vmov.s16 d4, #0
  1166. @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30)
  1167. .ifb \suffix
  1168. .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
  1169. vld1.16 {d\i}, [r2,:64]
  1170. vst1.16 {d4}, [r2,:64], r12
  1171. .endr
  1172. .endif
  1173. .ifc \suffix,_quarter
  1174. .irp i, 16, 17, 18, 19
  1175. vld1.16 {d\i}, [r2,:64]
  1176. vst1.16 {d4}, [r2,:64], r12
  1177. .endr
  1178. .endif
  1179. .ifc \suffix,_half
  1180. .irp i, 16, 17, 18, 19, 20, 21, 22, 23
  1181. vld1.16 {d\i}, [r2,:64]
  1182. vst1.16 {d4}, [r2,:64], r12
  1183. .endr
  1184. .endif
  1185. bl idct16\suffix
  1186. @ Move the idct32_odd coeffs back into q2-q3 for idct32_odd;
  1187. @ the constants for a vmul with a lane must be in q0-q3.
  1188. vmov q2, q4
  1189. vmov q3, q5
  1190. @ Do four 4x4 transposes. Originally, d16-d31 contain the
  1191. @ 16 rows. Afterwards, d16-d19, d20-d23, d24-d27, d28-d31
  1192. @ contain the transposed 4x4 blocks.
  1193. transpose16_q_4x_4x4 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
  1194. @ Store the registers a, b, c, d horizontally, followed
  1195. @ by the same registers d, c, b, a mirrored.
  1196. .macro store_rev a, b, c, d
  1197. .irp i, \a, \b, \c, \d
  1198. vst1.16 {d\i}, [r0,:64]!
  1199. vrev64.16 d\i, d\i
  1200. .endr
  1201. .irp i, \d, \c, \b, \a
  1202. vst1.16 {d\i}, [r0,:64]!
  1203. .endr
  1204. .endm
  1205. store_rev 16, 20, 24, 28
  1206. store_rev 17, 21, 25, 29
  1207. store_rev 18, 22, 26, 30
  1208. store_rev 19, 23, 27, 31
  1209. sub r0, r0, #256
  1210. .purgem store_rev
  1211. @ Move r2 back to the start of the input, and move
  1212. @ to the first odd row
  1213. .ifb \suffix
  1214. sub r2, r2, r12, lsl #4
  1215. .endif
  1216. .ifc \suffix,_quarter
  1217. sub r2, r2, r12, lsl #2
  1218. .endif
  1219. .ifc \suffix,_half
  1220. sub r2, r2, r12, lsl #3
  1221. .endif
  1222. add r2, r2, #64
  1223. vmov.s16 d8, #0
  1224. @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31)
  1225. .ifb \suffix
  1226. .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
  1227. vld1.16 {d\i}, [r2,:64]
  1228. vst1.16 {d8}, [r2,:64], r12
  1229. .endr
  1230. .endif
  1231. .ifc \suffix,_quarter
  1232. .irp i, 16, 17, 18, 19
  1233. vld1.16 {d\i}, [r2,:64]
  1234. vst1.16 {d8}, [r2,:64], r12
  1235. .endr
  1236. .endif
  1237. .ifc \suffix,_half
  1238. .irp i, 16, 17, 18, 19, 20, 21, 22, 23
  1239. vld1.16 {d\i}, [r2,:64]
  1240. vst1.16 {d8}, [r2,:64], r12
  1241. .endr
  1242. .endif
  1243. bl idct32_odd\suffix
  1244. transpose16_q_4x_4x4 q15, q14, q13, q12, q11, q10, q9, q8, d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16
  1245. @ Store the registers a, b, c, d horizontally,
  1246. @ adding into the output first, and then mirrored, subtracted
  1247. @ from the output.
  1248. .macro store_rev a, b, c, d
  1249. .irp i, \a, \b, \c, \d
  1250. vld1.16 {d8}, [r0,:64]
  1251. vadd.s16 d8, d8, d\i
  1252. vst1.16 {d8}, [r0,:64]!
  1253. vrev64.16 d\i, d\i
  1254. .endr
  1255. .irp i, \d, \c, \b, \a
  1256. vld1.16 {d8}, [r0,:64]
  1257. vsub.s16 d8, d8, d\i
  1258. vst1.16 {d8}, [r0,:64]!
  1259. .endr
  1260. .endm
  1261. store_rev 31, 27, 23, 19
  1262. store_rev 30, 26, 22, 18
  1263. store_rev 29, 25, 21, 17
  1264. store_rev 28, 24, 20, 16
  1265. .purgem store_rev
  1266. pop {pc}
  1267. endfunc
  1268. .ltorg
  1269. @ This is mostly the same as 4x32_pass1, but without the transpose,
  1270. @ and use the source as temp buffer between the two idct passes, and
  1271. @ add into the destination.
  1272. @ r0 = dst
  1273. @ r1 = dst stride
  1274. @ r2 = src (temp buffer)
  1275. function idct32_1d_4x32_pass2\suffix\()_neon
  1276. push {lr}
  1277. vmov q4, q2
  1278. vmov q5, q3
  1279. mov r12, #128
  1280. @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30)
  1281. .ifb \suffix
  1282. .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
  1283. vld1.16 {d\i}, [r2,:64], r12
  1284. .endr
  1285. sub r2, r2, r12, lsl #4
  1286. .endif
  1287. .ifc \suffix,_quarter
  1288. .irp i, 16, 17, 18, 19
  1289. vld1.16 {d\i}, [r2,:64], r12
  1290. .endr
  1291. sub r2, r2, r12, lsl #2
  1292. .endif
  1293. .ifc \suffix,_half
  1294. .irp i, 16, 17, 18, 19, 20, 21, 22, 23
  1295. vld1.16 {d\i}, [r2,:64], r12
  1296. .endr
  1297. sub r2, r2, r12, lsl #3
  1298. .endif
  1299. bl idct16\suffix
  1300. vmov q2, q4
  1301. vmov q3, q5
  1302. .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
  1303. vst1.16 {d\i}, [r2,:64], r12
  1304. .endr
  1305. sub r2, r2, r12, lsl #4
  1306. add r2, r2, #64
  1307. @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31)
  1308. .ifb \suffix
  1309. .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
  1310. vld1.16 {d\i}, [r2,:64], r12
  1311. .endr
  1312. sub r2, r2, r12, lsl #4
  1313. .endif
  1314. .ifc \suffix,_quarter
  1315. .irp i, 16, 17, 18, 19
  1316. vld1.16 {d\i}, [r2,:64], r12
  1317. .endr
  1318. sub r2, r2, r12, lsl #2
  1319. .endif
  1320. .ifc \suffix,_half
  1321. .irp i, 16, 17, 18, 19, 20, 21, 22, 23
  1322. vld1.16 {d\i}, [r2,:64], r12
  1323. .endr
  1324. sub r2, r2, r12, lsl #3
  1325. .endif
  1326. sub r2, r2, #64
  1327. bl idct32_odd\suffix
  1328. mov r12, #128
  1329. .macro load_acc_store a, b, c, d, neg=0
  1330. vld1.16 {d8}, [r2,:64], r12
  1331. vld1.16 {d9}, [r2,:64], r12
  1332. .if \neg == 0
  1333. vadd.s16 d8, d8, d\a
  1334. vld1.16 {d10}, [r2,:64], r12
  1335. vadd.s16 d9, d9, d\b
  1336. vld1.16 {d11}, [r2,:64], r12
  1337. vadd.s16 d10, d10, d\c
  1338. vadd.s16 d11, d11, d\d
  1339. .else
  1340. vsub.s16 d8, d8, d\a
  1341. vld1.16 {d10}, [r2,:64], r12
  1342. vsub.s16 d9, d9, d\b
  1343. vld1.16 {d11}, [r2,:64], r12
  1344. vsub.s16 d10, d10, d\c
  1345. vsub.s16 d11, d11, d\d
  1346. .endif
  1347. vld1.32 {d12[]}, [r0,:32], r1
  1348. vld1.32 {d12[1]}, [r0,:32], r1
  1349. vrshr.s16 q4, q4, #6
  1350. vld1.32 {d13[]}, [r0,:32], r1
  1351. vrshr.s16 q5, q5, #6
  1352. vld1.32 {d13[1]}, [r0,:32], r1
  1353. sub r0, r0, r1, lsl #2
  1354. vaddw.u8 q4, q4, d12
  1355. vaddw.u8 q5, q5, d13
  1356. vqmovun.s16 d8, q4
  1357. vqmovun.s16 d9, q5
  1358. vst1.32 {d8[0]}, [r0,:32], r1
  1359. vst1.32 {d8[1]}, [r0,:32], r1
  1360. vst1.32 {d9[0]}, [r0,:32], r1
  1361. vst1.32 {d9[1]}, [r0,:32], r1
  1362. .endm
  1363. load_acc_store 31, 30, 29, 28
  1364. load_acc_store 27, 26, 25, 24
  1365. load_acc_store 23, 22, 21, 20
  1366. load_acc_store 19, 18, 17, 16
  1367. sub r2, r2, r12
  1368. neg r12, r12
  1369. load_acc_store 16, 17, 18, 19, 1
  1370. load_acc_store 20, 21, 22, 23, 1
  1371. load_acc_store 24, 25, 26, 27, 1
  1372. load_acc_store 28, 29, 30, 31, 1
  1373. .purgem load_acc_store
  1374. pop {pc}
  1375. endfunc
  1376. .endm
  1377. idct32_funcs
  1378. idct32_funcs _quarter
  1379. idct32_funcs _half
  1380. const min_eob_idct_idct_32, align=4
  1381. .short 0, 9, 34, 70, 135, 240, 336, 448
  1382. endconst
  1383. function ff_vp9_idct_idct_32x32_add_neon, export=1
  1384. cmp r3, #1
  1385. beq idct32x32_dc_add_neon
  1386. push {r4-r8,lr}
  1387. vpush {q4-q6}
  1388. @ Align the stack, allocate a temp buffer
  1389. T mov r7, sp
  1390. T and r7, r7, #15
  1391. A and r7, sp, #15
  1392. add r7, r7, #2048
  1393. sub sp, sp, r7
  1394. mov r4, r0
  1395. mov r5, r1
  1396. mov r6, r2
  1397. movrel r12, idct_coeffs
  1398. vld1.16 {q0-q1}, [r12,:128]!
  1399. vld1.16 {q2-q3}, [r12,:128]
  1400. cmp r3, #34
  1401. ble idct32x32_quarter_add_neon
  1402. cmp r3, #135
  1403. ble idct32x32_half_add_neon
  1404. movrel r8, min_eob_idct_idct_32 + 2
  1405. .irp i, 0, 4, 8, 12, 16, 20, 24, 28
  1406. add r0, sp, #(\i*64)
  1407. .if \i > 0
  1408. ldrh_post r1, r8, #2
  1409. cmp r3, r1
  1410. it le
  1411. movle r1, #(32 - \i)/2
  1412. ble 1f
  1413. .endif
  1414. add r2, r6, #(\i*2)
  1415. bl idct32_1d_4x32_pass1_neon
  1416. .endr
  1417. b 3f
  1418. 1:
  1419. @ Write zeros to the temp buffer for pass 2
  1420. vmov.i16 q14, #0
  1421. vmov.i16 q15, #0
  1422. 2:
  1423. subs r1, r1, #1
  1424. .rept 4
  1425. vst1.16 {q14-q15}, [r0,:128]!
  1426. .endr
  1427. bne 2b
  1428. 3:
  1429. .irp i, 0, 4, 8, 12, 16, 20, 24, 28
  1430. add r0, r4, #(\i)
  1431. mov r1, r5
  1432. add r2, sp, #(\i*2)
  1433. bl idct32_1d_4x32_pass2_neon
  1434. .endr
  1435. add sp, sp, r7
  1436. vpop {q4-q6}
  1437. pop {r4-r8,pc}
  1438. endfunc
  1439. .macro idct32_partial size
  1440. function idct32x32_\size\()_add_neon
  1441. .irp i, 0, 4
  1442. add r0, sp, #(\i*64)
  1443. .ifc \size,quarter
  1444. .if \i == 4
  1445. cmp r3, #9
  1446. ble 1f
  1447. .endif
  1448. .endif
  1449. add r2, r6, #(\i*2)
  1450. bl idct32_1d_4x32_pass1_\size\()_neon
  1451. .endr
  1452. .ifc \size,half
  1453. .irp i, 8, 12
  1454. add r0, sp, #(\i*64)
  1455. .if \i == 12
  1456. cmp r3, #70
  1457. ble 1f
  1458. .endif
  1459. add r2, r6, #(\i*2)
  1460. bl idct32_1d_4x32_pass1_\size\()_neon
  1461. .endr
  1462. .endif
  1463. b 3f
  1464. 1:
  1465. @ Write zeros to the temp buffer for pass 2
  1466. vmov.i16 q14, #0
  1467. vmov.i16 q15, #0
  1468. .rept 8
  1469. vst1.16 {q14-q15}, [r0,:128]!
  1470. .endr
  1471. 3:
  1472. .irp i, 0, 4, 8, 12, 16, 20, 24, 28
  1473. add r0, r4, #(\i)
  1474. mov r1, r5
  1475. add r2, sp, #(\i*2)
  1476. bl idct32_1d_4x32_pass2_\size\()_neon
  1477. .endr
  1478. add sp, sp, r7
  1479. vpop {q4-q6}
  1480. pop {r4-r8,pc}
  1481. endfunc
  1482. .endm
  1483. idct32_partial quarter
  1484. idct32_partial half