dct-a.S 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. /****************************************************************************
  2. * dct-a.S: arm transform and zigzag
  3. *****************************************************************************
  4. * Copyright (C) 2009-2018 x264 project
  5. *
  6. * Authors: David Conrad <lessen42@gmail.com>
  7. * Martin Storsjo <martin@martin.st>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program 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
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
  22. *
  23. * This program is also available under a commercial proprietary license.
  24. * For more information, contact us at licensing@x264.com.
  25. *****************************************************************************/
  26. #include "asm.S"
  27. const scan4x4_frame, align=4
  28. .byte 0,1, 8,9, 2,3, 4,5
  29. .byte 2,3, 8,9, 16,17, 10,11
  30. .byte 12,13, 6,7, 14,15, 20,21
  31. .byte 10,11, 12,13, 6,7, 14,15
  32. endconst
  33. .text
  34. // sum = a + (b>>shift) sub = (a>>shift) - b
  35. .macro SUMSUB_SHR shift sum sub a b t0 t1
  36. vshr.s16 \t0, \b, #\shift
  37. vshr.s16 \t1, \a, #\shift
  38. vadd.s16 \sum, \a, \t0
  39. vsub.s16 \sub, \t1, \b
  40. .endm
  41. // sum = (a>>shift) + b sub = a - (b>>shift)
  42. .macro SUMSUB_SHR2 shift sum sub a b t0 t1
  43. vshr.s16 \t0, \a, #\shift
  44. vshr.s16 \t1, \b, #\shift
  45. vadd.s16 \sum, \t0, \b
  46. vsub.s16 \sub, \a, \t1
  47. .endm
  48. // a += 1.5*ma b -= 1.5*mb
  49. .macro SUMSUB_15 a b ma mb t0 t1
  50. vshr.s16 \t0, \ma, #1
  51. vshr.s16 \t1, \mb, #1
  52. vadd.s16 \t0, \t0, \ma
  53. vadd.s16 \t1, \t1, \mb
  54. vadd.s16 \a, \a, \t0
  55. vsub.s16 \b, \b, \t1
  56. .endm
  57. function dct4x4dc_neon
  58. vld1.64 {d0-d3}, [r0,:128]
  59. SUMSUB_ABCD d4, d5, d6, d7, d0, d1, d2, d3
  60. SUMSUB_ABCD d0, d2, d3, d1, d4, d6, d5, d7
  61. vmov.s16 d31, #1
  62. HADAMARD 1, sumsub, q2, q3, q0, q1
  63. vtrn.32 d4, d5
  64. vadd.s16 d16, d4, d31
  65. vtrn.32 d6, d7
  66. vadd.s16 d17, d6, d31
  67. vrhadd.s16 d0, d4, d5
  68. vhsub.s16 d1, d16, d5
  69. vhsub.s16 d2, d17, d7
  70. vrhadd.s16 d3, d6, d7
  71. vst1.64 {d0-d3}, [r0,:128]
  72. bx lr
  73. endfunc
  74. function idct4x4dc_neon
  75. vld1.64 {d0-d3}, [r0,:128]
  76. SUMSUB_ABCD d4, d5, d6, d7, d0, d1, d2, d3
  77. SUMSUB_ABCD d0, d2, d3, d1, d4, d6, d5, d7
  78. HADAMARD 1, sumsub, q2, q3, q0, q1
  79. HADAMARD 2, sumsub, d0, d1, d4, d5
  80. HADAMARD 2, sumsub, d3, d2, d6, d7
  81. vst1.64 {d0-d3}, [r0,:128]
  82. bx lr
  83. endfunc
  84. .macro DCT_1D d0 d1 d2 d3 d4 d5 d6 d7
  85. SUMSUB_AB \d1, \d6, \d5, \d6
  86. SUMSUB_AB \d3, \d7, \d4, \d7
  87. vadd.s16 \d0, \d3, \d1
  88. vadd.s16 \d4, \d7, \d7
  89. vadd.s16 \d5, \d6, \d6
  90. vsub.s16 \d2, \d3, \d1
  91. vadd.s16 \d1, \d4, \d6
  92. vsub.s16 \d3, \d7, \d5
  93. .endm
  94. function sub4x4_dct_neon
  95. mov r3, #FENC_STRIDE
  96. mov ip, #FDEC_STRIDE
  97. vld1.32 {d0[]}, [r1,:32], r3
  98. vld1.32 {d1[]}, [r2,:32], ip
  99. vld1.32 {d2[]}, [r1,:32], r3
  100. vsubl.u8 q8, d0, d1
  101. vld1.32 {d3[]}, [r2,:32], ip
  102. vld1.32 {d4[]}, [r1,:32], r3
  103. vsubl.u8 q9, d2, d3
  104. vld1.32 {d5[]}, [r2,:32], ip
  105. vld1.32 {d6[]}, [r1,:32], r3
  106. vsubl.u8 q10, d4, d5
  107. vld1.32 {d7[]}, [r2,:32], ip
  108. vsubl.u8 q11, d6, d7
  109. DCT_1D d0, d1, d2, d3, d16, d18, d20, d22
  110. TRANSPOSE4x4_16 d0, d1, d2, d3
  111. DCT_1D d4, d5, d6, d7, d0, d1, d2, d3
  112. vst1.64 {d4-d7}, [r0,:128]
  113. bx lr
  114. endfunc
  115. function sub8x4_dct_neon, export=0
  116. vld1.64 {d0}, [r1,:64], r3
  117. vld1.64 {d1}, [r2,:64], ip
  118. vsubl.u8 q8, d0, d1
  119. vld1.64 {d2}, [r1,:64], r3
  120. vld1.64 {d3}, [r2,:64], ip
  121. vsubl.u8 q9, d2, d3
  122. vld1.64 {d4}, [r1,:64], r3
  123. vld1.64 {d5}, [r2,:64], ip
  124. vsubl.u8 q10, d4, d5
  125. vld1.64 {d6}, [r1,:64], r3
  126. vld1.64 {d7}, [r2,:64], ip
  127. vsubl.u8 q11, d6, d7
  128. DCT_1D q0, q1, q2, q3, q8, q9, q10, q11
  129. TRANSPOSE4x4_16 q0, q1, q2, q3
  130. SUMSUB_AB q8, q12, q0, q3
  131. SUMSUB_AB q9, q10, q1, q2
  132. vadd.i16 q13, q12, q12
  133. vadd.i16 q11, q10, q10
  134. vadd.i16 d0, d16, d18
  135. vadd.i16 d1, d26, d20
  136. vsub.i16 d2, d16, d18
  137. vsub.i16 d3, d24, d22
  138. vst1.64 {d0-d1}, [r0,:128]!
  139. vadd.i16 d4, d17, d19
  140. vadd.i16 d5, d27, d21
  141. vst1.64 {d2-d3}, [r0,:128]!
  142. vsub.i16 d6, d17, d19
  143. vsub.i16 d7, d25, d23
  144. vst1.64 {d4-d5}, [r0,:128]!
  145. vst1.64 {d6-d7}, [r0,:128]!
  146. bx lr
  147. endfunc
  148. function sub8x8_dct_neon
  149. push {lr}
  150. mov r3, #FENC_STRIDE
  151. mov ip, #FDEC_STRIDE
  152. bl sub8x4_dct_neon
  153. pop {lr}
  154. b sub8x4_dct_neon
  155. endfunc
  156. function sub16x16_dct_neon
  157. push {lr}
  158. mov r3, #FENC_STRIDE
  159. mov ip, #FDEC_STRIDE
  160. bl sub8x4_dct_neon
  161. bl sub8x4_dct_neon
  162. sub r1, r1, #8*FENC_STRIDE-8
  163. sub r2, r2, #8*FDEC_STRIDE-8
  164. bl sub8x4_dct_neon
  165. bl sub8x4_dct_neon
  166. sub r1, r1, #8
  167. sub r2, r2, #8
  168. bl sub8x4_dct_neon
  169. bl sub8x4_dct_neon
  170. sub r1, r1, #8*FENC_STRIDE-8
  171. sub r2, r2, #8*FDEC_STRIDE-8
  172. bl sub8x4_dct_neon
  173. pop {lr}
  174. b sub8x4_dct_neon
  175. endfunc
  176. .macro DCT8_1D type
  177. SUMSUB_AB q2, q1, q11, q12 // s34/d34
  178. SUMSUB_AB q3, q11, q10, q13 // s25/d25
  179. SUMSUB_AB q13, q10, q9, q14 // s16/d16
  180. SUMSUB_AB q14, q8, q8, q15 // s07/d07
  181. SUMSUB_AB q9, q2, q14, q2 // a0/a2
  182. SUMSUB_AB q12, q14, q13, q3 // a1/a3
  183. SUMSUB_AB q3, q13, q8, q1 // a6/a5
  184. vshr.s16 q0, q10, #1
  185. vshr.s16 q15, q11, #1
  186. vadd.s16 q0, q0, q10
  187. vadd.s16 q15, q15, q11
  188. vsub.s16 q3, q3, q0
  189. vsub.s16 q13, q13, q15
  190. SUMSUB_AB q0, q15, q10, q11 // a4/a7
  191. vshr.s16 q10, q8, #1
  192. vshr.s16 q11, q1, #1
  193. vadd.s16 q10, q10, q8
  194. vadd.s16 q11, q11, q1
  195. vadd.s16 q10, q0, q10
  196. vadd.s16 q15, q15, q11
  197. SUMSUB_AB q8, q12, q9, q12
  198. SUMSUB_SHR 2, q9, q15, q10, q15, q0, q1
  199. SUMSUB_SHR 1, q10, q14, q2, q14, q0, q1
  200. SUMSUB_SHR2 2, q11, q13, q3, q13, q0, q1
  201. .endm
  202. function sub8x8_dct8_neon
  203. mov r3, #FENC_STRIDE
  204. mov ip, #FDEC_STRIDE
  205. vld1.64 {d16}, [r1,:64], r3
  206. vld1.64 {d17}, [r2,:64], ip
  207. vsubl.u8 q8, d16, d17
  208. vld1.64 {d18}, [r1,:64], r3
  209. vld1.64 {d19}, [r2,:64], ip
  210. vsubl.u8 q9, d18, d19
  211. vld1.64 {d20}, [r1,:64], r3
  212. vld1.64 {d21}, [r2,:64], ip
  213. vsubl.u8 q10, d20, d21
  214. vld1.64 {d22}, [r1,:64], r3
  215. vld1.64 {d23}, [r2,:64], ip
  216. vsubl.u8 q11, d22, d23
  217. vld1.64 {d24}, [r1,:64], r3
  218. vld1.64 {d25}, [r2,:64], ip
  219. vsubl.u8 q12, d24, d25
  220. vld1.64 {d26}, [r1,:64], r3
  221. vld1.64 {d27}, [r2,:64], ip
  222. vsubl.u8 q13, d26, d27
  223. vld1.64 {d28}, [r1,:64], r3
  224. vld1.64 {d29}, [r2,:64], ip
  225. vsubl.u8 q14, d28, d29
  226. vld1.64 {d30}, [r1,:64], r3
  227. vld1.64 {d31}, [r2,:64], ip
  228. vsubl.u8 q15, d30, d31
  229. DCT8_1D row
  230. vswp d17, d24 // 8, 12
  231. vswp d21, d28 // 10,14
  232. vtrn.32 q8, q10
  233. vtrn.32 q12, q14
  234. vswp d19, d26 // 9, 13
  235. vswp d23, d30 // 11,15
  236. vtrn.32 q9, q11
  237. vtrn.32 q13, q15
  238. vtrn.16 q10, q11
  239. vtrn.16 q12, q13
  240. vtrn.16 q8, q9
  241. vtrn.16 q14, q15
  242. DCT8_1D col
  243. vst1.64 {d16-d19}, [r0,:128]!
  244. vst1.64 {d20-d23}, [r0,:128]!
  245. vst1.64 {d24-d27}, [r0,:128]!
  246. vst1.64 {d28-d31}, [r0,:128]!
  247. bx lr
  248. endfunc
  249. function sub16x16_dct8_neon
  250. push {lr}
  251. bl X(sub8x8_dct8_neon)
  252. sub r1, r1, #FENC_STRIDE*8 - 8
  253. sub r2, r2, #FDEC_STRIDE*8 - 8
  254. bl X(sub8x8_dct8_neon)
  255. sub r1, r1, #8
  256. sub r2, r2, #8
  257. bl X(sub8x8_dct8_neon)
  258. pop {lr}
  259. sub r1, r1, #FENC_STRIDE*8 - 8
  260. sub r2, r2, #FDEC_STRIDE*8 - 8
  261. b X(sub8x8_dct8_neon)
  262. endfunc
  263. // First part of IDCT (minus final SUMSUB_BA)
  264. .macro IDCT_1D d4 d5 d6 d7 d0 d1 d2 d3
  265. SUMSUB_AB \d4, \d5, \d0, \d2
  266. vshr.s16 \d7, \d1, #1
  267. vshr.s16 \d6, \d3, #1
  268. vsub.s16 \d7, \d7, \d3
  269. vadd.s16 \d6, \d6, \d1
  270. .endm
  271. function add4x4_idct_neon
  272. mov r2, #FDEC_STRIDE
  273. vld1.64 {d0-d3}, [r1,:128]
  274. IDCT_1D d4, d5, d6, d7, d0, d1, d2, d3
  275. vld1.32 {d30[0]}, [r0,:32], r2
  276. SUMSUB_AB q0, q1, q2, q3
  277. TRANSPOSE4x4_16 d0, d1, d3, d2
  278. IDCT_1D d4, d5, d6, d7, d0, d1, d3, d2
  279. vld1.32 {d30[1]}, [r0,:32], r2
  280. SUMSUB_AB q0, q1, q2, q3
  281. vrshr.s16 q0, q0, #6
  282. vld1.32 {d31[1]}, [r0,:32], r2
  283. vrshr.s16 q1, q1, #6
  284. vld1.32 {d31[0]}, [r0,:32], r2
  285. sub r0, r0, r2, lsl #2
  286. vaddw.u8 q0, q0, d30
  287. vaddw.u8 q1, q1, d31
  288. vqmovun.s16 d0, q0
  289. vqmovun.s16 d2, q1
  290. vst1.32 {d0[0]}, [r0,:32], r2
  291. vst1.32 {d0[1]}, [r0,:32], r2
  292. vst1.32 {d2[1]}, [r0,:32], r2
  293. vst1.32 {d2[0]}, [r0,:32], r2
  294. bx lr
  295. endfunc
  296. function add8x4_idct_neon, export=0
  297. vld1.64 {d0-d3}, [r1,:128]!
  298. IDCT_1D d16, d18, d20, d22, d0, d1, d2, d3
  299. vld1.64 {d4-d7}, [r1,:128]!
  300. IDCT_1D d17, d19, d21, d23, d4, d5, d6, d7
  301. SUMSUB_AB q0, q3, q8, q10
  302. SUMSUB_AB q1, q2, q9, q11
  303. TRANSPOSE4x4_16 q0, q1, q2, q3
  304. IDCT_1D q8, q9, q10, q11, q0, q1, q2, q3
  305. SUMSUB_AB q0, q3, q8, q10
  306. SUMSUB_AB q1, q2, q9, q11
  307. vrshr.s16 q0, q0, #6
  308. vld1.32 {d28}, [r0,:64], r2
  309. vrshr.s16 q1, q1, #6
  310. vld1.32 {d29}, [r0,:64], r2
  311. vrshr.s16 q2, q2, #6
  312. vld1.32 {d30}, [r0,:64], r2
  313. vrshr.s16 q3, q3, #6
  314. vld1.32 {d31}, [r0,:64], r2
  315. sub r0, r0, r2, lsl #2
  316. vaddw.u8 q0, q0, d28
  317. vaddw.u8 q1, q1, d29
  318. vaddw.u8 q2, q2, d30
  319. vaddw.u8 q3, q3, d31
  320. vqmovun.s16 d0, q0
  321. vqmovun.s16 d1, q1
  322. vst1.32 {d0}, [r0,:64], r2
  323. vqmovun.s16 d2, q2
  324. vst1.32 {d1}, [r0,:64], r2
  325. vqmovun.s16 d3, q3
  326. vst1.32 {d2}, [r0,:64], r2
  327. vst1.32 {d3}, [r0,:64], r2
  328. bx lr
  329. endfunc
  330. function add8x8_idct_neon
  331. mov r2, #FDEC_STRIDE
  332. mov ip, lr
  333. bl add8x4_idct_neon
  334. mov lr, ip
  335. b add8x4_idct_neon
  336. endfunc
  337. function add16x16_idct_neon
  338. mov r2, #FDEC_STRIDE
  339. mov ip, lr
  340. bl add8x4_idct_neon
  341. bl add8x4_idct_neon
  342. sub r0, r0, #8*FDEC_STRIDE-8
  343. bl add8x4_idct_neon
  344. bl add8x4_idct_neon
  345. sub r0, r0, #8
  346. bl add8x4_idct_neon
  347. bl add8x4_idct_neon
  348. sub r0, r0, #8*FDEC_STRIDE-8
  349. bl add8x4_idct_neon
  350. mov lr, ip
  351. b add8x4_idct_neon
  352. endfunc
  353. .macro IDCT8_1D type
  354. .ifc \type, col
  355. vswp d21, d28
  356. .endif
  357. SUMSUB_AB q0, q1, q8, q12 // a0/a2
  358. .ifc \type, row
  359. vld1.64 {d28-d31}, [r1,:128]!
  360. .else
  361. vswp d19, d26
  362. .endif
  363. SUMSUB_SHR 1, q2, q3, q10, q14, q8, q12 // a6/a4
  364. .ifc \type, col
  365. vswp d23, d30
  366. .endif
  367. SUMSUB_AB q8, q10, q13, q11
  368. SUMSUB_15 q8, q10, q9, q15, q12, q14 // a7/a1
  369. SUMSUB_AB q14, q15, q15, q9
  370. SUMSUB_15 q15, q14, q13, q11, q12, q9 // a5/a3
  371. SUMSUB_SHR 2, q13, q14, q14, q15, q11, q9 // b3/b5
  372. SUMSUB_SHR2 2, q12, q15, q8, q10, q11, q9 // b1/b7
  373. SUMSUB_AB q10, q2, q0, q2 // b0/b6
  374. SUMSUB_AB q11, q3, q1, q3 // b2/b4
  375. SUMSUB_AB q8, q15, q10, q15
  376. SUMSUB_AB q9, q14, q11, q14
  377. SUMSUB_AB q10, q13, q3, q13
  378. .ifc \type, row
  379. vtrn.16 q8, q9
  380. .endif
  381. SUMSUB_AB q11, q12, q2, q12
  382. .endm
  383. function add8x8_idct8_neon
  384. mov r2, #FDEC_STRIDE
  385. vld1.64 {d16-d19}, [r1,:128]!
  386. vld1.64 {d20-d23}, [r1,:128]!
  387. vld1.64 {d24-d27}, [r1,:128]!
  388. IDCT8_1D row
  389. vtrn.16 q10, q11
  390. vtrn.16 q12, q13
  391. vtrn.16 q14, q15
  392. vtrn.32 q8, q10
  393. vtrn.32 q9, q11
  394. vtrn.32 q12, q14
  395. vtrn.32 q13, q15
  396. vswp d17, d24
  397. IDCT8_1D col
  398. vld1.64 {d0}, [r0,:64], r2
  399. vrshr.s16 q8, q8, #6
  400. vld1.64 {d1}, [r0,:64], r2
  401. vrshr.s16 q9, q9, #6
  402. vld1.64 {d2}, [r0,:64], r2
  403. vrshr.s16 q10, q10, #6
  404. vld1.64 {d3}, [r0,:64], r2
  405. vrshr.s16 q11, q11, #6
  406. vld1.64 {d4}, [r0,:64], r2
  407. vrshr.s16 q12, q12, #6
  408. vld1.64 {d5}, [r0,:64], r2
  409. vrshr.s16 q13, q13, #6
  410. vld1.64 {d6}, [r0,:64], r2
  411. vrshr.s16 q14, q14, #6
  412. vld1.64 {d7}, [r0,:64], r2
  413. vrshr.s16 q15, q15, #6
  414. sub r0, r0, r2, lsl #3
  415. vaddw.u8 q8, q8, d0
  416. vaddw.u8 q9, q9, d1
  417. vaddw.u8 q10, q10, d2
  418. vqmovun.s16 d0, q8
  419. vqmovun.s16 d1, q9
  420. vqmovun.s16 d2, q10
  421. vaddw.u8 q11, q11, d3
  422. vst1.64 {d0}, [r0,:64], r2
  423. vaddw.u8 q12, q12, d4
  424. vst1.64 {d1}, [r0,:64], r2
  425. vaddw.u8 q13, q13, d5
  426. vst1.64 {d2}, [r0,:64], r2
  427. vqmovun.s16 d3, q11
  428. vqmovun.s16 d4, q12
  429. vaddw.u8 q14, q14, d6
  430. vaddw.u8 q15, q15, d7
  431. vst1.64 {d3}, [r0,:64], r2
  432. vqmovun.s16 d5, q13
  433. vst1.64 {d4}, [r0,:64], r2
  434. vqmovun.s16 d6, q14
  435. vqmovun.s16 d7, q15
  436. vst1.64 {d5}, [r0,:64], r2
  437. vst1.64 {d6}, [r0,:64], r2
  438. vst1.64 {d7}, [r0,:64], r2
  439. bx lr
  440. endfunc
  441. function add16x16_idct8_neon
  442. mov ip, lr
  443. bl X(add8x8_idct8_neon)
  444. sub r0, r0, #8*FDEC_STRIDE-8
  445. bl X(add8x8_idct8_neon)
  446. sub r0, r0, #8
  447. bl X(add8x8_idct8_neon)
  448. sub r0, r0, #8*FDEC_STRIDE-8
  449. mov lr, ip
  450. b X(add8x8_idct8_neon)
  451. endfunc
  452. function add8x8_idct_dc_neon
  453. mov r2, #FDEC_STRIDE
  454. vld1.64 {d16}, [r1,:64]
  455. vrshr.s16 d16, d16, #6
  456. vld1.64 {d0}, [r0,:64], r2
  457. vmov.i16 q15, #0
  458. vld1.64 {d1}, [r0,:64], r2
  459. vld1.64 {d2}, [r0,:64], r2
  460. vdup.16 d20, d16[0]
  461. vld1.64 {d3}, [r0,:64], r2
  462. vdup.16 d21, d16[1]
  463. vld1.64 {d4}, [r0,:64], r2
  464. vdup.16 d22, d16[2]
  465. vld1.64 {d5}, [r0,:64], r2
  466. vdup.16 d23, d16[3]
  467. vld1.64 {d6}, [r0,:64], r2
  468. vsub.s16 q12, q15, q10
  469. vld1.64 {d7}, [r0,:64], r2
  470. vsub.s16 q13, q15, q11
  471. sub r0, r0, #8*FDEC_STRIDE
  472. vqmovun.s16 d20, q10
  473. vqmovun.s16 d22, q11
  474. vqmovun.s16 d24, q12
  475. vqmovun.s16 d26, q13
  476. vmov d21, d20
  477. vqadd.u8 q0, q0, q10
  478. vmov d23, d22
  479. vqadd.u8 q1, q1, q10
  480. vmov d25, d24
  481. vqadd.u8 q2, q2, q11
  482. vmov d27, d26
  483. vqadd.u8 q3, q3, q11
  484. vqsub.u8 q0, q0, q12
  485. vqsub.u8 q1, q1, q12
  486. vqsub.u8 q2, q2, q13
  487. vst1.64 {d0}, [r0,:64], r2
  488. vqsub.u8 q3, q3, q13
  489. vst1.64 {d1}, [r0,:64], r2
  490. vst1.64 {d2}, [r0,:64], r2
  491. vst1.64 {d3}, [r0,:64], r2
  492. vst1.64 {d4}, [r0,:64], r2
  493. vst1.64 {d5}, [r0,:64], r2
  494. vst1.64 {d6}, [r0,:64], r2
  495. vst1.64 {d7}, [r0,:64], r2
  496. bx lr
  497. endfunc
  498. .macro ADD16x4_IDCT_DC dc
  499. vld1.64 {d16-d17}, [r0,:128], r3
  500. vld1.64 {d18-d19}, [r0,:128], r3
  501. vdup.16 d4, \dc[0]
  502. vdup.16 d5, \dc[1]
  503. vld1.64 {d20-d21}, [r0,:128], r3
  504. vdup.16 d6, \dc[2]
  505. vdup.16 d7, \dc[3]
  506. vld1.64 {d22-d23}, [r0,:128], r3
  507. vsub.s16 q12, q15, q2
  508. vsub.s16 q13, q15, q3
  509. vqmovun.s16 d4, q2
  510. vqmovun.s16 d5, q3
  511. vqmovun.s16 d6, q12
  512. vqmovun.s16 d7, q13
  513. vqadd.u8 q8, q8, q2
  514. vqadd.u8 q9, q9, q2
  515. vqadd.u8 q10, q10, q2
  516. vqadd.u8 q11, q11, q2
  517. vqsub.u8 q8, q8, q3
  518. vqsub.u8 q9, q9, q3
  519. vqsub.u8 q10, q10, q3
  520. vst1.64 {d16-d17}, [r2,:128], r3
  521. vqsub.u8 q11, q11, q3
  522. vst1.64 {d18-d19}, [r2,:128], r3
  523. vst1.64 {d20-d21}, [r2,:128], r3
  524. vst1.64 {d22-d23}, [r2,:128], r3
  525. .endm
  526. function add16x16_idct_dc_neon
  527. mov r2, r0
  528. mov r3, #FDEC_STRIDE
  529. vmov.i16 q15, #0
  530. vld1.64 {d0-d3}, [r1,:64]
  531. vrshr.s16 q0, #6
  532. vrshr.s16 q1, #6
  533. ADD16x4_IDCT_DC d0
  534. ADD16x4_IDCT_DC d1
  535. ADD16x4_IDCT_DC d2
  536. ADD16x4_IDCT_DC d3
  537. bx lr
  538. endfunc
  539. function sub8x8_dct_dc_neon
  540. mov r3, #FENC_STRIDE
  541. mov ip, #FDEC_STRIDE
  542. vld1.64 {d16}, [r1,:64], r3
  543. vld1.64 {d17}, [r2,:64], ip
  544. vsubl.u8 q8, d16, d17
  545. vld1.64 {d18}, [r1,:64], r3
  546. vld1.64 {d19}, [r2,:64], ip
  547. vsubl.u8 q9, d18, d19
  548. vld1.64 {d20}, [r1,:64], r3
  549. vld1.64 {d21}, [r2,:64], ip
  550. vsubl.u8 q10, d20, d21
  551. vld1.64 {d22}, [r1,:64], r3
  552. vadd.s16 q0, q8, q9
  553. vld1.64 {d23}, [r2,:64], ip
  554. vsubl.u8 q11, d22, d23
  555. vld1.64 {d24}, [r1,:64], r3
  556. vadd.s16 q0, q0, q10
  557. vld1.64 {d25}, [r2,:64], ip
  558. vsubl.u8 q12, d24, d25
  559. vld1.64 {d26}, [r1,:64], r3
  560. vadd.s16 q0, q0, q11
  561. vld1.64 {d27}, [r2,:64], ip
  562. vsubl.u8 q13, d26, d27
  563. vld1.64 {d28}, [r1,:64], r3
  564. vld1.64 {d29}, [r2,:64], ip
  565. vsubl.u8 q14, d28, d29
  566. vld1.64 {d30}, [r1,:64], r3
  567. vadd.s16 q1, q12, q13
  568. vld1.64 {d31}, [r2,:64], ip
  569. vsubl.u8 q15, d30, d31
  570. vadd.s16 q1, q1, q14
  571. vadd.s16 d4, d0, d1
  572. vadd.s16 q1, q1, q15
  573. vsub.s16 d5, d0, d1
  574. vadd.s16 d6, d2, d3
  575. vsub.s16 d7, d2, d3
  576. vadd.s16 q0, q2, q3
  577. vsub.s16 q1, q2, q3
  578. vpadd.s16 d0, d0, d2
  579. vpadd.s16 d1, d1, d3
  580. vpadd.s16 d0, d0, d1
  581. vst1.64 {d0}, [r0,:64]
  582. bx lr
  583. endfunc
  584. function sub8x16_dct_dc_neon
  585. mov r3, #FENC_STRIDE
  586. mov ip, #FDEC_STRIDE
  587. vld1.64 {d16}, [r1,:64], r3
  588. vld1.64 {d17}, [r2,:64], ip
  589. vsubl.u8 q8, d16, d17
  590. vld1.64 {d18}, [r1,:64], r3
  591. vld1.64 {d19}, [r2,:64], ip
  592. vsubl.u8 q9, d18, d19
  593. vld1.64 {d20}, [r1,:64], r3
  594. vld1.64 {d21}, [r2,:64], ip
  595. vsubl.u8 q10, d20, d21
  596. vld1.64 {d22}, [r1,:64], r3
  597. vadd.s16 q0, q8, q9
  598. vld1.64 {d23}, [r2,:64], ip
  599. vsubl.u8 q11, d22, d23
  600. vld1.64 {d24}, [r1,:64], r3
  601. vadd.s16 q0, q0, q10
  602. vld1.64 {d25}, [r2,:64], ip
  603. vsubl.u8 q12, d24, d25
  604. vld1.64 {d26}, [r1,:64], r3
  605. vadd.s16 q0, q0, q11
  606. vld1.64 {d27}, [r2,:64], ip
  607. vsubl.u8 q13, d26, d27
  608. vld1.64 {d28}, [r1,:64], r3
  609. vld1.64 {d29}, [r2,:64], ip
  610. vsubl.u8 q14, d28, d29
  611. vld1.64 {d30}, [r1,:64], r3
  612. vadd.s16 q1, q12, q13
  613. vld1.64 {d31}, [r2,:64], ip
  614. vsubl.u8 q15, d30, d31
  615. vld1.64 {d16}, [r1,:64], r3
  616. vadd.s16 q1, q1, q14
  617. vld1.64 {d17}, [r2,:64], ip
  618. vadd.s16 q1, q1, q15
  619. vld1.64 {d18}, [r1,:64], r3
  620. vsubl.u8 q8, d16, d17
  621. vld1.64 {d19}, [r2,:64], ip
  622. vsubl.u8 q9, d18, d19
  623. vld1.64 {d20}, [r1,:64], r3
  624. vld1.64 {d21}, [r2,:64], ip
  625. vsubl.u8 q10, d20, d21
  626. vld1.64 {d22}, [r1,:64], r3
  627. vadd.s16 q2, q8, q9
  628. vld1.64 {d23}, [r2,:64], ip
  629. vsubl.u8 q11, d22, d23
  630. vld1.64 {d24}, [r1,:64], r3
  631. vadd.s16 q2, q2, q10
  632. vld1.64 {d25}, [r2,:64], ip
  633. vsubl.u8 q12, d24, d25
  634. vld1.64 {d26}, [r1,:64], r3
  635. vadd.s16 q2, q2, q11
  636. vld1.64 {d27}, [r2,:64], ip
  637. vsubl.u8 q13, d26, d27
  638. vld1.64 {d28}, [r1,:64], r3
  639. vld1.64 {d29}, [r2,:64], ip
  640. vsubl.u8 q14, d28, d29
  641. vld1.64 {d30}, [r1,:64], r3
  642. vadd.s16 q3, q12, q13
  643. vld1.64 {d31}, [r2,:64], ip
  644. vsubl.u8 q15, d30, d31
  645. vadd.s16 q3, q3, q14
  646. vadd.s16 d16, d0, d1 @ b0
  647. vadd.s16 q3, q3, q15
  648. vsub.s16 d17, d0, d1 @ b4
  649. vadd.s16 d18, d2, d3 @ b1
  650. vsub.s16 d19, d2, d3 @ b5
  651. vadd.s16 d20, d4, d5 @ b2
  652. vsub.s16 d21, d4, d5 @ b6
  653. vadd.s16 d22, d6, d7 @ b3
  654. vsub.s16 d23, d6, d7 @ b7
  655. vadd.s16 q0, q8, q9 @ b0 + b1, b4 + b5; a0, a2
  656. vsub.s16 q1, q8, q9 @ b0 - b1, b4 - b5; a4, a6
  657. vadd.s16 q2, q10, q11 @ b2 + b3, b6 + b7; a1, a3
  658. vsub.s16 q3, q10, q11 @ b2 - b3, b6 - b7; a5, a7
  659. vadd.s16 q8, q0, q2 @ a0 + a1, a2 + a3
  660. vsub.s16 q9, q0, q2 @ a0 - a1, a2 - a3
  661. vsub.s16 q10, q1, q3 @ a4 - a5, a6 - a7
  662. vadd.s16 q11, q1, q3 @ a4 + a5, a6 + a7
  663. vpadd.s16 d0, d16, d17
  664. vpadd.s16 d1, d18, d19
  665. vpadd.s16 d2, d20, d21
  666. vpadd.s16 d3, d22, d23
  667. vpadd.s16 d0, d0, d1
  668. vpadd.s16 d1, d2, d3
  669. vst1.64 {q0}, [r0,:64]
  670. bx lr
  671. endfunc
  672. function zigzag_scan_4x4_frame_neon
  673. movrel r2, scan4x4_frame
  674. vld1.64 {d0-d3}, [r1,:128]
  675. vld1.64 {d16-d19}, [r2,:128]
  676. vtbl.8 d4, {d0-d1}, d16
  677. vtbl.8 d5, {d1-d3}, d17
  678. vtbl.8 d6, {d0-d2}, d18
  679. vtbl.8 d7, {d2-d3}, d19
  680. vst1.64 {d4-d7}, [r0,:128]
  681. bx lr
  682. endfunc