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