ARM: replace some #if with if()
[ffmpeg.git] / libavcodec / arm / vp3dsp_neon.S
1 /*
2  * Copyright (c) 2009 David Conrad
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg 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  * FFmpeg 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 FFmpeg; 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 .section .rodata
24 .align 4
25
26 vp3_idct_constants:
27 .short 64277, 60547, 54491, 46341, 36410, 25080, 12785
28
29 #define xC1S7 d0[0]
30 #define xC2S6 d0[1]
31 #define xC3S5 d0[2]
32 #define xC4S4 d0[3]
33 #define xC5S3 d1[0]
34 #define xC6S2 d1[1]
35 #define xC7S1 d1[2]
36
37 .text
38
39 .macro vp3_loop_filter
40     vsubl.u8        q3,  d18, d17
41     vsubl.u8        q2,  d16, d19
42     vadd.i16        q1,  q3,  q3
43     vadd.i16        q2,  q2,  q3
44     vadd.i16        q0,  q1,  q2
45     vrshr.s16       q0,  q0,  #3
46     vmovl.u8        q9,  d18
47     vdup.u16        q15, r2
48
49     vabs.s16        q1,  q0
50     vshr.s16        q0,  q0,  #15
51     vqsub.u16       q2,  q15, q1
52     vqsub.u16       q3,  q2,  q1
53     vsub.i16        q1,  q2,  q3
54     veor            q1,  q1,  q0
55     vsub.i16        q0,  q1,  q0
56
57     vaddw.u8        q2,  q0,  d17
58     vsub.i16        q3,  q9,  q0
59     vqmovun.s16     d0,  q2
60     vqmovun.s16     d1,  q3
61 .endm
62
63 function ff_vp3_v_loop_filter_neon, export=1
64     sub             ip,  r0,  r1
65     sub             r0,  r0,  r1,  lsl #1
66     vld1.64         {d16}, [r0,:64], r1
67     vld1.64         {d17}, [r0,:64], r1
68     vld1.64         {d18}, [r0,:64], r1
69     vld1.64         {d19}, [r0,:64], r1
70     ldrb            r2,    [r2, #129*4]
71
72     vp3_loop_filter
73
74     vst1.64         {d0},  [ip,:64], r1
75     vst1.64         {d1},  [ip,:64], r1
76     bx              lr
77 .endfunc
78
79 function ff_vp3_h_loop_filter_neon, export=1
80     sub             ip,  r0,  #1
81     sub             r0,  r0,  #2
82     vld1.32         {d16[]},  [r0], r1
83     vld1.32         {d17[]},  [r0], r1
84     vld1.32         {d18[]},  [r0], r1
85     vld1.32         {d19[]},  [r0], r1
86     vld1.32         {d16[1]}, [r0], r1
87     vld1.32         {d17[1]}, [r0], r1
88     vld1.32         {d18[1]}, [r0], r1
89     vld1.32         {d19[1]}, [r0], r1
90     ldrb            r2,  [r2, #129*4]
91
92     vtrn.8          d16, d17
93     vtrn.8          d18, d19
94     vtrn.16         d16, d18
95     vtrn.16         d17, d19
96
97     vp3_loop_filter
98
99     vtrn.8          d0,  d1
100
101     vst1.16         {d0[0]}, [ip], r1
102     vst1.16         {d1[0]}, [ip], r1
103     vst1.16         {d0[1]}, [ip], r1
104     vst1.16         {d1[1]}, [ip], r1
105     vst1.16         {d0[2]}, [ip], r1
106     vst1.16         {d1[2]}, [ip], r1
107     vst1.16         {d0[3]}, [ip], r1
108     vst1.16         {d1[3]}, [ip], r1
109     bx              lr
110 .endfunc
111
112
113 function vp3_idct_start_neon
114     vpush           {d8-d15}
115     movrel          r3,  vp3_idct_constants
116     vld1.64         {d0-d1},   [r3,:128]
117     vld1.64         {d16-d19}, [r2,:128]!
118     vld1.64         {d20-d23}, [r2,:128]!
119     vld1.64         {d24-d27}, [r2,:128]!
120     vadd.s16        q1,  q8,  q12
121     vsub.s16        q8,  q8,  q12
122     vld1.64         {d28-d31}, [r2,:128]!
123 .endfunc
124
125 function vp3_idct_core_neon
126     vmull.s16       q2,  d18, xC1S7     // (ip[1] * C1) << 16
127     vmull.s16       q3,  d19, xC1S7
128     vmull.s16       q4,  d2,  xC4S4     // ((ip[0] + ip[4]) * C4) << 16
129     vmull.s16       q5,  d3,  xC4S4
130     vmull.s16       q6,  d16, xC4S4     // ((ip[0] - ip[4]) * C4) << 16
131     vmull.s16       q7,  d17, xC4S4
132     vshrn.s32       d4,  q2,  #16
133     vshrn.s32       d5,  q3,  #16
134     vshrn.s32       d6,  q4,  #16
135     vshrn.s32       d7,  q5,  #16
136     vshrn.s32       d8,  q6,  #16
137     vshrn.s32       d9,  q7,  #16
138     vadd.s16        q12, q1,  q3        // E = (ip[0] + ip[4]) * C4
139     vadd.s16        q8,  q8,  q4        // F = (ip[0] - ip[4]) * C4
140     vadd.s16        q1,  q2,  q9        // ip[1] * C1
141
142     vmull.s16       q2,  d30, xC1S7     // (ip[7] * C1) << 16
143     vmull.s16       q3,  d31, xC1S7
144     vmull.s16       q4,  d30, xC7S1     // (ip[7] * C7) << 16
145     vmull.s16       q5,  d31, xC7S1
146     vmull.s16       q6,  d18, xC7S1     // (ip[1] * C7) << 16
147     vmull.s16       q7,  d19, xC7S1
148     vshrn.s32       d4,  q2,  #16
149     vshrn.s32       d5,  q3,  #16
150     vshrn.s32       d6,  q4,  #16       // ip[7] * C7
151     vshrn.s32       d7,  q5,  #16
152     vshrn.s32       d8,  q6,  #16       // ip[1] * C7
153     vshrn.s32       d9,  q7,  #16
154     vadd.s16        q2,  q2,  q15       // ip[7] * C1
155     vadd.s16        q9,  q1,  q3        // A = ip[1] * C1 + ip[7] * C7
156     vsub.s16        q15, q4,  q2        // B = ip[1] * C7 - ip[7] * C1
157
158     vmull.s16       q2,  d22, xC5S3     // (ip[3] * C5) << 16
159     vmull.s16       q3,  d23, xC5S3
160     vmull.s16       q4,  d22, xC3S5     // (ip[3] * C3) << 16
161     vmull.s16       q5,  d23, xC3S5
162     vmull.s16       q6,  d26, xC5S3     // (ip[5] * C5) << 16
163     vmull.s16       q7,  d27, xC5S3
164     vshrn.s32       d4,  q2,  #16
165     vshrn.s32       d5,  q3,  #16
166     vshrn.s32       d6,  q4,  #16
167     vshrn.s32       d7,  q5,  #16
168     vshrn.s32       d8,  q6,  #16
169     vshrn.s32       d9,  q7,  #16
170     vadd.s16        q3,  q3,  q11       // ip[3] * C3
171     vadd.s16        q4,  q4,  q13       // ip[5] * C5
172     vadd.s16        q1,  q2,  q11       // ip[3] * C5
173     vadd.s16        q11, q3,  q4        // C = ip[3] * C3 + ip[5] * C5
174
175     vmull.s16       q2,  d26, xC3S5     // (ip[5] * C3) << 16
176     vmull.s16       q3,  d27, xC3S5
177     vmull.s16       q4,  d20, xC2S6     // (ip[2] * C2) << 16
178     vmull.s16       q5,  d21, xC2S6
179     vmull.s16       q6,  d28, xC6S2     // (ip[6] * C6) << 16
180     vmull.s16       q7,  d29, xC6S2
181     vshrn.s32       d4,  q2,  #16
182     vshrn.s32       d5,  q3,  #16
183     vshrn.s32       d6,  q4,  #16
184     vshrn.s32       d7,  q5,  #16
185     vshrn.s32       d8,  q6,  #16       // ip[6] * C6
186     vshrn.s32       d9,  q7,  #16
187     vadd.s16        q2,  q2,  q13       // ip[5] * C3
188     vadd.s16        q3,  q3,  q10       // ip[2] * C2
189     vsub.s16        q13, q2,  q1        // D = ip[5] * C3 - ip[3] * C5
190     vsub.s16        q1,  q9,  q11       // (A - C)
191     vadd.s16        q11, q9,  q11       // Cd = A + C
192     vsub.s16        q9,  q15, q13       // (B - D)
193     vadd.s16        q13, q15, q13       // Dd = B + D
194     vadd.s16        q15, q3,  q4        // G = ip[2] * C2 + ip[6] * C6
195
196     vmull.s16       q2,  d2,  xC4S4     // ((A - C) * C4) << 16
197     vmull.s16       q3,  d3,  xC4S4
198     vmull.s16       q4,  d28, xC2S6     // (ip[6] * C2) << 16
199     vmull.s16       q5,  d29, xC2S6
200     vmull.s16       q6,  d20, xC6S2     // (ip[2] * C6) << 16
201     vmull.s16       q7,  d21, xC6S2
202     vshrn.s32       d4,  q2,  #16
203     vshrn.s32       d5,  q3,  #16
204     vshrn.s32       d6,  q4,  #16
205     vshrn.s32       d7,  q5,  #16
206     vshrn.s32       d8,  q6,  #16       // ip[2] * C6
207     vmull.s16       q5,  d18, xC4S4     // ((B - D) * C4) << 16
208     vmull.s16       q6,  d19, xC4S4
209     vshrn.s32       d9,  q7,  #16
210     vadd.s16        q3,  q3,  q14       // ip[6] * C2
211     vadd.s16        q10, q1,  q2        // Ad = (A - C) * C4
212     vsub.s16        q14, q4,  q3        // H = ip[2] * C6 - ip[6] * C2
213     bx              lr
214 .endfunc
215
216 .macro VP3_IDCT_END type
217 function vp3_idct_end_\type\()_neon
218 .ifc \type, col
219     vdup.16         q0,  r3
220     vadd.s16        q12, q12, q0
221     vadd.s16        q8,  q8,  q0
222 .endif
223
224     vshrn.s32       d2,  q5,  #16
225     vshrn.s32       d3,  q6,  #16
226     vadd.s16        q2,  q12, q15       // Gd  = E + G
227     vadd.s16        q9,  q1,  q9        // (B - D) * C4
228     vsub.s16        q12, q12, q15       // Ed  = E - G
229     vsub.s16        q3,  q8,  q10       // Fd  = F - Ad
230     vadd.s16        q10, q8,  q10       // Add = F + Ad
231     vadd.s16        q4,  q9,  q14       // Hd  = Bd + H
232     vsub.s16        q14, q9,  q14       // Bdd = Bd - H
233     vadd.s16        q8,  q2,  q11       // [0] = Gd + Cd
234     vsub.s16        q15, q2,  q11       // [7] = Gd - Cd
235     vadd.s16        q9,  q10, q4        // [1] = Add + Hd
236     vsub.s16        q10, q10, q4        // [2] = Add - Hd
237     vadd.s16        q11, q12, q13       // [3] = Ed + Dd
238     vsub.s16        q12, q12, q13       // [4] = Ed - Dd
239 .ifc \type, row
240     vtrn.16         q8,  q9
241 .endif
242     vadd.s16        q13, q3,  q14       // [5] = Fd + Bdd
243     vsub.s16        q14, q3,  q14       // [6] = Fd - Bdd
244
245 .ifc \type, row
246     // 8x8 transpose
247     vtrn.16         q10, q11
248     vtrn.16         q12, q13
249     vtrn.16         q14, q15
250     vtrn.32         q8,  q10
251     vtrn.32         q9,  q11
252     vtrn.32         q12, q14
253     vtrn.32         q13, q15
254     vswp            d17, d24
255     vswp            d19, d26
256     vadd.s16        q1,  q8,  q12
257     vswp            d21, d28
258     vsub.s16        q8,  q8,  q12
259     vswp            d23, d30
260 .endif
261     bx              lr
262 .endfunc
263 .endm
264
265 VP3_IDCT_END row
266 VP3_IDCT_END col
267
268 function ff_vp3_idct_neon, export=1
269     mov             ip,  lr
270     mov             r2,  r0
271     bl              vp3_idct_start_neon
272     bl              vp3_idct_end_row_neon
273     mov             r3,  #8
274     bl              vp3_idct_core_neon
275     bl              vp3_idct_end_col_neon
276     mov             lr,  ip
277     vpop            {d8-d15}
278
279     vshr.s16        q8,  q8,  #4
280     vshr.s16        q9,  q9,  #4
281     vshr.s16        q10, q10, #4
282     vshr.s16        q11, q11, #4
283     vshr.s16        q12, q12, #4
284     vst1.64         {d16-d19}, [r0,:128]!
285     vshr.s16        q13, q13, #4
286     vshr.s16        q14, q14, #4
287     vst1.64         {d20-d23}, [r0,:128]!
288     vshr.s16        q15, q15, #4
289     vst1.64         {d24-d27}, [r0,:128]!
290     vst1.64         {d28-d31}, [r0,:128]!
291     bx              lr
292 .endfunc
293
294 function ff_vp3_idct_put_neon, export=1
295     mov             ip,  lr
296     bl              vp3_idct_start_neon
297     bl              vp3_idct_end_row_neon
298     mov             r3,  #8
299     add             r3,  r3,  #2048         // convert signed pixel to unsigned
300     bl              vp3_idct_core_neon
301     bl              vp3_idct_end_col_neon
302     mov             lr,  ip
303     vpop            {d8-d15}
304
305     vqshrun.s16     d0,  q8,  #4
306     vqshrun.s16     d1,  q9,  #4
307     vqshrun.s16     d2,  q10, #4
308     vqshrun.s16     d3,  q11, #4
309     vst1.64         {d0}, [r0,:64], r1
310     vqshrun.s16     d4,  q12, #4
311     vst1.64         {d1}, [r0,:64], r1
312     vqshrun.s16     d5,  q13, #4
313     vst1.64         {d2}, [r0,:64], r1
314     vqshrun.s16     d6,  q14, #4
315     vst1.64         {d3}, [r0,:64], r1
316     vqshrun.s16     d7,  q15, #4
317     vst1.64         {d4}, [r0,:64], r1
318     vst1.64         {d5}, [r0,:64], r1
319     vst1.64         {d6}, [r0,:64], r1
320     vst1.64         {d7}, [r0,:64], r1
321     bx              lr
322 .endfunc
323
324 function ff_vp3_idct_add_neon, export=1
325     mov             ip,  lr
326     bl              vp3_idct_start_neon
327     bl              vp3_idct_end_row_neon
328     mov             r3,  #8
329     bl              vp3_idct_core_neon
330     bl              vp3_idct_end_col_neon
331     mov             lr,  ip
332     vpop            {d8-d15}
333     mov             r2,  r0
334
335     vld1.64         {d0}, [r0,:64], r1
336     vshr.s16        q8,  q8,  #4
337     vld1.64         {d1}, [r0,:64], r1
338     vshr.s16        q9,  q9,  #4
339     vld1.64         {d2}, [r0,:64], r1
340     vaddw.u8        q8,  q8,  d0
341     vld1.64         {d3}, [r0,:64], r1
342     vaddw.u8        q9,  q9,  d1
343     vld1.64         {d4}, [r0,:64], r1
344     vshr.s16        q10, q10, #4
345     vld1.64         {d5}, [r0,:64], r1
346     vshr.s16        q11, q11, #4
347     vld1.64         {d6}, [r0,:64], r1
348     vqmovun.s16     d0,  q8
349     vld1.64         {d7}, [r0,:64], r1
350     vqmovun.s16     d1,  q9
351     vaddw.u8        q10, q10, d2
352     vaddw.u8        q11, q11, d3
353     vshr.s16        q12, q12, #4
354     vshr.s16        q13, q13, #4
355     vqmovun.s16     d2,  q10
356     vqmovun.s16     d3,  q11
357     vaddw.u8        q12, q12, d4
358     vaddw.u8        q13, q13, d5
359     vshr.s16        q14, q14, #4
360     vshr.s16        q15, q15, #4
361     vst1.64         {d0}, [r2,:64], r1
362     vqmovun.s16     d4,  q12
363     vst1.64         {d1}, [r2,:64], r1
364     vqmovun.s16     d5,  q13
365     vst1.64         {d2}, [r2,:64], r1
366     vaddw.u8        q14, q14, d6
367     vst1.64         {d3}, [r2,:64], r1
368     vaddw.u8        q15, q15, d7
369     vst1.64         {d4}, [r2,:64], r1
370     vqmovun.s16     d6,  q14
371     vst1.64         {d5}, [r2,:64], r1
372     vqmovun.s16     d7,  q15
373     vst1.64         {d6}, [r2,:64], r1
374     vst1.64         {d7}, [r2,:64], r1
375     bx              lr
376 .endfunc