|
- /*
- * Copyright (c) 2013 RISC OS Open Ltd
- * Author: Ben Avison <bavison@riscosopen.org>
- *
- * This file is part of Libav.
- *
- * Libav 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.
- *
- * Libav 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 Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- #include "libavutil/arm/asm.S"
-
- POUT .req a1
- PIN .req a2
- PCOEF .req a3
- DECIFACTOR .req a4
- OLDFPSCR .req a4
- COUNTER .req ip
-
- SCALE32 .req s28 @ use vector of 4 in place of 9th scalar when decifactor=32 / JMAX=8
- SCALE64 .req s0 @ spare register in scalar bank when decifactor=64 / JMAX=4
- IN0 .req s4
- IN1 .req s5
- IN2 .req s6
- IN3 .req s7
- IN4 .req s0
- IN5 .req s1
- IN6 .req s2
- IN7 .req s3
- COEF0 .req s8 @ coefficient elements
- COEF1 .req s9
- COEF2 .req s10
- COEF3 .req s11
- COEF4 .req s12
- COEF5 .req s13
- COEF6 .req s14
- COEF7 .req s15
- ACCUM0 .req s16 @ double-buffered multiply-accumulate results
- ACCUM4 .req s20
- POST0 .req s24 @ do long-latency post-multiply in this vector in parallel
- POST1 .req s25
- POST2 .req s26
- POST3 .req s27
-
-
- .macro inner_loop decifactor, dir, tail, head
- .ifc "\dir","up"
- .set X, 0
- .set Y, 4
- .else
- .set X, 4*JMAX*4 - 4
- .set Y, -4
- .endif
- .ifnc "\head",""
- vldr COEF0, [PCOEF, #X + (0*JMAX + 0) * Y]
- vldr COEF1, [PCOEF, #X + (1*JMAX + 0) * Y]
- vldr COEF2, [PCOEF, #X + (2*JMAX + 0) * Y]
- vldr COEF3, [PCOEF, #X + (3*JMAX + 0) * Y]
- .endif
- .ifnc "\tail",""
- vadd.f POST0, ACCUM0, ACCUM4 @ vector operation
- .endif
- .ifnc "\head",""
- vmul.f ACCUM0, COEF0, IN0 @ vector = vector * scalar
- vldr COEF4, [PCOEF, #X + (0*JMAX + 1) * Y]
- vldr COEF5, [PCOEF, #X + (1*JMAX + 1) * Y]
- vldr COEF6, [PCOEF, #X + (2*JMAX + 1) * Y]
- .endif
- .ifnc "\tail",""
- vmul.f POST0, POST0, SCALE\decifactor @ vector operation (SCALE may be scalar)
- .endif
- .ifnc "\head",""
- vldr COEF7, [PCOEF, #X + (3*JMAX + 1) * Y]
- .ifc "\tail",""
- vmul.f ACCUM4, COEF4, IN1 @ vector operation
- .endif
- vldr COEF0, [PCOEF, #X + (0*JMAX + 2) * Y]
- vldr COEF1, [PCOEF, #X + (1*JMAX + 2) * Y]
- .ifnc "\tail",""
- vmul.f ACCUM4, COEF4, IN1 @ vector operation
- .endif
- vldr COEF2, [PCOEF, #X + (2*JMAX + 2) * Y]
- vldr COEF3, [PCOEF, #X + (3*JMAX + 2) * Y]
- .endif
- .ifnc "\tail",""
- vstmia POUT!, {POST0-POST3}
- .endif
- .ifnc "\head",""
- vmla.f ACCUM0, COEF0, IN2 @ vector = vector * scalar
- vldr COEF4, [PCOEF, #X + (0*JMAX + 3) * Y]
- vldr COEF5, [PCOEF, #X + (1*JMAX + 3) * Y]
- vldr COEF6, [PCOEF, #X + (2*JMAX + 3) * Y]
- vldr COEF7, [PCOEF, #X + (3*JMAX + 3) * Y]
- vmla.f ACCUM4, COEF4, IN3 @ vector = vector * scalar
- .if \decifactor == 32
- vldr COEF0, [PCOEF, #X + (0*JMAX + 4) * Y]
- vldr COEF1, [PCOEF, #X + (1*JMAX + 4) * Y]
- vldr COEF2, [PCOEF, #X + (2*JMAX + 4) * Y]
- vldr COEF3, [PCOEF, #X + (3*JMAX + 4) * Y]
- vmla.f ACCUM0, COEF0, IN4 @ vector = vector * scalar
- vldr COEF4, [PCOEF, #X + (0*JMAX + 5) * Y]
- vldr COEF5, [PCOEF, #X + (1*JMAX + 5) * Y]
- vldr COEF6, [PCOEF, #X + (2*JMAX + 5) * Y]
- vldr COEF7, [PCOEF, #X + (3*JMAX + 5) * Y]
- vmla.f ACCUM4, COEF4, IN5 @ vector = vector * scalar
- vldr COEF0, [PCOEF, #X + (0*JMAX + 6) * Y]
- vldr COEF1, [PCOEF, #X + (1*JMAX + 6) * Y]
- vldr COEF2, [PCOEF, #X + (2*JMAX + 6) * Y]
- vldr COEF3, [PCOEF, #X + (3*JMAX + 6) * Y]
- vmla.f ACCUM0, COEF0, IN6 @ vector = vector * scalar
- vldr COEF4, [PCOEF, #X + (0*JMAX + 7) * Y]
- vldr COEF5, [PCOEF, #X + (1*JMAX + 7) * Y]
- vldr COEF6, [PCOEF, #X + (2*JMAX + 7) * Y]
- vldr COEF7, [PCOEF, #X + (3*JMAX + 7) * Y]
- vmla.f ACCUM4, COEF4, IN7 @ vector = vector * scalar
- .endif
- .endif
- .endm
-
- .macro dca_lfe_fir decifactor
- .if \decifactor == 32
- .set JMAX, 8
- vpush {s16-s31}
- vmov SCALE32, s0 @ duplicate scalar across vector
- vldr IN4, [PIN, #-4*4]
- vldr IN5, [PIN, #-5*4]
- vldr IN6, [PIN, #-6*4]
- vldr IN7, [PIN, #-7*4]
- .else
- .set JMAX, 4
- vpush {s16-s27}
- .endif
-
- mov COUNTER, #\decifactor/4 - 1
- inner_loop \decifactor, up,, head
- 1: add PCOEF, PCOEF, #4*JMAX*4
- subs COUNTER, COUNTER, #1
- inner_loop \decifactor, up, tail, head
- bne 1b
- inner_loop \decifactor, up, tail
-
- mov COUNTER, #\decifactor/4 - 1
- inner_loop \decifactor, down,, head
- 1: sub PCOEF, PCOEF, #4*JMAX*4
- subs COUNTER, COUNTER, #1
- inner_loop \decifactor, down, tail, head
- bne 1b
- inner_loop \decifactor, down, tail
-
- .if \decifactor == 32
- vpop {s16-s31}
- .else
- vpop {s16-s27}
- .endif
- fmxr FPSCR, OLDFPSCR
- bx lr
- .endm
-
-
- /* void ff_dca_lfe_fir_vfp(float *out, const float *in, const float *coefs,
- * int decifactor, float scale)
- */
- function ff_dca_lfe_fir_vfp, export=1
- teq DECIFACTOR, #32
- fmrx OLDFPSCR, FPSCR
- ldr ip, =0x03030000 @ RunFast mode, short vectors of length 4, stride 1
- fmxr FPSCR, ip
- NOVFP vldr s0, [sp]
- vldr IN0, [PIN, #-0*4]
- vldr IN1, [PIN, #-1*4]
- vldr IN2, [PIN, #-2*4]
- vldr IN3, [PIN, #-3*4]
- beq 32f
- 64: dca_lfe_fir 64
- .ltorg
- 32: dca_lfe_fir 32
- endfunc
-
- .unreq POUT
- .unreq PIN
- .unreq PCOEF
- .unreq DECIFACTOR
- .unreq OLDFPSCR
- .unreq COUNTER
-
- .unreq SCALE32
- .unreq SCALE64
- .unreq IN0
- .unreq IN1
- .unreq IN2
- .unreq IN3
- .unreq IN4
- .unreq IN5
- .unreq IN6
- .unreq IN7
- .unreq COEF0
- .unreq COEF1
- .unreq COEF2
- .unreq COEF3
- .unreq COEF4
- .unreq COEF5
- .unreq COEF6
- .unreq COEF7
- .unreq ACCUM0
- .unreq ACCUM4
- .unreq POST0
- .unreq POST1
- .unreq POST2
- .unreq POST3
|