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