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.

1163 lines
40KB

  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. .text
  25. function ff_clear_block_neon, export=1
  26. vmov.i16 q0, #0
  27. .rept 8
  28. vst1.16 {q0}, [r0,:128]!
  29. .endr
  30. bx lr
  31. endfunc
  32. function ff_clear_blocks_neon, export=1
  33. vmov.i16 q0, #0
  34. .rept 8*6
  35. vst1.16 {q0}, [r0,:128]!
  36. .endr
  37. bx lr
  38. endfunc
  39. .macro pixels16 avg=0
  40. .if \avg
  41. mov ip, r0
  42. .endif
  43. 1: vld1.64 {d0, d1}, [r1], r2
  44. vld1.64 {d2, d3}, [r1], r2
  45. vld1.64 {d4, d5}, [r1], r2
  46. pld [r1, r2, lsl #2]
  47. vld1.64 {d6, d7}, [r1], r2
  48. pld [r1]
  49. pld [r1, r2]
  50. pld [r1, r2, lsl #1]
  51. .if \avg
  52. vld1.64 {d16,d17}, [ip,:128], r2
  53. vrhadd.u8 q0, q0, q8
  54. vld1.64 {d18,d19}, [ip,:128], r2
  55. vrhadd.u8 q1, q1, q9
  56. vld1.64 {d20,d21}, [ip,:128], r2
  57. vrhadd.u8 q2, q2, q10
  58. vld1.64 {d22,d23}, [ip,:128], r2
  59. vrhadd.u8 q3, q3, q11
  60. .endif
  61. subs r3, r3, #4
  62. vst1.64 {d0, d1}, [r0,:128], r2
  63. vst1.64 {d2, d3}, [r0,:128], r2
  64. vst1.64 {d4, d5}, [r0,:128], r2
  65. vst1.64 {d6, d7}, [r0,:128], r2
  66. bne 1b
  67. bx lr
  68. .endm
  69. .macro pixels16_x2 vhadd=vrhadd.u8
  70. 1: vld1.64 {d0-d2}, [r1], r2
  71. vld1.64 {d4-d6}, [r1], r2
  72. pld [r1]
  73. pld [r1, r2]
  74. subs r3, r3, #2
  75. vext.8 q1, q0, q1, #1
  76. \vhadd q0, q0, q1
  77. vext.8 q3, q2, q3, #1
  78. \vhadd q2, q2, q3
  79. vst1.64 {d0, d1}, [r0,:128], r2
  80. vst1.64 {d4, d5}, [r0,:128], r2
  81. bne 1b
  82. bx lr
  83. .endm
  84. .macro pixels16_y2 vhadd=vrhadd.u8
  85. vld1.64 {d0, d1}, [r1], r2
  86. vld1.64 {d2, d3}, [r1], r2
  87. 1: subs r3, r3, #2
  88. \vhadd q2, q0, q1
  89. vld1.64 {d0, d1}, [r1], r2
  90. \vhadd q3, q0, q1
  91. vld1.64 {d2, d3}, [r1], r2
  92. pld [r1]
  93. pld [r1, r2]
  94. vst1.64 {d4, d5}, [r0,:128], r2
  95. vst1.64 {d6, d7}, [r0,:128], r2
  96. bne 1b
  97. bx lr
  98. .endm
  99. .macro pixels16_xy2 vshrn=vrshrn.u16 no_rnd=0
  100. vld1.64 {d0-d2}, [r1], r2
  101. vld1.64 {d4-d6}, [r1], r2
  102. .if \no_rnd
  103. vmov.i16 q13, #1
  104. .endif
  105. pld [r1]
  106. pld [r1, r2]
  107. vext.8 q1, q0, q1, #1
  108. vext.8 q3, q2, q3, #1
  109. vaddl.u8 q8, d0, d2
  110. vaddl.u8 q10, d1, d3
  111. vaddl.u8 q9, d4, d6
  112. vaddl.u8 q11, d5, d7
  113. 1: subs r3, r3, #2
  114. vld1.64 {d0-d2}, [r1], r2
  115. vadd.u16 q12, q8, q9
  116. pld [r1]
  117. .if \no_rnd
  118. vadd.u16 q12, q12, q13
  119. .endif
  120. vext.8 q15, q0, q1, #1
  121. vadd.u16 q1 , q10, q11
  122. \vshrn d28, q12, #2
  123. .if \no_rnd
  124. vadd.u16 q1, q1, q13
  125. .endif
  126. \vshrn d29, q1, #2
  127. vaddl.u8 q8, d0, d30
  128. vld1.64 {d2-d4}, [r1], r2
  129. vaddl.u8 q10, d1, d31
  130. vst1.64 {d28,d29}, [r0,:128], r2
  131. vadd.u16 q12, q8, q9
  132. pld [r1, r2]
  133. .if \no_rnd
  134. vadd.u16 q12, q12, q13
  135. .endif
  136. vext.8 q2, q1, q2, #1
  137. vadd.u16 q0, q10, q11
  138. \vshrn d30, q12, #2
  139. .if \no_rnd
  140. vadd.u16 q0, q0, q13
  141. .endif
  142. \vshrn d31, q0, #2
  143. vaddl.u8 q9, d2, d4
  144. vaddl.u8 q11, d3, d5
  145. vst1.64 {d30,d31}, [r0,:128], r2
  146. bgt 1b
  147. bx lr
  148. .endm
  149. .macro pixels8 avg=0
  150. 1: vld1.64 {d0}, [r1], r2
  151. vld1.64 {d1}, [r1], r2
  152. vld1.64 {d2}, [r1], r2
  153. pld [r1, r2, lsl #2]
  154. vld1.64 {d3}, [r1], r2
  155. pld [r1]
  156. pld [r1, r2]
  157. pld [r1, r2, lsl #1]
  158. .if \avg
  159. vld1.64 {d4}, [r0,:64], r2
  160. vrhadd.u8 d0, d0, d4
  161. vld1.64 {d5}, [r0,:64], r2
  162. vrhadd.u8 d1, d1, d5
  163. vld1.64 {d6}, [r0,:64], r2
  164. vrhadd.u8 d2, d2, d6
  165. vld1.64 {d7}, [r0,:64], r2
  166. vrhadd.u8 d3, d3, d7
  167. sub r0, r0, r2, lsl #2
  168. .endif
  169. subs r3, r3, #4
  170. vst1.64 {d0}, [r0,:64], r2
  171. vst1.64 {d1}, [r0,:64], r2
  172. vst1.64 {d2}, [r0,:64], r2
  173. vst1.64 {d3}, [r0,:64], r2
  174. bne 1b
  175. bx lr
  176. .endm
  177. .macro pixels8_x2 vhadd=vrhadd.u8
  178. 1: vld1.64 {d0, d1}, [r1], r2
  179. vext.8 d1, d0, d1, #1
  180. vld1.64 {d2, d3}, [r1], r2
  181. vext.8 d3, d2, d3, #1
  182. pld [r1]
  183. pld [r1, r2]
  184. subs r3, r3, #2
  185. vswp d1, d2
  186. \vhadd q0, q0, q1
  187. vst1.64 {d0}, [r0,:64], r2
  188. vst1.64 {d1}, [r0,:64], r2
  189. bne 1b
  190. bx lr
  191. .endm
  192. .macro pixels8_y2 vhadd=vrhadd.u8
  193. vld1.64 {d0}, [r1], r2
  194. vld1.64 {d1}, [r1], r2
  195. 1: subs r3, r3, #2
  196. \vhadd d4, d0, d1
  197. vld1.64 {d0}, [r1], r2
  198. \vhadd d5, d0, d1
  199. vld1.64 {d1}, [r1], r2
  200. pld [r1]
  201. pld [r1, r2]
  202. vst1.64 {d4}, [r0,:64], r2
  203. vst1.64 {d5}, [r0,:64], r2
  204. bne 1b
  205. bx lr
  206. .endm
  207. .macro pixels8_xy2 vshrn=vrshrn.u16 no_rnd=0
  208. vld1.64 {d0, d1}, [r1], r2
  209. vld1.64 {d2, d3}, [r1], r2
  210. .if \no_rnd
  211. vmov.i16 q11, #1
  212. .endif
  213. pld [r1]
  214. pld [r1, r2]
  215. vext.8 d4, d0, d1, #1
  216. vext.8 d6, d2, d3, #1
  217. vaddl.u8 q8, d0, d4
  218. vaddl.u8 q9, d2, d6
  219. 1: subs r3, r3, #2
  220. vld1.64 {d0, d1}, [r1], r2
  221. pld [r1]
  222. vadd.u16 q10, q8, q9
  223. vext.8 d4, d0, d1, #1
  224. .if \no_rnd
  225. vadd.u16 q10, q10, q11
  226. .endif
  227. vaddl.u8 q8, d0, d4
  228. \vshrn d5, q10, #2
  229. vld1.64 {d2, d3}, [r1], r2
  230. vadd.u16 q10, q8, q9
  231. pld [r1, r2]
  232. .if \no_rnd
  233. vadd.u16 q10, q10, q11
  234. .endif
  235. vst1.64 {d5}, [r0,:64], r2
  236. \vshrn d7, q10, #2
  237. vext.8 d6, d2, d3, #1
  238. vaddl.u8 q9, d2, d6
  239. vst1.64 {d7}, [r0,:64], r2
  240. bgt 1b
  241. bx lr
  242. .endm
  243. .macro pixfunc pfx name suf rnd_op args:vararg
  244. function ff_\pfx\name\suf\()_neon, export=1
  245. \name \rnd_op \args
  246. endfunc
  247. .endm
  248. .macro pixfunc2 pfx name args:vararg
  249. pixfunc \pfx \name
  250. pixfunc \pfx \name \args
  251. .endm
  252. function ff_put_h264_qpel16_mc00_neon, export=1
  253. mov r3, #16
  254. endfunc
  255. pixfunc put_ pixels16
  256. pixfunc2 put_ pixels16_x2, _no_rnd, vhadd.u8
  257. pixfunc2 put_ pixels16_y2, _no_rnd, vhadd.u8
  258. pixfunc2 put_ pixels16_xy2, _no_rnd, vshrn.u16, 1
  259. function ff_avg_h264_qpel16_mc00_neon, export=1
  260. mov r3, #16
  261. endfunc
  262. pixfunc avg_ pixels16,, 1
  263. function ff_put_h264_qpel8_mc00_neon, export=1
  264. mov r3, #8
  265. endfunc
  266. pixfunc put_ pixels8
  267. pixfunc2 put_ pixels8_x2, _no_rnd, vhadd.u8
  268. pixfunc2 put_ pixels8_y2, _no_rnd, vhadd.u8
  269. pixfunc2 put_ pixels8_xy2, _no_rnd, vshrn.u16, 1
  270. function ff_avg_h264_qpel8_mc00_neon, export=1
  271. mov r3, #8
  272. endfunc
  273. pixfunc avg_ pixels8,, 1
  274. function ff_put_pixels_clamped_neon, export=1
  275. vld1.64 {d16-d19}, [r0,:128]!
  276. vqmovun.s16 d0, q8
  277. vld1.64 {d20-d23}, [r0,:128]!
  278. vqmovun.s16 d1, q9
  279. vld1.64 {d24-d27}, [r0,:128]!
  280. vqmovun.s16 d2, q10
  281. vld1.64 {d28-d31}, [r0,:128]!
  282. vqmovun.s16 d3, q11
  283. vst1.64 {d0}, [r1,:64], r2
  284. vqmovun.s16 d4, q12
  285. vst1.64 {d1}, [r1,:64], r2
  286. vqmovun.s16 d5, q13
  287. vst1.64 {d2}, [r1,:64], r2
  288. vqmovun.s16 d6, q14
  289. vst1.64 {d3}, [r1,:64], r2
  290. vqmovun.s16 d7, q15
  291. vst1.64 {d4}, [r1,:64], r2
  292. vst1.64 {d5}, [r1,:64], r2
  293. vst1.64 {d6}, [r1,:64], r2
  294. vst1.64 {d7}, [r1,:64], r2
  295. bx lr
  296. endfunc
  297. function ff_put_signed_pixels_clamped_neon, export=1
  298. vmov.u8 d31, #128
  299. vld1.64 {d16-d17}, [r0,:128]!
  300. vqmovn.s16 d0, q8
  301. vld1.64 {d18-d19}, [r0,:128]!
  302. vqmovn.s16 d1, q9
  303. vld1.64 {d16-d17}, [r0,:128]!
  304. vqmovn.s16 d2, q8
  305. vld1.64 {d18-d19}, [r0,:128]!
  306. vadd.u8 d0, d0, d31
  307. vld1.64 {d20-d21}, [r0,:128]!
  308. vadd.u8 d1, d1, d31
  309. vld1.64 {d22-d23}, [r0,:128]!
  310. vadd.u8 d2, d2, d31
  311. vst1.64 {d0}, [r1,:64], r2
  312. vqmovn.s16 d3, q9
  313. vst1.64 {d1}, [r1,:64], r2
  314. vqmovn.s16 d4, q10
  315. vst1.64 {d2}, [r1,:64], r2
  316. vqmovn.s16 d5, q11
  317. vld1.64 {d24-d25}, [r0,:128]!
  318. vadd.u8 d3, d3, d31
  319. vld1.64 {d26-d27}, [r0,:128]!
  320. vadd.u8 d4, d4, d31
  321. vadd.u8 d5, d5, d31
  322. vst1.64 {d3}, [r1,:64], r2
  323. vqmovn.s16 d6, q12
  324. vst1.64 {d4}, [r1,:64], r2
  325. vqmovn.s16 d7, q13
  326. vst1.64 {d5}, [r1,:64], r2
  327. vadd.u8 d6, d6, d31
  328. vadd.u8 d7, d7, d31
  329. vst1.64 {d6}, [r1,:64], r2
  330. vst1.64 {d7}, [r1,:64], r2
  331. bx lr
  332. endfunc
  333. function ff_add_pixels_clamped_neon, export=1
  334. mov r3, r1
  335. vld1.64 {d16}, [r1,:64], r2
  336. vld1.64 {d0-d1}, [r0,:128]!
  337. vaddw.u8 q0, q0, d16
  338. vld1.64 {d17}, [r1,:64], r2
  339. vld1.64 {d2-d3}, [r0,:128]!
  340. vqmovun.s16 d0, q0
  341. vld1.64 {d18}, [r1,:64], r2
  342. vaddw.u8 q1, q1, d17
  343. vld1.64 {d4-d5}, [r0,:128]!
  344. vaddw.u8 q2, q2, d18
  345. vst1.64 {d0}, [r3,:64], r2
  346. vqmovun.s16 d2, q1
  347. vld1.64 {d19}, [r1,:64], r2
  348. vld1.64 {d6-d7}, [r0,:128]!
  349. vaddw.u8 q3, q3, d19
  350. vqmovun.s16 d4, q2
  351. vst1.64 {d2}, [r3,:64], r2
  352. vld1.64 {d16}, [r1,:64], r2
  353. vqmovun.s16 d6, q3
  354. vld1.64 {d0-d1}, [r0,:128]!
  355. vaddw.u8 q0, q0, d16
  356. vst1.64 {d4}, [r3,:64], r2
  357. vld1.64 {d17}, [r1,:64], r2
  358. vld1.64 {d2-d3}, [r0,:128]!
  359. vaddw.u8 q1, q1, d17
  360. vst1.64 {d6}, [r3,:64], r2
  361. vqmovun.s16 d0, q0
  362. vld1.64 {d18}, [r1,:64], r2
  363. vld1.64 {d4-d5}, [r0,:128]!
  364. vaddw.u8 q2, q2, d18
  365. vst1.64 {d0}, [r3,:64], r2
  366. vqmovun.s16 d2, q1
  367. vld1.64 {d19}, [r1,:64], r2
  368. vqmovun.s16 d4, q2
  369. vld1.64 {d6-d7}, [r0,:128]!
  370. vaddw.u8 q3, q3, d19
  371. vst1.64 {d2}, [r3,:64], r2
  372. vqmovun.s16 d6, q3
  373. vst1.64 {d4}, [r3,:64], r2
  374. vst1.64 {d6}, [r3,:64], r2
  375. bx lr
  376. endfunc
  377. function ff_float_to_int16_neon, export=1
  378. subs r2, r2, #8
  379. vld1.64 {d0-d1}, [r1,:128]!
  380. vcvt.s32.f32 q8, q0, #16
  381. vld1.64 {d2-d3}, [r1,:128]!
  382. vcvt.s32.f32 q9, q1, #16
  383. beq 3f
  384. bics ip, r2, #15
  385. beq 2f
  386. 1: subs ip, ip, #16
  387. vshrn.s32 d4, q8, #16
  388. vld1.64 {d0-d1}, [r1,:128]!
  389. vcvt.s32.f32 q0, q0, #16
  390. vshrn.s32 d5, q9, #16
  391. vld1.64 {d2-d3}, [r1,:128]!
  392. vcvt.s32.f32 q1, q1, #16
  393. vshrn.s32 d6, q0, #16
  394. vst1.64 {d4-d5}, [r0,:128]!
  395. vshrn.s32 d7, q1, #16
  396. vld1.64 {d16-d17},[r1,:128]!
  397. vcvt.s32.f32 q8, q8, #16
  398. vld1.64 {d18-d19},[r1,:128]!
  399. vcvt.s32.f32 q9, q9, #16
  400. vst1.64 {d6-d7}, [r0,:128]!
  401. bne 1b
  402. ands r2, r2, #15
  403. beq 3f
  404. 2: vld1.64 {d0-d1}, [r1,:128]!
  405. vshrn.s32 d4, q8, #16
  406. vcvt.s32.f32 q0, q0, #16
  407. vld1.64 {d2-d3}, [r1,:128]!
  408. vshrn.s32 d5, q9, #16
  409. vcvt.s32.f32 q1, q1, #16
  410. vshrn.s32 d6, q0, #16
  411. vst1.64 {d4-d5}, [r0,:128]!
  412. vshrn.s32 d7, q1, #16
  413. vst1.64 {d6-d7}, [r0,:128]!
  414. bx lr
  415. 3: vshrn.s32 d4, q8, #16
  416. vshrn.s32 d5, q9, #16
  417. vst1.64 {d4-d5}, [r0,:128]!
  418. bx lr
  419. endfunc
  420. function ff_float_to_int16_interleave_neon, export=1
  421. cmp r3, #2
  422. ldrlt r1, [r1]
  423. blt ff_float_to_int16_neon
  424. bne 4f
  425. ldr r3, [r1]
  426. ldr r1, [r1, #4]
  427. subs r2, r2, #8
  428. vld1.64 {d0-d1}, [r3,:128]!
  429. vcvt.s32.f32 q8, q0, #16
  430. vld1.64 {d2-d3}, [r3,:128]!
  431. vcvt.s32.f32 q9, q1, #16
  432. vld1.64 {d20-d21},[r1,:128]!
  433. vcvt.s32.f32 q10, q10, #16
  434. vld1.64 {d22-d23},[r1,:128]!
  435. vcvt.s32.f32 q11, q11, #16
  436. beq 3f
  437. bics ip, r2, #15
  438. beq 2f
  439. 1: subs ip, ip, #16
  440. vld1.64 {d0-d1}, [r3,:128]!
  441. vcvt.s32.f32 q0, q0, #16
  442. vsri.32 q10, q8, #16
  443. vld1.64 {d2-d3}, [r3,:128]!
  444. vcvt.s32.f32 q1, q1, #16
  445. vld1.64 {d24-d25},[r1,:128]!
  446. vcvt.s32.f32 q12, q12, #16
  447. vld1.64 {d26-d27},[r1,:128]!
  448. vsri.32 q11, q9, #16
  449. vst1.64 {d20-d21},[r0,:128]!
  450. vcvt.s32.f32 q13, q13, #16
  451. vst1.64 {d22-d23},[r0,:128]!
  452. vsri.32 q12, q0, #16
  453. vld1.64 {d16-d17},[r3,:128]!
  454. vsri.32 q13, q1, #16
  455. vst1.64 {d24-d25},[r0,:128]!
  456. vcvt.s32.f32 q8, q8, #16
  457. vld1.64 {d18-d19},[r3,:128]!
  458. vcvt.s32.f32 q9, q9, #16
  459. vld1.64 {d20-d21},[r1,:128]!
  460. vcvt.s32.f32 q10, q10, #16
  461. vld1.64 {d22-d23},[r1,:128]!
  462. vcvt.s32.f32 q11, q11, #16
  463. vst1.64 {d26-d27},[r0,:128]!
  464. bne 1b
  465. ands r2, r2, #15
  466. beq 3f
  467. 2: vsri.32 q10, q8, #16
  468. vld1.64 {d0-d1}, [r3,:128]!
  469. vcvt.s32.f32 q0, q0, #16
  470. vld1.64 {d2-d3}, [r3,:128]!
  471. vcvt.s32.f32 q1, q1, #16
  472. vld1.64 {d24-d25},[r1,:128]!
  473. vcvt.s32.f32 q12, q12, #16
  474. vsri.32 q11, q9, #16
  475. vld1.64 {d26-d27},[r1,:128]!
  476. vcvt.s32.f32 q13, q13, #16
  477. vst1.64 {d20-d21},[r0,:128]!
  478. vsri.32 q12, q0, #16
  479. vst1.64 {d22-d23},[r0,:128]!
  480. vsri.32 q13, q1, #16
  481. vst1.64 {d24-d27},[r0,:128]!
  482. bx lr
  483. 3: vsri.32 q10, q8, #16
  484. vsri.32 q11, q9, #16
  485. vst1.64 {d20-d23},[r0,:128]!
  486. bx lr
  487. 4: push {r4-r8,lr}
  488. cmp r3, #4
  489. lsl ip, r3, #1
  490. blt 4f
  491. @ 4 channels
  492. 5: ldmia r1!, {r4-r7}
  493. mov lr, r2
  494. mov r8, r0
  495. vld1.64 {d16-d17},[r4,:128]!
  496. vcvt.s32.f32 q8, q8, #16
  497. vld1.64 {d18-d19},[r5,:128]!
  498. vcvt.s32.f32 q9, q9, #16
  499. vld1.64 {d20-d21},[r6,:128]!
  500. vcvt.s32.f32 q10, q10, #16
  501. vld1.64 {d22-d23},[r7,:128]!
  502. vcvt.s32.f32 q11, q11, #16
  503. 6: subs lr, lr, #8
  504. vld1.64 {d0-d1}, [r4,:128]!
  505. vcvt.s32.f32 q0, q0, #16
  506. vsri.32 q9, q8, #16
  507. vld1.64 {d2-d3}, [r5,:128]!
  508. vcvt.s32.f32 q1, q1, #16
  509. vsri.32 q11, q10, #16
  510. vld1.64 {d4-d5}, [r6,:128]!
  511. vcvt.s32.f32 q2, q2, #16
  512. vzip.32 d18, d22
  513. vld1.64 {d6-d7}, [r7,:128]!
  514. vcvt.s32.f32 q3, q3, #16
  515. vzip.32 d19, d23
  516. vst1.64 {d18}, [r8], ip
  517. vsri.32 q1, q0, #16
  518. vst1.64 {d22}, [r8], ip
  519. vsri.32 q3, q2, #16
  520. vst1.64 {d19}, [r8], ip
  521. vzip.32 d2, d6
  522. vst1.64 {d23}, [r8], ip
  523. vzip.32 d3, d7
  524. beq 7f
  525. vld1.64 {d16-d17},[r4,:128]!
  526. vcvt.s32.f32 q8, q8, #16
  527. vst1.64 {d2}, [r8], ip
  528. vld1.64 {d18-d19},[r5,:128]!
  529. vcvt.s32.f32 q9, q9, #16
  530. vst1.64 {d6}, [r8], ip
  531. vld1.64 {d20-d21},[r6,:128]!
  532. vcvt.s32.f32 q10, q10, #16
  533. vst1.64 {d3}, [r8], ip
  534. vld1.64 {d22-d23},[r7,:128]!
  535. vcvt.s32.f32 q11, q11, #16
  536. vst1.64 {d7}, [r8], ip
  537. b 6b
  538. 7: vst1.64 {d2}, [r8], ip
  539. vst1.64 {d6}, [r8], ip
  540. vst1.64 {d3}, [r8], ip
  541. vst1.64 {d7}, [r8], ip
  542. subs r3, r3, #4
  543. popeq {r4-r8,pc}
  544. cmp r3, #4
  545. add r0, r0, #8
  546. bge 5b
  547. @ 2 channels
  548. 4: cmp r3, #2
  549. blt 4f
  550. ldmia r1!, {r4-r5}
  551. mov lr, r2
  552. mov r8, r0
  553. tst lr, #8
  554. vld1.64 {d16-d17},[r4,:128]!
  555. vcvt.s32.f32 q8, q8, #16
  556. vld1.64 {d18-d19},[r5,:128]!
  557. vcvt.s32.f32 q9, q9, #16
  558. vld1.64 {d20-d21},[r4,:128]!
  559. vcvt.s32.f32 q10, q10, #16
  560. vld1.64 {d22-d23},[r5,:128]!
  561. vcvt.s32.f32 q11, q11, #16
  562. beq 6f
  563. subs lr, lr, #8
  564. beq 7f
  565. vsri.32 d18, d16, #16
  566. vsri.32 d19, d17, #16
  567. vld1.64 {d16-d17},[r4,:128]!
  568. vcvt.s32.f32 q8, q8, #16
  569. vst1.32 {d18[0]}, [r8], ip
  570. vsri.32 d22, d20, #16
  571. vst1.32 {d18[1]}, [r8], ip
  572. vsri.32 d23, d21, #16
  573. vst1.32 {d19[0]}, [r8], ip
  574. vst1.32 {d19[1]}, [r8], ip
  575. vld1.64 {d18-d19},[r5,:128]!
  576. vcvt.s32.f32 q9, q9, #16
  577. vst1.32 {d22[0]}, [r8], ip
  578. vst1.32 {d22[1]}, [r8], ip
  579. vld1.64 {d20-d21},[r4,:128]!
  580. vcvt.s32.f32 q10, q10, #16
  581. vst1.32 {d23[0]}, [r8], ip
  582. vst1.32 {d23[1]}, [r8], ip
  583. vld1.64 {d22-d23},[r5,:128]!
  584. vcvt.s32.f32 q11, q11, #16
  585. 6: subs lr, lr, #16
  586. vld1.64 {d0-d1}, [r4,:128]!
  587. vcvt.s32.f32 q0, q0, #16
  588. vsri.32 d18, d16, #16
  589. vld1.64 {d2-d3}, [r5,:128]!
  590. vcvt.s32.f32 q1, q1, #16
  591. vsri.32 d19, d17, #16
  592. vld1.64 {d4-d5}, [r4,:128]!
  593. vcvt.s32.f32 q2, q2, #16
  594. vld1.64 {d6-d7}, [r5,:128]!
  595. vcvt.s32.f32 q3, q3, #16
  596. vst1.32 {d18[0]}, [r8], ip
  597. vsri.32 d22, d20, #16
  598. vst1.32 {d18[1]}, [r8], ip
  599. vsri.32 d23, d21, #16
  600. vst1.32 {d19[0]}, [r8], ip
  601. vsri.32 d2, d0, #16
  602. vst1.32 {d19[1]}, [r8], ip
  603. vsri.32 d3, d1, #16
  604. vst1.32 {d22[0]}, [r8], ip
  605. vsri.32 d6, d4, #16
  606. vst1.32 {d22[1]}, [r8], ip
  607. vsri.32 d7, d5, #16
  608. vst1.32 {d23[0]}, [r8], ip
  609. vst1.32 {d23[1]}, [r8], ip
  610. beq 6f
  611. vld1.64 {d16-d17},[r4,:128]!
  612. vcvt.s32.f32 q8, q8, #16
  613. vst1.32 {d2[0]}, [r8], ip
  614. vst1.32 {d2[1]}, [r8], ip
  615. vld1.64 {d18-d19},[r5,:128]!
  616. vcvt.s32.f32 q9, q9, #16
  617. vst1.32 {d3[0]}, [r8], ip
  618. vst1.32 {d3[1]}, [r8], ip
  619. vld1.64 {d20-d21},[r4,:128]!
  620. vcvt.s32.f32 q10, q10, #16
  621. vst1.32 {d6[0]}, [r8], ip
  622. vst1.32 {d6[1]}, [r8], ip
  623. vld1.64 {d22-d23},[r5,:128]!
  624. vcvt.s32.f32 q11, q11, #16
  625. vst1.32 {d7[0]}, [r8], ip
  626. vst1.32 {d7[1]}, [r8], ip
  627. bgt 6b
  628. 6: vst1.32 {d2[0]}, [r8], ip
  629. vst1.32 {d2[1]}, [r8], ip
  630. vst1.32 {d3[0]}, [r8], ip
  631. vst1.32 {d3[1]}, [r8], ip
  632. vst1.32 {d6[0]}, [r8], ip
  633. vst1.32 {d6[1]}, [r8], ip
  634. vst1.32 {d7[0]}, [r8], ip
  635. vst1.32 {d7[1]}, [r8], ip
  636. b 8f
  637. 7: vsri.32 d18, d16, #16
  638. vsri.32 d19, d17, #16
  639. vst1.32 {d18[0]}, [r8], ip
  640. vsri.32 d22, d20, #16
  641. vst1.32 {d18[1]}, [r8], ip
  642. vsri.32 d23, d21, #16
  643. vst1.32 {d19[0]}, [r8], ip
  644. vst1.32 {d19[1]}, [r8], ip
  645. vst1.32 {d22[0]}, [r8], ip
  646. vst1.32 {d22[1]}, [r8], ip
  647. vst1.32 {d23[0]}, [r8], ip
  648. vst1.32 {d23[1]}, [r8], ip
  649. 8: subs r3, r3, #2
  650. add r0, r0, #4
  651. popeq {r4-r8,pc}
  652. @ 1 channel
  653. 4: ldr r4, [r1],#4
  654. tst r2, #8
  655. mov lr, r2
  656. mov r5, r0
  657. vld1.64 {d0-d1}, [r4,:128]!
  658. vcvt.s32.f32 q0, q0, #16
  659. vld1.64 {d2-d3}, [r4,:128]!
  660. vcvt.s32.f32 q1, q1, #16
  661. bne 8f
  662. 6: subs lr, lr, #16
  663. vld1.64 {d4-d5}, [r4,:128]!
  664. vcvt.s32.f32 q2, q2, #16
  665. vld1.64 {d6-d7}, [r4,:128]!
  666. vcvt.s32.f32 q3, q3, #16
  667. vst1.16 {d0[1]}, [r5,:16], ip
  668. vst1.16 {d0[3]}, [r5,:16], ip
  669. vst1.16 {d1[1]}, [r5,:16], ip
  670. vst1.16 {d1[3]}, [r5,:16], ip
  671. vst1.16 {d2[1]}, [r5,:16], ip
  672. vst1.16 {d2[3]}, [r5,:16], ip
  673. vst1.16 {d3[1]}, [r5,:16], ip
  674. vst1.16 {d3[3]}, [r5,:16], ip
  675. beq 7f
  676. vld1.64 {d0-d1}, [r4,:128]!
  677. vcvt.s32.f32 q0, q0, #16
  678. vld1.64 {d2-d3}, [r4,:128]!
  679. vcvt.s32.f32 q1, q1, #16
  680. 7: vst1.16 {d4[1]}, [r5,:16], ip
  681. vst1.16 {d4[3]}, [r5,:16], ip
  682. vst1.16 {d5[1]}, [r5,:16], ip
  683. vst1.16 {d5[3]}, [r5,:16], ip
  684. vst1.16 {d6[1]}, [r5,:16], ip
  685. vst1.16 {d6[3]}, [r5,:16], ip
  686. vst1.16 {d7[1]}, [r5,:16], ip
  687. vst1.16 {d7[3]}, [r5,:16], ip
  688. bgt 6b
  689. pop {r4-r8,pc}
  690. 8: subs lr, lr, #8
  691. vst1.16 {d0[1]}, [r5,:16], ip
  692. vst1.16 {d0[3]}, [r5,:16], ip
  693. vst1.16 {d1[1]}, [r5,:16], ip
  694. vst1.16 {d1[3]}, [r5,:16], ip
  695. vst1.16 {d2[1]}, [r5,:16], ip
  696. vst1.16 {d2[3]}, [r5,:16], ip
  697. vst1.16 {d3[1]}, [r5,:16], ip
  698. vst1.16 {d3[3]}, [r5,:16], ip
  699. popeq {r4-r8,pc}
  700. vld1.64 {d0-d1}, [r4,:128]!
  701. vcvt.s32.f32 q0, q0, #16
  702. vld1.64 {d2-d3}, [r4,:128]!
  703. vcvt.s32.f32 q1, q1, #16
  704. b 6b
  705. endfunc
  706. function ff_vector_fmul_neon, export=1
  707. mov r3, r0
  708. subs r2, r2, #8
  709. vld1.64 {d0-d3}, [r0,:128]!
  710. vld1.64 {d4-d7}, [r1,:128]!
  711. vmul.f32 q8, q0, q2
  712. vmul.f32 q9, q1, q3
  713. beq 3f
  714. bics ip, r2, #15
  715. beq 2f
  716. 1: subs ip, ip, #16
  717. vld1.64 {d0-d1}, [r0,:128]!
  718. vld1.64 {d4-d5}, [r1,:128]!
  719. vmul.f32 q10, q0, q2
  720. vld1.64 {d2-d3}, [r0,:128]!
  721. vld1.64 {d6-d7}, [r1,:128]!
  722. vmul.f32 q11, q1, q3
  723. vst1.64 {d16-d19},[r3,:128]!
  724. vld1.64 {d0-d1}, [r0,:128]!
  725. vld1.64 {d4-d5}, [r1,:128]!
  726. vmul.f32 q8, q0, q2
  727. vld1.64 {d2-d3}, [r0,:128]!
  728. vld1.64 {d6-d7}, [r1,:128]!
  729. vmul.f32 q9, q1, q3
  730. vst1.64 {d20-d23},[r3,:128]!
  731. bne 1b
  732. ands r2, r2, #15
  733. beq 3f
  734. 2: vld1.64 {d0-d1}, [r0,:128]!
  735. vld1.64 {d4-d5}, [r1,:128]!
  736. vst1.64 {d16-d17},[r3,:128]!
  737. vmul.f32 q8, q0, q2
  738. vld1.64 {d2-d3}, [r0,:128]!
  739. vld1.64 {d6-d7}, [r1,:128]!
  740. vst1.64 {d18-d19},[r3,:128]!
  741. vmul.f32 q9, q1, q3
  742. 3: vst1.64 {d16-d19},[r3,:128]!
  743. bx lr
  744. endfunc
  745. function ff_vector_fmul_window_neon, export=1
  746. VFP vdup.32 q8, d0[0]
  747. NOVFP vld1.32 {d16[],d17[]}, [sp,:32]
  748. push {r4,r5,lr}
  749. VFP ldr lr, [sp, #12]
  750. NOVFP ldr lr, [sp, #16]
  751. sub r2, r2, #8
  752. sub r5, lr, #2
  753. add r2, r2, r5, lsl #2
  754. add r4, r3, r5, lsl #3
  755. add ip, r0, r5, lsl #3
  756. mov r5, #-16
  757. vld1.64 {d0,d1}, [r1,:128]!
  758. vld1.64 {d2,d3}, [r2,:128], r5
  759. vld1.64 {d4,d5}, [r3,:128]!
  760. vld1.64 {d6,d7}, [r4,:128], r5
  761. 1: subs lr, lr, #4
  762. vmov q11, q8
  763. vmla.f32 d22, d0, d4
  764. vmov q10, q8
  765. vmla.f32 d23, d1, d5
  766. vrev64.32 q3, q3
  767. vmla.f32 d20, d0, d7
  768. vrev64.32 q1, q1
  769. vmla.f32 d21, d1, d6
  770. beq 2f
  771. vmla.f32 d22, d3, d7
  772. vld1.64 {d0,d1}, [r1,:128]!
  773. vmla.f32 d23, d2, d6
  774. vld1.64 {d18,d19},[r2,:128], r5
  775. vmls.f32 d20, d3, d4
  776. vld1.64 {d24,d25},[r3,:128]!
  777. vmls.f32 d21, d2, d5
  778. vld1.64 {d6,d7}, [r4,:128], r5
  779. vmov q1, q9
  780. vrev64.32 q11, q11
  781. vmov q2, q12
  782. vswp d22, d23
  783. vst1.64 {d20,d21},[r0,:128]!
  784. vst1.64 {d22,d23},[ip,:128], r5
  785. b 1b
  786. 2: vmla.f32 d22, d3, d7
  787. vmla.f32 d23, d2, d6
  788. vmls.f32 d20, d3, d4
  789. vmls.f32 d21, d2, d5
  790. vrev64.32 q11, q11
  791. vswp d22, d23
  792. vst1.64 {d20,d21},[r0,:128]!
  793. vst1.64 {d22,d23},[ip,:128], r5
  794. pop {r4,r5,pc}
  795. endfunc
  796. #if CONFIG_VORBIS_DECODER
  797. function ff_vorbis_inverse_coupling_neon, export=1
  798. vmov.i32 q10, #1<<31
  799. subs r2, r2, #4
  800. mov r3, r0
  801. mov r12, r1
  802. beq 3f
  803. vld1.32 {d24-d25},[r1,:128]!
  804. vld1.32 {d22-d23},[r0,:128]!
  805. vcle.s32 q8, q12, #0
  806. vand q9, q11, q10
  807. veor q12, q12, q9
  808. vand q2, q12, q8
  809. vbic q3, q12, q8
  810. vadd.f32 q12, q11, q2
  811. vsub.f32 q11, q11, q3
  812. 1: 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. vst1.32 {d24-d25},[r3, :128]!
  818. vst1.32 {d22-d23},[r12,:128]!
  819. vand q2, q1, q8
  820. vbic q3, q1, q8
  821. vadd.f32 q1, q0, q2
  822. vsub.f32 q0, q0, q3
  823. subs r2, r2, #8
  824. ble 2f
  825. vld1.32 {d24-d25},[r1,:128]!
  826. vld1.32 {d22-d23},[r0,:128]!
  827. vcle.s32 q8, q12, #0
  828. vand q9, q11, q10
  829. veor q12, q12, q9
  830. vst1.32 {d2-d3}, [r3, :128]!
  831. vst1.32 {d0-d1}, [r12,:128]!
  832. vand q2, q12, q8
  833. vbic q3, q12, q8
  834. vadd.f32 q12, q11, q2
  835. vsub.f32 q11, q11, q3
  836. b 1b
  837. 2: vst1.32 {d2-d3}, [r3, :128]!
  838. vst1.32 {d0-d1}, [r12,:128]!
  839. bxlt lr
  840. 3: vld1.32 {d2-d3}, [r1,:128]
  841. vld1.32 {d0-d1}, [r0,:128]
  842. vcle.s32 q8, q1, #0
  843. vand q9, q0, q10
  844. veor q1, q1, q9
  845. vand q2, q1, q8
  846. vbic q3, q1, q8
  847. vadd.f32 q1, q0, q2
  848. vsub.f32 q0, q0, q3
  849. vst1.32 {d2-d3}, [r0,:128]!
  850. vst1.32 {d0-d1}, [r1,:128]!
  851. bx lr
  852. endfunc
  853. #endif
  854. function ff_vector_fmul_scalar_neon, export=1
  855. VFP len .req r2
  856. NOVFP len .req r3
  857. VFP vdup.32 q8, d0[0]
  858. NOVFP vdup.32 q8, r2
  859. bics r12, len, #15
  860. beq 3f
  861. vld1.32 {q0},[r1,:128]!
  862. vld1.32 {q1},[r1,:128]!
  863. 1: vmul.f32 q0, q0, q8
  864. vld1.32 {q2},[r1,:128]!
  865. vmul.f32 q1, q1, q8
  866. vld1.32 {q3},[r1,:128]!
  867. vmul.f32 q2, q2, q8
  868. vst1.32 {q0},[r0,:128]!
  869. vmul.f32 q3, q3, q8
  870. vst1.32 {q1},[r0,:128]!
  871. subs r12, r12, #16
  872. beq 2f
  873. vld1.32 {q0},[r1,:128]!
  874. vst1.32 {q2},[r0,:128]!
  875. vld1.32 {q1},[r1,:128]!
  876. vst1.32 {q3},[r0,:128]!
  877. b 1b
  878. 2: vst1.32 {q2},[r0,:128]!
  879. vst1.32 {q3},[r0,:128]!
  880. ands len, len, #15
  881. bxeq lr
  882. 3: vld1.32 {q0},[r1,:128]!
  883. vmul.f32 q0, q0, q8
  884. vst1.32 {q0},[r0,:128]!
  885. subs len, len, #4
  886. bgt 3b
  887. bx lr
  888. .unreq len
  889. endfunc
  890. function ff_vector_fmul_sv_scalar_2_neon, export=1
  891. VFP vdup.32 d16, d0[0]
  892. NOVFP vdup.32 d16, r3
  893. NOVFP ldr r3, [sp]
  894. vld1.32 {d0},[r1,:64]!
  895. vld1.32 {d1},[r1,:64]!
  896. 1: subs r3, r3, #4
  897. vmul.f32 d4, d0, d16
  898. vmul.f32 d5, d1, d16
  899. ldr r12, [r2], #4
  900. vld1.32 {d2},[r12,:64]
  901. ldr r12, [r2], #4
  902. vld1.32 {d3},[r12,:64]
  903. vmul.f32 d4, d4, d2
  904. vmul.f32 d5, d5, d3
  905. beq 2f
  906. vld1.32 {d0},[r1,:64]!
  907. vld1.32 {d1},[r1,:64]!
  908. vst1.32 {d4},[r0,:64]!
  909. vst1.32 {d5},[r0,:64]!
  910. b 1b
  911. 2: vst1.32 {d4},[r0,:64]!
  912. vst1.32 {d5},[r0,:64]!
  913. bx lr
  914. endfunc
  915. function ff_vector_fmul_sv_scalar_4_neon, export=1
  916. VFP vdup.32 q10, d0[0]
  917. NOVFP vdup.32 q10, r3
  918. NOVFP ldr r3, [sp]
  919. push {lr}
  920. bics lr, r3, #7
  921. beq 3f
  922. vld1.32 {q0},[r1,:128]!
  923. vld1.32 {q2},[r1,:128]!
  924. 1: ldr r12, [r2], #4
  925. vld1.32 {q1},[r12,:128]
  926. ldr r12, [r2], #4
  927. vld1.32 {q3},[r12,:128]
  928. vmul.f32 q8, q0, q10
  929. vmul.f32 q8, q8, q1
  930. vmul.f32 q9, q2, q10
  931. vmul.f32 q9, q9, q3
  932. subs lr, lr, #8
  933. beq 2f
  934. vld1.32 {q0},[r1,:128]!
  935. vld1.32 {q2},[r1,:128]!
  936. vst1.32 {q8},[r0,:128]!
  937. vst1.32 {q9},[r0,:128]!
  938. b 1b
  939. 2: vst1.32 {q8},[r0,:128]!
  940. vst1.32 {q9},[r0,:128]!
  941. ands r3, r3, #7
  942. popeq {pc}
  943. 3: vld1.32 {q0},[r1,:128]!
  944. ldr r12, [r2], #4
  945. vld1.32 {q1},[r12,:128]
  946. vmul.f32 q0, q0, q10
  947. vmul.f32 q0, q0, q1
  948. vst1.32 {q0},[r0,:128]!
  949. subs r3, r3, #4
  950. bgt 3b
  951. pop {pc}
  952. endfunc
  953. function ff_sv_fmul_scalar_2_neon, export=1
  954. VFP len .req r2
  955. NOVFP len .req r3
  956. VFP vdup.32 q8, d0[0]
  957. NOVFP vdup.32 q8, r2
  958. ldr r12, [r1], #4
  959. vld1.32 {d0},[r12,:64]
  960. ldr r12, [r1], #4
  961. vld1.32 {d1},[r12,:64]
  962. 1: vmul.f32 q1, q0, q8
  963. subs len, len, #4
  964. beq 2f
  965. ldr r12, [r1], #4
  966. vld1.32 {d0},[r12,:64]
  967. ldr r12, [r1], #4
  968. vld1.32 {d1},[r12,:64]
  969. vst1.32 {q1},[r0,:128]!
  970. b 1b
  971. 2: vst1.32 {q1},[r0,:128]!
  972. bx lr
  973. .unreq len
  974. endfunc
  975. function ff_sv_fmul_scalar_4_neon, export=1
  976. VFP len .req r2
  977. NOVFP len .req r3
  978. VFP vdup.32 q8, d0[0]
  979. NOVFP vdup.32 q8, r2
  980. 1: ldr r12, [r1], #4
  981. vld1.32 {q0},[r12,:128]
  982. vmul.f32 q0, q0, q8
  983. vst1.32 {q0},[r0,:128]!
  984. subs len, len, #4
  985. bgt 1b
  986. bx lr
  987. .unreq len
  988. endfunc
  989. function ff_butterflies_float_neon, export=1
  990. 1: vld1.32 {q0},[r0,:128]
  991. vld1.32 {q1},[r1,:128]
  992. vsub.f32 q2, q0, q1
  993. vadd.f32 q1, q0, q1
  994. vst1.32 {q2},[r1,:128]!
  995. vst1.32 {q1},[r0,:128]!
  996. subs r2, r2, #4
  997. bgt 1b
  998. bx lr
  999. endfunc
  1000. function ff_scalarproduct_float_neon, export=1
  1001. vmov.f32 q2, #0.0
  1002. 1: vld1.32 {q0},[r0,:128]!
  1003. vld1.32 {q1},[r1,:128]!
  1004. vmla.f32 q2, q0, q1
  1005. subs r2, r2, #4
  1006. bgt 1b
  1007. vadd.f32 d0, d4, d5
  1008. vpadd.f32 d0, d0, d0
  1009. NOVFP vmov.32 r0, d0[0]
  1010. bx lr
  1011. endfunc
  1012. function ff_int32_to_float_fmul_scalar_neon, export=1
  1013. VFP vdup.32 q0, d0[0]
  1014. VFP len .req r2
  1015. NOVFP vdup.32 q0, r2
  1016. NOVFP len .req r3
  1017. vld1.32 {q1},[r1,:128]!
  1018. vcvt.f32.s32 q3, q1
  1019. vld1.32 {q2},[r1,:128]!
  1020. vcvt.f32.s32 q8, q2
  1021. 1: subs len, len, #8
  1022. pld [r1, #16]
  1023. vmul.f32 q9, q3, q0
  1024. vmul.f32 q10, q8, q0
  1025. beq 2f
  1026. vld1.32 {q1},[r1,:128]!
  1027. vcvt.f32.s32 q3, q1
  1028. vld1.32 {q2},[r1,:128]!
  1029. vcvt.f32.s32 q8, q2
  1030. vst1.32 {q9}, [r0,:128]!
  1031. vst1.32 {q10},[r0,:128]!
  1032. b 1b
  1033. 2: vst1.32 {q9}, [r0,:128]!
  1034. vst1.32 {q10},[r0,:128]!
  1035. bx lr
  1036. .unreq len
  1037. endfunc
  1038. function ff_vector_fmul_reverse_neon, export=1
  1039. add r2, r2, r3, lsl #2
  1040. sub r2, r2, #32
  1041. mov r12, #-32
  1042. vld1.32 {q0-q1}, [r1,:128]!
  1043. vld1.32 {q2-q3}, [r2,:128], r12
  1044. 1: pld [r1, #32]
  1045. vrev64.32 q3, q3
  1046. vmul.f32 d16, d0, d7
  1047. vmul.f32 d17, d1, d6
  1048. pld [r2, #-32]
  1049. vrev64.32 q2, q2
  1050. vmul.f32 d18, d2, d5
  1051. vmul.f32 d19, d3, d4
  1052. subs r3, r3, #8
  1053. beq 2f
  1054. vld1.32 {q0-q1}, [r1,:128]!
  1055. vld1.32 {q2-q3}, [r2,:128], r12
  1056. vst1.32 {q8-q9}, [r0,:128]!
  1057. b 1b
  1058. 2: vst1.32 {q8-q9}, [r0,:128]!
  1059. bx lr
  1060. endfunc
  1061. function ff_vector_fmul_add_neon, export=1
  1062. ldr r12, [sp]
  1063. vld1.32 {q0-q1}, [r1,:128]!
  1064. vld1.32 {q8-q9}, [r2,:128]!
  1065. vld1.32 {q2-q3}, [r3,:128]!
  1066. vmul.f32 q10, q0, q8
  1067. vmul.f32 q11, q1, q9
  1068. 1: vadd.f32 q12, q2, q10
  1069. vadd.f32 q13, q3, q11
  1070. pld [r1, #16]
  1071. pld [r2, #16]
  1072. pld [r3, #16]
  1073. subs r12, r12, #8
  1074. beq 2f
  1075. vld1.32 {q0}, [r1,:128]!
  1076. vld1.32 {q8}, [r2,:128]!
  1077. vmul.f32 q10, q0, q8
  1078. vld1.32 {q1}, [r1,:128]!
  1079. vld1.32 {q9}, [r2,:128]!
  1080. vmul.f32 q11, q1, q9
  1081. vld1.32 {q2-q3}, [r3,:128]!
  1082. vst1.32 {q12-q13},[r0,:128]!
  1083. b 1b
  1084. 2: vst1.32 {q12-q13},[r0,:128]!
  1085. bx lr
  1086. endfunc
  1087. function ff_vector_clipf_neon, export=1
  1088. VFP vdup.32 q1, d0[1]
  1089. VFP vdup.32 q0, d0[0]
  1090. NOVFP vdup.32 q0, r2
  1091. NOVFP vdup.32 q1, r3
  1092. NOVFP ldr r2, [sp]
  1093. vld1.f32 {q2},[r1,:128]!
  1094. vmin.f32 q10, q2, q1
  1095. vld1.f32 {q3},[r1,:128]!
  1096. vmin.f32 q11, q3, q1
  1097. 1: vmax.f32 q8, q10, q0
  1098. vmax.f32 q9, q11, q0
  1099. subs r2, r2, #8
  1100. beq 2f
  1101. vld1.f32 {q2},[r1,:128]!
  1102. vmin.f32 q10, q2, q1
  1103. vld1.f32 {q3},[r1,:128]!
  1104. vmin.f32 q11, q3, q1
  1105. vst1.f32 {q8},[r0,:128]!
  1106. vst1.f32 {q9},[r0,:128]!
  1107. b 1b
  1108. 2: vst1.f32 {q8},[r0,:128]!
  1109. vst1.f32 {q9},[r0,:128]!
  1110. bx lr
  1111. endfunc