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