Upstream version 10.38.222.0
[platform/framework/web/crosswalk.git] / src / third_party / libvpx / source / libvpx / vp8 / common / arm / neon / vp8_subpixelvariance16x16_neon.asm
1 ;
2 ;  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 ;
4 ;  Use of this source code is governed by a BSD-style license
5 ;  that can be found in the LICENSE file in the root of the source
6 ;  tree. An additional intellectual property rights grant can be found
7 ;  in the file PATENTS.  All contributing project authors may
8 ;  be found in the AUTHORS file in the root of the source tree.
9 ;
10
11
12 ;-----------------
13
14     EXPORT  |vp8_sub_pixel_variance16x16_neon_func|
15     ARM
16     REQUIRE8
17     PRESERVE8
18
19     AREA ||.text||, CODE, READONLY, ALIGN=2
20 ; r0    unsigned char  *src_ptr,
21 ; r1    int  src_pixels_per_line,
22 ; r2    int  xoffset,
23 ; r3    int  yoffset,
24 ; stack(r4) unsigned char *dst_ptr,
25 ; stack(r5) int dst_pixels_per_line,
26 ; stack(r6) unsigned int *sse
27 ;note: most of the code is copied from bilinear_predict16x16_neon and vp8_variance16x16_neon.
28
29 bilinear_taps_coeff
30     DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
31
32 |vp8_sub_pixel_variance16x16_neon_func| PROC
33     push            {r4-r6, lr}
34     vpush           {d8-d15}
35
36     adr             r12, bilinear_taps_coeff
37     ldr             r4, [sp, #80]           ;load *dst_ptr from stack
38     ldr             r5, [sp, #84]           ;load dst_pixels_per_line from stack
39     ldr             r6, [sp, #88]           ;load *sse from stack
40
41     cmp             r2, #0                  ;skip first_pass filter if xoffset=0
42     beq             secondpass_bfilter16x16_only
43
44     add             r2, r12, r2, lsl #3     ;calculate filter location
45
46     cmp             r3, #0                  ;skip second_pass filter if yoffset=0
47
48     vld1.s32        {d31}, [r2]             ;load first_pass filter
49
50     beq             firstpass_bfilter16x16_only
51
52     sub             sp, sp, #272            ;reserve space on stack for temporary storage
53     vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
54     mov             lr, sp
55     vld1.u8         {d5, d6, d7}, [r0], r1
56
57     mov             r2, #3                  ;loop counter
58     vld1.u8         {d8, d9, d10}, [r0], r1
59
60     vdup.8          d0, d31[0]              ;first_pass filter (d0 d1)
61     vld1.u8         {d11, d12, d13}, [r0], r1
62
63     vdup.8          d1, d31[4]
64
65 ;First Pass: output_height lines x output_width columns (17x16)
66 vp8e_filt_blk2d_fp16x16_loop_neon
67     pld             [r0]
68     pld             [r0, r1]
69     pld             [r0, r1, lsl #1]
70
71     vmull.u8        q7, d2, d0              ;(src_ptr[0] * Filter[0])
72     vmull.u8        q8, d3, d0
73     vmull.u8        q9, d5, d0
74     vmull.u8        q10, d6, d0
75     vmull.u8        q11, d8, d0
76     vmull.u8        q12, d9, d0
77     vmull.u8        q13, d11, d0
78     vmull.u8        q14, d12, d0
79
80     vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
81     vext.8          d5, d5, d6, #1
82     vext.8          d8, d8, d9, #1
83     vext.8          d11, d11, d12, #1
84
85     vmlal.u8        q7, d2, d1              ;(src_ptr[0] * Filter[1])
86     vmlal.u8        q9, d5, d1
87     vmlal.u8        q11, d8, d1
88     vmlal.u8        q13, d11, d1
89
90     vext.8          d3, d3, d4, #1
91     vext.8          d6, d6, d7, #1
92     vext.8          d9, d9, d10, #1
93     vext.8          d12, d12, d13, #1
94
95     vmlal.u8        q8, d3, d1              ;(src_ptr[0] * Filter[1])
96     vmlal.u8        q10, d6, d1
97     vmlal.u8        q12, d9, d1
98     vmlal.u8        q14, d12, d1
99
100     subs            r2, r2, #1
101
102     vqrshrn.u16    d14, q7, #7              ;shift/round/saturate to u8
103     vqrshrn.u16    d15, q8, #7
104     vqrshrn.u16    d16, q9, #7
105     vqrshrn.u16    d17, q10, #7
106     vqrshrn.u16    d18, q11, #7
107     vqrshrn.u16    d19, q12, #7
108     vqrshrn.u16    d20, q13, #7
109
110     vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
111     vqrshrn.u16    d21, q14, #7
112     vld1.u8         {d5, d6, d7}, [r0], r1
113
114     vst1.u8         {d14, d15, d16, d17}, [lr]!     ;store result
115     vld1.u8         {d8, d9, d10}, [r0], r1
116     vst1.u8         {d18, d19, d20, d21}, [lr]!
117     vld1.u8         {d11, d12, d13}, [r0], r1
118
119     bne             vp8e_filt_blk2d_fp16x16_loop_neon
120
121 ;First-pass filtering for rest 5 lines
122     vld1.u8         {d14, d15, d16}, [r0], r1
123
124     vmull.u8        q9, d2, d0              ;(src_ptr[0] * Filter[0])
125     vmull.u8        q10, d3, d0
126     vmull.u8        q11, d5, d0
127     vmull.u8        q12, d6, d0
128     vmull.u8        q13, d8, d0
129     vmull.u8        q14, d9, d0
130
131     vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
132     vext.8          d5, d5, d6, #1
133     vext.8          d8, d8, d9, #1
134
135     vmlal.u8        q9, d2, d1              ;(src_ptr[0] * Filter[1])
136     vmlal.u8        q11, d5, d1
137     vmlal.u8        q13, d8, d1
138
139     vext.8          d3, d3, d4, #1
140     vext.8          d6, d6, d7, #1
141     vext.8          d9, d9, d10, #1
142
143     vmlal.u8        q10, d3, d1             ;(src_ptr[0] * Filter[1])
144     vmlal.u8        q12, d6, d1
145     vmlal.u8        q14, d9, d1
146
147     vmull.u8        q1, d11, d0
148     vmull.u8        q2, d12, d0
149     vmull.u8        q3, d14, d0
150     vmull.u8        q4, d15, d0
151
152     vext.8          d11, d11, d12, #1       ;construct src_ptr[1]
153     vext.8          d14, d14, d15, #1
154
155     vmlal.u8        q1, d11, d1             ;(src_ptr[0] * Filter[1])
156     vmlal.u8        q3, d14, d1
157
158     vext.8          d12, d12, d13, #1
159     vext.8          d15, d15, d16, #1
160
161     vmlal.u8        q2, d12, d1             ;(src_ptr[0] * Filter[1])
162     vmlal.u8        q4, d15, d1
163
164     vqrshrn.u16    d10, q9, #7              ;shift/round/saturate to u8
165     vqrshrn.u16    d11, q10, #7
166     vqrshrn.u16    d12, q11, #7
167     vqrshrn.u16    d13, q12, #7
168     vqrshrn.u16    d14, q13, #7
169     vqrshrn.u16    d15, q14, #7
170     vqrshrn.u16    d16, q1, #7
171     vqrshrn.u16    d17, q2, #7
172     vqrshrn.u16    d18, q3, #7
173     vqrshrn.u16    d19, q4, #7
174
175     vst1.u8         {d10, d11, d12, d13}, [lr]!         ;store result
176     vst1.u8         {d14, d15, d16, d17}, [lr]!
177     vst1.u8         {d18, d19}, [lr]!
178
179 ;Second pass: 16x16
180 ;secondpass_filter
181     add             r3, r12, r3, lsl #3
182     sub             lr, lr, #272
183
184     vld1.u32        {d31}, [r3]             ;load second_pass filter
185
186     sub             sp, sp, #256
187     mov             r3, sp
188
189     vld1.u8         {d22, d23}, [lr]!       ;load src data
190
191     vdup.8          d0, d31[0]              ;second_pass filter parameters (d0 d1)
192     vdup.8          d1, d31[4]
193     mov             r12, #4                 ;loop counter
194
195 vp8e_filt_blk2d_sp16x16_loop_neon
196     vld1.u8         {d24, d25}, [lr]!
197     vmull.u8        q1, d22, d0             ;(src_ptr[0] * Filter[0])
198     vld1.u8         {d26, d27}, [lr]!
199     vmull.u8        q2, d23, d0
200     vld1.u8         {d28, d29}, [lr]!
201     vmull.u8        q3, d24, d0
202     vld1.u8         {d30, d31}, [lr]!
203
204     vmull.u8        q4, d25, d0
205     vmull.u8        q5, d26, d0
206     vmull.u8        q6, d27, d0
207     vmull.u8        q7, d28, d0
208     vmull.u8        q8, d29, d0
209
210     vmlal.u8        q1, d24, d1             ;(src_ptr[pixel_step] * Filter[1])
211     vmlal.u8        q2, d25, d1
212     vmlal.u8        q3, d26, d1
213     vmlal.u8        q4, d27, d1
214     vmlal.u8        q5, d28, d1
215     vmlal.u8        q6, d29, d1
216     vmlal.u8        q7, d30, d1
217     vmlal.u8        q8, d31, d1
218
219     subs            r12, r12, #1
220
221     vqrshrn.u16    d2, q1, #7               ;shift/round/saturate to u8
222     vqrshrn.u16    d3, q2, #7
223     vqrshrn.u16    d4, q3, #7
224     vqrshrn.u16    d5, q4, #7
225     vqrshrn.u16    d6, q5, #7
226     vqrshrn.u16    d7, q6, #7
227     vqrshrn.u16    d8, q7, #7
228     vqrshrn.u16    d9, q8, #7
229
230     vst1.u8         {d2, d3}, [r3]!         ;store result
231     vst1.u8         {d4, d5}, [r3]!
232     vst1.u8         {d6, d7}, [r3]!
233     vmov            q11, q15
234     vst1.u8         {d8, d9}, [r3]!
235
236     bne             vp8e_filt_blk2d_sp16x16_loop_neon
237
238     b               sub_pixel_variance16x16_neon
239
240 ;--------------------
241 firstpass_bfilter16x16_only
242     mov             r2, #4                      ;loop counter
243     sub             sp, sp, #528            ;reserve space on stack for temporary storage
244     vdup.8          d0, d31[0]                  ;first_pass filter (d0 d1)
245     vdup.8          d1, d31[4]
246     mov             r3, sp
247
248 ;First Pass: output_height lines x output_width columns (16x16)
249 vp8e_filt_blk2d_fpo16x16_loop_neon
250     vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
251     vld1.u8         {d5, d6, d7}, [r0], r1
252     vld1.u8         {d8, d9, d10}, [r0], r1
253     vld1.u8         {d11, d12, d13}, [r0], r1
254
255     pld             [r0]
256     pld             [r0, r1]
257     pld             [r0, r1, lsl #1]
258
259     vmull.u8        q7, d2, d0              ;(src_ptr[0] * Filter[0])
260     vmull.u8        q8, d3, d0
261     vmull.u8        q9, d5, d0
262     vmull.u8        q10, d6, d0
263     vmull.u8        q11, d8, d0
264     vmull.u8        q12, d9, d0
265     vmull.u8        q13, d11, d0
266     vmull.u8        q14, d12, d0
267
268     vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
269     vext.8          d5, d5, d6, #1
270     vext.8          d8, d8, d9, #1
271     vext.8          d11, d11, d12, #1
272
273     vmlal.u8        q7, d2, d1              ;(src_ptr[0] * Filter[1])
274     vmlal.u8        q9, d5, d1
275     vmlal.u8        q11, d8, d1
276     vmlal.u8        q13, d11, d1
277
278     vext.8          d3, d3, d4, #1
279     vext.8          d6, d6, d7, #1
280     vext.8          d9, d9, d10, #1
281     vext.8          d12, d12, d13, #1
282
283     vmlal.u8        q8, d3, d1              ;(src_ptr[0] * Filter[1])
284     vmlal.u8        q10, d6, d1
285     vmlal.u8        q12, d9, d1
286     vmlal.u8        q14, d12, d1
287
288     subs            r2, r2, #1
289
290     vqrshrn.u16    d14, q7, #7              ;shift/round/saturate to u8
291     vqrshrn.u16    d15, q8, #7
292     vqrshrn.u16    d16, q9, #7
293     vqrshrn.u16    d17, q10, #7
294     vqrshrn.u16    d18, q11, #7
295     vqrshrn.u16    d19, q12, #7
296     vqrshrn.u16    d20, q13, #7
297     vst1.u8         {d14, d15}, [r3]!       ;store result
298     vqrshrn.u16    d21, q14, #7
299
300     vst1.u8         {d16, d17}, [r3]!
301     vst1.u8         {d18, d19}, [r3]!
302     vst1.u8         {d20, d21}, [r3]!
303
304     bne             vp8e_filt_blk2d_fpo16x16_loop_neon
305
306     b               sub_pixel_variance16x16_neon
307
308 ;---------------------
309 secondpass_bfilter16x16_only
310 ;Second pass: 16x16
311 ;secondpass_filter
312     sub             sp, sp, #528            ;reserve space on stack for temporary storage
313     add             r3, r12, r3, lsl #3
314     mov             r12, #4                     ;loop counter
315     vld1.u32        {d31}, [r3]                 ;load second_pass filter
316     vld1.u8         {d22, d23}, [r0], r1        ;load src data
317     mov             r3, sp
318
319     vdup.8          d0, d31[0]                  ;second_pass filter parameters (d0 d1)
320     vdup.8          d1, d31[4]
321
322 vp8e_filt_blk2d_spo16x16_loop_neon
323     vld1.u8         {d24, d25}, [r0], r1
324     vmull.u8        q1, d22, d0             ;(src_ptr[0] * Filter[0])
325     vld1.u8         {d26, d27}, [r0], r1
326     vmull.u8        q2, d23, d0
327     vld1.u8         {d28, d29}, [r0], r1
328     vmull.u8        q3, d24, d0
329     vld1.u8         {d30, d31}, [r0], r1
330
331     vmull.u8        q4, d25, d0
332     vmull.u8        q5, d26, d0
333     vmull.u8        q6, d27, d0
334     vmull.u8        q7, d28, d0
335     vmull.u8        q8, d29, d0
336
337     vmlal.u8        q1, d24, d1             ;(src_ptr[pixel_step] * Filter[1])
338     vmlal.u8        q2, d25, d1
339     vmlal.u8        q3, d26, d1
340     vmlal.u8        q4, d27, d1
341     vmlal.u8        q5, d28, d1
342     vmlal.u8        q6, d29, d1
343     vmlal.u8        q7, d30, d1
344     vmlal.u8        q8, d31, d1
345
346     vqrshrn.u16    d2, q1, #7               ;shift/round/saturate to u8
347     vqrshrn.u16    d3, q2, #7
348     vqrshrn.u16    d4, q3, #7
349     vqrshrn.u16    d5, q4, #7
350     vqrshrn.u16    d6, q5, #7
351     vqrshrn.u16    d7, q6, #7
352     vqrshrn.u16    d8, q7, #7
353     vqrshrn.u16    d9, q8, #7
354
355     vst1.u8         {d2, d3}, [r3]!         ;store result
356     subs            r12, r12, #1
357     vst1.u8         {d4, d5}, [r3]!
358     vmov            q11, q15
359     vst1.u8         {d6, d7}, [r3]!
360     vst1.u8         {d8, d9}, [r3]!
361
362     bne             vp8e_filt_blk2d_spo16x16_loop_neon
363
364     b               sub_pixel_variance16x16_neon
365
366 ;----------------------------
367 ;variance16x16
368 sub_pixel_variance16x16_neon
369     vmov.i8         q8, #0                      ;q8 - sum
370     vmov.i8         q9, #0                      ;q9, q10 - sse
371     vmov.i8         q10, #0
372
373     sub             r3, r3, #256
374     mov             r12, #8
375
376 sub_pixel_variance16x16_neon_loop
377     vld1.8          {q0}, [r3]!                 ;Load up source and reference
378     vld1.8          {q2}, [r4], r5
379     vld1.8          {q1}, [r3]!
380     vld1.8          {q3}, [r4], r5
381
382     vsubl.u8        q11, d0, d4                 ;diff
383     vsubl.u8        q12, d1, d5
384     vsubl.u8        q13, d2, d6
385     vsubl.u8        q14, d3, d7
386
387     vpadal.s16      q8, q11                     ;sum
388     vmlal.s16       q9, d22, d22                ;sse
389     vmlal.s16       q10, d23, d23
390
391     subs            r12, r12, #1
392
393     vpadal.s16      q8, q12
394     vmlal.s16       q9, d24, d24
395     vmlal.s16       q10, d25, d25
396     vpadal.s16      q8, q13
397     vmlal.s16       q9, d26, d26
398     vmlal.s16       q10, d27, d27
399     vpadal.s16      q8, q14
400     vmlal.s16       q9, d28, d28
401     vmlal.s16       q10, d29, d29
402
403     bne             sub_pixel_variance16x16_neon_loop
404
405     vadd.u32        q10, q9, q10                ;accumulate sse
406     vpaddl.s32      q0, q8                      ;accumulate sum
407
408     vpaddl.u32      q1, q10
409     vadd.s64        d0, d0, d1
410     vadd.u64        d1, d2, d3
411
412     vmull.s32       q5, d0, d0
413     vst1.32         {d1[0]}, [r6]               ;store sse
414     vshr.u32        d10, d10, #8
415     vsub.u32        d0, d1, d10
416
417     add             sp, sp, #528
418     vmov.32         r0, d0[0]                   ;return
419
420     vpop            {d8-d15}
421     pop             {r4-r6,pc}
422
423     ENDP
424
425     END