Statistics
| Branch: | Revision:

ffmpeg / libavcodec / arm / simple_idct_neon.S @ a2fc0f6a

History | View | Annotate | Download (12.2 KB)

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

    
26
#include "asm.S"
27

    
28
#define W1  22725  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
29
#define W2  21407  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
30
#define W3  19266  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
31
#define W4  16383  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
32
#define W5  12873  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
33
#define W6  8867   //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
34
#define W7  4520   //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
35
#define W4c ((1<<(COL_SHIFT-1))/W4)
36
#define ROW_SHIFT 11
37
#define COL_SHIFT 20
38

    
39
#define w1 d0[0]
40
#define w2 d0[1]
41
#define w3 d0[2]
42
#define w4 d0[3]
43
#define w5 d1[0]
44
#define w6 d1[1]
45
#define w7 d1[2]
46
#define w4c d1[3]
47

    
48
        .fpu neon
49

    
50
        .macro idct_col4_top
51
        vmull.s16       q7,  d6,  w2    /* q9   = W2 * col[2] */
52
        vmull.s16       q8,  d6,  w6    /* q10  = W6 * col[2] */
53
        vmull.s16       q9,  d4,  w1    /* q9   = W1 * col[1] */
54
        vadd.i32        q11, q15, q7
55
        vmull.s16       q10, d4,  w3    /* q10  = W3 * col[1] */
56
        vadd.i32        q12, q15, q8
57
        vmull.s16       q5,  d4,  w5    /* q5   = W5 * col[1] */
58
        vsub.i32        q13, q15, q8
59
        vmull.s16       q6,  d4,  w7    /* q6   = W7 * col[1] */
60
        vsub.i32        q14, q15, q7
61

    
62
        vmlal.s16       q9,  d8,  w3    /* q9  += W3 * col[3] */
63
        vmlsl.s16       q10, d8,  w7    /* q10 -= W7 * col[3] */
64
        vmlsl.s16       q5,  d8,  w1    /* q5  -= W1 * col[3] */
65
        vmlsl.s16       q6,  d8,  w5    /* q6  -= W5 * col[3] */
66
        .endm
67

    
68
        .text
69
        .align 6
70

    
71
function idct_row4_neon
72
        vmov.i32        q15, #(1<<(ROW_SHIFT-1))
73
        vld1.64         {d2-d5},  [r2,:128]!
74
        vmlal.s16       q15, d2,  w4    /* q15  += W4 * col[0] */
75
        vld1.64         {d6,d7},  [r2,:128]!
76
        vorr            d10, d3,  d5
77
        vld1.64         {d8,d9},  [r2,:128]!
78
        add             r2,  r2,  #-64
79

    
80
        vorr            d11, d7,  d9
81
        vorr            d10, d10, d11
82
        vmov            r3,  r4,  d10
83

    
84
        idct_col4_top
85

    
86
        orrs            r3,  r3,  r4
87
        beq             1f
88

    
89
        vmull.s16       q7,  d3,  w4    /* q7   = W4 * col[4] */
90
        vmlal.s16       q9,  d5,  w5    /* q9  += W5 * col[5] */
91
        vmlsl.s16       q10, d5,  w1    /* q10 -= W1 * col[5] */
92
        vmull.s16       q8,  d7,  w2    /* q8   = W2 * col[6] */
93
        vmlal.s16       q5,  d5,  w7    /* q5  += W7 * col[5] */
94
        vadd.i32        q11, q11, q7
95
        vsub.i32        q12, q12, q7
96
        vsub.i32        q13, q13, q7
97
        vadd.i32        q14, q14, q7
98
        vmlal.s16       q6,  d5,  w3    /* q6  += W3 * col[5] */
99
        vmull.s16       q7,  d7,  w6    /* q7   = W6 * col[6] */
100
        vmlal.s16       q9,  d9,  w7
101
        vmlsl.s16       q10, d9,  w5
102
        vmlal.s16       q5,  d9,  w3
103
        vmlsl.s16       q6,  d9,  w1
104
        vadd.i32        q11, q11, q7
105
        vsub.i32        q12, q12, q8
106
        vadd.i32        q13, q13, q8
107
        vsub.i32        q14, q14, q7
108

    
109
1:      vadd.i32        q3,  q11, q9
110
        vadd.i32        q4,  q12, q10
111
        vshrn.i32       d2,  q3,  #ROW_SHIFT
112
        vshrn.i32       d4,  q4,  #ROW_SHIFT
113
        vadd.i32        q7,  q13, q5
114
        vadd.i32        q8,  q14, q6
115
        vtrn.16         d2,  d4
116
        vshrn.i32       d6,  q7,  #ROW_SHIFT
117
        vshrn.i32       d8,  q8,  #ROW_SHIFT
118
        vsub.i32        q14, q14, q6
119
        vsub.i32        q11, q11, q9
120
        vtrn.16         d6,  d8
121
        vsub.i32        q13, q13, q5
122
        vshrn.i32       d3,  q14, #ROW_SHIFT
123
        vtrn.32         d2,  d6
124
        vsub.i32        q12, q12, q10
125
        vtrn.32         d4,  d8
126
        vshrn.i32       d5,  q13, #ROW_SHIFT
127
        vshrn.i32       d7,  q12, #ROW_SHIFT
128
        vshrn.i32       d9,  q11, #ROW_SHIFT
129

    
130
        vtrn.16         d3,  d5
131
        vtrn.16         d7,  d9
132
        vtrn.32         d3,  d7
133
        vtrn.32         d5,  d9
134

    
135
        vst1.64         {d2-d5},  [r2,:128]!
136
        vst1.64         {d6-d9},  [r2,:128]!
137

    
138
        bx              lr
139
        .endfunc
140

    
141
function idct_col4_neon
142
        mov             ip,  #16
143
        vld1.64         {d2}, [r2,:64], ip /* d2 = col[0] */
144
        vdup.16         d30, w4c
145
        vld1.64         {d4}, [r2,:64], ip /* d3 = col[1] */
146
        vadd.i16        d30, d30, d2
147
        vld1.64         {d6}, [r2,:64], ip /* d4 = col[2] */
148
        vmull.s16       q15, d30, w4 /* q15 = W4*(col[0]+(1<<COL_SHIFT-1)/W4)*/
149
        vld1.64         {d8}, [r2,:64], ip /* d5 = col[3] */
150

    
151
        ldrd            r4,  [r2]
152
        ldrd            r6,  [r2, #16]
153
        orrs            r4,  r4,  r5
154

    
155
        idct_col4_top
156
        addeq           r2,  r2,  #16
157
        beq             1f
158

    
159
        vld1.64         {d3}, [r2,:64], ip /* d6 = col[4] */
160
        vmull.s16       q7,  d3,  w4    /* q7   = W4 * col[4] */
161
        vadd.i32        q11, q11, q7
162
        vsub.i32        q12, q12, q7
163
        vsub.i32        q13, q13, q7
164
        vadd.i32        q14, q14, q7
165

    
166
1:      orrs            r6,  r6,  r7
167
        ldrd            r4,  [r2, #16]
168
        addeq           r2,  r2,  #16
169
        beq             2f
170

    
171
        vld1.64         {d5}, [r2,:64], ip /* d7 = col[5] */
172
        vmlal.s16       q9,  d5,  w5    /* q9  += W5 * col[5] */
173
        vmlsl.s16       q10, d5,  w1    /* q10 -= W1 * col[5] */
174
        vmlal.s16       q5,  d5,  w7    /* q5  += W7 * col[5] */
175
        vmlal.s16       q6,  d5,  w3    /* q6  += W3 * col[5] */
176

    
177
2:      orrs            r4,  r4,  r5
178
        ldrd            r4,  [r2, #16]
179
        addeq           r2,  r2,  #16
180
        beq             3f
181

    
182
        vld1.64         {d7}, [r2,:64], ip /* d8 = col[6] */
183
        vmull.s16       q7,  d7,  w6    /* q7   = W6 * col[6] */
184
        vmull.s16       q8,  d7,  w2    /* q8   = W2 * col[6] */
185
        vadd.i32        q11, q11, q7
186
        vsub.i32        q14, q14, q7
187
        vsub.i32        q12, q12, q8
188
        vadd.i32        q13, q13, q8
189

    
190
3:      orrs            r4,  r4,  r5
191
        addeq           r2,  r2,  #16
192
        beq             4f
193

    
194
        vld1.64         {d9}, [r2,:64], ip /* d9 = col[7] */
195
        vmlal.s16       q9,  d9,  w7
196
        vmlsl.s16       q10, d9,  w5
197
        vmlal.s16       q5,  d9,  w3
198
        vmlsl.s16       q6,  d9,  w1
199

    
200
4:      vaddhn.i32      d2,  q11, q9
201
        vaddhn.i32      d3,  q12, q10
202
        vaddhn.i32      d4,  q13, q5
203
        vaddhn.i32      d5,  q14, q6
204
        vsubhn.i32      d9,  q11, q9
205
        vsubhn.i32      d8,  q12, q10
206
        vsubhn.i32      d7,  q13, q5
207
        vsubhn.i32      d6,  q14, q6
208

    
209
        bx              lr
210
        .endfunc
211

    
212
        .align 6
213

    
214
function idct_col4_st8_neon
215
        vqshrun.s16     d2,  q1,  #COL_SHIFT-16
216
        vqshrun.s16     d3,  q2,  #COL_SHIFT-16
217
        vqshrun.s16     d4,  q3,  #COL_SHIFT-16
218
        vqshrun.s16     d5,  q4,  #COL_SHIFT-16
219
        vst1.32         {d2[0]}, [r0,:32], r1
220
        vst1.32         {d2[1]}, [r0,:32], r1
221
        vst1.32         {d3[0]}, [r0,:32], r1
222
        vst1.32         {d3[1]}, [r0,:32], r1
223
        vst1.32         {d4[0]}, [r0,:32], r1
224
        vst1.32         {d4[1]}, [r0,:32], r1
225
        vst1.32         {d5[0]}, [r0,:32], r1
226
        vst1.32         {d5[1]}, [r0,:32], r1
227

    
228
        bx              lr
229
        .endfunc
230

    
231
        .section .rodata
232
        .align 4
233
const:  .short W1, W2, W3, W4, W5, W6, W7, W4c
234
        .previous
235

    
236
        .macro idct_start data
237
        push            {r4-r7, lr}
238
        pld             [\data]
239
        pld             [\data, #64]
240
        vpush           {d8-d15}
241
        movw            r3, #:lower16:const
242
        movt            r3, #:upper16:const
243
        vld1.64         {d0,d1}, [r3,:128]
244
        .endm
245

    
246
        .macro idct_end
247
        vpop            {d8-d15}
248
        pop             {r4-r7, pc}
249
        .endm
250

    
251
/* void ff_simple_idct_put_neon(uint8_t *dst, int line_size, DCTELEM *data); */
252
function ff_simple_idct_put_neon, export=1
253
        idct_start      r2
254

    
255
        bl              idct_row4_neon
256
        bl              idct_row4_neon
257
        add             r2,  r2,  #-128
258
        bl              idct_col4_neon
259
        bl              idct_col4_st8_neon
260
        sub             r0,  r0,  r1, lsl #3
261
        add             r0,  r0,  #4
262
        add             r2,  r2,  #-120
263
        bl              idct_col4_neon
264
        bl              idct_col4_st8_neon
265

    
266
        idct_end
267
        .endfunc
268

    
269
        .align 6
270

    
271
function idct_col4_add8_neon
272
        mov             ip,  r0
273

    
274
        vld1.32         {d10[0]}, [r0,:32], r1
275
        vshr.s16        q1,  q1,  #COL_SHIFT-16
276
        vld1.32         {d10[1]}, [r0,:32], r1
277
        vshr.s16        q2,  q2,  #COL_SHIFT-16
278
        vld1.32         {d11[0]}, [r0,:32], r1
279
        vshr.s16        q3,  q3,  #COL_SHIFT-16
280
        vld1.32         {d11[1]}, [r0,:32], r1
281
        vshr.s16        q4,  q4,  #COL_SHIFT-16
282
        vld1.32         {d12[0]}, [r0,:32], r1
283
        vaddw.u8        q1,  q1,  d10
284
        vld1.32         {d12[1]}, [r0,:32], r1
285
        vaddw.u8        q2,  q2,  d11
286
        vld1.32         {d13[0]}, [r0,:32], r1
287
        vqmovun.s16     d2,  q1
288
        vld1.32         {d13[1]}, [r0,:32], r1
289
        vaddw.u8        q3,  q3,  d12
290
        vst1.32         {d2[0]},  [ip,:32], r1
291
        vqmovun.s16     d3,  q2
292
        vst1.32         {d2[1]},  [ip,:32], r1
293
        vaddw.u8        q4,  q4,  d13
294
        vst1.32         {d3[0]},  [ip,:32], r1
295
        vqmovun.s16     d4,  q3
296
        vst1.32         {d3[1]},  [ip,:32], r1
297
        vqmovun.s16     d5,  q4
298
        vst1.32         {d4[0]},  [ip,:32], r1
299
        vst1.32         {d4[1]},  [ip,:32], r1
300
        vst1.32         {d5[0]},  [ip,:32], r1
301
        vst1.32         {d5[1]},  [ip,:32], r1
302

    
303
        bx              lr
304
        .endfunc
305

    
306
/* void ff_simple_idct_add_neon(uint8_t *dst, int line_size, DCTELEM *data); */
307
function ff_simple_idct_add_neon, export=1
308
        idct_start      r2
309

    
310
        bl              idct_row4_neon
311
        bl              idct_row4_neon
312
        add             r2,  r2,  #-128
313
        bl              idct_col4_neon
314
        bl              idct_col4_add8_neon
315
        sub             r0,  r0,  r1, lsl #3
316
        add             r0,  r0,  #4
317
        add             r2,  r2,  #-120
318
        bl              idct_col4_neon
319
        bl              idct_col4_add8_neon
320

    
321
        idct_end
322
        .endfunc
323

    
324
        .align 6
325

    
326
function idct_col4_st16_neon
327
        mov             ip,  #16
328

    
329
        vshr.s16        q1,  q1,  #COL_SHIFT-16
330
        vshr.s16        q2,  q2,  #COL_SHIFT-16
331
        vst1.64         {d2}, [r2,:64], ip
332
        vshr.s16        q3,  q3,  #COL_SHIFT-16
333
        vst1.64         {d3}, [r2,:64], ip
334
        vshr.s16        q4,  q4,  #COL_SHIFT-16
335
        vst1.64         {d4}, [r2,:64], ip
336
        vst1.64         {d5}, [r2,:64], ip
337
        vst1.64         {d6}, [r2,:64], ip
338
        vst1.64         {d7}, [r2,:64], ip
339
        vst1.64         {d8}, [r2,:64], ip
340
        vst1.64         {d9}, [r2,:64], ip
341

    
342
        bx              lr
343
        .endfunc
344

    
345
/* void ff_simple_idct_neon(DCTELEM *data); */
346
function ff_simple_idct_neon, export=1
347
        idct_start      r0
348

    
349
        mov             r2,  r0
350
        bl              idct_row4_neon
351
        bl              idct_row4_neon
352
        add             r2,  r2,  #-128
353
        bl              idct_col4_neon
354
        add             r2,  r2,  #-128
355
        bl              idct_col4_st16_neon
356
        add             r2,  r2,  #-120
357
        bl              idct_col4_neon
358
        add             r2,  r2,  #-128
359
        bl              idct_col4_st16_neon
360

    
361
        idct_end
362
        .endfunc