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.

627 lines
21KB

  1. /*
  2. * ARM NEON optimised IDCT functions for HEVC decoding
  3. *
  4. * Copyright (c) 2014 Seppo Tomperi <seppo.tomperi@vtt.fi>
  5. * Copyright (c) 2017 Alexandra Hájková
  6. *
  7. * This file is part of Libav.
  8. *
  9. * Libav is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2.1 of the License, or (at your option) any later version.
  13. *
  14. * Libav is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with Libav; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. */
  23. #include "libavutil/arm/asm.S"
  24. const trans, align=4
  25. .short 64, 83, 64, 36
  26. .short 89, 75, 50, 18
  27. .short 90, 87, 80, 70
  28. .short 57, 43, 25, 9
  29. endconst
  30. function ff_hevc_add_residual_4x4_8_neon, export=1
  31. vld1.16 {q0-q1}, [r1, :128]
  32. vld1.32 d4[0], [r0, :32], r2
  33. vld1.32 d4[1], [r0, :32], r2
  34. vld1.32 d5[0], [r0, :32], r2
  35. vld1.32 d5[1], [r0, :32], r2
  36. sub r0, r0, r2, lsl #2
  37. vmovl.u8 q8, d4
  38. vmovl.u8 q9, d5
  39. vqadd.s16 q0, q0, q8
  40. vqadd.s16 q1, q1, q9
  41. vqmovun.s16 d0, q0
  42. vqmovun.s16 d1, q1
  43. vst1.32 d0[0], [r0, :32], r2
  44. vst1.32 d0[1], [r0, :32], r2
  45. vst1.32 d1[0], [r0, :32], r2
  46. vst1.32 d1[1], [r0, :32], r2
  47. bx lr
  48. endfunc
  49. function ff_hevc_add_residual_8x8_8_neon, export=1
  50. add r12, r0, r2
  51. add r2, r2, r2
  52. mov r3, #8
  53. 1: subs r3, #2
  54. vld1.8 {d16}, [r0, :64]
  55. vld1.8 {d17}, [r12, :64]
  56. vmovl.u8 q9, d16
  57. vld1.16 {q0-q1}, [r1, :128]!
  58. vmovl.u8 q8, d17
  59. vqadd.s16 q0, q9
  60. vqadd.s16 q1, q8
  61. vqmovun.s16 d0, q0
  62. vqmovun.s16 d1, q1
  63. vst1.8 d0, [r0, :64], r2
  64. vst1.8 d1, [r12, :64], r2
  65. bne 1b
  66. bx lr
  67. endfunc
  68. function ff_hevc_add_residual_16x16_8_neon, export=1
  69. mov r3, #16
  70. add r12, r0, r2
  71. add r2, r2, r2
  72. 1: subs r3, #2
  73. vld1.8 {q8}, [r0, :128]
  74. vld1.16 {q0, q1}, [r1, :128]!
  75. vld1.8 {q11}, [r12, :128]
  76. vld1.16 {q2, q3}, [r1, :128]!
  77. vmovl.u8 q9, d16
  78. vmovl.u8 q10, d17
  79. vmovl.u8 q12, d22
  80. vmovl.u8 q13, d23
  81. vqadd.s16 q0, q9
  82. vqadd.s16 q1, q10
  83. vqadd.s16 q2, q12
  84. vqadd.s16 q3, q13
  85. vqmovun.s16 d0, q0
  86. vqmovun.s16 d1, q1
  87. vqmovun.s16 d2, q2
  88. vqmovun.s16 d3, q3
  89. vst1.8 {q0}, [r0, :128], r2
  90. vst1.8 {q1}, [r12, :128], r2
  91. bne 1b
  92. bx lr
  93. endfunc
  94. function ff_hevc_add_residual_32x32_8_neon, export=1
  95. vpush {q4-q7}
  96. add r12, r0, r2
  97. add r2, r2, r2
  98. mov r3, #32
  99. 1: subs r3, #2
  100. vld1.8 {q12, q13}, [r0, :128]
  101. vmovl.u8 q8, d24
  102. vmovl.u8 q9, d25
  103. vld1.8 {q14, q15}, [r12, :128]
  104. vmovl.u8 q10, d26
  105. vmovl.u8 q11, d27
  106. vmovl.u8 q12, d28
  107. vldm r1!, {q0-q7}
  108. vmovl.u8 q13, d29
  109. vmovl.u8 q14, d30
  110. vmovl.u8 q15, d31
  111. vqadd.s16 q0, q8
  112. vqadd.s16 q1, q9
  113. vqadd.s16 q2, q10
  114. vqadd.s16 q3, q11
  115. vqadd.s16 q4, q12
  116. vqadd.s16 q5, q13
  117. vqadd.s16 q6, q14
  118. vqadd.s16 q7, q15
  119. vqmovun.s16 d0, q0
  120. vqmovun.s16 d1, q1
  121. vqmovun.s16 d2, q2
  122. vqmovun.s16 d3, q3
  123. vqmovun.s16 d4, q4
  124. vqmovun.s16 d5, q5
  125. vst1.8 {q0, q1}, [r0, :128], r2
  126. vqmovun.s16 d6, q6
  127. vqmovun.s16 d7, q7
  128. vst1.8 {q2, q3}, [r12, :128], r2
  129. bne 1b
  130. vpop {q4-q7}
  131. bx lr
  132. endfunc
  133. .macro idct_4x4_dc bitdepth
  134. function ff_hevc_idct_4x4_dc_\bitdepth\()_neon, export=1
  135. ldrsh r1, [r0]
  136. ldr r2, =(1 << (13 - \bitdepth))
  137. add r1, #1
  138. asr r1, #1
  139. add r1, r2
  140. asr r1, #(14 - \bitdepth)
  141. vdup.16 q0, r1
  142. vdup.16 q1, r1
  143. vst1.16 {q0, q1}, [r0, :128]
  144. bx lr
  145. endfunc
  146. .endm
  147. .macro idct_8x8_dc bitdepth
  148. function ff_hevc_idct_8x8_dc_\bitdepth\()_neon, export=1
  149. ldrsh r1, [r0]
  150. ldr r2, =(1 << (13 - \bitdepth))
  151. add r1, #1
  152. asr r1, #1
  153. add r1, r2
  154. asr r1, #(14 - \bitdepth)
  155. vdup.16 q8, r1
  156. vdup.16 q9, r1
  157. vmov.16 q10, q8
  158. vmov.16 q11, q8
  159. vmov.16 q12, q8
  160. vmov.16 q13, q8
  161. vmov.16 q14, q8
  162. vmov.16 q15, q8
  163. vstm r0, {q8-q15}
  164. bx lr
  165. endfunc
  166. .endm
  167. .macro idct_16x16_dc bitdepth
  168. function ff_hevc_idct_16x16_dc_\bitdepth\()_neon, export=1
  169. ldrsh r1, [r0]
  170. ldr r2, =(1 << (13 - \bitdepth))
  171. add r1, #1
  172. asr r1, #1
  173. add r1, r2
  174. asr r1, #(14 - \bitdepth)
  175. vdup.16 q8, r1
  176. vdup.16 q9, r1
  177. vmov.16 q10, q8
  178. vmov.16 q11, q8
  179. vmov.16 q12, q8
  180. vmov.16 q13, q8
  181. vmov.16 q14, q8
  182. vmov.16 q15, q8
  183. vstm r0!, {q8-q15}
  184. vstm r0!, {q8-q15}
  185. vstm r0!, {q8-q15}
  186. vstm r0, {q8-q15}
  187. bx lr
  188. endfunc
  189. .endm
  190. .macro idct_32x32_dc bitdepth
  191. function ff_hevc_idct_32x32_dc_\bitdepth\()_neon, export=1
  192. ldrsh r1, [r0]
  193. ldr r2, =(1 << (13 - \bitdepth))
  194. add r1, #1
  195. asr r1, #1
  196. add r1, r2
  197. asr r1, #(14 - \bitdepth)
  198. mov r3, #16
  199. vdup.16 q8, r1
  200. vdup.16 q9, r1
  201. vmov.16 q10, q8
  202. vmov.16 q11, q8
  203. vmov.16 q12, q8
  204. vmov.16 q13, q8
  205. vmov.16 q14, q8
  206. vmov.16 q15, q8
  207. 1: subs r3, #1
  208. vstm r0!, {q8-q15}
  209. bne 1b
  210. bx lr
  211. endfunc
  212. .endm
  213. .macro sum_sub out, in, c, op
  214. .ifc \op, +
  215. vmlal.s16 \out, \in, \c
  216. .else
  217. vmlsl.s16 \out, \in, \c
  218. .endif
  219. .endm
  220. .macro tr_4x4 in0, in1, in2, in3, out0, out1, out2, out3, shift, tmp0, tmp1, tmp2, tmp3, tmp4
  221. vshll.s16 \tmp0, \in0, #6
  222. vmull.s16 \tmp2, \in1, d4[1]
  223. vmov \tmp1, \tmp0
  224. vmull.s16 \tmp3, \in1, d4[3]
  225. vmlal.s16 \tmp0, \in2, d4[0] @e0
  226. vmlsl.s16 \tmp1, \in2, d4[0] @e1
  227. vmlal.s16 \tmp2, \in3, d4[3] @o0
  228. vmlsl.s16 \tmp3, \in3, d4[1] @o1
  229. vadd.s32 \tmp4, \tmp0, \tmp2
  230. vsub.s32 \tmp0, \tmp0, \tmp2
  231. vadd.s32 \tmp2, \tmp1, \tmp3
  232. vsub.s32 \tmp1, \tmp1, \tmp3
  233. vqrshrn.s32 \out0, \tmp4, #\shift
  234. vqrshrn.s32 \out3, \tmp0, #\shift
  235. vqrshrn.s32 \out1, \tmp2, #\shift
  236. vqrshrn.s32 \out2, \tmp1, #\shift
  237. .endm
  238. .macro tr_4x4_8 in0, in1, in2, in3, out0, out1, out2, out3, tmp0, tmp1, tmp2, tmp3
  239. vshll.s16 \tmp0, \in0, #6
  240. vld1.s16 {\in0}, [r1, :64]!
  241. vmov \tmp1, \tmp0
  242. vmull.s16 \tmp2, \in1, \in0[1]
  243. vmull.s16 \tmp3, \in1, \in0[3]
  244. vmlal.s16 \tmp0, \in2, \in0[0] @e0
  245. vmlsl.s16 \tmp1, \in2, \in0[0] @e1
  246. vmlal.s16 \tmp2, \in3, \in0[3] @o0
  247. vmlsl.s16 \tmp3, \in3, \in0[1] @o1
  248. vld1.s16 {\in0}, [r1, :64]
  249. vadd.s32 \out0, \tmp0, \tmp2
  250. vadd.s32 \out1, \tmp1, \tmp3
  251. vsub.s32 \out2, \tmp1, \tmp3
  252. vsub.s32 \out3, \tmp0, \tmp2
  253. sub r1, r1, #8
  254. .endm
  255. @ Do a 4x4 transpose, using q registers for the subtransposes that don't
  256. @ need to address the indiviudal d registers.
  257. @ r0,r1 == rq0, r2,r3 == rq1
  258. .macro transpose_4x4 rq0, rq1, r0, r1, r2, r3
  259. vtrn.32 \rq0, \rq1
  260. vtrn.16 \r0, \r1
  261. vtrn.16 \r2, \r3
  262. .endm
  263. .macro idct_4x4 bitdepth
  264. function ff_hevc_idct_4x4_\bitdepth\()_neon, export=1
  265. @r0 - coeffs
  266. vld1.s16 {q0-q1}, [r0, :128]
  267. movrel r1, trans
  268. vld1.s16 {d4}, [r1, :64]
  269. tr_4x4 d0, d1, d2, d3, d16, d17, d18, d19, 7, q10, q11, q12, q13, q0
  270. transpose_4x4 q8, q9, d16, d17, d18, d19
  271. tr_4x4 d16, d17, d18, d19, d0, d1, d2, d3, 20 - \bitdepth, q10, q11, q12, q13, q0
  272. transpose_4x4 q0, q1, d0, d1, d2, d3
  273. vst1.s16 {d0-d3}, [r0, :128]
  274. bx lr
  275. endfunc
  276. .endm
  277. .macro transpose8_4x4 r0, r1, r2, r3
  278. vtrn.16 \r0, \r1
  279. vtrn.16 \r2, \r3
  280. vtrn.32 \r0, \r2
  281. vtrn.32 \r1, \r3
  282. .endm
  283. .macro transpose_8x8 r0, r1, r2, r3, r4, r5, r6, r7, l0, l1, l2, l3, l4, l5, l6, l7
  284. transpose8_4x4 \r0, \r1, \r2, \r3
  285. transpose8_4x4 \r4, \r5, \r6, \r7
  286. transpose8_4x4 \l0, \l1, \l2, \l3
  287. transpose8_4x4 \l4, \l5, \l6, \l7
  288. .endm
  289. .macro tr_8x4 shift, in0, in1, in2, in3, in4, in5, in6, in7
  290. tr_4x4_8 \in0, \in2, \in4, \in6, q8, q9, q10, q11, q12, q13, q14, q15
  291. vmull.s16 q14, \in1, \in0[2]
  292. vmull.s16 q12, \in1, \in0[0]
  293. vmull.s16 q13, \in1, \in0[1]
  294. sum_sub q14, \in3, \in0[0], -
  295. sum_sub q12, \in3, \in0[1], +
  296. sum_sub q13, \in3, \in0[3], -
  297. sum_sub q14, \in5, \in0[3], +
  298. sum_sub q12, \in5, \in0[2], +
  299. sum_sub q13, \in5, \in0[0], -
  300. sum_sub q14, \in7, \in0[1], +
  301. sum_sub q12, \in7, \in0[3], +
  302. sum_sub q13, \in7, \in0[2], -
  303. vadd.s32 q15, q10, q14
  304. vsub.s32 q10, q10, q14
  305. vqrshrn.s32 \in2, q15, \shift
  306. vmull.s16 q15, \in1, \in0[3]
  307. sum_sub q15, \in3, \in0[2], -
  308. sum_sub q15, \in5, \in0[1], +
  309. sum_sub q15, \in7, \in0[0], -
  310. vqrshrn.s32 \in5, q10, \shift
  311. vadd.s32 q10, q8, q12
  312. vsub.s32 q8, q8, q12
  313. vadd.s32 q12, q9, q13
  314. vsub.s32 q9, q9, q13
  315. vadd.s32 q14, q11, q15
  316. vsub.s32 q11, q11, q15
  317. vqrshrn.s32 \in0, q10, \shift
  318. vqrshrn.s32 \in7, q8, \shift
  319. vqrshrn.s32 \in1, q12, \shift
  320. vqrshrn.s32 \in6, q9, \shift
  321. vqrshrn.s32 \in3, q14, \shift
  322. vqrshrn.s32 \in4, q11, \shift
  323. .endm
  324. .macro idct_8x8 bitdepth
  325. function ff_hevc_idct_8x8_\bitdepth\()_neon, export=1
  326. @r0 - coeffs
  327. vpush {q4-q7}
  328. mov r1, r0
  329. mov r2, #64
  330. add r3, r0, #32
  331. vld1.s16 {q0-q1}, [r1,:128], r2
  332. vld1.s16 {q2-q3}, [r3,:128], r2
  333. vld1.s16 {q4-q5}, [r1,:128], r2
  334. vld1.s16 {q6-q7}, [r3,:128], r2
  335. movrel r1, trans
  336. tr_8x4 7, d0, d2, d4, d6, d8, d10, d12, d14
  337. tr_8x4 7, d1, d3, d5, d7, d9, d11, d13, d15
  338. @ Transpose each 4x4 block, and swap how d4-d7 and d8-d11 are used.
  339. @ Layout before:
  340. @ d0 d1
  341. @ d2 d3
  342. @ d4 d5
  343. @ d6 d7
  344. @ d8 d9
  345. @ d10 d11
  346. @ d12 d13
  347. @ d14 d15
  348. transpose_8x8 d0, d2, d4, d6, d8, d10, d12, d14, d1, d3, d5, d7, d9, d11, d13, d15
  349. @ Now the layout is:
  350. @ d0 d8
  351. @ d2 d10
  352. @ d4 d12
  353. @ d6 d14
  354. @ d1 d9
  355. @ d3 d11
  356. @ d5 d13
  357. @ d7 d15
  358. tr_8x4 20 - \bitdepth, d0, d2, d4, d6, d1, d3, d5, d7
  359. vswp d0, d8
  360. tr_8x4 20 - \bitdepth, d0, d10, d12, d14, d9, d11, d13, d15
  361. vswp d0, d8
  362. transpose_8x8 d0, d2, d4, d6, d8, d10, d12, d14, d1, d3, d5, d7, d9, d11, d13, d15
  363. mov r1, r0
  364. mov r2, #64
  365. add r3, r0, #32
  366. vst1.s16 {q0-q1}, [r1,:128], r2
  367. vst1.s16 {q2-q3}, [r3,:128], r2
  368. vst1.s16 {q4-q5}, [r1,:128], r2
  369. vst1.s16 {q6-q7}, [r3,:128], r2
  370. vpop {q4-q7}
  371. bx lr
  372. endfunc
  373. .endm
  374. .macro butterfly e, o, tmp_p, tmp_m
  375. vadd.s32 \tmp_p, \e, \o
  376. vsub.s32 \tmp_m, \e, \o
  377. .endm
  378. .macro tr16_8x4 in0, in1, in2, in3, in4, in5, in6, in7
  379. tr_4x4_8 \in0, \in2, \in4, \in6, q8, q9, q10, q11, q12, q13, q14, q15
  380. vmull.s16 q12, \in1, \in0[0]
  381. vmull.s16 q13, \in1, \in0[1]
  382. vmull.s16 q14, \in1, \in0[2]
  383. vmull.s16 q15, \in1, \in0[3]
  384. sum_sub q12, \in3, \in0[1], +
  385. sum_sub q13, \in3, \in0[3], -
  386. sum_sub q14, \in3, \in0[0], -
  387. sum_sub q15, \in3, \in0[2], -
  388. sum_sub q12, \in5, \in0[2], +
  389. sum_sub q13, \in5, \in0[0], -
  390. sum_sub q14, \in5, \in0[3], +
  391. sum_sub q15, \in5, \in0[1], +
  392. sum_sub q12, \in7, \in0[3], +
  393. sum_sub q13, \in7, \in0[2], -
  394. sum_sub q14, \in7, \in0[1], +
  395. sum_sub q15, \in7, \in0[0], -
  396. butterfly q8, q12, q0, q7
  397. butterfly q9, q13, q1, q6
  398. butterfly q10, q14, q2, q5
  399. butterfly q11, q15, q3, q4
  400. add r4, sp, #512
  401. vst1.s16 {q0-q1}, [r4, :128]!
  402. vst1.s16 {q2-q3}, [r4, :128]!
  403. vst1.s16 {q4-q5}, [r4, :128]!
  404. vst1.s16 {q6-q7}, [r4, :128]
  405. .endm
  406. .macro load16 in0, in1, in2, in3, in4, in5, in6, in7
  407. vld1.s16 {\in0}, [r1, :64], r2
  408. vld1.s16 {\in1}, [r3, :64], r2
  409. vld1.s16 {\in2}, [r1, :64], r2
  410. vld1.s16 {\in3}, [r3, :64], r2
  411. vld1.s16 {\in4}, [r1, :64], r2
  412. vld1.s16 {\in5}, [r3, :64], r2
  413. vld1.s16 {\in6}, [r1, :64], r2
  414. vld1.s16 {\in7}, [r3, :64], r2
  415. .endm
  416. .macro add_member in, t0, t1, t2, t3, t4, t5, t6, t7, op0, op1, op2, op3, op4, op5, op6, op7
  417. sum_sub q5, \in, \t0, \op0
  418. sum_sub q6, \in, \t1, \op1
  419. sum_sub q7, \in, \t2, \op2
  420. sum_sub q8, \in, \t3, \op3
  421. sum_sub q9, \in, \t4, \op4
  422. sum_sub q10, \in, \t5, \op5
  423. sum_sub q11, \in, \t6, \op6
  424. sum_sub q12, \in, \t7, \op7
  425. .endm
  426. .macro butterfly16 in0, in1, in2, in3, in4, in5, in6, in7
  427. vadd.s32 q4, \in0, \in1
  428. vsub.s32 \in0, \in0, \in1
  429. vadd.s32 \in1, \in2, \in3
  430. vsub.s32 \in2, \in2, \in3
  431. vadd.s32 \in3, \in4, \in5
  432. vsub.s32 \in4, \in4, \in5
  433. vadd.s32 \in5, \in6, \in7
  434. vsub.s32 \in6, \in6, \in7
  435. .endm
  436. .macro store16 in0, in1, in2, in3, in4, in5, in6, in7
  437. vst1.s16 \in0, [r1, :64], r2
  438. vst1.s16 \in1, [r3, :64], r4
  439. vst1.s16 \in2, [r1, :64], r2
  440. vst1.s16 \in3, [r3, :64], r4
  441. vst1.s16 \in4, [r1, :64], r2
  442. vst1.s16 \in5, [r3, :64], r4
  443. vst1.s16 \in6, [r1, :64], r2
  444. vst1.s16 \in7, [r3, :64], r4
  445. .endm
  446. .macro scale out0, out1, out2, out3, out4, out5, out6, out7, in0, in1, in2, in3, in4, in5, in6, in7, shift
  447. vqrshrn.s32 \out0, \in0, \shift
  448. vqrshrn.s32 \out1, \in1, \shift
  449. vqrshrn.s32 \out2, \in2, \shift
  450. vqrshrn.s32 \out3, \in3, \shift
  451. vqrshrn.s32 \out4, \in4, \shift
  452. vqrshrn.s32 \out5, \in5, \shift
  453. vqrshrn.s32 \out6, \in6, \shift
  454. vqrshrn.s32 \out7, \in7, \shift
  455. .endm
  456. .macro tr_16x4 name, shift
  457. function func_tr_16x4_\name
  458. mov r1, r5
  459. add r3, r5, #64
  460. mov r2, #128
  461. load16 d0, d1, d2, d3, d4, d5, d6, d7
  462. movrel r1, trans
  463. tr16_8x4 d0, d1, d2, d3, d4, d5, d6, d7
  464. add r1, r5, #32
  465. add r3, r5, #(64 + 32)
  466. mov r2, #128
  467. load16 d8, d9, d2, d3, d4, d5, d6, d7
  468. movrel r1, trans + 16
  469. vld1.s16 {q0}, [r1, :128]
  470. vmull.s16 q5, d8, d0[0]
  471. vmull.s16 q6, d8, d0[1]
  472. vmull.s16 q7, d8, d0[2]
  473. vmull.s16 q8, d8, d0[3]
  474. vmull.s16 q9, d8, d1[0]
  475. vmull.s16 q10, d8, d1[1]
  476. vmull.s16 q11, d8, d1[2]
  477. vmull.s16 q12, d8, d1[3]
  478. add_member d9, d0[1], d1[0], d1[3], d1[1], d0[2], d0[0], d0[3], d1[2], +, +, +, -, -, -, -, -
  479. add_member d2, d0[2], d1[3], d0[3], d0[1], d1[2], d1[0], d0[0], d1[1], +, +, -, -, -, +, +, +
  480. add_member d3, d0[3], d1[1], d0[1], d1[3], d0[0], d1[2], d0[2], d1[0], +, -, -, +, +, +, -, -
  481. add_member d4, d1[0], d0[2], d1[2], d0[0], d1[3], d0[1], d1[1], d0[3], +, -, -, +, -, -, +, +
  482. add_member d5, d1[1], d0[0], d1[0], d1[2], d0[1], d0[3], d1[3], d0[2], +, -, +, +, -, +, +, -
  483. add_member d6, d1[2], d0[3], d0[0], d0[2], d1[1], d1[3], d1[0], d0[1], +, -, +, -, +, +, -, +
  484. add_member d7, d1[3], d1[2], d1[1], d1[0], d0[3], d0[2], d0[1], d0[0], +, -, +, -, +, -, +, -
  485. add r4, sp, #512
  486. vld1.s16 {q0-q1}, [r4, :128]!
  487. vld1.s16 {q2-q3}, [r4, :128]!
  488. butterfly16 q0, q5, q1, q6, q2, q7, q3, q8
  489. scale d26, d27, d28, d29, d30, d31, d16, d17, q4, q0, q5, q1, q6, q2, q7, q3, \shift
  490. transpose8_4x4 d26, d28, d30, d16
  491. transpose8_4x4 d17, d31, d29, d27
  492. mov r1, r6
  493. add r3, r6, #(24 +3*32)
  494. mov r2, #32
  495. mov r4, #-32
  496. store16 d26, d27, d28, d29, d30, d31, d16, d17
  497. add r4, sp, #576
  498. vld1.s16 {q0-q1}, [r4, :128]!
  499. vld1.s16 {q2-q3}, [r4, :128]
  500. butterfly16 q0, q9, q1, q10, q2, q11, q3, q12
  501. scale d26, d27, d28, d29, d30, d31, d8, d9, q4, q0, q9, q1, q10, q2, q11, q3, \shift
  502. transpose8_4x4 d26, d28, d30, d8
  503. transpose8_4x4 d9, d31, d29, d27
  504. add r1, r6, #8
  505. add r3, r6, #(16 + 3 * 32)
  506. mov r2, #32
  507. mov r4, #-32
  508. store16 d26, d27, d28, d29, d30, d31, d8, d9
  509. bx lr
  510. endfunc
  511. .endm
  512. .macro idct_16x16 bitdepth
  513. function ff_hevc_idct_16x16_\bitdepth\()_neon, export=1
  514. @r0 - coeffs
  515. push {r4-r7, lr}
  516. vpush {q4-q7}
  517. @ Align the stack, allocate a temp buffer
  518. T mov r7, sp
  519. T and r7, r7, #15
  520. A and r7, sp, #15
  521. add r7, r7, #640
  522. sub sp, sp, r7
  523. .irp i, 0, 1, 2, 3
  524. add r5, r0, #(8 * \i)
  525. add r6, sp, #(8 * \i * 16)
  526. bl func_tr_16x4_firstpass
  527. .endr
  528. .irp i, 0, 1, 2, 3
  529. add r5, sp, #(8 * \i)
  530. add r6, r0, #(8 * \i * 16)
  531. bl func_tr_16x4_secondpass_\bitdepth
  532. .endr
  533. add sp, sp, r7
  534. vpop {q4-q7}
  535. pop {r4-r7, pc}
  536. endfunc
  537. .endm
  538. tr_16x4 firstpass, 7
  539. tr_16x4 secondpass_8, 20 - 8
  540. tr_16x4 secondpass_10, 20 - 10
  541. .ltorg
  542. idct_4x4 8
  543. idct_4x4_dc 8
  544. idct_4x4 10
  545. idct_4x4_dc 10
  546. idct_8x8 8
  547. idct_8x8_dc 8
  548. idct_8x8 10
  549. idct_8x8_dc 10
  550. idct_16x16 8
  551. idct_16x16_dc 8
  552. idct_16x16 10
  553. idct_16x16_dc 10
  554. idct_32x32_dc 8
  555. idct_32x32_dc 10