arm: remove duplicate functions
[libvpx.git] / vp8 / common / arm / neon / bilinearpredict16x16_neon.asm
blobbb72bad1f0ba35a49651ab98db151a4dbf77e5ed
2 ; Copyright (c) 2010 The WebM project authors. All Rights Reserved.
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.
12 EXPORT |vp8_bilinear_predict16x16_neon|
13 ARM
14 REQUIRE8
15 PRESERVE8
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
25 |vp8_bilinear_predict16x16_neon| PROC
26 push {r4-r5, lr}
28 ldr r12, _bifilter16_coeff_
29 ldr r4, [sp, #12] ;load parameters from stack
30 ldr r5, [sp, #16] ;load parameters from stack
32 cmp r2, #0 ;skip first_pass filter if xoffset=0
33 beq secondpass_bfilter16x16_only
35 add r2, r12, r2, lsl #3 ;calculate filter location
37 cmp r3, #0 ;skip second_pass filter if yoffset=0
39 vld1.s32 {d31}, [r2] ;load first_pass filter
41 beq firstpass_bfilter16x16_only
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
48 mov r2, #3 ;loop counter
49 vld1.u8 {d8, d9, d10}, [r0], r1
51 vdup.8 d0, d31[0] ;first_pass filter (d0 d1)
52 vld1.u8 {d11, d12, d13}, [r0], r1
54 vdup.8 d1, d31[4]
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]
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
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
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
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
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
91 subs r2, r2, #1
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
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
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
110 bne filt_blk2d_fp16x16_loop_neon
112 ;First-pass filtering for rest 5 lines
113 vld1.u8 {d14, d15, d16}, [r0], r1
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
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
126 vmlal.u8 q9, d2, d1 ;(src_ptr[0] * vp8_filter[1])
127 vmlal.u8 q11, d5, d1
128 vmlal.u8 q13, d8, d1
130 vext.8 d3, d3, d4, #1
131 vext.8 d6, d6, d7, #1
132 vext.8 d9, d9, d10, #1
134 vmlal.u8 q10, d3, d1 ;(src_ptr[0] * vp8_filter[1])
135 vmlal.u8 q12, d6, d1
136 vmlal.u8 q14, d9, d1
138 vmull.u8 q1, d11, d0
139 vmull.u8 q2, d12, d0
140 vmull.u8 q3, d14, d0
141 vmull.u8 q4, d15, d0
143 vext.8 d11, d11, d12, #1 ;construct src_ptr[1]
144 vext.8 d14, d14, d15, #1
146 vmlal.u8 q1, d11, d1 ;(src_ptr[0] * vp8_filter[1])
147 vmlal.u8 q3, d14, d1
149 vext.8 d12, d12, d13, #1
150 vext.8 d15, d15, d16, #1
152 vmlal.u8 q2, d12, d1 ;(src_ptr[0] * vp8_filter[1])
153 vmlal.u8 q4, d15, d1
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
166 vst1.u8 {d10, d11, d12, d13}, [lr]! ;store result
167 vst1.u8 {d14, d15, d16, d17}, [lr]!
168 vst1.u8 {d18, d19}, [lr]!
170 ;Second pass: 16x16
171 ;secondpass_filter
172 add r3, r12, r3, lsl #3
173 sub lr, lr, #272
175 vld1.u32 {d31}, [r3] ;load second_pass filter
177 vld1.u8 {d22, d23}, [lr]! ;load src data
179 vdup.8 d0, d31[0] ;second_pass filter parameters (d0 d1)
180 vdup.8 d1, d31[4]
181 mov r12, #4 ;loop counter
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]!
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
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
207 subs r12, r12, #1
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
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
224 bne filt_blk2d_sp16x16_loop_neon
226 add sp, sp, #272
228 pop {r4-r5,pc}
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]
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
243 pld [r0]
244 pld [r0, r1]
245 pld [r0, r1, lsl #1]
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
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
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
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
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
276 subs r2, r2, #1
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
288 vst1.u8 {d16, d17}, [r4], r5
289 vst1.u8 {d18, d19}, [r4], r5
290 vst1.u8 {d20, d21}, [r4], r5
292 bne filt_blk2d_fpo16x16_loop_neon
293 pop {r4-r5,pc}
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
304 vdup.8 d0, d31[0] ;second_pass filter parameters (d0 d1)
305 vdup.8 d1, d31[4]
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
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
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
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
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
347 bne filt_blk2d_spo16x16_loop_neon
348 pop {r4-r5,pc}
350 ENDP
352 ;-----------------
353 AREA bifilters16_dat, DATA, READWRITE ;read/write by default
354 ;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
355 ;One word each is reserved. Label filter_coeff can be used to access the data.
356 ;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
357 _bifilter16_coeff_
358 DCD bifilter16_coeff
359 bifilter16_coeff
360 DCD 128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112