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.

861 lines
31KB

  1. /*
  2. * ARM NEON optimised DSP functions
  3. * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include "config.h"
  22. #include "asm.S"
  23. preserve8
  24. .fpu neon
  25. .text
  26. .macro pixels16 avg=0
  27. .if \avg
  28. mov ip, r0
  29. .endif
  30. 1: vld1.64 {d0, d1}, [r1], r2
  31. vld1.64 {d2, d3}, [r1], r2
  32. vld1.64 {d4, d5}, [r1], r2
  33. pld [r1, r2, lsl #2]
  34. vld1.64 {d6, d7}, [r1], r2
  35. pld [r1]
  36. pld [r1, r2]
  37. pld [r1, r2, lsl #1]
  38. .if \avg
  39. vld1.64 {d16,d17}, [ip,:128], r2
  40. vrhadd.u8 q0, q0, q8
  41. vld1.64 {d18,d19}, [ip,:128], r2
  42. vrhadd.u8 q1, q1, q9
  43. vld1.64 {d20,d21}, [ip,:128], r2
  44. vrhadd.u8 q2, q2, q10
  45. vld1.64 {d22,d23}, [ip,:128], r2
  46. vrhadd.u8 q3, q3, q11
  47. .endif
  48. subs r3, r3, #4
  49. vst1.64 {d0, d1}, [r0,:128], r2
  50. vst1.64 {d2, d3}, [r0,:128], r2
  51. vst1.64 {d4, d5}, [r0,:128], r2
  52. vst1.64 {d6, d7}, [r0,:128], r2
  53. bne 1b
  54. bx lr
  55. .endm
  56. .macro pixels16_x2 vhadd=vrhadd.u8
  57. 1: vld1.64 {d0-d2}, [r1], r2
  58. vld1.64 {d4-d6}, [r1], r2
  59. pld [r1]
  60. pld [r1, r2]
  61. subs r3, r3, #2
  62. vext.8 q1, q0, q1, #1
  63. \vhadd q0, q0, q1
  64. vext.8 q3, q2, q3, #1
  65. \vhadd q2, q2, q3
  66. vst1.64 {d0, d1}, [r0,:128], r2
  67. vst1.64 {d4, d5}, [r0,:128], r2
  68. bne 1b
  69. bx lr
  70. .endm
  71. .macro pixels16_y2 vhadd=vrhadd.u8
  72. vld1.64 {d0, d1}, [r1], r2
  73. vld1.64 {d2, d3}, [r1], r2
  74. 1: subs r3, r3, #2
  75. \vhadd q2, q0, q1
  76. vld1.64 {d0, d1}, [r1], r2
  77. \vhadd q3, q0, q1
  78. vld1.64 {d2, d3}, [r1], r2
  79. pld [r1]
  80. pld [r1, r2]
  81. vst1.64 {d4, d5}, [r0,:128], r2
  82. vst1.64 {d6, d7}, [r0,:128], r2
  83. bne 1b
  84. bx lr
  85. .endm
  86. .macro pixels16_xy2 vshrn=vrshrn.u16 no_rnd=0
  87. vld1.64 {d0-d2}, [r1], r2
  88. vld1.64 {d4-d6}, [r1], r2
  89. .if \no_rnd
  90. vmov.i16 q13, #1
  91. .endif
  92. pld [r1]
  93. pld [r1, r2]
  94. vext.8 q1, q0, q1, #1
  95. vext.8 q3, q2, q3, #1
  96. vaddl.u8 q8, d0, d2
  97. vaddl.u8 q10, d1, d3
  98. vaddl.u8 q9, d4, d6
  99. vaddl.u8 q11, d5, d7
  100. 1: subs r3, r3, #2
  101. vld1.64 {d0-d2}, [r1], r2
  102. vadd.u16 q12, q8, q9
  103. pld [r1]
  104. .if \no_rnd
  105. vadd.u16 q12, q12, q13
  106. .endif
  107. vext.8 q15, q0, q1, #1
  108. vadd.u16 q1 , q10, q11
  109. \vshrn d28, q12, #2
  110. .if \no_rnd
  111. vadd.u16 q1, q1, q13
  112. .endif
  113. \vshrn d29, q1, #2
  114. vaddl.u8 q8, d0, d30
  115. vld1.64 {d2-d4}, [r1], r2
  116. vaddl.u8 q10, d1, d31
  117. vst1.64 {d28,d29}, [r0,:128], r2
  118. vadd.u16 q12, q8, q9
  119. pld [r1, r2]
  120. .if \no_rnd
  121. vadd.u16 q12, q12, q13
  122. .endif
  123. vext.8 q2, q1, q2, #1
  124. vadd.u16 q0, q10, q11
  125. \vshrn d30, q12, #2
  126. .if \no_rnd
  127. vadd.u16 q0, q0, q13
  128. .endif
  129. \vshrn d31, q0, #2
  130. vaddl.u8 q9, d2, d4
  131. vaddl.u8 q11, d3, d5
  132. vst1.64 {d30,d31}, [r0,:128], r2
  133. bgt 1b
  134. bx lr
  135. .endm
  136. .macro pixels8
  137. 1: vld1.64 {d0}, [r1], r2
  138. vld1.64 {d1}, [r1], r2
  139. vld1.64 {d2}, [r1], r2
  140. pld [r1, r2, lsl #2]
  141. vld1.64 {d3}, [r1], r2
  142. pld [r1]
  143. pld [r1, r2]
  144. pld [r1, r2, lsl #1]
  145. subs r3, r3, #4
  146. vst1.64 {d0}, [r0,:64], r2
  147. vst1.64 {d1}, [r0,:64], r2
  148. vst1.64 {d2}, [r0,:64], r2
  149. vst1.64 {d3}, [r0,:64], r2
  150. bne 1b
  151. bx lr
  152. .endm
  153. .macro pixels8_x2 vhadd=vrhadd.u8
  154. 1: vld1.64 {d0, d1}, [r1], r2
  155. vext.8 d1, d0, d1, #1
  156. vld1.64 {d2, d3}, [r1], r2
  157. vext.8 d3, d2, d3, #1
  158. pld [r1]
  159. pld [r1, r2]
  160. subs r3, r3, #2
  161. vswp d1, d2
  162. \vhadd q0, q0, q1
  163. vst1.64 {d0}, [r0,:64], r2
  164. vst1.64 {d1}, [r0,:64], r2
  165. bne 1b
  166. bx lr
  167. .endm
  168. .macro pixels8_y2 vhadd=vrhadd.u8
  169. vld1.64 {d0}, [r1], r2
  170. vld1.64 {d1}, [r1], r2
  171. 1: subs r3, r3, #2
  172. \vhadd d4, d0, d1
  173. vld1.64 {d0}, [r1], r2
  174. \vhadd d5, d0, d1
  175. vld1.64 {d1}, [r1], r2
  176. pld [r1]
  177. pld [r1, r2]
  178. vst1.64 {d4}, [r0,:64], r2
  179. vst1.64 {d5}, [r0,:64], r2
  180. bne 1b
  181. bx lr
  182. .endm
  183. .macro pixels8_xy2 vshrn=vrshrn.u16 no_rnd=0
  184. vld1.64 {d0, d1}, [r1], r2
  185. vld1.64 {d2, d3}, [r1], r2
  186. .if \no_rnd
  187. vmov.i16 q11, #1
  188. .endif
  189. pld [r1]
  190. pld [r1, r2]
  191. vext.8 d4, d0, d1, #1
  192. vext.8 d6, d2, d3, #1
  193. vaddl.u8 q8, d0, d4
  194. vaddl.u8 q9, d2, d6
  195. 1: subs r3, r3, #2
  196. vld1.64 {d0, d1}, [r1], r2
  197. pld [r1]
  198. vadd.u16 q10, q8, q9
  199. vext.8 d4, d0, d1, #1
  200. .if \no_rnd
  201. vadd.u16 q10, q10, q11
  202. .endif
  203. vaddl.u8 q8, d0, d4
  204. \vshrn d5, q10, #2
  205. vld1.64 {d2, d3}, [r1], r2
  206. vadd.u16 q10, q8, q9
  207. pld [r1, r2]
  208. .if \no_rnd
  209. vadd.u16 q10, q10, q11
  210. .endif
  211. vst1.64 {d5}, [r0,:64], r2
  212. \vshrn d7, q10, #2
  213. vext.8 d6, d2, d3, #1
  214. vaddl.u8 q9, d2, d6
  215. vst1.64 {d7}, [r0,:64], r2
  216. bgt 1b
  217. bx lr
  218. .endm
  219. .macro pixfunc pfx name suf rnd_op args:vararg
  220. function ff_\pfx\name\suf\()_neon, export=1
  221. \name \rnd_op \args
  222. .endfunc
  223. .endm
  224. .macro pixfunc2 pfx name args:vararg
  225. pixfunc \pfx \name
  226. pixfunc \pfx \name \args
  227. .endm
  228. function ff_put_h264_qpel16_mc00_neon, export=1
  229. mov r3, #16
  230. .endfunc
  231. pixfunc put_ pixels16
  232. pixfunc2 put_ pixels16_x2, _no_rnd, vhadd.u8
  233. pixfunc2 put_ pixels16_y2, _no_rnd, vhadd.u8
  234. pixfunc2 put_ pixels16_xy2, _no_rnd, vshrn.u16, 1
  235. function ff_avg_h264_qpel16_mc00_neon, export=1
  236. mov r3, #16
  237. .endfunc
  238. pixfunc avg_ pixels16,, 1
  239. function ff_put_h264_qpel8_mc00_neon, export=1
  240. mov r3, #8
  241. .endfunc
  242. pixfunc put_ pixels8
  243. pixfunc2 put_ pixels8_x2, _no_rnd, vhadd.u8
  244. pixfunc2 put_ pixels8_y2, _no_rnd, vhadd.u8
  245. pixfunc2 put_ pixels8_xy2, _no_rnd, vshrn.u16, 1
  246. function ff_put_pixels_clamped_neon, export=1
  247. vld1.64 {d16-d19}, [r0,:128]!
  248. vqmovun.s16 d0, q8
  249. vld1.64 {d20-d23}, [r0,:128]!
  250. vqmovun.s16 d1, q9
  251. vld1.64 {d24-d27}, [r0,:128]!
  252. vqmovun.s16 d2, q10
  253. vld1.64 {d28-d31}, [r0,:128]!
  254. vqmovun.s16 d3, q11
  255. vst1.64 {d0}, [r1,:64], r2
  256. vqmovun.s16 d4, q12
  257. vst1.64 {d1}, [r1,:64], r2
  258. vqmovun.s16 d5, q13
  259. vst1.64 {d2}, [r1,:64], r2
  260. vqmovun.s16 d6, q14
  261. vst1.64 {d3}, [r1,:64], r2
  262. vqmovun.s16 d7, q15
  263. vst1.64 {d4}, [r1,:64], r2
  264. vst1.64 {d5}, [r1,:64], r2
  265. vst1.64 {d6}, [r1,:64], r2
  266. vst1.64 {d7}, [r1,:64], r2
  267. bx lr
  268. .endfunc
  269. function ff_put_signed_pixels_clamped_neon, export=1
  270. vmov.u8 d31, #128
  271. vld1.64 {d16-d17}, [r0,:128]!
  272. vqmovn.s16 d0, q8
  273. vld1.64 {d18-d19}, [r0,:128]!
  274. vqmovn.s16 d1, q9
  275. vld1.64 {d16-d17}, [r0,:128]!
  276. vqmovn.s16 d2, q8
  277. vld1.64 {d18-d19}, [r0,:128]!
  278. vadd.u8 d0, d0, d31
  279. vld1.64 {d20-d21}, [r0,:128]!
  280. vadd.u8 d1, d1, d31
  281. vld1.64 {d22-d23}, [r0,:128]!
  282. vadd.u8 d2, d2, d31
  283. vst1.64 {d0}, [r1,:64], r2
  284. vqmovn.s16 d3, q9
  285. vst1.64 {d1}, [r1,:64], r2
  286. vqmovn.s16 d4, q10
  287. vst1.64 {d2}, [r1,:64], r2
  288. vqmovn.s16 d5, q11
  289. vld1.64 {d24-d25}, [r0,:128]!
  290. vadd.u8 d3, d3, d31
  291. vld1.64 {d26-d27}, [r0,:128]!
  292. vadd.u8 d4, d4, d31
  293. vadd.u8 d5, d5, d31
  294. vst1.64 {d3}, [r1,:64], r2
  295. vqmovn.s16 d6, q12
  296. vst1.64 {d4}, [r1,:64], r2
  297. vqmovn.s16 d7, q13
  298. vst1.64 {d5}, [r1,:64], r2
  299. vadd.u8 d6, d6, d31
  300. vadd.u8 d7, d7, d31
  301. vst1.64 {d6}, [r1,:64], r2
  302. vst1.64 {d7}, [r1,:64], r2
  303. bx lr
  304. .endfunc
  305. function ff_add_pixels_clamped_neon, export=1
  306. mov r3, r1
  307. vld1.64 {d16}, [r1,:64], r2
  308. vld1.64 {d0-d1}, [r0,:128]!
  309. vaddw.u8 q0, q0, d16
  310. vld1.64 {d17}, [r1,:64], r2
  311. vld1.64 {d2-d3}, [r0,:128]!
  312. vqmovun.s16 d0, q0
  313. vld1.64 {d18}, [r1,:64], r2
  314. vaddw.u8 q1, q1, d17
  315. vld1.64 {d4-d5}, [r0,:128]!
  316. vaddw.u8 q2, q2, d18
  317. vst1.64 {d0}, [r3,:64], r2
  318. vqmovun.s16 d2, q1
  319. vld1.64 {d19}, [r1,:64], r2
  320. vld1.64 {d6-d7}, [r0,:128]!
  321. vaddw.u8 q3, q3, d19
  322. vqmovun.s16 d4, q2
  323. vst1.64 {d2}, [r3,:64], r2
  324. vld1.64 {d16}, [r1,:64], r2
  325. vqmovun.s16 d6, q3
  326. vld1.64 {d0-d1}, [r0,:128]!
  327. vaddw.u8 q0, q0, d16
  328. vst1.64 {d4}, [r3,:64], r2
  329. vld1.64 {d17}, [r1,:64], r2
  330. vld1.64 {d2-d3}, [r0,:128]!
  331. vaddw.u8 q1, q1, d17
  332. vst1.64 {d6}, [r3,:64], r2
  333. vqmovun.s16 d0, q0
  334. vld1.64 {d18}, [r1,:64], r2
  335. vld1.64 {d4-d5}, [r0,:128]!
  336. vaddw.u8 q2, q2, d18
  337. vst1.64 {d0}, [r3,:64], r2
  338. vqmovun.s16 d2, q1
  339. vld1.64 {d19}, [r1,:64], r2
  340. vqmovun.s16 d4, q2
  341. vld1.64 {d6-d7}, [r0,:128]!
  342. vaddw.u8 q3, q3, d19
  343. vst1.64 {d2}, [r3,:64], r2
  344. vqmovun.s16 d6, q3
  345. vst1.64 {d4}, [r3,:64], r2
  346. vst1.64 {d6}, [r3,:64], r2
  347. bx lr
  348. .endfunc
  349. function ff_float_to_int16_neon, export=1
  350. subs r2, r2, #8
  351. vld1.64 {d0-d1}, [r1,:128]!
  352. vcvt.s32.f32 q8, q0, #16
  353. vld1.64 {d2-d3}, [r1,:128]!
  354. vcvt.s32.f32 q9, q1, #16
  355. beq 3f
  356. bics ip, r2, #15
  357. beq 2f
  358. 1: subs ip, ip, #16
  359. vshrn.s32 d4, q8, #16
  360. vld1.64 {d0-d1}, [r1,:128]!
  361. vcvt.s32.f32 q0, q0, #16
  362. vshrn.s32 d5, q9, #16
  363. vld1.64 {d2-d3}, [r1,:128]!
  364. vcvt.s32.f32 q1, q1, #16
  365. vshrn.s32 d6, q0, #16
  366. vst1.64 {d4-d5}, [r0,:128]!
  367. vshrn.s32 d7, q1, #16
  368. vld1.64 {d16-d17},[r1,:128]!
  369. vcvt.s32.f32 q8, q8, #16
  370. vld1.64 {d18-d19},[r1,:128]!
  371. vcvt.s32.f32 q9, q9, #16
  372. vst1.64 {d6-d7}, [r0,:128]!
  373. bne 1b
  374. ands r2, r2, #15
  375. beq 3f
  376. 2: vld1.64 {d0-d1}, [r1,:128]!
  377. vshrn.s32 d4, q8, #16
  378. vcvt.s32.f32 q0, q0, #16
  379. vld1.64 {d2-d3}, [r1,:128]!
  380. vshrn.s32 d5, q9, #16
  381. vcvt.s32.f32 q1, q1, #16
  382. vshrn.s32 d6, q0, #16
  383. vst1.64 {d4-d5}, [r0,:128]!
  384. vshrn.s32 d7, q1, #16
  385. vst1.64 {d6-d7}, [r0,:128]!
  386. bx lr
  387. 3: vshrn.s32 d4, q8, #16
  388. vshrn.s32 d5, q9, #16
  389. vst1.64 {d4-d5}, [r0,:128]!
  390. bx lr
  391. .endfunc
  392. function ff_float_to_int16_interleave_neon, export=1
  393. cmp r3, #2
  394. ldrlt r1, [r1]
  395. blt ff_float_to_int16_neon
  396. bne 4f
  397. ldr r3, [r1]
  398. ldr r1, [r1, #4]
  399. subs r2, r2, #8
  400. vld1.64 {d0-d1}, [r3,:128]!
  401. vcvt.s32.f32 q8, q0, #16
  402. vld1.64 {d2-d3}, [r3,:128]!
  403. vcvt.s32.f32 q9, q1, #16
  404. vld1.64 {d20-d21},[r1,:128]!
  405. vcvt.s32.f32 q10, q10, #16
  406. vld1.64 {d22-d23},[r1,:128]!
  407. vcvt.s32.f32 q11, q11, #16
  408. beq 3f
  409. bics ip, r2, #15
  410. beq 2f
  411. 1: subs ip, ip, #16
  412. vld1.64 {d0-d1}, [r3,:128]!
  413. vcvt.s32.f32 q0, q0, #16
  414. vsri.32 q10, q8, #16
  415. vld1.64 {d2-d3}, [r3,:128]!
  416. vcvt.s32.f32 q1, q1, #16
  417. vld1.64 {d24-d25},[r1,:128]!
  418. vcvt.s32.f32 q12, q12, #16
  419. vld1.64 {d26-d27},[r1,:128]!
  420. vsri.32 q11, q9, #16
  421. vst1.64 {d20-d21},[r0,:128]!
  422. vcvt.s32.f32 q13, q13, #16
  423. vst1.64 {d22-d23},[r0,:128]!
  424. vsri.32 q12, q0, #16
  425. vld1.64 {d16-d17},[r3,:128]!
  426. vsri.32 q13, q1, #16
  427. vst1.64 {d24-d25},[r0,:128]!
  428. vcvt.s32.f32 q8, q8, #16
  429. vld1.64 {d18-d19},[r3,:128]!
  430. vcvt.s32.f32 q9, q9, #16
  431. vld1.64 {d20-d21},[r1,:128]!
  432. vcvt.s32.f32 q10, q10, #16
  433. vld1.64 {d22-d23},[r1,:128]!
  434. vcvt.s32.f32 q11, q11, #16
  435. vst1.64 {d26-d27},[r0,:128]!
  436. bne 1b
  437. ands r2, r2, #15
  438. beq 3f
  439. 2: vsri.32 q10, q8, #16
  440. vld1.64 {d0-d1}, [r3,:128]!
  441. vcvt.s32.f32 q0, q0, #16
  442. vld1.64 {d2-d3}, [r3,:128]!
  443. vcvt.s32.f32 q1, q1, #16
  444. vld1.64 {d24-d25},[r1,:128]!
  445. vcvt.s32.f32 q12, q12, #16
  446. vsri.32 q11, q9, #16
  447. vld1.64 {d26-d27},[r1,:128]!
  448. vcvt.s32.f32 q13, q13, #16
  449. vst1.64 {d20-d21},[r0,:128]!
  450. vsri.32 q12, q0, #16
  451. vst1.64 {d22-d23},[r0,:128]!
  452. vsri.32 q13, q1, #16
  453. vst1.64 {d24-d27},[r0,:128]!
  454. bx lr
  455. 3: vsri.32 q10, q8, #16
  456. vsri.32 q11, q9, #16
  457. vst1.64 {d20-d23},[r0,:128]!
  458. bx lr
  459. 4: push {r4-r8,lr}
  460. cmp r3, #4
  461. lsl ip, r3, #1
  462. blt 4f
  463. @ 4 channels
  464. 5: ldmia r1!, {r4-r7}
  465. mov lr, r2
  466. mov r8, r0
  467. vld1.64 {d16-d17},[r4,:128]!
  468. vcvt.s32.f32 q8, q8, #16
  469. vld1.64 {d18-d19},[r5,:128]!
  470. vcvt.s32.f32 q9, q9, #16
  471. vld1.64 {d20-d21},[r6,:128]!
  472. vcvt.s32.f32 q10, q10, #16
  473. vld1.64 {d22-d23},[r7,:128]!
  474. vcvt.s32.f32 q11, q11, #16
  475. 6: subs lr, lr, #8
  476. vld1.64 {d0-d1}, [r4,:128]!
  477. vcvt.s32.f32 q0, q0, #16
  478. vsri.32 q9, q8, #16
  479. vld1.64 {d2-d3}, [r5,:128]!
  480. vcvt.s32.f32 q1, q1, #16
  481. vsri.32 q11, q10, #16
  482. vld1.64 {d4-d5}, [r6,:128]!
  483. vcvt.s32.f32 q2, q2, #16
  484. vzip.32 d18, d22
  485. vld1.64 {d6-d7}, [r7,:128]!
  486. vcvt.s32.f32 q3, q3, #16
  487. vzip.32 d19, d23
  488. vst1.64 {d18}, [r8], ip
  489. vsri.32 q1, q0, #16
  490. vst1.64 {d22}, [r8], ip
  491. vsri.32 q3, q2, #16
  492. vst1.64 {d19}, [r8], ip
  493. vzip.32 d2, d6
  494. vst1.64 {d23}, [r8], ip
  495. vzip.32 d3, d7
  496. beq 7f
  497. vld1.64 {d16-d17},[r4,:128]!
  498. vcvt.s32.f32 q8, q8, #16
  499. vst1.64 {d2}, [r8], ip
  500. vld1.64 {d18-d19},[r5,:128]!
  501. vcvt.s32.f32 q9, q9, #16
  502. vst1.64 {d6}, [r8], ip
  503. vld1.64 {d20-d21},[r6,:128]!
  504. vcvt.s32.f32 q10, q10, #16
  505. vst1.64 {d3}, [r8], ip
  506. vld1.64 {d22-d23},[r7,:128]!
  507. vcvt.s32.f32 q11, q11, #16
  508. vst1.64 {d7}, [r8], ip
  509. b 6b
  510. 7: vst1.64 {d2}, [r8], ip
  511. vst1.64 {d6}, [r8], ip
  512. vst1.64 {d3}, [r8], ip
  513. vst1.64 {d7}, [r8], ip
  514. subs r3, r3, #4
  515. popeq {r4-r8,pc}
  516. cmp r3, #4
  517. add r0, r0, #8
  518. bge 5b
  519. @ 2 channels
  520. 4: cmp r3, #2
  521. blt 4f
  522. ldmia r1!, {r4-r5}
  523. mov lr, r2
  524. mov r8, r0
  525. tst lr, #8
  526. vld1.64 {d16-d17},[r4,:128]!
  527. vcvt.s32.f32 q8, q8, #16
  528. vld1.64 {d18-d19},[r5,:128]!
  529. vcvt.s32.f32 q9, q9, #16
  530. vld1.64 {d20-d21},[r4,:128]!
  531. vcvt.s32.f32 q10, q10, #16
  532. vld1.64 {d22-d23},[r5,:128]!
  533. vcvt.s32.f32 q11, q11, #16
  534. beq 6f
  535. subs lr, lr, #8
  536. beq 7f
  537. vsri.32 d18, d16, #16
  538. vsri.32 d19, d17, #16
  539. vld1.64 {d16-d17},[r4,:128]!
  540. vcvt.s32.f32 q8, q8, #16
  541. vst1.32 {d18[0]}, [r8], ip
  542. vsri.32 d22, d20, #16
  543. vst1.32 {d18[1]}, [r8], ip
  544. vsri.32 d23, d21, #16
  545. vst1.32 {d19[0]}, [r8], ip
  546. vst1.32 {d19[1]}, [r8], ip
  547. vld1.64 {d18-d19},[r5,:128]!
  548. vcvt.s32.f32 q9, q9, #16
  549. vst1.32 {d22[0]}, [r8], ip
  550. vst1.32 {d22[1]}, [r8], ip
  551. vld1.64 {d20-d21},[r4,:128]!
  552. vcvt.s32.f32 q10, q10, #16
  553. vst1.32 {d23[0]}, [r8], ip
  554. vst1.32 {d23[1]}, [r8], ip
  555. vld1.64 {d22-d23},[r5,:128]!
  556. vcvt.s32.f32 q11, q11, #16
  557. 6: subs lr, lr, #16
  558. vld1.64 {d0-d1}, [r4,:128]!
  559. vcvt.s32.f32 q0, q0, #16
  560. vsri.32 d18, d16, #16
  561. vld1.64 {d2-d3}, [r5,:128]!
  562. vcvt.s32.f32 q1, q1, #16
  563. vsri.32 d19, d17, #16
  564. vld1.64 {d4-d5}, [r4,:128]!
  565. vcvt.s32.f32 q2, q2, #16
  566. vld1.64 {d6-d7}, [r5,:128]!
  567. vcvt.s32.f32 q3, q3, #16
  568. vst1.32 {d18[0]}, [r8], ip
  569. vsri.32 d22, d20, #16
  570. vst1.32 {d18[1]}, [r8], ip
  571. vsri.32 d23, d21, #16
  572. vst1.32 {d19[0]}, [r8], ip
  573. vsri.32 d2, d0, #16
  574. vst1.32 {d19[1]}, [r8], ip
  575. vsri.32 d3, d1, #16
  576. vst1.32 {d22[0]}, [r8], ip
  577. vsri.32 d6, d4, #16
  578. vst1.32 {d22[1]}, [r8], ip
  579. vsri.32 d7, d5, #16
  580. vst1.32 {d23[0]}, [r8], ip
  581. vst1.32 {d23[1]}, [r8], ip
  582. beq 6f
  583. vld1.64 {d16-d17},[r4,:128]!
  584. vcvt.s32.f32 q8, q8, #16
  585. vst1.32 {d2[0]}, [r8], ip
  586. vst1.32 {d2[1]}, [r8], ip
  587. vld1.64 {d18-d19},[r5,:128]!
  588. vcvt.s32.f32 q9, q9, #16
  589. vst1.32 {d3[0]}, [r8], ip
  590. vst1.32 {d3[1]}, [r8], ip
  591. vld1.64 {d20-d21},[r4,:128]!
  592. vcvt.s32.f32 q10, q10, #16
  593. vst1.32 {d6[0]}, [r8], ip
  594. vst1.32 {d6[1]}, [r8], ip
  595. vld1.64 {d22-d23},[r5,:128]!
  596. vcvt.s32.f32 q11, q11, #16
  597. vst1.32 {d7[0]}, [r8], ip
  598. vst1.32 {d7[1]}, [r8], ip
  599. bgt 6b
  600. 6: vst1.32 {d2[0]}, [r8], ip
  601. vst1.32 {d2[1]}, [r8], ip
  602. vst1.32 {d3[0]}, [r8], ip
  603. vst1.32 {d3[1]}, [r8], ip
  604. vst1.32 {d6[0]}, [r8], ip
  605. vst1.32 {d6[1]}, [r8], ip
  606. vst1.32 {d7[0]}, [r8], ip
  607. vst1.32 {d7[1]}, [r8], ip
  608. b 8f
  609. 7: vsri.32 d18, d16, #16
  610. vsri.32 d19, d17, #16
  611. vst1.32 {d18[0]}, [r8], ip
  612. vsri.32 d22, d20, #16
  613. vst1.32 {d18[1]}, [r8], ip
  614. vsri.32 d23, d21, #16
  615. vst1.32 {d19[0]}, [r8], ip
  616. vst1.32 {d19[1]}, [r8], ip
  617. vst1.32 {d22[0]}, [r8], ip
  618. vst1.32 {d22[1]}, [r8], ip
  619. vst1.32 {d23[0]}, [r8], ip
  620. vst1.32 {d23[1]}, [r8], ip
  621. 8: subs r3, r3, #2
  622. add r0, r0, #4
  623. popeq {r4-r8,pc}
  624. @ 1 channel
  625. 4: ldr r4, [r1],#4
  626. tst r2, #8
  627. mov lr, r2
  628. mov r5, r0
  629. vld1.64 {d0-d1}, [r4,:128]!
  630. vcvt.s32.f32 q0, q0, #16
  631. vld1.64 {d2-d3}, [r4,:128]!
  632. vcvt.s32.f32 q1, q1, #16
  633. bne 8f
  634. 6: subs lr, lr, #16
  635. vld1.64 {d4-d5}, [r4,:128]!
  636. vcvt.s32.f32 q2, q2, #16
  637. vld1.64 {d6-d7}, [r4,:128]!
  638. vcvt.s32.f32 q3, q3, #16
  639. vst1.16 {d0[1]}, [r5,:16], ip
  640. vst1.16 {d0[3]}, [r5,:16], ip
  641. vst1.16 {d1[1]}, [r5,:16], ip
  642. vst1.16 {d1[3]}, [r5,:16], ip
  643. vst1.16 {d2[1]}, [r5,:16], ip
  644. vst1.16 {d2[3]}, [r5,:16], ip
  645. vst1.16 {d3[1]}, [r5,:16], ip
  646. vst1.16 {d3[3]}, [r5,:16], ip
  647. beq 7f
  648. vld1.64 {d0-d1}, [r4,:128]!
  649. vcvt.s32.f32 q0, q0, #16
  650. vld1.64 {d2-d3}, [r4,:128]!
  651. vcvt.s32.f32 q1, q1, #16
  652. 7: vst1.16 {d4[1]}, [r5,:16], ip
  653. vst1.16 {d4[3]}, [r5,:16], ip
  654. vst1.16 {d5[1]}, [r5,:16], ip
  655. vst1.16 {d5[3]}, [r5,:16], ip
  656. vst1.16 {d6[1]}, [r5,:16], ip
  657. vst1.16 {d6[3]}, [r5,:16], ip
  658. vst1.16 {d7[1]}, [r5,:16], ip
  659. vst1.16 {d7[3]}, [r5,:16], ip
  660. bgt 6b
  661. pop {r4-r8,pc}
  662. 8: subs lr, lr, #8
  663. vst1.16 {d0[1]}, [r5,:16], ip
  664. vst1.16 {d0[3]}, [r5,:16], ip
  665. vst1.16 {d1[1]}, [r5,:16], ip
  666. vst1.16 {d1[3]}, [r5,:16], ip
  667. vst1.16 {d2[1]}, [r5,:16], ip
  668. vst1.16 {d2[3]}, [r5,:16], ip
  669. vst1.16 {d3[1]}, [r5,:16], ip
  670. vst1.16 {d3[3]}, [r5,:16], ip
  671. popeq {r4-r8,pc}
  672. vld1.64 {d0-d1}, [r4,:128]!
  673. vcvt.s32.f32 q0, q0, #16
  674. vld1.64 {d2-d3}, [r4,:128]!
  675. vcvt.s32.f32 q1, q1, #16
  676. b 6b
  677. .endfunc
  678. function ff_vector_fmul_neon, export=1
  679. mov r3, r0
  680. subs r2, r2, #8
  681. vld1.64 {d0-d3}, [r0,:128]!
  682. vld1.64 {d4-d7}, [r1,:128]!
  683. vmul.f32 q8, q0, q2
  684. vmul.f32 q9, q1, q3
  685. beq 3f
  686. bics ip, r2, #15
  687. beq 2f
  688. 1: subs ip, ip, #16
  689. vld1.64 {d0-d1}, [r0,:128]!
  690. vld1.64 {d4-d5}, [r1,:128]!
  691. vmul.f32 q10, q0, q2
  692. vld1.64 {d2-d3}, [r0,:128]!
  693. vld1.64 {d6-d7}, [r1,:128]!
  694. vmul.f32 q11, q1, q3
  695. vst1.64 {d16-d19},[r3,:128]!
  696. vld1.64 {d0-d1}, [r0,:128]!
  697. vld1.64 {d4-d5}, [r1,:128]!
  698. vmul.f32 q8, q0, q2
  699. vld1.64 {d2-d3}, [r0,:128]!
  700. vld1.64 {d6-d7}, [r1,:128]!
  701. vmul.f32 q9, q1, q3
  702. vst1.64 {d20-d23},[r3,:128]!
  703. bne 1b
  704. ands r2, r2, #15
  705. beq 3f
  706. 2: vld1.64 {d0-d1}, [r0,:128]!
  707. vld1.64 {d4-d5}, [r1,:128]!
  708. vst1.64 {d16-d17},[r3,:128]!
  709. vmul.f32 q8, q0, q2
  710. vld1.64 {d2-d3}, [r0,:128]!
  711. vld1.64 {d6-d7}, [r1,:128]!
  712. vst1.64 {d18-d19},[r3,:128]!
  713. vmul.f32 q9, q1, q3
  714. 3: vst1.64 {d16-d19},[r3,:128]!
  715. bx lr
  716. .endfunc
  717. function ff_vector_fmul_window_neon, export=1
  718. VFP vdup.32 q8, d0[0]
  719. NOVFP vld1.32 {d16[],d17[]}, [sp,:32]
  720. push {r4,r5,lr}
  721. VFP ldr lr, [sp, #12]
  722. NOVFP ldr lr, [sp, #16]
  723. sub r2, r2, #8
  724. sub r5, lr, #2
  725. add r2, r2, r5, lsl #2
  726. add r4, r3, r5, lsl #3
  727. add ip, r0, r5, lsl #3
  728. mov r5, #-16
  729. vld1.64 {d0,d1}, [r1,:128]!
  730. vld1.64 {d2,d3}, [r2,:128], r5
  731. vld1.64 {d4,d5}, [r3,:128]!
  732. vld1.64 {d6,d7}, [r4,:128], r5
  733. 1: subs lr, lr, #4
  734. vmov q11, q8
  735. vmla.f32 d22, d0, d4
  736. vmov q10, q8
  737. vmla.f32 d23, d1, d5
  738. vrev64.32 q3, q3
  739. vmla.f32 d20, d0, d7
  740. vrev64.32 q1, q1
  741. vmla.f32 d21, d1, d6
  742. beq 2f
  743. vmla.f32 d22, d3, d7
  744. vld1.64 {d0,d1}, [r1,:128]!
  745. vmla.f32 d23, d2, d6
  746. vld1.64 {d18,d19},[r2,:128], r5
  747. vmls.f32 d20, d3, d4
  748. vld1.64 {d24,d25},[r3,:128]!
  749. vmls.f32 d21, d2, d5
  750. vld1.64 {d6,d7}, [r4,:128], r5
  751. vmov q1, q9
  752. vrev64.32 q11, q11
  753. vmov q2, q12
  754. vswp d22, d23
  755. vst1.64 {d20,d21},[r0,:128]!
  756. vst1.64 {d22,d23},[ip,:128], r5
  757. b 1b
  758. 2: vmla.f32 d22, d3, d7
  759. vmla.f32 d23, d2, d6
  760. vmls.f32 d20, d3, d4
  761. vmls.f32 d21, d2, d5
  762. vrev64.32 q11, q11
  763. vswp d22, d23
  764. vst1.64 {d20,d21},[r0,:128]!
  765. vst1.64 {d22,d23},[ip,:128], r5
  766. pop {r4,r5,pc}
  767. .endfunc
  768. #if CONFIG_VORBIS_DECODER
  769. function ff_vorbis_inverse_coupling_neon, export=1
  770. vmov.i32 q10, #1<<31
  771. subs r2, r2, #4
  772. mov r3, r0
  773. mov r12, r1
  774. beq 3f
  775. vld1.32 {d24-d25},[r1,:128]!
  776. vld1.32 {d22-d23},[r0,:128]!
  777. vcle.s32 q8, q12, #0
  778. vand q9, q11, q10
  779. veor q12, q12, q9
  780. vand q2, q12, q8
  781. vbic q3, q12, q8
  782. vadd.f32 q12, q11, q2
  783. vsub.f32 q11, q11, q3
  784. 1: vld1.32 {d2-d3}, [r1,:128]!
  785. vld1.32 {d0-d1}, [r0,:128]!
  786. vcle.s32 q8, q1, #0
  787. vand q9, q0, q10
  788. veor q1, q1, q9
  789. vst1.32 {d24-d25},[r3, :128]!
  790. vst1.32 {d22-d23},[r12,:128]!
  791. vand q2, q1, q8
  792. vbic q3, q1, q8
  793. vadd.f32 q1, q0, q2
  794. vsub.f32 q0, q0, q3
  795. subs r2, r2, #8
  796. ble 2f
  797. vld1.32 {d24-d25},[r1,:128]!
  798. vld1.32 {d22-d23},[r0,:128]!
  799. vcle.s32 q8, q12, #0
  800. vand q9, q11, q10
  801. veor q12, q12, q9
  802. vst1.32 {d2-d3}, [r3, :128]!
  803. vst1.32 {d0-d1}, [r12,:128]!
  804. vand q2, q12, q8
  805. vbic q3, q12, q8
  806. vadd.f32 q12, q11, q2
  807. vsub.f32 q11, q11, q3
  808. b 1b
  809. 2: vst1.32 {d2-d3}, [r3, :128]!
  810. vst1.32 {d0-d1}, [r12,:128]!
  811. bxlt lr
  812. 3: vld1.32 {d2-d3}, [r1,:128]
  813. vld1.32 {d0-d1}, [r0,:128]
  814. vcle.s32 q8, q1, #0
  815. vand q9, q0, q10
  816. veor q1, q1, q9
  817. vand q2, q1, q8
  818. vbic q3, q1, q8
  819. vadd.f32 q1, q0, q2
  820. vsub.f32 q0, q0, q3
  821. vst1.32 {d2-d3}, [r0,:128]!
  822. vst1.32 {d0-d1}, [r1,:128]!
  823. bx lr
  824. .endfunc
  825. #endif