Fix TEXTRELs in the ARM asm.
[profile/ivi/libvpx.git] / vp8 / common / arm / neon / bilinearpredict16x16_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_bilinear_predict16x16_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 ; r4    unsigned char *dst_ptr,
23 ; stack(r5) int  dst_pitch
24
25 |vp8_bilinear_predict16x16_neon| PROC
26     push            {r4-r5, lr}
27
28     adr             r12, bifilter16_coeff
29     ldr             r4, [sp, #12]           ;load parameters from stack
30     ldr             r5, [sp, #16]           ;load parameters from stack
31
32     cmp             r2, #0                  ;skip first_pass filter if xoffset=0
33     beq             secondpass_bfilter16x16_only
34
35     add             r2, r12, r2, lsl #3     ;calculate filter location
36
37     cmp             r3, #0                  ;skip second_pass filter if yoffset=0
38
39     vld1.s32        {d31}, [r2]             ;load first_pass filter
40
41     beq             firstpass_bfilter16x16_only
42
43     sub             sp, sp, #272            ;reserve space on stack for temporary storage
44     vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
45     mov             lr, sp
46     vld1.u8         {d5, d6, d7}, [r0], r1
47
48     mov             r2, #3                  ;loop counter
49     vld1.u8         {d8, d9, d10}, [r0], r1
50
51     vdup.8          d0, d31[0]              ;first_pass filter (d0 d1)
52     vld1.u8         {d11, d12, d13}, [r0], r1
53
54     vdup.8          d1, d31[4]
55
56 ;First Pass: output_height lines x output_width columns (17x16)
57 filt_blk2d_fp16x16_loop_neon
58     pld             [r0]
59     pld             [r0, r1]
60     pld             [r0, r1, lsl #1]
61
62     vmull.u8        q7, d2, d0              ;(src_ptr[0] * vp8_filter[0])
63     vmull.u8        q8, d3, d0
64     vmull.u8        q9, d5, d0
65     vmull.u8        q10, d6, d0
66     vmull.u8        q11, d8, d0
67     vmull.u8        q12, d9, d0
68     vmull.u8        q13, d11, d0
69     vmull.u8        q14, d12, d0
70
71     vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
72     vext.8          d5, d5, d6, #1
73     vext.8          d8, d8, d9, #1
74     vext.8          d11, d11, d12, #1
75
76     vmlal.u8        q7, d2, d1              ;(src_ptr[0] * vp8_filter[1])
77     vmlal.u8        q9, d5, d1
78     vmlal.u8        q11, d8, d1
79     vmlal.u8        q13, d11, d1
80
81     vext.8          d3, d3, d4, #1
82     vext.8          d6, d6, d7, #1
83     vext.8          d9, d9, d10, #1
84     vext.8          d12, d12, d13, #1
85
86     vmlal.u8        q8, d3, d1              ;(src_ptr[0] * vp8_filter[1])
87     vmlal.u8        q10, d6, d1
88     vmlal.u8        q12, d9, d1
89     vmlal.u8        q14, d12, d1
90
91     subs            r2, r2, #1
92
93     vqrshrn.u16    d14, q7, #7              ;shift/round/saturate to u8
94     vqrshrn.u16    d15, q8, #7
95     vqrshrn.u16    d16, q9, #7
96     vqrshrn.u16    d17, q10, #7
97     vqrshrn.u16    d18, q11, #7
98     vqrshrn.u16    d19, q12, #7
99     vqrshrn.u16    d20, q13, #7
100
101     vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
102     vqrshrn.u16    d21, q14, #7
103     vld1.u8         {d5, d6, d7}, [r0], r1
104
105     vst1.u8         {d14, d15, d16, d17}, [lr]!     ;store result
106     vld1.u8         {d8, d9, d10}, [r0], r1
107     vst1.u8         {d18, d19, d20, d21}, [lr]!
108     vld1.u8         {d11, d12, d13}, [r0], r1
109
110     bne             filt_blk2d_fp16x16_loop_neon
111
112 ;First-pass filtering for rest 5 lines
113     vld1.u8         {d14, d15, d16}, [r0], r1
114
115     vmull.u8        q9, d2, d0              ;(src_ptr[0] * vp8_filter[0])
116     vmull.u8        q10, d3, d0
117     vmull.u8        q11, d5, d0
118     vmull.u8        q12, d6, d0
119     vmull.u8        q13, d8, d0
120     vmull.u8        q14, d9, d0
121
122     vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
123     vext.8          d5, d5, d6, #1
124     vext.8          d8, d8, d9, #1
125
126     vmlal.u8        q9, d2, d1              ;(src_ptr[0] * vp8_filter[1])
127     vmlal.u8        q11, d5, d1
128     vmlal.u8        q13, d8, d1
129
130     vext.8          d3, d3, d4, #1
131     vext.8          d6, d6, d7, #1
132     vext.8          d9, d9, d10, #1
133
134     vmlal.u8        q10, d3, d1             ;(src_ptr[0] * vp8_filter[1])
135     vmlal.u8        q12, d6, d1
136     vmlal.u8        q14, d9, d1
137
138     vmull.u8        q1, d11, d0
139     vmull.u8        q2, d12, d0
140     vmull.u8        q3, d14, d0
141     vmull.u8        q4, d15, d0
142
143     vext.8          d11, d11, d12, #1       ;construct src_ptr[1]
144     vext.8          d14, d14, d15, #1
145
146     vmlal.u8        q1, d11, d1             ;(src_ptr[0] * vp8_filter[1])
147     vmlal.u8        q3, d14, d1
148
149     vext.8          d12, d12, d13, #1
150     vext.8          d15, d15, d16, #1
151
152     vmlal.u8        q2, d12, d1             ;(src_ptr[0] * vp8_filter[1])
153     vmlal.u8        q4, d15, d1
154
155     vqrshrn.u16    d10, q9, #7              ;shift/round/saturate to u8
156     vqrshrn.u16    d11, q10, #7
157     vqrshrn.u16    d12, q11, #7
158     vqrshrn.u16    d13, q12, #7
159     vqrshrn.u16    d14, q13, #7
160     vqrshrn.u16    d15, q14, #7
161     vqrshrn.u16    d16, q1, #7
162     vqrshrn.u16    d17, q2, #7
163     vqrshrn.u16    d18, q3, #7
164     vqrshrn.u16    d19, q4, #7
165
166     vst1.u8         {d10, d11, d12, d13}, [lr]!         ;store result
167     vst1.u8         {d14, d15, d16, d17}, [lr]!
168     vst1.u8         {d18, d19}, [lr]!
169
170 ;Second pass: 16x16
171 ;secondpass_filter
172     add             r3, r12, r3, lsl #3
173     sub             lr, lr, #272
174
175     vld1.u32        {d31}, [r3]             ;load second_pass filter
176
177     vld1.u8         {d22, d23}, [lr]!       ;load src data
178
179     vdup.8          d0, d31[0]              ;second_pass filter parameters (d0 d1)
180     vdup.8          d1, d31[4]
181     mov             r12, #4                 ;loop counter
182
183 filt_blk2d_sp16x16_loop_neon
184     vld1.u8         {d24, d25}, [lr]!
185     vmull.u8        q1, d22, d0             ;(src_ptr[0] * vp8_filter[0])
186     vld1.u8         {d26, d27}, [lr]!
187     vmull.u8        q2, d23, d0
188     vld1.u8         {d28, d29}, [lr]!
189     vmull.u8        q3, d24, d0
190     vld1.u8         {d30, d31}, [lr]!
191
192     vmull.u8        q4, d25, d0
193     vmull.u8        q5, d26, d0
194     vmull.u8        q6, d27, d0
195     vmull.u8        q7, d28, d0
196     vmull.u8        q8, d29, d0
197
198     vmlal.u8        q1, d24, d1             ;(src_ptr[pixel_step] * vp8_filter[1])
199     vmlal.u8        q2, d25, d1
200     vmlal.u8        q3, d26, d1
201     vmlal.u8        q4, d27, d1
202     vmlal.u8        q5, d28, d1
203     vmlal.u8        q6, d29, d1
204     vmlal.u8        q7, d30, d1
205     vmlal.u8        q8, d31, d1
206
207     subs            r12, r12, #1
208
209     vqrshrn.u16    d2, q1, #7               ;shift/round/saturate to u8
210     vqrshrn.u16    d3, q2, #7
211     vqrshrn.u16    d4, q3, #7
212     vqrshrn.u16    d5, q4, #7
213     vqrshrn.u16    d6, q5, #7
214     vqrshrn.u16    d7, q6, #7
215     vqrshrn.u16    d8, q7, #7
216     vqrshrn.u16    d9, q8, #7
217
218     vst1.u8         {d2, d3}, [r4], r5      ;store result
219     vst1.u8         {d4, d5}, [r4], r5
220     vst1.u8         {d6, d7}, [r4], r5
221     vmov            q11, q15
222     vst1.u8         {d8, d9}, [r4], r5
223
224     bne             filt_blk2d_sp16x16_loop_neon
225
226     add             sp, sp, #272
227
228     pop             {r4-r5,pc}
229
230 ;--------------------
231 firstpass_bfilter16x16_only
232     mov             r2, #4                      ;loop counter
233     vdup.8          d0, d31[0]                  ;first_pass filter (d0 d1)
234     vdup.8          d1, d31[4]
235
236 ;First Pass: output_height lines x output_width columns (16x16)
237 filt_blk2d_fpo16x16_loop_neon
238     vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
239     vld1.u8         {d5, d6, d7}, [r0], r1
240     vld1.u8         {d8, d9, d10}, [r0], r1
241     vld1.u8         {d11, d12, d13}, [r0], r1
242
243     pld             [r0]
244     pld             [r0, r1]
245     pld             [r0, r1, lsl #1]
246
247     vmull.u8        q7, d2, d0              ;(src_ptr[0] * vp8_filter[0])
248     vmull.u8        q8, d3, d0
249     vmull.u8        q9, d5, d0
250     vmull.u8        q10, d6, d0
251     vmull.u8        q11, d8, d0
252     vmull.u8        q12, d9, d0
253     vmull.u8        q13, d11, d0
254     vmull.u8        q14, d12, d0
255
256     vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
257     vext.8          d5, d5, d6, #1
258     vext.8          d8, d8, d9, #1
259     vext.8          d11, d11, d12, #1
260
261     vmlal.u8        q7, d2, d1              ;(src_ptr[0] * vp8_filter[1])
262     vmlal.u8        q9, d5, d1
263     vmlal.u8        q11, d8, d1
264     vmlal.u8        q13, d11, d1
265
266     vext.8          d3, d3, d4, #1
267     vext.8          d6, d6, d7, #1
268     vext.8          d9, d9, d10, #1
269     vext.8          d12, d12, d13, #1
270
271     vmlal.u8        q8, d3, d1              ;(src_ptr[0] * vp8_filter[1])
272     vmlal.u8        q10, d6, d1
273     vmlal.u8        q12, d9, d1
274     vmlal.u8        q14, d12, d1
275
276     subs            r2, r2, #1
277
278     vqrshrn.u16    d14, q7, #7              ;shift/round/saturate to u8
279     vqrshrn.u16    d15, q8, #7
280     vqrshrn.u16    d16, q9, #7
281     vqrshrn.u16    d17, q10, #7
282     vqrshrn.u16    d18, q11, #7
283     vqrshrn.u16    d19, q12, #7
284     vqrshrn.u16    d20, q13, #7
285     vst1.u8         {d14, d15}, [r4], r5        ;store result
286     vqrshrn.u16    d21, q14, #7
287
288     vst1.u8         {d16, d17}, [r4], r5
289     vst1.u8         {d18, d19}, [r4], r5
290     vst1.u8         {d20, d21}, [r4], r5
291
292     bne             filt_blk2d_fpo16x16_loop_neon
293     pop             {r4-r5,pc}
294
295 ;---------------------
296 secondpass_bfilter16x16_only
297 ;Second pass: 16x16
298 ;secondpass_filter
299     add             r3, r12, r3, lsl #3
300     mov             r12, #4                     ;loop counter
301     vld1.u32        {d31}, [r3]                 ;load second_pass filter
302     vld1.u8         {d22, d23}, [r0], r1        ;load src data
303
304     vdup.8          d0, d31[0]                  ;second_pass filter parameters (d0 d1)
305     vdup.8          d1, d31[4]
306
307 filt_blk2d_spo16x16_loop_neon
308     vld1.u8         {d24, d25}, [r0], r1
309     vmull.u8        q1, d22, d0             ;(src_ptr[0] * vp8_filter[0])
310     vld1.u8         {d26, d27}, [r0], r1
311     vmull.u8        q2, d23, d0
312     vld1.u8         {d28, d29}, [r0], r1
313     vmull.u8        q3, d24, d0
314     vld1.u8         {d30, d31}, [r0], r1
315
316     vmull.u8        q4, d25, d0
317     vmull.u8        q5, d26, d0
318     vmull.u8        q6, d27, d0
319     vmull.u8        q7, d28, d0
320     vmull.u8        q8, d29, d0
321
322     vmlal.u8        q1, d24, d1             ;(src_ptr[pixel_step] * vp8_filter[1])
323     vmlal.u8        q2, d25, d1
324     vmlal.u8        q3, d26, d1
325     vmlal.u8        q4, d27, d1
326     vmlal.u8        q5, d28, d1
327     vmlal.u8        q6, d29, d1
328     vmlal.u8        q7, d30, d1
329     vmlal.u8        q8, d31, d1
330
331     vqrshrn.u16    d2, q1, #7               ;shift/round/saturate to u8
332     vqrshrn.u16    d3, q2, #7
333     vqrshrn.u16    d4, q3, #7
334     vqrshrn.u16    d5, q4, #7
335     vqrshrn.u16    d6, q5, #7
336     vqrshrn.u16    d7, q6, #7
337     vqrshrn.u16    d8, q7, #7
338     vqrshrn.u16    d9, q8, #7
339
340     vst1.u8         {d2, d3}, [r4], r5      ;store result
341     subs            r12, r12, #1
342     vst1.u8         {d4, d5}, [r4], r5
343     vmov            q11, q15
344     vst1.u8         {d6, d7}, [r4], r5
345     vst1.u8         {d8, d9}, [r4], r5
346
347     bne             filt_blk2d_spo16x16_loop_neon
348     pop             {r4-r5,pc}
349
350     ENDP
351
352 ;-----------------
353
354 bifilter16_coeff
355     DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
356
357     END