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