dsputil_neon.S 27.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * ARM NEON optimised DSP functions
 * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

22
#include "config.h"
23
#include "libavutil/arm/asm.S"
24

25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
function ff_clear_block_neon, export=1
        vmov.i16        q0,  #0
        .rept           8
        vst1.16         {q0}, [r0,:128]!
        .endr
        bx              lr
endfunc

function ff_clear_blocks_neon, export=1
        vmov.i16        q0,  #0
        .rept           8*6
        vst1.16         {q0}, [r0,:128]!
        .endr
        bx              lr
endfunc

41 42
.macro  pixels16        rnd=1, avg=0
  .if \avg
43
        mov             r12, r0
44
  .endif
45 46 47
1:      vld1.8          {q0},     [r1], r2
        vld1.8          {q1},     [r1], r2
        vld1.8          {q2},     [r1], r2
48
        pld             [r1, r2, lsl #2]
49
        vld1.8          {q3},     [r1], r2
50 51 52
        pld             [r1]
        pld             [r1, r2]
        pld             [r1, r2, lsl #1]
53
  .if \avg
54
        vld1.8          {q8},     [r12,:128], r2
55
        vrhadd.u8       q0,  q0,  q8
56
        vld1.8          {q9},     [r12,:128], r2
57
        vrhadd.u8       q1,  q1,  q9
58
        vld1.8          {q10},    [r12,:128], r2
59
        vrhadd.u8       q2,  q2,  q10
60
        vld1.8          {q11},    [r12,:128], r2
61
        vrhadd.u8       q3,  q3,  q11
62
  .endif
63
        subs            r3,  r3,  #4
64 65 66 67
        vst1.64         {q0},     [r0,:128], r2
        vst1.64         {q1},     [r0,:128], r2
        vst1.64         {q2},     [r0,:128], r2
        vst1.64         {q3},     [r0,:128], r2
68 69
        bne             1b
        bx              lr
70
.endm
71

72
.macro  pixels16_x2     rnd=1, avg=0
73 74
1:      vld1.8          {d0-d2},  [r1], r2
        vld1.8          {d4-d6},  [r1], r2
75 76 77 78
        pld             [r1]
        pld             [r1, r2]
        subs            r3,  r3,  #2
        vext.8          q1,  q0,  q1,  #1
79
        avg             q0,  q0,  q1
80
        vext.8          q3,  q2,  q3,  #1
81
        avg             q2,  q2,  q3
82 83 84 85 86 87 88
  .if \avg
        vld1.8          {q1},     [r0,:128], r2
        vld1.8          {q3},     [r0,:128]
        vrhadd.u8       q0,  q0,  q1
        vrhadd.u8       q2,  q2,  q3
        sub             r0,  r0,  r2
  .endif
89 90
        vst1.8          {q0},     [r0,:128], r2
        vst1.8          {q2},     [r0,:128], r2
91 92
        bne             1b
        bx              lr
93
.endm
94

95
.macro  pixels16_y2     rnd=1, avg=0
96
        sub             r3,  r3,  #2
97 98
        vld1.8          {q0},     [r1], r2
        vld1.8          {q1},     [r1], r2
99
1:      subs            r3,  r3,  #2
100
        avg             q2,  q0,  q1
101
        vld1.8          {q0},     [r1], r2
102
        avg             q3,  q0,  q1
103
        vld1.8          {q1},     [r1], r2
104
        pld             [r1]
105
        pld             [r1, r2]
106 107 108 109 110 111 112
  .if \avg
        vld1.8          {q8},     [r0,:128], r2
        vld1.8          {q9},     [r0,:128]
        vrhadd.u8       q2,  q2,  q8
        vrhadd.u8       q3,  q3,  q9
        sub             r0,  r0,  r2
  .endif
113 114
        vst1.8          {q2},     [r0,:128], r2
        vst1.8          {q3},     [r0,:128], r2
115
        bne             1b
116 117

        avg             q2,  q0,  q1
118
        vld1.8          {q0},     [r1], r2
119 120 121 122 123 124 125 126
        avg             q3,  q0,  q1
  .if \avg
        vld1.8          {q8},     [r0,:128], r2
        vld1.8          {q9},     [r0,:128]
        vrhadd.u8       q2,  q2,  q8
        vrhadd.u8       q3,  q3,  q9
        sub             r0,  r0,  r2
  .endif
127 128
        vst1.8          {q2},     [r0,:128], r2
        vst1.8          {q3},     [r0,:128], r2
129

130
        bx              lr
131
.endm
132

133
.macro  pixels16_xy2    rnd=1, avg=0
134
        sub             r3,  r3,  #2
135 136
        vld1.8          {d0-d2},  [r1], r2
        vld1.8          {d4-d6},  [r1], r2
137
NRND    vmov.i16        q13, #1
138
        pld             [r1]
139
        pld             [r1, r2]
140 141 142 143 144 145 146
        vext.8          q1,  q0,  q1,  #1
        vext.8          q3,  q2,  q3,  #1
        vaddl.u8        q8,  d0,  d2
        vaddl.u8        q10, d1,  d3
        vaddl.u8        q9,  d4,  d6
        vaddl.u8        q11, d5,  d7
1:      subs            r3,  r3,  #2
147
        vld1.8          {d0-d2},  [r1], r2
148 149
        vadd.u16        q12, q8,  q9
        pld             [r1]
150
NRND    vadd.u16        q12, q12, q13
151 152
        vext.8          q15, q0,  q1,  #1
        vadd.u16        q1 , q10, q11
153
        shrn            d28, q12, #2
154
NRND    vadd.u16        q1,  q1,  q13
155
        shrn            d29, q1,  #2
156 157 158 159
  .if \avg
        vld1.8          {q8},     [r0,:128]
        vrhadd.u8       q14, q14, q8
  .endif
160
        vaddl.u8        q8,  d0,  d30
161
        vld1.8          {d2-d4},  [r1], r2
162
        vaddl.u8        q10, d1,  d31
163
        vst1.8          {q14},    [r0,:128], r2
164
        vadd.u16        q12, q8,  q9
165
        pld             [r1, r2]
166
NRND    vadd.u16        q12, q12, q13
167 168
        vext.8          q2,  q1,  q2,  #1
        vadd.u16        q0,  q10, q11
169
        shrn            d30, q12, #2
170
NRND    vadd.u16        q0,  q0,  q13
171
        shrn            d31, q0,  #2
172 173 174 175
  .if \avg
        vld1.8          {q9},     [r0,:128]
        vrhadd.u8       q15, q15, q9
  .endif
176 177
        vaddl.u8        q9,  d2,  d4
        vaddl.u8        q11, d3,  d5
178
        vst1.8          {q15},    [r0,:128], r2
179
        bgt             1b
180

181
        vld1.8          {d0-d2},  [r1], r2
182
        vadd.u16        q12, q8,  q9
183
NRND    vadd.u16        q12, q12, q13
184 185 186
        vext.8          q15, q0,  q1,  #1
        vadd.u16        q1 , q10, q11
        shrn            d28, q12, #2
187
NRND    vadd.u16        q1,  q1,  q13
188 189 190 191 192 193 194
        shrn            d29, q1,  #2
  .if \avg
        vld1.8          {q8},     [r0,:128]
        vrhadd.u8       q14, q14, q8
  .endif
        vaddl.u8        q8,  d0,  d30
        vaddl.u8        q10, d1,  d31
195
        vst1.8          {q14},    [r0,:128], r2
196
        vadd.u16        q12, q8,  q9
197
NRND    vadd.u16        q12, q12, q13
198 199
        vadd.u16        q0,  q10, q11
        shrn            d30, q12, #2
200
NRND    vadd.u16        q0,  q0,  q13
201 202 203 204 205
        shrn            d31, q0,  #2
  .if \avg
        vld1.8          {q9},     [r0,:128]
        vrhadd.u8       q15, q15, q9
  .endif
206
        vst1.8          {q15},    [r0,:128], r2
207

208
        bx              lr
209
.endm
210

211
.macro  pixels8         rnd=1, avg=0
212 213 214
1:      vld1.8          {d0},     [r1], r2
        vld1.8          {d1},     [r1], r2
        vld1.8          {d2},     [r1], r2
215
        pld             [r1, r2, lsl #2]
216
        vld1.8          {d3},     [r1], r2
217 218 219
        pld             [r1]
        pld             [r1, r2]
        pld             [r1, r2, lsl #1]
220
  .if \avg
221
        vld1.8          {d4},     [r0,:64], r2
222
        vrhadd.u8       d0,  d0,  d4
223
        vld1.8          {d5},     [r0,:64], r2
224
        vrhadd.u8       d1,  d1,  d5
225
        vld1.8          {d6},     [r0,:64], r2
226
        vrhadd.u8       d2,  d2,  d6
227
        vld1.8          {d7},     [r0,:64], r2
228 229
        vrhadd.u8       d3,  d3,  d7
        sub             r0,  r0,  r2,  lsl #2
230
  .endif
231
        subs            r3,  r3,  #4
232 233 234 235
        vst1.8          {d0},     [r0,:64], r2
        vst1.8          {d1},     [r0,:64], r2
        vst1.8          {d2},     [r0,:64], r2
        vst1.8          {d3},     [r0,:64], r2
236 237
        bne             1b
        bx              lr
238
.endm
239

240
.macro  pixels8_x2      rnd=1, avg=0
241
1:      vld1.8          {q0},     [r1], r2
242
        vext.8          d1,  d0,  d1,  #1
243
        vld1.8          {q1},     [r1], r2
244 245 246 247 248
        vext.8          d3,  d2,  d3,  #1
        pld             [r1]
        pld             [r1, r2]
        subs            r3,  r3,  #2
        vswp            d1,  d2
249
        avg             q0,  q0,  q1
250 251 252 253 254 255
  .if \avg
        vld1.8          {d4},     [r0,:64], r2
        vld1.8          {d5},     [r0,:64]
        vrhadd.u8       q0,  q0,  q2
        sub             r0,  r0,  r2
  .endif
256 257
        vst1.8          {d0},     [r0,:64], r2
        vst1.8          {d1},     [r0,:64], r2
258 259
        bne             1b
        bx              lr
260
.endm
261

262
.macro  pixels8_y2      rnd=1, avg=0
263
        sub             r3,  r3,  #2
264 265
        vld1.8          {d0},     [r1], r2
        vld1.8          {d1},     [r1], r2
266
1:      subs            r3,  r3,  #2
267
        avg             d4,  d0,  d1
268
        vld1.8          {d0},     [r1], r2
269
        avg             d5,  d0,  d1
270
        vld1.8          {d1},     [r1], r2
271
        pld             [r1]
272
        pld             [r1, r2]
273 274 275 276 277 278
  .if \avg
        vld1.8          {d2},     [r0,:64], r2
        vld1.8          {d3},     [r0,:64]
        vrhadd.u8       q2,  q2,  q1
        sub             r0,  r0,  r2
  .endif
279 280
        vst1.8          {d4},     [r0,:64], r2
        vst1.8          {d5},     [r0,:64], r2
281
        bne             1b
282 283

        avg             d4,  d0,  d1
284
        vld1.8          {d0},     [r1], r2
285 286 287 288 289 290 291
        avg             d5,  d0,  d1
  .if \avg
        vld1.8          {d2},     [r0,:64], r2
        vld1.8          {d3},     [r0,:64]
        vrhadd.u8       q2,  q2,  q1
        sub             r0,  r0,  r2
  .endif
292 293
        vst1.8          {d4},     [r0,:64], r2
        vst1.8          {d5},     [r0,:64], r2
294

295
        bx              lr
296
.endm
297

298
.macro  pixels8_xy2     rnd=1, avg=0
299
        sub             r3,  r3,  #2
300 301
        vld1.8          {q0},     [r1], r2
        vld1.8          {q1},     [r1], r2
302
NRND    vmov.i16        q11, #1
303
        pld             [r1]
304
        pld             [r1, r2]
305 306 307 308 309
        vext.8          d4,  d0,  d1,  #1
        vext.8          d6,  d2,  d3,  #1
        vaddl.u8        q8,  d0,  d4
        vaddl.u8        q9,  d2,  d6
1:      subs            r3,  r3,  #2
310
        vld1.8          {q0},     [r1], r2
311 312 313
        pld             [r1]
        vadd.u16        q10, q8,  q9
        vext.8          d4,  d0,  d1,  #1
314
NRND    vadd.u16        q10, q10, q11
315
        vaddl.u8        q8,  d0,  d4
316
        shrn            d5,  q10, #2
317
        vld1.8          {q1},     [r1], r2
318
        vadd.u16        q10, q8,  q9
319
        pld             [r1, r2]
320 321 322 323
  .if \avg
        vld1.8          {d7},     [r0,:64]
        vrhadd.u8       d5,  d5,  d7
  .endif
324
NRND    vadd.u16        q10, q10, q11
325
        vst1.8          {d5},     [r0,:64], r2
326
        shrn            d7,  q10, #2
327 328 329 330
  .if \avg
        vld1.8          {d5},     [r0,:64]
        vrhadd.u8       d7,  d7,  d5
  .endif
331 332
        vext.8          d6,  d2,  d3,  #1
        vaddl.u8        q9,  d2,  d6
333
        vst1.8          {d7},     [r0,:64], r2
334
        bgt             1b
335

336
        vld1.8          {q0},     [r1], r2
337 338
        vadd.u16        q10, q8,  q9
        vext.8          d4,  d0,  d1,  #1
339
NRND    vadd.u16        q10, q10, q11
340 341 342 343 344 345 346
        vaddl.u8        q8,  d0,  d4
        shrn            d5,  q10, #2
        vadd.u16        q10, q8,  q9
  .if \avg
        vld1.8          {d7},     [r0,:64]
        vrhadd.u8       d5,  d5,  d7
  .endif
347
NRND    vadd.u16        q10, q10, q11
348
        vst1.8          {d5},     [r0,:64], r2
349 350 351 352 353
        shrn            d7,  q10, #2
  .if \avg
        vld1.8          {d5},     [r0,:64]
        vrhadd.u8       d7,  d7,  d5
  .endif
354
        vst1.8          {d7},     [r0,:64], r2
355

356
        bx              lr
357
.endm
358

359 360 361 362 363 364 365 366
.macro  pixfunc         pfx, name, suf, rnd=1, avg=0
  .if \rnd
    .macro avg  rd, rn, rm
        vrhadd.u8       \rd, \rn, \rm
    .endm
    .macro shrn rd, rn, rm
        vrshrn.u16      \rd, \rn, \rm
    .endm
367 368
    .macro NRND insn:vararg
    .endm
369 370 371 372 373 374 375
  .else
    .macro avg  rd, rn, rm
        vhadd.u8        \rd, \rn, \rm
    .endm
    .macro shrn rd, rn, rm
        vshrn.u16       \rd, \rn, \rm
    .endm
376 377 378
    .macro NRND insn:vararg
        \insn
    .endm
379
  .endif
380
function ff_\pfx\name\suf\()_neon, export=1
381
        \name           \rnd, \avg
382
endfunc
383 384
        .purgem         avg
        .purgem         shrn
385
        .purgem         NRND
386
.endm
387

388 389 390 391
.macro  pixfunc2        pfx, name, avg=0
        pixfunc         \pfx, \name,          rnd=1, avg=\avg
        pixfunc         \pfx, \name, _no_rnd, rnd=0, avg=\avg
.endm
392 393

function ff_put_h264_qpel16_mc00_neon, export=1
394
        mov             r3,  #16
395
endfunc
396

397 398 399 400
        pixfunc         put_, pixels16,     avg=0
        pixfunc2        put_, pixels16_x2,  avg=0
        pixfunc2        put_, pixels16_y2,  avg=0
        pixfunc2        put_, pixels16_xy2, avg=0
401 402

function ff_avg_h264_qpel16_mc00_neon, export=1
403
        mov             r3,  #16
404
endfunc
405

406
        pixfunc         avg_, pixels16,     avg=1
407 408 409
        pixfunc2        avg_, pixels16_x2,  avg=1
        pixfunc2        avg_, pixels16_y2,  avg=1
        pixfunc2        avg_, pixels16_xy2, avg=1
410 411

function ff_put_h264_qpel8_mc00_neon, export=1
412
        mov             r3,  #8
413
endfunc
414

415 416 417 418
        pixfunc         put_, pixels8,     avg=0
        pixfunc2        put_, pixels8_x2,  avg=0
        pixfunc2        put_, pixels8_y2,  avg=0
        pixfunc2        put_, pixels8_xy2, avg=0
419

420 421
function ff_avg_h264_qpel8_mc00_neon, export=1
        mov             r3,  #8
422
endfunc
423

424
        pixfunc         avg_, pixels8,     avg=1
425 426 427
        pixfunc2        avg_, pixels8_x2,  avg=1
        pixfunc2        avg_, pixels8_y2,  avg=1
        pixfunc2        avg_, pixels8_xy2, avg=1
428

429
function ff_put_pixels_clamped_neon, export=1
430
        vld1.16         {d16-d19}, [r0,:128]!
431
        vqmovun.s16     d0, q8
432
        vld1.16         {d20-d23}, [r0,:128]!
433
        vqmovun.s16     d1, q9
434
        vld1.16         {d24-d27}, [r0,:128]!
435
        vqmovun.s16     d2, q10
436
        vld1.16         {d28-d31}, [r0,:128]!
437
        vqmovun.s16     d3, q11
438
        vst1.8          {d0},      [r1,:64], r2
439
        vqmovun.s16     d4, q12
440
        vst1.8          {d1},      [r1,:64], r2
441
        vqmovun.s16     d5, q13
442
        vst1.8          {d2},      [r1,:64], r2
443
        vqmovun.s16     d6, q14
444
        vst1.8          {d3},      [r1,:64], r2
445
        vqmovun.s16     d7, q15
446 447 448 449
        vst1.8          {d4},      [r1,:64], r2
        vst1.8          {d5},      [r1,:64], r2
        vst1.8          {d6},      [r1,:64], r2
        vst1.8          {d7},      [r1,:64], r2
450
        bx              lr
451
endfunc
452

453 454
function ff_put_signed_pixels_clamped_neon, export=1
        vmov.u8         d31, #128
455
        vld1.16         {d16-d17}, [r0,:128]!
456
        vqmovn.s16      d0, q8
457
        vld1.16         {d18-d19}, [r0,:128]!
458
        vqmovn.s16      d1, q9
459
        vld1.16         {d16-d17}, [r0,:128]!
460
        vqmovn.s16      d2, q8
461
        vld1.16         {d18-d19}, [r0,:128]!
462
        vadd.u8         d0, d0, d31
463
        vld1.16         {d20-d21}, [r0,:128]!
464
        vadd.u8         d1, d1, d31
465
        vld1.16         {d22-d23}, [r0,:128]!
466
        vadd.u8         d2, d2, d31
467
        vst1.8          {d0},      [r1,:64], r2
468
        vqmovn.s16      d3, q9
469
        vst1.8          {d1},      [r1,:64], r2
470
        vqmovn.s16      d4, q10
471
        vst1.8          {d2},      [r1,:64], r2
472
        vqmovn.s16      d5, q11
473
        vld1.16         {d24-d25}, [r0,:128]!
474
        vadd.u8         d3, d3, d31
475
        vld1.16         {d26-d27}, [r0,:128]!
476 477
        vadd.u8         d4, d4, d31
        vadd.u8         d5, d5, d31
478
        vst1.8          {d3},      [r1,:64], r2
479
        vqmovn.s16      d6, q12
480
        vst1.8          {d4},      [r1,:64], r2
481
        vqmovn.s16      d7, q13
482
        vst1.8          {d5},      [r1,:64], r2
483 484
        vadd.u8         d6, d6, d31
        vadd.u8         d7, d7, d31
485 486
        vst1.8          {d6},      [r1,:64], r2
        vst1.8          {d7},      [r1,:64], r2
487
        bx              lr
488
endfunc
489

490 491
function ff_add_pixels_clamped_neon, export=1
        mov             r3, r1
492 493
        vld1.8          {d16},   [r1,:64], r2
        vld1.16         {d0-d1}, [r0,:128]!
494
        vaddw.u8        q0, q0, d16
495 496
        vld1.8          {d17},   [r1,:64], r2
        vld1.16         {d2-d3}, [r0,:128]!
497
        vqmovun.s16     d0, q0
498
        vld1.8          {d18},   [r1,:64], r2
499
        vaddw.u8        q1, q1, d17
500
        vld1.16         {d4-d5}, [r0,:128]!
501
        vaddw.u8        q2, q2, d18
502
        vst1.8          {d0},    [r3,:64], r2
503
        vqmovun.s16     d2, q1
504 505
        vld1.8          {d19},   [r1,:64], r2
        vld1.16         {d6-d7}, [r0,:128]!
506 507
        vaddw.u8        q3, q3, d19
        vqmovun.s16     d4, q2
508 509
        vst1.8          {d2},    [r3,:64], r2
        vld1.8          {d16},   [r1,:64], r2
510
        vqmovun.s16     d6, q3
511
        vld1.16         {d0-d1}, [r0,:128]!
512
        vaddw.u8        q0, q0, d16
513 514 515
        vst1.8          {d4},    [r3,:64], r2
        vld1.8          {d17},   [r1,:64], r2
        vld1.16         {d2-d3}, [r0,:128]!
516
        vaddw.u8        q1, q1, d17
517
        vst1.8          {d6},    [r3,:64], r2
518
        vqmovun.s16     d0, q0
519 520
        vld1.8          {d18},   [r1,:64], r2
        vld1.16         {d4-d5}, [r0,:128]!
521
        vaddw.u8        q2, q2, d18
522
        vst1.8          {d0},    [r3,:64], r2
523
        vqmovun.s16     d2, q1
524
        vld1.8          {d19},   [r1,:64], r2
525
        vqmovun.s16     d4, q2
526
        vld1.16         {d6-d7}, [r0,:128]!
527
        vaddw.u8        q3, q3, d19
528
        vst1.8          {d2},    [r3,:64], r2
529
        vqmovun.s16     d6, q3
530 531
        vst1.8          {d4},    [r3,:64], r2
        vst1.8          {d6},    [r3,:64], r2
532
        bx              lr
533
endfunc
534

535 536
function ff_vector_fmul_window_neon, export=1
        push            {r4,r5,lr}
537
        ldr             lr,  [sp, #12]
538 539 540 541 542 543
        sub             r2,  r2,  #8
        sub             r5,  lr,  #2
        add             r2,  r2,  r5, lsl #2
        add             r4,  r3,  r5, lsl #3
        add             ip,  r0,  r5, lsl #3
        mov             r5,  #-16
544 545 546 547
        vld1.32         {d0,d1},  [r1,:128]!
        vld1.32         {d2,d3},  [r2,:128], r5
        vld1.32         {d4,d5},  [r3,:128]!
        vld1.32         {d6,d7},  [r4,:128], r5
548
1:      subs            lr,  lr,  #4
549
        vmul.f32        d22, d0,  d4
550
        vrev64.32       q3,  q3
551
        vmul.f32        d23, d1,  d5
552
        vrev64.32       q1,  q1
553 554
        vmul.f32        d20, d0,  d7
        vmul.f32        d21, d1,  d6
555 556
        beq             2f
        vmla.f32        d22, d3,  d7
557
        vld1.32         {d0,d1},  [r1,:128]!
558
        vmla.f32        d23, d2,  d6
559
        vld1.32         {d18,d19},[r2,:128], r5
560
        vmls.f32        d20, d3,  d4
561
        vld1.32         {d24,d25},[r3,:128]!
562
        vmls.f32        d21, d2,  d5
563
        vld1.32         {d6,d7},  [r4,:128], r5
564 565 566 567
        vmov            q1,  q9
        vrev64.32       q11, q11
        vmov            q2,  q12
        vswp            d22, d23
568 569
        vst1.32         {d20,d21},[r0,:128]!
        vst1.32         {d22,d23},[ip,:128], r5
570 571 572 573 574 575 576
        b               1b
2:      vmla.f32        d22, d3,  d7
        vmla.f32        d23, d2,  d6
        vmls.f32        d20, d3,  d4
        vmls.f32        d21, d2,  d5
        vrev64.32       q11, q11
        vswp            d22, d23
577 578
        vst1.32         {d20,d21},[r0,:128]!
        vst1.32         {d22,d23},[ip,:128], r5
579
        pop             {r4,r5,pc}
580
endfunc
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626

#if CONFIG_VORBIS_DECODER
function ff_vorbis_inverse_coupling_neon, export=1
        vmov.i32        q10, #1<<31
        subs            r2,  r2,  #4
        mov             r3,  r0
        mov             r12, r1
        beq             3f

        vld1.32         {d24-d25},[r1,:128]!
        vld1.32         {d22-d23},[r0,:128]!
        vcle.s32        q8,  q12, #0
        vand            q9,  q11, q10
        veor            q12, q12, q9
        vand            q2,  q12, q8
        vbic            q3,  q12, q8
        vadd.f32        q12, q11, q2
        vsub.f32        q11, q11, q3
1:      vld1.32         {d2-d3},  [r1,:128]!
        vld1.32         {d0-d1},  [r0,:128]!
        vcle.s32        q8,  q1,  #0
        vand            q9,  q0,  q10
        veor            q1,  q1,  q9
        vst1.32         {d24-d25},[r3, :128]!
        vst1.32         {d22-d23},[r12,:128]!
        vand            q2,  q1,  q8
        vbic            q3,  q1,  q8
        vadd.f32        q1,  q0,  q2
        vsub.f32        q0,  q0,  q3
        subs            r2,  r2,  #8
        ble             2f
        vld1.32         {d24-d25},[r1,:128]!
        vld1.32         {d22-d23},[r0,:128]!
        vcle.s32        q8,  q12, #0
        vand            q9,  q11, q10
        veor            q12, q12, q9
        vst1.32         {d2-d3},  [r3, :128]!
        vst1.32         {d0-d1},  [r12,:128]!
        vand            q2,  q12, q8
        vbic            q3,  q12, q8
        vadd.f32        q12, q11, q2
        vsub.f32        q11, q11, q3
        b               1b

2:      vst1.32         {d2-d3},  [r3, :128]!
        vst1.32         {d0-d1},  [r12,:128]!
627
        it              lt
628 629 630 631 632 633 634 635 636 637 638 639 640 641
        bxlt            lr

3:      vld1.32         {d2-d3},  [r1,:128]
        vld1.32         {d0-d1},  [r0,:128]
        vcle.s32        q8,  q1,  #0
        vand            q9,  q0,  q10
        veor            q1,  q1,  q9
        vand            q2,  q1,  q8
        vbic            q3,  q1,  q8
        vadd.f32        q1,  q0,  q2
        vsub.f32        q0,  q0,  q3
        vst1.32         {d2-d3},  [r0,:128]!
        vst1.32         {d0-d1},  [r1,:128]!
        bx              lr
642
endfunc
643
#endif
644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671

function ff_vector_fmul_scalar_neon, export=1
VFP     len .req r2
NOVFP   len .req r3
VFP     vdup.32         q8,  d0[0]
NOVFP   vdup.32         q8,  r2
        bics            r12, len, #15
        beq             3f
        vld1.32         {q0},[r1,:128]!
        vld1.32         {q1},[r1,:128]!
1:      vmul.f32        q0,  q0,  q8
        vld1.32         {q2},[r1,:128]!
        vmul.f32        q1,  q1,  q8
        vld1.32         {q3},[r1,:128]!
        vmul.f32        q2,  q2,  q8
        vst1.32         {q0},[r0,:128]!
        vmul.f32        q3,  q3,  q8
        vst1.32         {q1},[r0,:128]!
        subs            r12, r12, #16
        beq             2f
        vld1.32         {q0},[r1,:128]!
        vst1.32         {q2},[r0,:128]!
        vld1.32         {q1},[r1,:128]!
        vst1.32         {q3},[r0,:128]!
        b               1b
2:      vst1.32         {q2},[r0,:128]!
        vst1.32         {q3},[r0,:128]!
        ands            len, len, #15
672
        it              eq
673 674 675 676 677 678 679 680
        bxeq            lr
3:      vld1.32         {q0},[r1,:128]!
        vmul.f32        q0,  q0,  q8
        vst1.32         {q0},[r0,:128]!
        subs            len, len, #4
        bgt             3b
        bx              lr
        .unreq          len
681
endfunc
682 683 684 685 686 687 688 689 690 691 692

function ff_butterflies_float_neon, export=1
1:      vld1.32         {q0},[r0,:128]
        vld1.32         {q1},[r1,:128]
        vsub.f32        q2,  q0,  q1
        vadd.f32        q1,  q0,  q1
        vst1.32         {q2},[r1,:128]!
        vst1.32         {q1},[r0,:128]!
        subs            r2,  r2,  #4
        bgt             1b
        bx              lr
693
endfunc
694 695 696 697 698 699 700 701 702 703 704 705

function ff_scalarproduct_float_neon, export=1
        vmov.f32        q2,  #0.0
1:      vld1.32         {q0},[r0,:128]!
        vld1.32         {q1},[r1,:128]!
        vmla.f32        q2,  q0,  q1
        subs            r2,  r2,  #4
        bgt             1b
        vadd.f32        d0,  d4,  d5
        vpadd.f32       d0,  d0,  d0
NOVFP   vmov.32         r0,  d0[0]
        bx              lr
706
endfunc
707

708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729
function ff_vector_fmul_reverse_neon, export=1
        add             r2,  r2,  r3,  lsl #2
        sub             r2,  r2,  #32
        mov             r12, #-32
        vld1.32         {q0-q1},  [r1,:128]!
        vld1.32         {q2-q3},  [r2,:128], r12
1:      pld             [r1, #32]
        vrev64.32       q3,  q3
        vmul.f32        d16, d0,  d7
        vmul.f32        d17, d1,  d6
        pld             [r2, #-32]
        vrev64.32       q2,  q2
        vmul.f32        d18, d2,  d5
        vmul.f32        d19, d3,  d4
        subs            r3,  r3,  #8
        beq             2f
        vld1.32         {q0-q1},  [r1,:128]!
        vld1.32         {q2-q3},  [r2,:128], r12
        vst1.32         {q8-q9},  [r0,:128]!
        b               1b
2:      vst1.32         {q8-q9},  [r0,:128]!
        bx              lr
730
endfunc
731

732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756
function ff_vector_fmul_add_neon, export=1
        ldr             r12, [sp]
        vld1.32         {q0-q1},  [r1,:128]!
        vld1.32         {q8-q9},  [r2,:128]!
        vld1.32         {q2-q3},  [r3,:128]!
        vmul.f32        q10, q0,  q8
        vmul.f32        q11, q1,  q9
1:      vadd.f32        q12, q2,  q10
        vadd.f32        q13, q3,  q11
        pld             [r1, #16]
        pld             [r2, #16]
        pld             [r3, #16]
        subs            r12, r12, #8
        beq             2f
        vld1.32         {q0},     [r1,:128]!
        vld1.32         {q8},     [r2,:128]!
        vmul.f32        q10, q0,  q8
        vld1.32         {q1},     [r1,:128]!
        vld1.32         {q9},     [r2,:128]!
        vmul.f32        q11, q1,  q9
        vld1.32         {q2-q3},  [r3,:128]!
        vst1.32         {q12-q13},[r0,:128]!
        b               1b
2:      vst1.32         {q12-q13},[r0,:128]!
        bx              lr
757
endfunc
758

759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782
function ff_vector_clipf_neon, export=1
VFP     vdup.32         q1,  d0[1]
VFP     vdup.32         q0,  d0[0]
NOVFP   vdup.32         q0,  r2
NOVFP   vdup.32         q1,  r3
NOVFP   ldr             r2,  [sp]
        vld1.f32        {q2},[r1,:128]!
        vmin.f32        q10, q2,  q1
        vld1.f32        {q3},[r1,:128]!
        vmin.f32        q11, q3,  q1
1:      vmax.f32        q8,  q10, q0
        vmax.f32        q9,  q11, q0
        subs            r2,  r2,  #8
        beq             2f
        vld1.f32        {q2},[r1,:128]!
        vmin.f32        q10, q2,  q1
        vld1.f32        {q3},[r1,:128]!
        vmin.f32        q11, q3,  q1
        vst1.f32        {q8},[r0,:128]!
        vst1.f32        {q9},[r0,:128]!
        b               1b
2:      vst1.f32        {q8},[r0,:128]!
        vst1.f32        {q9},[r0,:128]!
        bx              lr
783
endfunc
784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806

function ff_apply_window_int16_neon, export=1
        push            {r4,lr}
        add             r4,  r1,  r3,  lsl #1
        add             lr,  r0,  r3,  lsl #1
        sub             r4,  r4,  #16
        sub             lr,  lr,  #16
        mov             r12, #-16
1:
        vld1.16         {q0},     [r1,:128]!
        vld1.16         {q2},     [r2,:128]!
        vld1.16         {q1},     [r4,:128], r12
        vrev64.16       q3,  q2
        vqrdmulh.s16    q0,  q0,  q2
        vqrdmulh.s16    d2,  d2,  d7
        vqrdmulh.s16    d3,  d3,  d6
        vst1.16         {q0},     [r0,:128]!
        vst1.16         {q1},     [lr,:128], r12
        subs            r3,  r3,  #16
        bgt             1b

        pop             {r4,pc}
endfunc
807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822

function ff_vector_clip_int32_neon, export=1
        vdup.32         q0,  r2
        vdup.32         q1,  r3
        ldr             r2,  [sp]
1:
        vld1.32         {q2-q3},  [r1,:128]!
        vmin.s32        q2,  q2,  q1
        vmin.s32        q3,  q3,  q1
        vmax.s32        q2,  q2,  q0
        vmax.s32        q3,  q3,  q0
        vst1.32         {q2-q3},  [r0,:128]!
        subs            r2,  r2,  #8
        bgt             1b
        bx              lr
endfunc