]> git.sesse.net Git - x264/blob - common/arm/quant-a.S
arm: Implement x264_denoise_dct_neon
[x264] / common / arm / quant-a.S
1 /****************************************************************************
2  * quant.S: arm quantization and level-run
3  *****************************************************************************
4  * Copyright (C) 2009-2015 x264 project
5  *
6  * Authors: David Conrad <lessen42@gmail.com>
7  *          Janne Grunau <janne-x264@jannau.net>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
22  *
23  * This program is also available under a commercial proprietary license.
24  * For more information, contact us at licensing@x264.com.
25  *****************************************************************************/
26
27 #include "asm.S"
28
29 .section .rodata
30 .align 4
31 pmovmskb_byte:
32 .byte 1,2,4,8,16,32,64,128
33 .byte 1,2,4,8,16,32,64,128
34
35 .text
36
37 .macro QUANT_TWO bias0 bias1 mf0 mf1 mf2 mf3 mask load_mf=no
38     vadd.u16    q8,  q8,  \bias0
39     vadd.u16    q9,  q9,  \bias1
40 .ifc \load_mf, yes
41     vld1.64     {\mf0-\mf3}, [r1,:128]!
42 .endif
43     vmull.u16   q10, d16, \mf0
44     vmull.u16   q11, d17, \mf1
45     vmull.u16   q12, d18, \mf2
46     vmull.u16   q13, d19, \mf3
47     vshr.s16    q14, q14, #15
48     vshr.s16    q15, q15, #15
49     vshrn.u32   d16, q10, #16
50     vshrn.u32   d17, q11, #16
51     vshrn.u32   d18, q12, #16
52     vshrn.u32   d19, q13, #16
53     veor        q8,  q8,  q14
54     veor        q9,  q9,  q15
55     vsub.s16    q8,  q8,  q14
56     vsub.s16    q9,  q9,  q15
57     vorr        \mask, q8,  q9
58     vst1.64     {d16-d19}, [r0,:128]!
59 .endm
60
61 .macro QUANT_END d
62     vmov        r2,  r3,  \d
63     orrs        r0,  r2,  r3
64     movne       r0,  #1
65     bx          lr
66 .endm
67
68 // quant_2x2_dc( int16_t dct[4], int mf, int bias )
69 function x264_quant_2x2_dc_neon
70     vld1.64     {d0}, [r0,:64]
71     vabs.s16    d3,  d0
72     vdup.16     d2,  r2
73     vdup.16     d1,  r1
74     vadd.u16    d3,  d3,  d2
75     vmull.u16   q3,  d3,  d1
76     vshr.s16    d0,  d0,  #15
77     vshrn.u32   d3,  q3,  #16
78     veor        d3,  d3,  d0
79     vsub.s16    d3,  d3,  d0
80     vst1.64     {d3}, [r0,:64]
81     QUANT_END   d3
82 endfunc
83
84 // quant_4x4_dc( int16_t dct[16], int mf, int bias )
85 function x264_quant_4x4_dc_neon
86     vld1.64     {d28-d31}, [r0,:128]
87     vabs.s16    q8,  q14
88     vabs.s16    q9,  q15
89     vdup.16     q0,  r2
90     vdup.16     q2,  r1
91     QUANT_TWO   q0,  q0,  d4,  d5,  d4,  d5,  q0
92     vorr        d0,  d0,  d1
93     QUANT_END   d0
94 endfunc
95
96 // quant_4x4( int16_t dct[16], uint16_t mf[16], uint16_t bias[16] )
97 function x264_quant_4x4_neon
98     vld1.64     {d28-d31}, [r0,:128]
99     vabs.s16    q8,  q14
100     vabs.s16    q9,  q15
101     vld1.64     {d0-d3}, [r2,:128]
102     vld1.64     {d4-d7}, [r1,:128]
103     QUANT_TWO   q0,  q1,  d4,  d5,  d6,  d7, q0
104     vorr        d0,  d0,  d1
105     QUANT_END   d0
106 endfunc
107
108 // quant_4x4x4( int16_t dct[4][16], uint16_t mf[16], uint16_t bias[16] )
109 function x264_quant_4x4x4_neon
110     vpush       {d8-d15}
111     vld1.64     {d28-d31}, [r0,:128]
112     vabs.s16    q8,  q14
113     vabs.s16    q9,  q15
114     vld1.64     {d0-d3},   [r2,:128]
115     vld1.64     {d4-d7},   [r1,:128]
116     QUANT_TWO   q0,  q1,  d4,  d5,  d6,  d7,  q4
117     vld1.64     {d28-d31}, [r0,:128]
118     vabs.s16    q8,  q14
119     vabs.s16    q9,  q15
120     QUANT_TWO   q0,  q1,  d4,  d5,  d6,  d7,  q5
121     vld1.64     {d28-d31}, [r0,:128]
122     vabs.s16    q8,  q14
123     vabs.s16    q9,  q15
124     QUANT_TWO   q0,  q1,  d4,  d5,  d6,  d7,  q6
125     vld1.64     {d28-d31}, [r0,:128]
126     vabs.s16    q8,  q14
127     vabs.s16    q9,  q15
128     QUANT_TWO   q0,  q1,  d4,  d5,  d6,  d7,  q7
129     vorr        d8,  d8,  d9
130     vorr       d10, d10, d11
131     vorr       d12, d12, d13
132     vorr       d14, d14, d15
133     vmov        r0,  r1,  d8
134     vmov        r2,  r3, d10
135     orrs        r0,  r1
136     movne       r0,  #1
137     orrs        r2,  r3
138     orrne       r0,  #2
139     vmov        r1,  r2, d12
140     vmov        r3,  ip, d14
141     orrs        r1,  r2
142     orrne       r0,  #4
143     orrs        r3,  ip
144     orrne       r0,  #8
145     vpop        {d8-d15}
146     bx          lr
147 endfunc
148
149 // quant_8x8( int16_t dct[64], uint16_t mf[64], uint16_t bias[64] )
150 function x264_quant_8x8_neon
151     vld1.64     {d28-d31}, [r0,:128]
152     vabs.s16    q8,  q14
153     vabs.s16    q9,  q15
154     vld1.64     {d0-d3},   [r2,:128]!
155     vld1.64     {d4-d7},   [r1,:128]!
156     QUANT_TWO   q0,  q1,  d4,  d5,  d6,  d7,  q0
157 .rept 3
158     vld1.64     {d28-d31}, [r0,:128]
159     vabs.s16    q8,  q14
160     vabs.s16    q9,  q15
161     vld1.64     {d2-d5},   [r2,:128]!
162     QUANT_TWO   q1,  q2,  d4,  d5,  d6,  d7,  q1, yes
163     vorr        q0,  q0,  q1
164 .endr
165     vorr        d0,  d0,  d1
166     QUANT_END   d0
167 endfunc
168
169 .macro DEQUANT_START mf_size offset dc=no
170     mov         r3,  #0x2b
171     mul         r3,  r3,  r2
172     lsr         r3,  r3,  #8            // i_qbits = i_qp / 6
173     add         ip,  r3,  r3,  lsl #1
174     sub         r2,  r2,  ip,  lsl #1   // i_mf = i_qp % 6
175 .ifc \dc,no
176     add         r1,  r1,  r2, lsl #\mf_size  // dequant_mf[i_mf]
177 .else
178     ldr         r1, [r1,  r2, lsl #\mf_size] // dequant_mf[i_mf][0][0]
179 .endif
180     subs        r3,  r3,  #\offset      // 6 for 8x8
181 .endm
182
183 // dequant_4x4( int16_t dct[16], int dequant_mf[6][16], int i_qp )
184 .macro DEQUANT size bits
185 function x264_dequant_\size\()_neon
186     DEQUANT_START \bits+2, \bits
187 .ifc \size, 8x8
188     mov         r2,  #4
189 .endif
190     blt         dequant_\size\()_rshift
191
192     vdup.16     q15, r3
193 dequant_\size\()_lshift_loop:
194 .ifc \size, 8x8
195     subs        r2,  r2,  #1
196 .endif
197     vld1.32     {d16-d17}, [r1,:128]!
198     vld1.32     {d18-d19}, [r1,:128]!
199     vmovn.s32   d4,  q8
200     vld1.32     {d20-d21}, [r1,:128]!
201     vmovn.s32   d5,  q9
202     vld1.32     {d22-d23}, [r1,:128]!
203     vmovn.s32   d6,  q10
204     vld1.16     {d0-d3},   [r0,:128]
205     vmovn.s32   d7,  q11
206     vmul.s16    q0,  q0,  q2
207     vmul.s16    q1,  q1,  q3
208     vshl.s16    q0,  q0,  q15
209     vshl.s16    q1,  q1,  q15
210     vst1.16     {d0-d3},   [r0,:128]!
211 .ifc \size, 8x8
212     bgt         dequant_\size\()_lshift_loop
213 .endif
214     bx          lr
215
216 dequant_\size\()_rshift:
217     vdup.32     q15, r3
218     rsb         r3,  r3,  #0
219     mov         ip,  #1
220     sub         r3,  r3,  #1
221     lsl         ip,  ip,  r3
222
223 .ifc \size, 8x8
224 dequant_\size\()_rshift_loop:
225     subs        r2,  r2,  #1
226 .endif
227     vdup.32     q10, ip
228     vld1.32     {d16-d17}, [r1,:128]!
229     vdup.32     q11, ip
230     vld1.32     {d18-d19}, [r1,:128]!
231     vmovn.s32   d4,  q8
232     vld1.32     {d16-d17}, [r1,:128]!
233     vmovn.s32   d5,  q9
234     vld1.32     {d18-d19}, [r1,:128]!
235     vmovn.s32   d6,  q8
236     vld1.16     {d0-d3},   [r0,:128]
237     vmovn.s32   d7,  q9
238     vdup.32     q12, ip
239     vdup.32     q13, ip
240
241     vmlal.s16   q10, d0,  d4
242     vmlal.s16   q11, d1,  d5
243     vmlal.s16   q12, d2,  d6
244     vmlal.s16   q13, d3,  d7
245     vshl.s32    q10, q10, q15
246     vshl.s32    q11, q11, q15
247     vshl.s32    q12, q12, q15
248     vshl.s32    q13, q13, q15
249
250     vmovn.s32   d0,  q10
251     vmovn.s32   d1,  q11
252     vmovn.s32   d2,  q12
253     vmovn.s32   d3,  q13
254     vst1.16     {d0-d3},   [r0,:128]!
255 .ifc \size, 8x8
256     bgt         dequant_\size\()_rshift_loop
257 .endif
258     bx          lr
259 endfunc
260 .endm
261
262 DEQUANT 4x4, 4
263 DEQUANT 8x8, 6
264
265 // dequant_4x4_dc( int16_t dct[16], int dequant_mf[6][16], int i_qp )
266 function x264_dequant_4x4_dc_neon
267     DEQUANT_START 6, 6, yes
268     blt         dequant_4x4_dc_rshift
269
270     lsl         r1,  r1,  r3
271     vdup.16     q2,  r1
272     vld1.16     {d0-d3},   [r0,:128]
273     vdup.16     q15, r3
274
275     vmul.s16    q0,  q0,  q2
276     vmul.s16    q1,  q1,  q2
277     vst1.16     {d0-d3},   [r0,:128]
278     bx          lr
279
280 dequant_4x4_dc_rshift:
281     vdup.16     d4,  r1
282     vdup.32     q15, r3
283     rsb         r3,  r3,  #0
284     mov         ip,  #1
285     sub         r3,  r3,  #1
286     lsl         ip,  ip,  r3
287
288     vdup.32     q10, ip
289     vdup.32     q11, ip
290     vld1.16     {d0-d3},   [r0,:128]
291     vdup.32     q12, ip
292     vdup.32     q13, ip
293
294     vmlal.s16   q10, d0,  d4
295     vmlal.s16   q11, d1,  d4
296     vmlal.s16   q12, d2,  d4
297     vmlal.s16   q13, d3,  d4
298     vshl.s32    q10, q10, q15
299     vshl.s32    q11, q11, q15
300     vshl.s32    q12, q12, q15
301     vshl.s32    q13, q13, q15
302
303     vmovn.s32   d0,  q10
304     vmovn.s32   d1,  q11
305     vmovn.s32   d2,  q12
306     vmovn.s32   d3,  q13
307     vst1.16     {d0-d3},   [r0,:128]
308     bx          lr
309 endfunc
310
311
312 // int coeff_last( int16_t *l )
313 function x264_coeff_last4_arm
314     ldrd        r2,  r3,  [r0]
315     subs        r0,  r3,  #0
316     movne       r0,  #2
317     movne       r2,  r3
318     lsrs        r2,  r2,  #16
319     addne       r0,  r0,  #1
320     bx          lr
321 endfunc
322
323 function x264_coeff_last8_arm
324     ldrd        r2,  r3,  [r0, #8]
325     orrs        ip,  r2,  r3
326     movne       r0,  #4
327     ldrdeq      r2,  r3,  [r0]
328     moveq       r0,  #0
329     tst         r3,  r3
330     addne       r0,  #2
331     movne       r2,  r3
332     lsrs        r2,  r2,  #16
333     addne       r0,  r0,  #1
334     bx          lr
335 endfunc
336
337 .macro COEFF_LAST_1x size
338 function x264_coeff_last\size\()_neon
339 .if \size == 15
340     sub         r0,  r0,  #2
341 .endif
342     vld1.64     {d0-d3}, [r0,:128]
343     vtst.16     q0,  q0
344     vtst.16     q1,  q1
345     vshrn.u16   d0,  q0,  #8
346     vshrn.u16   d1,  q1,  #8
347     vshrn.u16   d0,  q0,  #4
348     vclz.i32    d0,  d0
349     mov         ip,  #7
350     mov         r3,  #\size - 9
351     vmov        r0,  r1,  d0
352
353     subs        r1,  ip,  r1,  lsr #2
354     addge       r0,  r1,  #\size - 8
355     subslt      r0,  r3,  r0,  lsr #2
356     movlt       r0,  #0
357     bx          lr
358 endfunc
359 .endm
360
361 COEFF_LAST_1x 15
362 COEFF_LAST_1x 16
363
364 function x264_coeff_last64_neon
365     vld1.64     {d16-d19}, [r0,:128]!
366     vqmovn.u16  d16, q8
367     vqmovn.u16  d17, q9
368     vld1.64     {d20-d23}, [r0,:128]!
369     vqmovn.u16  d18, q10
370     vqmovn.u16  d19, q11
371     vld1.64     {d24-d27}, [r0,:128]!
372     vqmovn.u16  d20, q12
373     vqmovn.u16  d21, q13
374     vld1.64     {d28-d31}, [r0,:128]!
375     vqmovn.u16  d22, q14
376     vqmovn.u16  d23, q15
377
378     movrel      r1, pmovmskb_byte
379     vld1.64     {d0-d1}, [r1,:128]
380
381     vtst.8      q8,  q8
382     vtst.8      q9,  q9
383     vtst.8      q10, q10
384     vtst.8      q11, q11
385
386     vand        q8,  q8,  q0
387     vand        q9,  q9,  q0
388     vand        q10, q10, q0
389     vand        q11, q11, q0
390
391     vpadd.u8    d0,  d16, d17
392     vpadd.u8    d1,  d18, d19
393     vpadd.u8    d2,  d20, d21
394     vpadd.u8    d3,  d22, d23
395     vpadd.u8    d0,  d0,  d1
396     vpadd.u8    d1,  d2,  d3
397     vpadd.u8    d0,  d0,  d1
398     vclz.i32    d0,  d0
399     mov         ip,  #31
400     vmov        r0,  r1,  d0
401
402     subs        r1,  ip,  r1
403     addge       r0,  r1,  #32
404     subslt      r0,  ip,  r0
405     movlt       r0,  #0
406     bx          lr
407 endfunc
408
409 function x264_denoise_dct_neon
410 1:  subs        r3,  r3,  #16
411     vld1.16     {q0,  q1},  [r0]
412     vld1.32     {q12, q13}, [r1]!
413     vld1.32     {q14, q15}, [r1]
414     sub         r1,  #32
415     vabs.s16    q8,  q0
416     vabs.s16    q9,  q1
417     vld1.16     {q2, q3}, [r2]!
418     vclt.s16    q10, q0,  #0
419     vclt.s16    q11, q1,  #0
420     vaddw.u16   q12, q12, d16
421     vaddw.u16   q13, q13, d17
422     vqsub.u16   q0,  q8,  q2
423     vqsub.u16   q1,  q9,  q3
424     vaddw.u16   q14, q14, d18
425     vaddw.u16   q15, q15, d19
426     vneg.s16    q8,  q0
427     vneg.s16    q9,  q1
428     vbsl        q10, q8,  q0
429     vbsl        q11, q9,  q1
430     vst1.32     {q12, q13}, [r1]!
431     vst1.32     {q14, q15}, [r1]!
432     vst1.16     {q10, q11}, [r0]!
433     bgt         1b
434     bx          lr
435 endfunc