rv34: NEON optimised 4x4 dequant
[ffmpeg.git] / libavcodec / arm / rv34dsp_neon.S
1 /*
2  * Copyright (c) 2011 Janne Grunau <janne-libav@jannau.net>
3  *
4  * This file is part of Libav.
5  *
6  * Libav is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * Libav is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with Libav; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 #include "asm.S"
22
23 .macro rv34_inv_transform
24         mov             r1,  #16
25         vld1.16         {d28}, [r0,:64], r1     @ block[i+8*0]
26         vld1.16         {d29}, [r0,:64], r1     @ block[i+8*1]
27         vld1.16         {d30}, [r0,:64], r1     @ block[i+8*2]
28         vld1.16         {d31}, [r0,:64], r1     @ block[i+8*3]
29         vmov.s16        d0,  #13
30         vshll.s16       q12, d29, #3
31         vshll.s16       q13, d29, #4
32         vshll.s16       q9,  d31, #3
33         vshll.s16       q1,  d31, #4
34         vmull.s16       q10, d28, d0
35         vmlal.s16       q10, d30, d0
36         vmull.s16       q11, d28, d0
37         vmlsl.s16       q11, d30, d0
38         vsubw.s16       q12, q12, d29   @ z2 = block[i+8*1]*7
39         vaddw.s16       q13, q13, d29   @ z3 = block[i+8*1]*17
40         vsubw.s16       q9,  q9,  d31
41         vaddw.s16       q1,  q1,  d31
42         vadd.s32        q13, q13, q9    @ z3 = 17*block[i+8*1] +  7*block[i+8*3]
43         vsub.s32        q12, q12, q1    @ z2 = 7*block[i+8*1]  - 17*block[i+8*3]
44         vadd.s32        q1,  q10, q13   @ z0 + z3
45         vadd.s32        q2,  q11, q12   @ z1 + z2
46         vsub.s32        q8,  q10, q13   @ z0 - z3
47         vsub.s32        q3,  q11, q12   @ z1 - z2
48         vtrn.32         q1,  q2
49         vtrn.32         q3,  q8
50         vswp            d3,  d6
51         vswp            d5,  d16
52         vmov.s32        d0,  #13
53         vadd.s32        q10, q1,  q3
54         vsub.s32        q11, q1,  q3
55         vshl.s32        q12, q2,  #3
56         vshl.s32        q9,  q2,  #4
57         vmul.s32        q13, q11, d0[0]
58         vshl.s32        q11, q8,  #4
59         vadd.s32        q9,  q9,  q2
60         vshl.s32        q15, q8,  #3
61         vsub.s32        q12, q12, q2
62         vadd.s32        q11, q11, q8
63         vmul.s32        q14, q10, d0[0]
64         vsub.s32        q8,  q15, q8
65         vsub.s32        q12, q12, q11
66         vadd.s32        q9,  q9,  q8
67         vadd.s32        q2,  q13, q12   @ z1 + z2
68         vadd.s32        q1,  q14, q9    @ z0 + z3
69         vsub.s32        q3,  q13, q12   @ z1 - z2
70         vsub.s32        q15, q14, q9    @ z0 - z3
71 .endm
72
73 /* void ff_rv34_inv_transform_neon(DCTELEM *block); */
74 function ff_rv34_inv_transform_neon, export=1
75         mov             r2,  r0
76         rv34_inv_transform
77         vrshrn.s32      d1,  q2,  #10   @ (z1 + z2) >> 10
78         vrshrn.s32      d0,  q1,  #10   @ (z0 + z3) >> 10
79         vrshrn.s32      d2,  q3,  #10   @ (z1 - z2) >> 10
80         vrshrn.s32      d3,  q15, #10   @ (z0 - z3) >> 10
81         vst4.16         {d0[0], d1[0], d2[0], d3[0]}, [r2,:64], r1
82         vst4.16         {d0[1], d1[1], d2[1], d3[1]}, [r2,:64], r1
83         vst4.16         {d0[2], d1[2], d2[2], d3[2]}, [r2,:64], r1
84         vst4.16         {d0[3], d1[3], d2[3], d3[3]}, [r2,:64], r1
85         bx              lr
86 endfunc
87
88 /* void rv34_inv_transform_noround_neon(DCTELEM *block); */
89 function ff_rv34_inv_transform_noround_neon, export=1
90         mov             r2,  r0
91         rv34_inv_transform
92         vshl.s32        q11, q2,  #1
93         vshl.s32        q10, q1,  #1
94         vshl.s32        q12, q3,  #1
95         vshl.s32        q13, q15, #1
96         vadd.s32        q11, q11, q2
97         vadd.s32        q10, q10, q1
98         vadd.s32        q12, q12, q3
99         vadd.s32        q13, q13, q15
100         vshrn.s32       d0,  q10, #11   @ (z0 + z3)*3 >> 11
101         vshrn.s32       d1,  q11, #11   @ (z1 + z2)*3 >> 11
102         vshrn.s32       d2,  q12, #11   @ (z1 - z2)*3 >> 11
103         vshrn.s32       d3,  q13, #11   @ (z0 - z3)*3 >> 11
104         vst4.16         {d0[0], d1[0], d2[0], d3[0]}, [r2,:64], r1
105         vst4.16         {d0[1], d1[1], d2[1], d3[1]}, [r2,:64], r1
106         vst4.16         {d0[2], d1[2], d2[2], d3[2]}, [r2,:64], r1
107         vst4.16         {d0[3], d1[3], d2[3], d3[3]}, [r2,:64], r1
108         bx              lr
109 endfunc
110
111 function ff_rv34_dequant4x4_neon, export=1
112         mov             r3,  r0
113         mov             r12, #16
114         vdup.16         q0,  r2
115         vmov.16         d0[0], r1
116         vld1.16         {d2},     [r0,:64], r12
117         vld1.16         {d4},     [r0,:64], r12
118         vld1.16         {d6},     [r0,:64], r12
119         vld1.16         {d16},    [r0,:64], r12
120         vmull.s16       q1,  d2,  d0
121         vmull.s16       q2,  d4,  d1
122         vmull.s16       q3,  d6,  d1
123         vmull.s16       q8,  d16, d1
124         vqrshrn.s32     d2,  q1,  #4
125         vqrshrn.s32     d4,  q2,  #4
126         vqrshrn.s32     d6,  q3,  #4
127         vqrshrn.s32     d16, q8,  #4
128         vst1.16         {d2},     [r3,:64], r12
129         vst1.16         {d4},     [r3,:64], r12
130         vst1.16         {d6},     [r3,:64], r12
131         vst1.16         {d16},    [r3,:64], r12
132         bx              lr
133 endfunc