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.

985 lines
34KB

  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. .short 90, 90, 88, 85
  30. .short 82, 78, 73, 67
  31. .short 61, 54, 46, 38
  32. .short 31, 22, 13, 4
  33. endconst
  34. .macro clip10 in1, in2, c1, c2
  35. vmax.s16 \in1, \in1, \c1
  36. vmax.s16 \in2, \in2, \c1
  37. vmin.s16 \in1, \in1, \c2
  38. vmin.s16 \in2, \in2, \c2
  39. .endm
  40. function ff_hevc_add_residual_4x4_8_neon, export=1
  41. vld1.16 {q0-q1}, [r1, :128]
  42. vld1.32 d4[0], [r0, :32], r2
  43. vld1.32 d4[1], [r0, :32], r2
  44. vld1.32 d5[0], [r0, :32], r2
  45. vld1.32 d5[1], [r0, :32], r2
  46. sub r0, r0, r2, lsl #2
  47. vmovl.u8 q8, d4
  48. vmovl.u8 q9, d5
  49. vqadd.s16 q0, q0, q8
  50. vqadd.s16 q1, q1, q9
  51. vqmovun.s16 d0, q0
  52. vqmovun.s16 d1, q1
  53. vst1.32 d0[0], [r0, :32], r2
  54. vst1.32 d0[1], [r0, :32], r2
  55. vst1.32 d1[0], [r0, :32], r2
  56. vst1.32 d1[1], [r0, :32], r2
  57. bx lr
  58. endfunc
  59. function ff_hevc_add_residual_4x4_10_neon, export=1
  60. mov r12, r0
  61. vld1.16 {q0-q1}, [r1, :128]
  62. vld1.16 d4, [r12, :64], r2
  63. vld1.16 d5, [r12, :64], r2
  64. vld1.16 d6, [r12, :64], r2
  65. vqadd.s16 q0, q2
  66. vld1.16 d7, [r12, :64], r2
  67. vmov.s16 q12, #0
  68. vqadd.s16 q1, q3
  69. vmvn.s16 q13, #0xFC00 @ vmov.s16 #0x3FF
  70. clip10 q0, q1, q12, q13
  71. vst1.16 d0, [r0, :64], r2
  72. vst1.16 d1, [r0, :64], r2
  73. vst1.16 d2, [r0, :64], r2
  74. vst1.16 d3, [r0, :64], r2
  75. bx lr
  76. endfunc
  77. function ff_hevc_add_residual_8x8_8_neon, export=1
  78. add r12, r0, r2
  79. add r2, r2, r2
  80. mov r3, #8
  81. 1: subs r3, #2
  82. vld1.8 {d16}, [r0, :64]
  83. vld1.8 {d17}, [r12, :64]
  84. vmovl.u8 q9, d16
  85. vld1.16 {q0-q1}, [r1, :128]!
  86. vmovl.u8 q8, d17
  87. vqadd.s16 q0, q9
  88. vqadd.s16 q1, q8
  89. vqmovun.s16 d0, q0
  90. vqmovun.s16 d1, q1
  91. vst1.8 d0, [r0, :64], r2
  92. vst1.8 d1, [r12, :64], r2
  93. bne 1b
  94. bx lr
  95. endfunc
  96. function ff_hevc_add_residual_8x8_10_neon, export=1
  97. add r12, r0, r2
  98. add r2, r2, r2
  99. mov r3, #8
  100. vmov.s16 q12, #0
  101. vmvn.s16 q13, #0xFC00 @ vmov.s16 #0x3FF
  102. 1: subs r3, #2
  103. vld1.16 {q0-q1}, [r1, :128]!
  104. vld1.16 {q8}, [r0, :128]
  105. vqadd.s16 q0, q8
  106. vld1.16 {q9}, [r12, :128]
  107. vqadd.s16 q1, q9
  108. clip10 q0, q1, q12, q13
  109. vst1.16 {q0}, [r0, :128], r2
  110. vst1.16 {q1}, [r12, :128], r2
  111. bne 1b
  112. bx lr
  113. endfunc
  114. function ff_hevc_add_residual_16x16_8_neon, export=1
  115. mov r3, #16
  116. add r12, r0, r2
  117. add r2, r2, r2
  118. 1: subs r3, #2
  119. vld1.8 {q8}, [r0, :128]
  120. vld1.16 {q0, q1}, [r1, :128]!
  121. vld1.8 {q11}, [r12, :128]
  122. vld1.16 {q2, q3}, [r1, :128]!
  123. vmovl.u8 q9, d16
  124. vmovl.u8 q10, d17
  125. vmovl.u8 q12, d22
  126. vmovl.u8 q13, d23
  127. vqadd.s16 q0, q9
  128. vqadd.s16 q1, q10
  129. vqadd.s16 q2, q12
  130. vqadd.s16 q3, q13
  131. vqmovun.s16 d0, q0
  132. vqmovun.s16 d1, q1
  133. vqmovun.s16 d2, q2
  134. vqmovun.s16 d3, q3
  135. vst1.8 {q0}, [r0, :128], r2
  136. vst1.8 {q1}, [r12, :128], r2
  137. bne 1b
  138. bx lr
  139. endfunc
  140. function ff_hevc_add_residual_16x16_10_neon, export=1
  141. mov r3, #16
  142. vmov.s16 q12, #0
  143. vmvn.s16 q13, #0xFC00 @ vmov.s16 #0x3FF
  144. add r12, r0, r2
  145. add r2, r2, r2
  146. 1: subs r3, #2
  147. vld1.16 {q8-q9}, [r0, :128]
  148. vld1.16 {q0, q1}, [r1, :128]!
  149. vqadd.s16 q0, q8
  150. vld1.16 {q10-q11}, [r12, :128]
  151. vqadd.s16 q1, q9
  152. vld1.16 {q2, q3}, [r1, :128]!
  153. vqadd.s16 q2, q10
  154. vqadd.s16 q3, q11
  155. clip10 q0, q1, q12, q13
  156. clip10 q2, q3, q12, q13
  157. vst1.16 {q0-q1}, [r0, :128], r2
  158. vst1.16 {q2-q3}, [r12, :128], r2
  159. bne 1b
  160. bx lr
  161. endfunc
  162. function ff_hevc_add_residual_32x32_8_neon, export=1
  163. vpush {q4-q7}
  164. add r12, r0, r2
  165. add r2, r2, r2
  166. mov r3, #32
  167. 1: subs r3, #2
  168. vld1.8 {q12, q13}, [r0, :128]
  169. vmovl.u8 q8, d24
  170. vmovl.u8 q9, d25
  171. vld1.8 {q14, q15}, [r12, :128]
  172. vmovl.u8 q10, d26
  173. vmovl.u8 q11, d27
  174. vmovl.u8 q12, d28
  175. vldm r1!, {q0-q7}
  176. vmovl.u8 q13, d29
  177. vmovl.u8 q14, d30
  178. vmovl.u8 q15, d31
  179. vqadd.s16 q0, q8
  180. vqadd.s16 q1, q9
  181. vqadd.s16 q2, q10
  182. vqadd.s16 q3, q11
  183. vqadd.s16 q4, q12
  184. vqadd.s16 q5, q13
  185. vqadd.s16 q6, q14
  186. vqadd.s16 q7, q15
  187. vqmovun.s16 d0, q0
  188. vqmovun.s16 d1, q1
  189. vqmovun.s16 d2, q2
  190. vqmovun.s16 d3, q3
  191. vqmovun.s16 d4, q4
  192. vqmovun.s16 d5, q5
  193. vst1.8 {q0, q1}, [r0, :128], r2
  194. vqmovun.s16 d6, q6
  195. vqmovun.s16 d7, q7
  196. vst1.8 {q2, q3}, [r12, :128], r2
  197. bne 1b
  198. vpop {q4-q7}
  199. bx lr
  200. endfunc
  201. function ff_hevc_add_residual_32x32_10_neon, export=1
  202. mov r3, #32
  203. add r12, r0, #32
  204. vmov.s16 q12, #0
  205. vmvn.s16 q13, #0xFC00 @ vmov.s16 #0x3FF
  206. 1: subs r3, #1
  207. vldm r1!, {q0-q3}
  208. vld1.16 {q8, q9}, [r0, :128]
  209. vld1.16 {q10, q11}, [r12, :128]
  210. vqadd.s16 q0, q8
  211. vqadd.s16 q1, q9
  212. vqadd.s16 q2, q10
  213. vqadd.s16 q3, q11
  214. clip10 q0, q1, q12, q13
  215. clip10 q2, q3, q12, q13
  216. vst1.16 {q0-q1}, [r0, :128], r2
  217. vst1.16 {q2-q3}, [r12, :128], r2
  218. bne 1b
  219. bx lr
  220. endfunc
  221. .macro idct_4x4_dc bitdepth
  222. function ff_hevc_idct_4x4_dc_\bitdepth\()_neon, export=1
  223. ldrsh r1, [r0]
  224. ldr r2, =(1 << (13 - \bitdepth))
  225. add r1, #1
  226. asr r1, #1
  227. add r1, r2
  228. asr r1, #(14 - \bitdepth)
  229. vdup.16 q0, r1
  230. vdup.16 q1, r1
  231. vst1.16 {q0, q1}, [r0, :128]
  232. bx lr
  233. endfunc
  234. .endm
  235. .macro idct_8x8_dc bitdepth
  236. function ff_hevc_idct_8x8_dc_\bitdepth\()_neon, export=1
  237. ldrsh r1, [r0]
  238. ldr r2, =(1 << (13 - \bitdepth))
  239. add r1, #1
  240. asr r1, #1
  241. add r1, r2
  242. asr r1, #(14 - \bitdepth)
  243. vdup.16 q8, r1
  244. vdup.16 q9, r1
  245. vmov.16 q10, q8
  246. vmov.16 q11, q8
  247. vmov.16 q12, q8
  248. vmov.16 q13, q8
  249. vmov.16 q14, q8
  250. vmov.16 q15, q8
  251. vstm r0, {q8-q15}
  252. bx lr
  253. endfunc
  254. .endm
  255. .macro idct_16x16_dc bitdepth
  256. function ff_hevc_idct_16x16_dc_\bitdepth\()_neon, export=1
  257. ldrsh r1, [r0]
  258. ldr r2, =(1 << (13 - \bitdepth))
  259. add r1, #1
  260. asr r1, #1
  261. add r1, r2
  262. asr r1, #(14 - \bitdepth)
  263. vdup.16 q8, r1
  264. vdup.16 q9, r1
  265. vmov.16 q10, q8
  266. vmov.16 q11, q8
  267. vmov.16 q12, q8
  268. vmov.16 q13, q8
  269. vmov.16 q14, q8
  270. vmov.16 q15, q8
  271. vstm r0!, {q8-q15}
  272. vstm r0!, {q8-q15}
  273. vstm r0!, {q8-q15}
  274. vstm r0, {q8-q15}
  275. bx lr
  276. endfunc
  277. .endm
  278. .macro idct_32x32_dc bitdepth
  279. function ff_hevc_idct_32x32_dc_\bitdepth\()_neon, export=1
  280. ldrsh r1, [r0]
  281. ldr r2, =(1 << (13 - \bitdepth))
  282. add r1, #1
  283. asr r1, #1
  284. add r1, r2
  285. asr r1, #(14 - \bitdepth)
  286. mov r3, #16
  287. vdup.16 q8, r1
  288. vdup.16 q9, r1
  289. vmov.16 q10, q8
  290. vmov.16 q11, q8
  291. vmov.16 q12, q8
  292. vmov.16 q13, q8
  293. vmov.16 q14, q8
  294. vmov.16 q15, q8
  295. 1: subs r3, #1
  296. vstm r0!, {q8-q15}
  297. bne 1b
  298. bx lr
  299. endfunc
  300. .endm
  301. .macro sum_sub out, in, c, op
  302. .ifc \op, +
  303. vmlal.s16 \out, \in, \c
  304. .else
  305. vmlsl.s16 \out, \in, \c
  306. .endif
  307. .endm
  308. .macro tr_4x4 in0, in1, in2, in3, out0, out1, out2, out3, shift, tmp0, tmp1, tmp2, tmp3, tmp4
  309. vshll.s16 \tmp0, \in0, #6
  310. vmull.s16 \tmp2, \in1, d4[1]
  311. vmov \tmp1, \tmp0
  312. vmull.s16 \tmp3, \in1, d4[3]
  313. vmlal.s16 \tmp0, \in2, d4[0] @e0
  314. vmlsl.s16 \tmp1, \in2, d4[0] @e1
  315. vmlal.s16 \tmp2, \in3, d4[3] @o0
  316. vmlsl.s16 \tmp3, \in3, d4[1] @o1
  317. vadd.s32 \tmp4, \tmp0, \tmp2
  318. vsub.s32 \tmp0, \tmp0, \tmp2
  319. vadd.s32 \tmp2, \tmp1, \tmp3
  320. vsub.s32 \tmp1, \tmp1, \tmp3
  321. vqrshrn.s32 \out0, \tmp4, #\shift
  322. vqrshrn.s32 \out3, \tmp0, #\shift
  323. vqrshrn.s32 \out1, \tmp2, #\shift
  324. vqrshrn.s32 \out2, \tmp1, #\shift
  325. .endm
  326. .macro tr_4x4_8 in0, in1, in2, in3, out0, out1, out2, out3, tmp0, tmp1, tmp2, tmp3
  327. vshll.s16 \tmp0, \in0, #6
  328. vld1.s16 {\in0}, [r1, :64]!
  329. vmov \tmp1, \tmp0
  330. vmull.s16 \tmp2, \in1, \in0[1]
  331. vmull.s16 \tmp3, \in1, \in0[3]
  332. vmlal.s16 \tmp0, \in2, \in0[0] @e0
  333. vmlsl.s16 \tmp1, \in2, \in0[0] @e1
  334. vmlal.s16 \tmp2, \in3, \in0[3] @o0
  335. vmlsl.s16 \tmp3, \in3, \in0[1] @o1
  336. vld1.s16 {\in0}, [r1, :64]
  337. vadd.s32 \out0, \tmp0, \tmp2
  338. vadd.s32 \out1, \tmp1, \tmp3
  339. vsub.s32 \out2, \tmp1, \tmp3
  340. vsub.s32 \out3, \tmp0, \tmp2
  341. sub r1, r1, #8
  342. .endm
  343. @ Do a 4x4 transpose, using q registers for the subtransposes that don't
  344. @ need to address the indiviudal d registers.
  345. @ r0,r1 == rq0, r2,r3 == rq1
  346. .macro transpose_4x4 rq0, rq1, r0, r1, r2, r3
  347. vtrn.32 \rq0, \rq1
  348. vtrn.16 \r0, \r1
  349. vtrn.16 \r2, \r3
  350. .endm
  351. .macro idct_4x4 bitdepth
  352. function ff_hevc_idct_4x4_\bitdepth\()_neon, export=1
  353. @r0 - coeffs
  354. vld1.s16 {q0-q1}, [r0, :128]
  355. movrel r1, trans
  356. vld1.s16 {d4}, [r1, :64]
  357. tr_4x4 d0, d1, d2, d3, d16, d17, d18, d19, 7, q10, q11, q12, q13, q0
  358. transpose_4x4 q8, q9, d16, d17, d18, d19
  359. tr_4x4 d16, d17, d18, d19, d0, d1, d2, d3, 20 - \bitdepth, q10, q11, q12, q13, q0
  360. transpose_4x4 q0, q1, d0, d1, d2, d3
  361. vst1.s16 {d0-d3}, [r0, :128]
  362. bx lr
  363. endfunc
  364. .endm
  365. .macro transpose8_4x4 r0, r1, r2, r3
  366. vtrn.16 \r0, \r1
  367. vtrn.16 \r2, \r3
  368. vtrn.32 \r0, \r2
  369. vtrn.32 \r1, \r3
  370. .endm
  371. .macro transpose_8x8 r0, r1, r2, r3, r4, r5, r6, r7, l0, l1, l2, l3, l4, l5, l6, l7
  372. transpose8_4x4 \r0, \r1, \r2, \r3
  373. transpose8_4x4 \r4, \r5, \r6, \r7
  374. transpose8_4x4 \l0, \l1, \l2, \l3
  375. transpose8_4x4 \l4, \l5, \l6, \l7
  376. .endm
  377. .macro tr_8x4 shift, in0, in1, in2, in3, in4, in5, in6, in7
  378. tr_4x4_8 \in0, \in2, \in4, \in6, q8, q9, q10, q11, q12, q13, q14, q15
  379. vmull.s16 q14, \in1, \in0[2]
  380. vmull.s16 q12, \in1, \in0[0]
  381. vmull.s16 q13, \in1, \in0[1]
  382. sum_sub q14, \in3, \in0[0], -
  383. sum_sub q12, \in3, \in0[1], +
  384. sum_sub q13, \in3, \in0[3], -
  385. sum_sub q14, \in5, \in0[3], +
  386. sum_sub q12, \in5, \in0[2], +
  387. sum_sub q13, \in5, \in0[0], -
  388. sum_sub q14, \in7, \in0[1], +
  389. sum_sub q12, \in7, \in0[3], +
  390. sum_sub q13, \in7, \in0[2], -
  391. vadd.s32 q15, q10, q14
  392. vsub.s32 q10, q10, q14
  393. vqrshrn.s32 \in2, q15, \shift
  394. vmull.s16 q15, \in1, \in0[3]
  395. sum_sub q15, \in3, \in0[2], -
  396. sum_sub q15, \in5, \in0[1], +
  397. sum_sub q15, \in7, \in0[0], -
  398. vqrshrn.s32 \in5, q10, \shift
  399. vadd.s32 q10, q8, q12
  400. vsub.s32 q8, q8, q12
  401. vadd.s32 q12, q9, q13
  402. vsub.s32 q9, q9, q13
  403. vadd.s32 q14, q11, q15
  404. vsub.s32 q11, q11, q15
  405. vqrshrn.s32 \in0, q10, \shift
  406. vqrshrn.s32 \in7, q8, \shift
  407. vqrshrn.s32 \in1, q12, \shift
  408. vqrshrn.s32 \in6, q9, \shift
  409. vqrshrn.s32 \in3, q14, \shift
  410. vqrshrn.s32 \in4, q11, \shift
  411. .endm
  412. .macro idct_8x8 bitdepth
  413. function ff_hevc_idct_8x8_\bitdepth\()_neon, export=1
  414. @r0 - coeffs
  415. vpush {q4-q7}
  416. mov r1, r0
  417. mov r2, #64
  418. add r3, r0, #32
  419. vld1.s16 {q0-q1}, [r1,:128], r2
  420. vld1.s16 {q2-q3}, [r3,:128], r2
  421. vld1.s16 {q4-q5}, [r1,:128], r2
  422. vld1.s16 {q6-q7}, [r3,:128], r2
  423. movrel r1, trans
  424. tr_8x4 7, d0, d2, d4, d6, d8, d10, d12, d14
  425. tr_8x4 7, d1, d3, d5, d7, d9, d11, d13, d15
  426. @ Transpose each 4x4 block, and swap how d4-d7 and d8-d11 are used.
  427. @ Layout before:
  428. @ d0 d1
  429. @ d2 d3
  430. @ d4 d5
  431. @ d6 d7
  432. @ d8 d9
  433. @ d10 d11
  434. @ d12 d13
  435. @ d14 d15
  436. transpose_8x8 d0, d2, d4, d6, d8, d10, d12, d14, d1, d3, d5, d7, d9, d11, d13, d15
  437. @ Now the layout is:
  438. @ d0 d8
  439. @ d2 d10
  440. @ d4 d12
  441. @ d6 d14
  442. @ d1 d9
  443. @ d3 d11
  444. @ d5 d13
  445. @ d7 d15
  446. tr_8x4 20 - \bitdepth, d0, d2, d4, d6, d1, d3, d5, d7
  447. vswp d0, d8
  448. tr_8x4 20 - \bitdepth, d0, d10, d12, d14, d9, d11, d13, d15
  449. vswp d0, d8
  450. transpose_8x8 d0, d2, d4, d6, d8, d10, d12, d14, d1, d3, d5, d7, d9, d11, d13, d15
  451. mov r1, r0
  452. mov r2, #64
  453. add r3, r0, #32
  454. vst1.s16 {q0-q1}, [r1,:128], r2
  455. vst1.s16 {q2-q3}, [r3,:128], r2
  456. vst1.s16 {q4-q5}, [r1,:128], r2
  457. vst1.s16 {q6-q7}, [r3,:128], r2
  458. vpop {q4-q7}
  459. bx lr
  460. endfunc
  461. .endm
  462. .macro butterfly e, o, tmp_p, tmp_m
  463. vadd.s32 \tmp_p, \e, \o
  464. vsub.s32 \tmp_m, \e, \o
  465. .endm
  466. .macro tr16_8x4 in0, in1, in2, in3, in4, in5, in6, in7, offset
  467. tr_4x4_8 \in0, \in2, \in4, \in6, q8, q9, q10, q11, q12, q13, q14, q15
  468. vmull.s16 q12, \in1, \in0[0]
  469. vmull.s16 q13, \in1, \in0[1]
  470. vmull.s16 q14, \in1, \in0[2]
  471. vmull.s16 q15, \in1, \in0[3]
  472. sum_sub q12, \in3, \in0[1], +
  473. sum_sub q13, \in3, \in0[3], -
  474. sum_sub q14, \in3, \in0[0], -
  475. sum_sub q15, \in3, \in0[2], -
  476. sum_sub q12, \in5, \in0[2], +
  477. sum_sub q13, \in5, \in0[0], -
  478. sum_sub q14, \in5, \in0[3], +
  479. sum_sub q15, \in5, \in0[1], +
  480. sum_sub q12, \in7, \in0[3], +
  481. sum_sub q13, \in7, \in0[2], -
  482. sum_sub q14, \in7, \in0[1], +
  483. sum_sub q15, \in7, \in0[0], -
  484. butterfly q8, q12, q0, q7
  485. butterfly q9, q13, q1, q6
  486. butterfly q10, q14, q2, q5
  487. butterfly q11, q15, q3, q4
  488. add r4, sp, #\offset
  489. vst1.s32 {q0-q1}, [r4, :128]!
  490. vst1.s32 {q2-q3}, [r4, :128]!
  491. vst1.s32 {q4-q5}, [r4, :128]!
  492. vst1.s32 {q6-q7}, [r4, :128]
  493. .endm
  494. .macro load16 in0, in1, in2, in3, in4, in5, in6, in7
  495. vld1.s16 {\in0}, [r1, :64], r2
  496. vld1.s16 {\in1}, [r3, :64], r2
  497. vld1.s16 {\in2}, [r1, :64], r2
  498. vld1.s16 {\in3}, [r3, :64], r2
  499. vld1.s16 {\in4}, [r1, :64], r2
  500. vld1.s16 {\in5}, [r3, :64], r2
  501. vld1.s16 {\in6}, [r1, :64], r2
  502. vld1.s16 {\in7}, [r3, :64], r2
  503. .endm
  504. .macro add_member in, t0, t1, t2, t3, t4, t5, t6, t7, op0, op1, op2, op3, op4, op5, op6, op7
  505. sum_sub q5, \in, \t0, \op0
  506. sum_sub q6, \in, \t1, \op1
  507. sum_sub q7, \in, \t2, \op2
  508. sum_sub q8, \in, \t3, \op3
  509. sum_sub q9, \in, \t4, \op4
  510. sum_sub q10, \in, \t5, \op5
  511. sum_sub q11, \in, \t6, \op6
  512. sum_sub q12, \in, \t7, \op7
  513. .endm
  514. .macro butterfly16 in0, in1, in2, in3, in4, in5, in6, in7
  515. vadd.s32 q4, \in0, \in1
  516. vsub.s32 \in0, \in0, \in1
  517. vadd.s32 \in1, \in2, \in3
  518. vsub.s32 \in2, \in2, \in3
  519. vadd.s32 \in3, \in4, \in5
  520. vsub.s32 \in4, \in4, \in5
  521. vadd.s32 \in5, \in6, \in7
  522. vsub.s32 \in6, \in6, \in7
  523. .endm
  524. .macro store16 in0, in1, in2, in3, in4, in5, in6, in7, rx
  525. vst1.s16 \in0, [r1, :64], r2
  526. vst1.s16 \in1, [r3, :64], \rx
  527. vst1.s16 \in2, [r1, :64], r2
  528. vst1.s16 \in3, [r3, :64], \rx
  529. vst1.s16 \in4, [r1, :64], r2
  530. vst1.s16 \in5, [r3, :64], \rx
  531. vst1.s16 \in6, [r1, :64], r2
  532. vst1.s16 \in7, [r3, :64], \rx
  533. .endm
  534. .macro scale out0, out1, out2, out3, out4, out5, out6, out7, in0, in1, in2, in3, in4, in5, in6, in7, shift
  535. vqrshrn.s32 \out0, \in0, \shift
  536. vqrshrn.s32 \out1, \in1, \shift
  537. vqrshrn.s32 \out2, \in2, \shift
  538. vqrshrn.s32 \out3, \in3, \shift
  539. vqrshrn.s32 \out4, \in4, \shift
  540. vqrshrn.s32 \out5, \in5, \shift
  541. vqrshrn.s32 \out6, \in6, \shift
  542. vqrshrn.s32 \out7, \in7, \shift
  543. .endm
  544. @stores in1, in2, in4, in6 ascending from off1 and
  545. @stores in1, in3, in5, in7 descending from off2
  546. .macro store_to_stack off1, off2, in0, in2, in4, in6, in7, in5, in3, in1
  547. add r1, sp, #\off1
  548. add r3, sp, #\off2
  549. mov r2, #-16
  550. vst1.s32 {\in0}, [r1, :128]!
  551. vst1.s32 {\in1}, [r3, :128], r2
  552. vst1.s32 {\in2}, [r1, :128]!
  553. vst1.s32 {\in3}, [r3, :128], r2
  554. vst1.s32 {\in4}, [r1, :128]!
  555. vst1.s32 {\in5}, [r3, :128], r2
  556. vst1.s32 {\in6}, [r1, :128]
  557. vst1.s32 {\in7}, [r3, :128]
  558. .endm
  559. .macro tr_16x4 name, shift, offset, step
  560. function func_tr_16x4_\name
  561. mov r1, r5
  562. add r3, r5, #(\step * 64)
  563. mov r2, #(\step * 128)
  564. load16 d0, d1, d2, d3, d4, d5, d6, d7
  565. movrel r1, trans
  566. tr16_8x4 d0, d1, d2, d3, d4, d5, d6, d7, \offset
  567. add r1, r5, #(\step * 32)
  568. add r3, r5, #(\step * 3 *32)
  569. mov r2, #(\step * 128)
  570. load16 d8, d9, d2, d3, d4, d5, d6, d7
  571. movrel r1, trans + 16
  572. vld1.s16 {q0}, [r1, :128]
  573. vmull.s16 q5, d8, d0[0]
  574. vmull.s16 q6, d8, d0[1]
  575. vmull.s16 q7, d8, d0[2]
  576. vmull.s16 q8, d8, d0[3]
  577. vmull.s16 q9, d8, d1[0]
  578. vmull.s16 q10, d8, d1[1]
  579. vmull.s16 q11, d8, d1[2]
  580. vmull.s16 q12, d8, d1[3]
  581. add_member d9, d0[1], d1[0], d1[3], d1[1], d0[2], d0[0], d0[3], d1[2], +, +, +, -, -, -, -, -
  582. add_member d2, d0[2], d1[3], d0[3], d0[1], d1[2], d1[0], d0[0], d1[1], +, +, -, -, -, +, +, +
  583. add_member d3, d0[3], d1[1], d0[1], d1[3], d0[0], d1[2], d0[2], d1[0], +, -, -, +, +, +, -, -
  584. add_member d4, d1[0], d0[2], d1[2], d0[0], d1[3], d0[1], d1[1], d0[3], +, -, -, +, -, -, +, +
  585. add_member d5, d1[1], d0[0], d1[0], d1[2], d0[1], d0[3], d1[3], d0[2], +, -, +, +, -, +, +, -
  586. add_member d6, d1[2], d0[3], d0[0], d0[2], d1[1], d1[3], d1[0], d0[1], +, -, +, -, +, +, -, +
  587. add_member d7, d1[3], d1[2], d1[1], d1[0], d0[3], d0[2], d0[1], d0[0], +, -, +, -, +, -, +, -
  588. add r4, sp, #\offset
  589. vld1.s32 {q0-q1}, [r4, :128]!
  590. vld1.s32 {q2-q3}, [r4, :128]!
  591. butterfly16 q0, q5, q1, q6, q2, q7, q3, q8
  592. .if \shift > 0
  593. scale d26, d27, d28, d29, d30, d31, d16, d17, q4, q0, q5, q1, q6, q2, q7, q3, \shift
  594. transpose8_4x4 d26, d28, d30, d16
  595. transpose8_4x4 d17, d31, d29, d27
  596. mov r1, r6
  597. add r3, r6, #(24 +3*32)
  598. mov r2, #32
  599. mov r4, #-32
  600. store16 d26, d27, d28, d29, d30, d31, d16, d17, r4
  601. .else
  602. store_to_stack \offset, (\offset + 240), q4, q5, q6, q7, q3, q2, q1, q0
  603. .endif
  604. add r4, sp, #(\offset + 64)
  605. vld1.s32 {q0-q1}, [r4, :128]!
  606. vld1.s32 {q2-q3}, [r4, :128]
  607. butterfly16 q0, q9, q1, q10, q2, q11, q3, q12
  608. .if \shift > 0
  609. scale d26, d27, d28, d29, d30, d31, d8, d9, q4, q0, q9, q1, q10, q2, q11, q3, \shift
  610. transpose8_4x4 d26, d28, d30, d8
  611. transpose8_4x4 d9, d31, d29, d27
  612. add r1, r6, #8
  613. add r3, r6, #(16 + 3 * 32)
  614. mov r2, #32
  615. mov r4, #-32
  616. store16 d26, d27, d28, d29, d30, d31, d8, d9, r4
  617. .else
  618. store_to_stack (\offset + 64), (\offset + 176), q4, q9, q10, q11, q3, q2, q1, q0
  619. .endif
  620. bx lr
  621. endfunc
  622. .endm
  623. .macro idct_16x16 bitdepth
  624. function ff_hevc_idct_16x16_\bitdepth\()_neon, export=1
  625. @r0 - coeffs
  626. push {r4-r7, lr}
  627. vpush {q4-q7}
  628. @ Align the stack, allocate a temp buffer
  629. T mov r7, sp
  630. T and r7, r7, #15
  631. A and r7, sp, #15
  632. add r7, r7, #640
  633. sub sp, sp, r7
  634. .irp i, 0, 1, 2, 3
  635. add r5, r0, #(8 * \i)
  636. add r6, sp, #(8 * \i * 16)
  637. bl func_tr_16x4_firstpass
  638. .endr
  639. .irp i, 0, 1, 2, 3
  640. add r5, sp, #(8 * \i)
  641. add r6, r0, #(8 * \i * 16)
  642. bl func_tr_16x4_secondpass_\bitdepth
  643. .endr
  644. add sp, sp, r7
  645. vpop {q4-q7}
  646. pop {r4-r7, pc}
  647. endfunc
  648. .endm
  649. .macro load32
  650. add r1, r5, #64
  651. add r3, r1, #128
  652. mov r2, #256
  653. vld1.s16 {d4}, [r1, :64], r2
  654. vld1.s16 {d5}, [r3, :64], r2
  655. vld1.s16 {d6}, [r1, :64], r2
  656. vld1.s16 {d7}, [r3, :64], r2
  657. vld1.s16 {d8}, [r1, :64], r2
  658. vld1.s16 {d9}, [r3, :64], r2
  659. vld1.s16 {d10}, [r1, :64], r2
  660. vld1.s16 {d11}, [r3, :64], r2
  661. vld1.s16 {d12}, [r1, :64], r2
  662. vld1.s16 {d13}, [r3, :64], r2
  663. vld1.s16 {d14}, [r1, :64], r2
  664. vld1.s16 {d15}, [r3, :64], r2
  665. vld1.s16 {d16}, [r1, :64], r2
  666. vld1.s16 {d17}, [r3, :64], r2
  667. vld1.s16 {d18}, [r1, :64], r2
  668. vld1.s16 {d19}, [r3, :64], r2
  669. .endm
  670. .macro add_member32 in, t0, t1, t2, t3, op0, op1, op2, op3
  671. sum_sub q10, \in, \t0, \op0
  672. sum_sub q11, \in, \t1, \op1
  673. sum_sub q12, \in, \t2, \op2
  674. sum_sub q13, \in, \t3, \op3
  675. .endm
  676. .macro butterfly32 in0, in1, in2, in3
  677. vadd.s32 q1, \in0, \in1
  678. vsub.s32 \in0, \in0, \in1
  679. vadd.s32 \in1, \in2, \in3
  680. vsub.s32 \in2, \in2, \in3
  681. .endm
  682. .macro scale32 out0, out1, out2, out3, in0, in1, in2, in3, shift
  683. vqrshrn.s32 \out0, \in0, \shift
  684. vqrshrn.s32 \out1, \in1, \shift
  685. vqrshrn.s32 \out2, \in2, \shift
  686. vqrshrn.s32 \out3, \in3, \shift
  687. .endm
  688. .macro multiply in
  689. vmull.s16 q10, d4, \in[0]
  690. vmull.s16 q11, d4, \in[1]
  691. vmull.s16 q12, d4, \in[2]
  692. vmull.s16 q13, d4, \in[3]
  693. .endm
  694. .macro scale_store shift
  695. vld1.s16 {q14-q15}, [r4, :128]!
  696. butterfly32 q14, q10, q15, q11
  697. scale32 d22, d23, d20, d21, q1, q14, q10, q15, \shift
  698. vld1.s16 {q14-q15}, [r4, :128]!
  699. butterfly32 q14, q12, q15, q13
  700. scale32 d2, d3, d28, d29, q1, q14, q12, q15, \shift
  701. transpose8_4x4 d22, d20, d2, d28
  702. transpose8_4x4 d29, d3, d21, d23
  703. store16 d22, d23, d20, d21, d2, d3, d28, d29, r8
  704. @ reload multiplication coefficiens to q1
  705. vld1.s16 {q1}, [r9, :128]
  706. .endm
  707. function tr_block1
  708. multiply d0
  709. add_member32 d5, d0[1], d1[0], d1[3], d2[2], +, +, +, +
  710. add_member32 d6, d0[2], d1[3], d3[0], d3[2], +, +, +, -
  711. add_member32 d7, d0[3], d2[2], d3[2], d1[3], +, +, -, -
  712. add_member32 d8, d1[0], d3[1], d2[1], d0[0], +, +, -, -
  713. add_member32 d9, d1[1], d3[3], d1[0], d1[2], +, -, -, -
  714. add_member32 d10, d1[2], d3[0], d0[0], d3[1], +, -, -, -
  715. add_member32 d11, d1[3], d2[1], d1[1], d2[3], +, -, -, +
  716. add_member32 d12, d2[0], d1[2], d2[2], d1[0], +, -, -, +
  717. add_member32 d13, d2[1], d0[3], d3[3], d0[2], +, -, -, +
  718. add_member32 d14, d2[2], d0[1], d2[3], d2[1], +, -, +, +
  719. add_member32 d15, d2[3], d0[2], d1[2], d3[3], +, -, +, -
  720. add_member32 d16, d3[0], d1[1], d0[1], d2[0], +, -, +, -
  721. add_member32 d17, d3[1], d2[0], d0[3], d0[1], +, -, +, -
  722. add_member32 d18, d3[2], d2[3], d2[0], d1[1], +, -, +, -
  723. add_member32 d19, d3[3], d3[2], d3[1], d3[0], +, -, +, -
  724. bx lr
  725. endfunc
  726. function tr_block2
  727. multiply d1
  728. add_member32 d5, d3[1], d3[3], d3[0], d2[1], +, -, -, -
  729. add_member32 d6, d2[1], d1[0], d0[0], d1[1], -, -, -, -
  730. add_member32 d7, d0[0], d1[2], d3[1], d2[3], -, -, -, +
  731. add_member32 d8, d2[0], d3[2], d1[1], d0[3], -, +, +, +
  732. add_member32 d9, d3[2], d0[3], d1[3], d3[1], +, +, +, -
  733. add_member32 d10, d1[1], d1[3], d2[3], d0[0], +, +, -, -
  734. add_member32 d11, d0[3], d3[1], d0[1], d3[3], +, -, -, +
  735. add_member32 d12, d3[0], d0[2], d3[2], d0[1], +, -, -, +
  736. add_member32 d13, d2[2], d2[0], d1[0], d3[2], -, -, +, +
  737. add_member32 d14, d0[1], d3[0], d2[0], d0[2], -, +, +, -
  738. add_member32 d15, d1[3], d0[1], d2[2], d3[0], -, +, -, -
  739. add_member32 d16, d3[3], d2[1], d0[2], d1[0], +, +, -, +
  740. add_member32 d17, d1[2], d2[3], d3[3], d2[2], +, -, -, +
  741. add_member32 d18, d0[2], d0[1], d0[3], d1[2], +, -, +, -
  742. add_member32 d19, d2[3], d2[2], d2[1], d2[0], +, -, +, -
  743. bx lr
  744. endfunc
  745. function tr_block3
  746. multiply d2
  747. add_member32 d5, d1[2], d0[3], d0[0], d0[2], -, -, -, -
  748. add_member32 d6, d2[2], d3[3], d2[3], d1[2], -, -, +, +
  749. add_member32 d7, d1[0], d0[2], d2[1], d3[3], +, +, +, -
  750. add_member32 d8, d3[0], d2[2], d0[1], d1[3], +, -, -, -
  751. add_member32 d9, d0[2], d2[0], d3[0], d0[0], -, -, +, +
  752. add_member32 d10, d3[2], d1[0], d2[0], d2[2], -, +, +, -
  753. add_member32 d11, d0[0], d3[2], d0[2], d3[0], +, +, -, -
  754. add_member32 d12, d3[3], d0[1], d3[1], d0[3], -, -, +, +
  755. add_member32 d13, d0[1], d2[3], d1[3], d1[1], -, +, +, -
  756. add_member32 d14, d3[1], d1[3], d0[3], d3[2], +, +, -, +
  757. add_member32 d15, d0[3], d1[1], d3[2], d2[0], +, -, +, +
  758. add_member32 d16, d2[3], d3[1], d1[2], d0[1], -, -, +, -
  759. add_member32 d17, d1[1], d0[0], d1[0], d2[1], -, +, -, +
  760. add_member32 d18, d2[1], d3[0], d3[3], d3[1], +, -, +, +
  761. add_member32 d19, d1[3], d1[2], d1[1], d1[0], +, -, +, -
  762. bx lr
  763. endfunc
  764. function tr_block4
  765. multiply d3
  766. add_member32 d5, d1[1], d2[0], d2[3], d3[2], -, -, -, -
  767. add_member32 d6, d0[0], d0[3], d2[0], d3[1], +, +, +, +
  768. add_member32 d7, d2[0], d0[0], d1[1], d3[0], -, -, -, -
  769. add_member32 d8, d3[3], d1[2], d0[2], d2[3], +, +, +, +
  770. add_member32 d9, d2[1], d2[3], d0[0], d2[2], +, -, -, -
  771. add_member32 d10, d0[2], d3[3], d0[3], d2[1], -, -, +, +
  772. add_member32 d11, d1[0], d2[2], d1[2], d2[0], +, +, -, -
  773. add_member32 d12, d2[3], d1[1], d2[1], d1[3], -, -, +, +
  774. add_member32 d13, d3[1], d0[1], d3[0], d1[2], -, +, -, -
  775. add_member32 d14, d1[2], d1[0], d3[3], d1[1], +, -, +, +
  776. add_member32 d15, d0[1], d2[1], d3[1], d1[0], -, +, +, -
  777. add_member32 d16, d1[3], d3[2], d2[2], d0[3], +, -, -, +
  778. add_member32 d17, d3[2], d3[0], d1[3], d0[2], -, -, +, -
  779. add_member32 d18, d2[2], d1[3], d1[0], d0[1], -, +, -, +
  780. add_member32 d19, d0[3], d0[2], d0[1], d0[0], +, -, +, -
  781. bx lr
  782. endfunc
  783. .macro tr_32x4 name, shift
  784. function func_tr_32x4_\name
  785. mov r10, lr
  786. bl func_tr_16x4_noscale
  787. load32
  788. movrel r9, trans + 32
  789. vld1.s16 {q0}, [r9, :128]!
  790. vld1.s16 {q1}, [r9, :128]
  791. bl tr_block1
  792. add r4, sp, #2048
  793. vld1.s16 {q14-q15}, [r4, :128]!
  794. butterfly32 q14, q10, q15, q11
  795. scale32 d22, d23, d20, d21, q1, q14, q10, q15, \shift
  796. vld1.s16 {q14-q15}, [r4, :128]!
  797. butterfly32 q14, q12, q15, q13
  798. scale32 d2, d3, d28, d29, q1, q14, q12, q15, \shift
  799. transpose8_4x4 d22, d20, d2, d28
  800. transpose8_4x4 d29, d3, d21, d23
  801. mov r1, r11
  802. mov r2, #64
  803. mov r8, #-64
  804. add r3, r11, #(56 + 3 * 64)
  805. store16 d22, d23, d20, d21, d2, d3, d28, d29, r8
  806. @ reload multiplication coefficiens to q1
  807. vld1.s16 {q1}, [r9, :128]
  808. bl tr_block2
  809. add r1, r11, #8
  810. add r3, r11, #(48 + 3 * 64)
  811. mov r2, #64
  812. mov r8, #-64
  813. scale_store \shift
  814. bl tr_block3
  815. add r1, r11, #16
  816. add r3, r11, #(40 + 3 * 64)
  817. mov r2, #64
  818. mov r8, #-64
  819. scale_store \shift
  820. bl tr_block4
  821. add r1, r11, #24
  822. add r3, r11, #(32 + 3 * 64)
  823. mov r2, #64
  824. mov r8, #-64
  825. scale_store \shift
  826. bx r10
  827. endfunc
  828. .endm
  829. .macro idct_32x32 bitdepth
  830. function ff_hevc_idct_32x32_\bitdepth\()_neon, export=1
  831. @r0 - coeffs
  832. push {r4-r11, lr}
  833. vpush {q4-q7}
  834. @ Align the stack, allocate a temp buffer
  835. T mov r7, sp
  836. T and r7, r7, #15
  837. A and r7, sp, #15
  838. add r7, r7, #2432
  839. sub sp, sp, r7
  840. .irp i, 0, 1, 2, 3, 4, 5, 6, 7
  841. add r5, r0, #(8 * \i)
  842. add r11, sp, #(8 * \i * 32)
  843. bl func_tr_32x4_firstpass
  844. .endr
  845. .irp i, 0, 1, 2, 3, 4, 5, 6, 7
  846. add r5, sp, #(8 * \i)
  847. add r11, r0, #(8 * \i * 32)
  848. bl func_tr_32x4_secondpass_\bitdepth
  849. .endr
  850. add sp, sp, r7
  851. vpop {q4-q7}
  852. pop {r4-r11, pc}
  853. endfunc
  854. .endm
  855. tr_16x4 firstpass, 7, 512, 1
  856. tr_16x4 secondpass_8, 20 - 8, 512, 1
  857. tr_16x4 secondpass_10, 20 - 10, 512, 1
  858. tr_16x4 noscale, 0, 2048, 4
  859. .ltorg
  860. tr_32x4 firstpass, 7
  861. tr_32x4 secondpass_8, 20 - 8
  862. tr_32x4 secondpass_10, 20 - 10
  863. .ltorg
  864. idct_4x4 8
  865. idct_4x4_dc 8
  866. idct_4x4 10
  867. idct_4x4_dc 10
  868. idct_8x8 8
  869. idct_8x8_dc 8
  870. idct_8x8 10
  871. idct_8x8_dc 10
  872. idct_16x16 8
  873. idct_16x16_dc 8
  874. idct_16x16 10
  875. idct_16x16_dc 10
  876. idct_32x32 8
  877. idct_32x32_dc 8
  878. idct_32x32 10
  879. idct_32x32_dc 10