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