|
1 /* |
|
2 * Copyright © 2011 SCore Corporation |
|
3 * |
|
4 * Permission is hereby granted, free of charge, to any person obtaining a |
|
5 * copy of this software and associated documentation files (the "Software"), |
|
6 * to deal in the Software without restriction, including without limitation |
|
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
|
8 * and/or sell copies of the Software, and to permit persons to whom the |
|
9 * Software is furnished to do so, subject to the following conditions: |
|
10 * |
|
11 * The above copyright notice and this permission notice (including the next |
|
12 * paragraph) shall be included in all copies or substantial portions of the |
|
13 * Software. |
|
14 * |
|
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|
21 * DEALINGS IN THE SOFTWARE. |
|
22 * |
|
23 * Author: Siarhei Siamashka (siarhei.siamashka@nokia.com) |
|
24 * Author: Taekyun Kim (tkq.kim@samsung.com) |
|
25 */ |
|
26 |
|
27 /* |
|
28 * This file contains scaled bilinear scanline functions implemented |
|
29 * using older siarhei's bilinear macro template. |
|
30 * |
|
31 * << General scanline function procedures >> |
|
32 * 1. bilinear interpolate source pixels |
|
33 * 2. load mask pixels |
|
34 * 3. load destination pixels |
|
35 * 4. duplicate mask to fill whole register |
|
36 * 5. interleave source & destination pixels |
|
37 * 6. apply mask to source pixels |
|
38 * 7. combine source & destination pixels |
|
39 * 8, Deinterleave final result |
|
40 * 9. store destination pixels |
|
41 * |
|
42 * All registers with single number (i.e. src0, tmp0) are 64-bits registers. |
|
43 * Registers with double numbers(src01, dst01) are 128-bits registers. |
|
44 * All temp registers can be used freely outside the code block. |
|
45 * Assume that symbol(register .req) OUT and MASK are defined at caller of these macro blocks. |
|
46 * |
|
47 * Remarks |
|
48 * There can be lots of pipeline stalls inside code block and between code blocks. |
|
49 * Further optimizations will be done by new macro templates using head/tail_head/tail scheme. |
|
50 */ |
|
51 |
|
52 /* Prevent the stack from becoming executable for no reason... */ |
|
53 #if defined(__linux__) && defined (__ELF__) |
|
54 .section .note.GNU-stack,"",%progbits |
|
55 #endif |
|
56 |
|
57 .text |
|
58 .fpu neon |
|
59 .arch armv7a |
|
60 .object_arch armv4 |
|
61 .eabi_attribute 10, 0 |
|
62 .eabi_attribute 12, 0 |
|
63 .arm |
|
64 .altmacro |
|
65 .p2align 2 |
|
66 |
|
67 #include "pixman-private.h" |
|
68 #include "pixman-arm-neon-asm.h" |
|
69 |
|
70 /* |
|
71 * Bilinear macros from pixman-arm-neon-asm.S |
|
72 */ |
|
73 |
|
74 /* Supplementary macro for setting function attributes */ |
|
75 .macro pixman_asm_function fname |
|
76 .func fname |
|
77 .global fname |
|
78 #ifdef __ELF__ |
|
79 .hidden fname |
|
80 .type fname, %function |
|
81 #endif |
|
82 fname: |
|
83 .endm |
|
84 |
|
85 /* |
|
86 * Bilinear scaling support code which tries to provide pixel fetching, color |
|
87 * format conversion, and interpolation as separate macros which can be used |
|
88 * as the basic building blocks for constructing bilinear scanline functions. |
|
89 */ |
|
90 |
|
91 .macro bilinear_load_8888 reg1, reg2, tmp |
|
92 mov TMP1, X, asr #16 |
|
93 add X, X, UX |
|
94 add TMP1, TOP, TMP1, asl #2 |
|
95 vld1.32 {reg1}, [TMP1], STRIDE |
|
96 vld1.32 {reg2}, [TMP1] |
|
97 .endm |
|
98 |
|
99 .macro bilinear_load_0565 reg1, reg2, tmp |
|
100 mov TMP1, X, asr #16 |
|
101 add X, X, UX |
|
102 add TMP1, TOP, TMP1, asl #1 |
|
103 vld1.32 {reg2[0]}, [TMP1], STRIDE |
|
104 vld1.32 {reg2[1]}, [TMP1] |
|
105 convert_four_0565_to_x888_packed reg2, reg1, reg2, tmp |
|
106 .endm |
|
107 |
|
108 .macro bilinear_load_and_vertical_interpolate_two_8888 \ |
|
109 acc1, acc2, reg1, reg2, reg3, reg4, tmp1, tmp2 |
|
110 |
|
111 bilinear_load_8888 reg1, reg2, tmp1 |
|
112 vmull.u8 acc1, reg1, d28 |
|
113 vmlal.u8 acc1, reg2, d29 |
|
114 bilinear_load_8888 reg3, reg4, tmp2 |
|
115 vmull.u8 acc2, reg3, d28 |
|
116 vmlal.u8 acc2, reg4, d29 |
|
117 .endm |
|
118 |
|
119 .macro bilinear_load_and_vertical_interpolate_four_8888 \ |
|
120 xacc1, xacc2, xreg1, xreg2, xreg3, xreg4, xacc2lo, xacc2hi \ |
|
121 yacc1, yacc2, yreg1, yreg2, yreg3, yreg4, yacc2lo, yacc2hi |
|
122 |
|
123 bilinear_load_and_vertical_interpolate_two_8888 \ |
|
124 xacc1, xacc2, xreg1, xreg2, xreg3, xreg4, xacc2lo, xacc2hi |
|
125 bilinear_load_and_vertical_interpolate_two_8888 \ |
|
126 yacc1, yacc2, yreg1, yreg2, yreg3, yreg4, yacc2lo, yacc2hi |
|
127 .endm |
|
128 |
|
129 .macro bilinear_load_and_vertical_interpolate_two_0565 \ |
|
130 acc1, acc2, reg1, reg2, reg3, reg4, acc2lo, acc2hi |
|
131 |
|
132 mov TMP1, X, asr #16 |
|
133 add X, X, UX |
|
134 add TMP1, TOP, TMP1, asl #1 |
|
135 mov TMP2, X, asr #16 |
|
136 add X, X, UX |
|
137 add TMP2, TOP, TMP2, asl #1 |
|
138 vld1.32 {acc2lo[0]}, [TMP1], STRIDE |
|
139 vld1.32 {acc2hi[0]}, [TMP2], STRIDE |
|
140 vld1.32 {acc2lo[1]}, [TMP1] |
|
141 vld1.32 {acc2hi[1]}, [TMP2] |
|
142 convert_0565_to_x888 acc2, reg3, reg2, reg1 |
|
143 vzip.u8 reg1, reg3 |
|
144 vzip.u8 reg2, reg4 |
|
145 vzip.u8 reg3, reg4 |
|
146 vzip.u8 reg1, reg2 |
|
147 vmull.u8 acc1, reg1, d28 |
|
148 vmlal.u8 acc1, reg2, d29 |
|
149 vmull.u8 acc2, reg3, d28 |
|
150 vmlal.u8 acc2, reg4, d29 |
|
151 .endm |
|
152 |
|
153 .macro bilinear_load_and_vertical_interpolate_four_0565 \ |
|
154 xacc1, xacc2, xreg1, xreg2, xreg3, xreg4, xacc2lo, xacc2hi \ |
|
155 yacc1, yacc2, yreg1, yreg2, yreg3, yreg4, yacc2lo, yacc2hi |
|
156 |
|
157 mov TMP1, X, asr #16 |
|
158 add X, X, UX |
|
159 add TMP1, TOP, TMP1, asl #1 |
|
160 mov TMP2, X, asr #16 |
|
161 add X, X, UX |
|
162 add TMP2, TOP, TMP2, asl #1 |
|
163 vld1.32 {xacc2lo[0]}, [TMP1], STRIDE |
|
164 vld1.32 {xacc2hi[0]}, [TMP2], STRIDE |
|
165 vld1.32 {xacc2lo[1]}, [TMP1] |
|
166 vld1.32 {xacc2hi[1]}, [TMP2] |
|
167 convert_0565_to_x888 xacc2, xreg3, xreg2, xreg1 |
|
168 mov TMP1, X, asr #16 |
|
169 add X, X, UX |
|
170 add TMP1, TOP, TMP1, asl #1 |
|
171 mov TMP2, X, asr #16 |
|
172 add X, X, UX |
|
173 add TMP2, TOP, TMP2, asl #1 |
|
174 vld1.32 {yacc2lo[0]}, [TMP1], STRIDE |
|
175 vzip.u8 xreg1, xreg3 |
|
176 vld1.32 {yacc2hi[0]}, [TMP2], STRIDE |
|
177 vzip.u8 xreg2, xreg4 |
|
178 vld1.32 {yacc2lo[1]}, [TMP1] |
|
179 vzip.u8 xreg3, xreg4 |
|
180 vld1.32 {yacc2hi[1]}, [TMP2] |
|
181 vzip.u8 xreg1, xreg2 |
|
182 convert_0565_to_x888 yacc2, yreg3, yreg2, yreg1 |
|
183 vmull.u8 xacc1, xreg1, d28 |
|
184 vzip.u8 yreg1, yreg3 |
|
185 vmlal.u8 xacc1, xreg2, d29 |
|
186 vzip.u8 yreg2, yreg4 |
|
187 vmull.u8 xacc2, xreg3, d28 |
|
188 vzip.u8 yreg3, yreg4 |
|
189 vmlal.u8 xacc2, xreg4, d29 |
|
190 vzip.u8 yreg1, yreg2 |
|
191 vmull.u8 yacc1, yreg1, d28 |
|
192 vmlal.u8 yacc1, yreg2, d29 |
|
193 vmull.u8 yacc2, yreg3, d28 |
|
194 vmlal.u8 yacc2, yreg4, d29 |
|
195 .endm |
|
196 |
|
197 .macro bilinear_store_8888 numpix, tmp1, tmp2 |
|
198 .if numpix == 4 |
|
199 vst1.32 {d0, d1}, [OUT]! |
|
200 .elseif numpix == 2 |
|
201 vst1.32 {d0}, [OUT]! |
|
202 .elseif numpix == 1 |
|
203 vst1.32 {d0[0]}, [OUT, :32]! |
|
204 .else |
|
205 .error bilinear_store_8888 numpix is unsupported |
|
206 .endif |
|
207 .endm |
|
208 |
|
209 .macro bilinear_store_0565 numpix, tmp1, tmp2 |
|
210 vuzp.u8 d0, d1 |
|
211 vuzp.u8 d2, d3 |
|
212 vuzp.u8 d1, d3 |
|
213 vuzp.u8 d0, d2 |
|
214 convert_8888_to_0565 d2, d1, d0, q1, tmp1, tmp2 |
|
215 .if numpix == 4 |
|
216 vst1.16 {d2}, [OUT]! |
|
217 .elseif numpix == 2 |
|
218 vst1.32 {d2[0]}, [OUT]! |
|
219 .elseif numpix == 1 |
|
220 vst1.16 {d2[0]}, [OUT]! |
|
221 .else |
|
222 .error bilinear_store_0565 numpix is unsupported |
|
223 .endif |
|
224 .endm |
|
225 |
|
226 |
|
227 /* |
|
228 * Macros for loading mask pixels into register 'mask'. |
|
229 * vdup must be done in somewhere else. |
|
230 */ |
|
231 .macro bilinear_load_mask_x numpix, mask |
|
232 .endm |
|
233 |
|
234 .macro bilinear_load_mask_8 numpix, mask |
|
235 .if numpix == 4 |
|
236 vld1.32 {mask[0]}, [MASK]! |
|
237 .elseif numpix == 2 |
|
238 vld1.16 {mask[0]}, [MASK]! |
|
239 .elseif numpix == 1 |
|
240 vld1.8 {mask[0]}, [MASK]! |
|
241 .else |
|
242 .error bilinear_load_mask_8 numpix is unsupported |
|
243 .endif |
|
244 pld [MASK, #prefetch_offset] |
|
245 .endm |
|
246 |
|
247 .macro bilinear_load_mask mask_fmt, numpix, mask |
|
248 bilinear_load_mask_&mask_fmt numpix, mask |
|
249 .endm |
|
250 |
|
251 |
|
252 /* |
|
253 * Macros for loading destination pixels into register 'dst0' and 'dst1'. |
|
254 * Interleave should be done somewhere else. |
|
255 */ |
|
256 .macro bilinear_load_dst_0565_src numpix, dst0, dst1, dst01 |
|
257 .endm |
|
258 |
|
259 .macro bilinear_load_dst_8888_src numpix, dst0, dst1, dst01 |
|
260 .endm |
|
261 |
|
262 .macro bilinear_load_dst_8888 numpix, dst0, dst1, dst01 |
|
263 .if numpix == 4 |
|
264 vld1.32 {dst0, dst1}, [OUT] |
|
265 .elseif numpix == 2 |
|
266 vld1.32 {dst0}, [OUT] |
|
267 .elseif numpix == 1 |
|
268 vld1.32 {dst0[0]}, [OUT] |
|
269 .else |
|
270 .error bilinear_load_dst_8888 numpix is unsupported |
|
271 .endif |
|
272 pld [OUT, #(prefetch_offset * 4)] |
|
273 .endm |
|
274 |
|
275 .macro bilinear_load_dst_8888_over numpix, dst0, dst1, dst01 |
|
276 bilinear_load_dst_8888 numpix, dst0, dst1, dst01 |
|
277 .endm |
|
278 |
|
279 .macro bilinear_load_dst_8888_add numpix, dst0, dst1, dst01 |
|
280 bilinear_load_dst_8888 numpix, dst0, dst1, dst01 |
|
281 .endm |
|
282 |
|
283 .macro bilinear_load_dst dst_fmt, op, numpix, dst0, dst1, dst01 |
|
284 bilinear_load_dst_&dst_fmt&_&op numpix, dst0, dst1, dst01 |
|
285 .endm |
|
286 |
|
287 /* |
|
288 * Macros for duplicating partially loaded mask to fill entire register. |
|
289 * We will apply mask to interleaved source pixels, that is |
|
290 * (r0, r1, r2, r3, g0, g1, g2, g3) x (m0, m1, m2, m3, m0, m1, m2, m3) |
|
291 * (b0, b1, b2, b3, a0, a1, a2, a3) x (m0, m1, m2, m3, m0, m1, m2, m3) |
|
292 * So, we need to duplicate loaded mask into whole register. |
|
293 * |
|
294 * For two pixel case |
|
295 * (r0, r1, x, x, g0, g1, x, x) x (m0, m1, m0, m1, m0, m1, m0, m1) |
|
296 * (b0, b1, x, x, a0, a1, x, x) x (m0, m1, m0, m1, m0, m1, m0, m1) |
|
297 * We can do some optimizations for this including last pixel cases. |
|
298 */ |
|
299 .macro bilinear_duplicate_mask_x numpix, mask |
|
300 .endm |
|
301 |
|
302 .macro bilinear_duplicate_mask_8 numpix, mask |
|
303 .if numpix == 4 |
|
304 vdup.32 mask, mask[0] |
|
305 .elseif numpix == 2 |
|
306 vdup.16 mask, mask[0] |
|
307 .elseif numpix == 1 |
|
308 vdup.8 mask, mask[0] |
|
309 .else |
|
310 .error bilinear_duplicate_mask_8 is unsupported |
|
311 .endif |
|
312 .endm |
|
313 |
|
314 .macro bilinear_duplicate_mask mask_fmt, numpix, mask |
|
315 bilinear_duplicate_mask_&mask_fmt numpix, mask |
|
316 .endm |
|
317 |
|
318 /* |
|
319 * Macros for interleaving src and dst pixels to rrrr gggg bbbb aaaa form. |
|
320 * Interleave should be done when maks is enabled or operator is 'over'. |
|
321 */ |
|
322 .macro bilinear_interleave src0, src1, dst0, dst1 |
|
323 vuzp.8 src0, src1 |
|
324 vuzp.8 dst0, dst1 |
|
325 vuzp.8 src0, src1 |
|
326 vuzp.8 dst0, dst1 |
|
327 .endm |
|
328 |
|
329 .macro bilinear_interleave_src_dst_x_src \ |
|
330 numpix, src0, src1, src01, dst0, dst1, dst01 |
|
331 .endm |
|
332 |
|
333 .macro bilinear_interleave_src_dst_x_over \ |
|
334 numpix, src0, src1, src01, dst0, dst1, dst01 |
|
335 |
|
336 bilinear_interleave src0, src1, dst0, dst1 |
|
337 .endm |
|
338 |
|
339 .macro bilinear_interleave_src_dst_x_add \ |
|
340 numpix, src0, src1, src01, dst0, dst1, dst01 |
|
341 .endm |
|
342 |
|
343 .macro bilinear_interleave_src_dst_8_src \ |
|
344 numpix, src0, src1, src01, dst0, dst1, dst01 |
|
345 |
|
346 bilinear_interleave src0, src1, dst0, dst1 |
|
347 .endm |
|
348 |
|
349 .macro bilinear_interleave_src_dst_8_over \ |
|
350 numpix, src0, src1, src01, dst0, dst1, dst01 |
|
351 |
|
352 bilinear_interleave src0, src1, dst0, dst1 |
|
353 .endm |
|
354 |
|
355 .macro bilinear_interleave_src_dst_8_add \ |
|
356 numpix, src0, src1, src01, dst0, dst1, dst01 |
|
357 |
|
358 bilinear_interleave src0, src1, dst0, dst1 |
|
359 .endm |
|
360 |
|
361 .macro bilinear_interleave_src_dst \ |
|
362 mask_fmt, op, numpix, src0, src1, src01, dst0, dst1, dst01 |
|
363 |
|
364 bilinear_interleave_src_dst_&mask_fmt&_&op \ |
|
365 numpix, src0, src1, src01, dst0, dst1, dst01 |
|
366 .endm |
|
367 |
|
368 |
|
369 /* |
|
370 * Macros for applying masks to src pixels. (see combine_mask_u() function) |
|
371 * src, dst should be in interleaved form. |
|
372 * mask register should be in form (m0, m1, m2, m3). |
|
373 */ |
|
374 .macro bilinear_apply_mask_to_src_x \ |
|
375 numpix, src0, src1, src01, mask, \ |
|
376 tmp01, tmp23, tmp45, tmp67 |
|
377 .endm |
|
378 |
|
379 .macro bilinear_apply_mask_to_src_8 \ |
|
380 numpix, src0, src1, src01, mask, \ |
|
381 tmp01, tmp23, tmp45, tmp67 |
|
382 |
|
383 vmull.u8 tmp01, src0, mask |
|
384 vmull.u8 tmp23, src1, mask |
|
385 /* bubbles */ |
|
386 vrshr.u16 tmp45, tmp01, #8 |
|
387 vrshr.u16 tmp67, tmp23, #8 |
|
388 /* bubbles */ |
|
389 vraddhn.u16 src0, tmp45, tmp01 |
|
390 vraddhn.u16 src1, tmp67, tmp23 |
|
391 .endm |
|
392 |
|
393 .macro bilinear_apply_mask_to_src \ |
|
394 mask_fmt, numpix, src0, src1, src01, mask, \ |
|
395 tmp01, tmp23, tmp45, tmp67 |
|
396 |
|
397 bilinear_apply_mask_to_src_&mask_fmt \ |
|
398 numpix, src0, src1, src01, mask, \ |
|
399 tmp01, tmp23, tmp45, tmp67 |
|
400 .endm |
|
401 |
|
402 |
|
403 /* |
|
404 * Macros for combining src and destination pixels. |
|
405 * Interleave or not is depending on operator 'op'. |
|
406 */ |
|
407 .macro bilinear_combine_src \ |
|
408 numpix, src0, src1, src01, dst0, dst1, dst01, \ |
|
409 tmp01, tmp23, tmp45, tmp67, tmp8 |
|
410 .endm |
|
411 |
|
412 .macro bilinear_combine_over \ |
|
413 numpix, src0, src1, src01, dst0, dst1, dst01, \ |
|
414 tmp01, tmp23, tmp45, tmp67, tmp8 |
|
415 |
|
416 vdup.32 tmp8, src1[1] |
|
417 /* bubbles */ |
|
418 vmvn.8 tmp8, tmp8 |
|
419 /* bubbles */ |
|
420 vmull.u8 tmp01, dst0, tmp8 |
|
421 /* bubbles */ |
|
422 vmull.u8 tmp23, dst1, tmp8 |
|
423 /* bubbles */ |
|
424 vrshr.u16 tmp45, tmp01, #8 |
|
425 vrshr.u16 tmp67, tmp23, #8 |
|
426 /* bubbles */ |
|
427 vraddhn.u16 dst0, tmp45, tmp01 |
|
428 vraddhn.u16 dst1, tmp67, tmp23 |
|
429 /* bubbles */ |
|
430 vqadd.u8 src01, dst01, src01 |
|
431 .endm |
|
432 |
|
433 .macro bilinear_combine_add \ |
|
434 numpix, src0, src1, src01, dst0, dst1, dst01, \ |
|
435 tmp01, tmp23, tmp45, tmp67, tmp8 |
|
436 |
|
437 vqadd.u8 src01, dst01, src01 |
|
438 .endm |
|
439 |
|
440 .macro bilinear_combine \ |
|
441 op, numpix, src0, src1, src01, dst0, dst1, dst01, \ |
|
442 tmp01, tmp23, tmp45, tmp67, tmp8 |
|
443 |
|
444 bilinear_combine_&op \ |
|
445 numpix, src0, src1, src01, dst0, dst1, dst01, \ |
|
446 tmp01, tmp23, tmp45, tmp67, tmp8 |
|
447 .endm |
|
448 |
|
449 /* |
|
450 * Macros for final deinterleaving of destination pixels if needed. |
|
451 */ |
|
452 .macro bilinear_deinterleave numpix, dst0, dst1, dst01 |
|
453 vuzp.8 dst0, dst1 |
|
454 /* bubbles */ |
|
455 vuzp.8 dst0, dst1 |
|
456 .endm |
|
457 |
|
458 .macro bilinear_deinterleave_dst_x_src numpix, dst0, dst1, dst01 |
|
459 .endm |
|
460 |
|
461 .macro bilinear_deinterleave_dst_x_over numpix, dst0, dst1, dst01 |
|
462 bilinear_deinterleave numpix, dst0, dst1, dst01 |
|
463 .endm |
|
464 |
|
465 .macro bilinear_deinterleave_dst_x_add numpix, dst0, dst1, dst01 |
|
466 .endm |
|
467 |
|
468 .macro bilinear_deinterleave_dst_8_src numpix, dst0, dst1, dst01 |
|
469 bilinear_deinterleave numpix, dst0, dst1, dst01 |
|
470 .endm |
|
471 |
|
472 .macro bilinear_deinterleave_dst_8_over numpix, dst0, dst1, dst01 |
|
473 bilinear_deinterleave numpix, dst0, dst1, dst01 |
|
474 .endm |
|
475 |
|
476 .macro bilinear_deinterleave_dst_8_add numpix, dst0, dst1, dst01 |
|
477 bilinear_deinterleave numpix, dst0, dst1, dst01 |
|
478 .endm |
|
479 |
|
480 .macro bilinear_deinterleave_dst mask_fmt, op, numpix, dst0, dst1, dst01 |
|
481 bilinear_deinterleave_dst_&mask_fmt&_&op numpix, dst0, dst1, dst01 |
|
482 .endm |
|
483 |
|
484 |
|
485 .macro bilinear_interpolate_last_pixel src_fmt, mask_fmt, dst_fmt, op |
|
486 bilinear_load_&src_fmt d0, d1, d2 |
|
487 bilinear_load_mask mask_fmt, 1, d4 |
|
488 bilinear_load_dst dst_fmt, op, 1, d18, d19, q9 |
|
489 vmull.u8 q1, d0, d28 |
|
490 vmlal.u8 q1, d1, d29 |
|
491 /* 5 cycles bubble */ |
|
492 vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS |
|
493 vmlsl.u16 q0, d2, d30 |
|
494 vmlal.u16 q0, d3, d30 |
|
495 /* 5 cycles bubble */ |
|
496 bilinear_duplicate_mask mask_fmt, 1, d4 |
|
497 vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
498 /* 3 cycles bubble */ |
|
499 vmovn.u16 d0, q0 |
|
500 /* 1 cycle bubble */ |
|
501 bilinear_interleave_src_dst \ |
|
502 mask_fmt, op, 1, d0, d1, q0, d18, d19, q9 |
|
503 bilinear_apply_mask_to_src \ |
|
504 mask_fmt, 1, d0, d1, q0, d4, \ |
|
505 q3, q8, q10, q11 |
|
506 bilinear_combine \ |
|
507 op, 1, d0, d1, q0, d18, d19, q9, \ |
|
508 q3, q8, q10, q11, d5 |
|
509 bilinear_deinterleave_dst mask_fmt, op, 1, d0, d1, q0 |
|
510 bilinear_store_&dst_fmt 1, q2, q3 |
|
511 .endm |
|
512 |
|
513 .macro bilinear_interpolate_two_pixels src_fmt, mask_fmt, dst_fmt, op |
|
514 bilinear_load_and_vertical_interpolate_two_&src_fmt \ |
|
515 q1, q11, d0, d1, d20, d21, d22, d23 |
|
516 bilinear_load_mask mask_fmt, 2, d4 |
|
517 bilinear_load_dst dst_fmt, op, 2, d18, d19, q9 |
|
518 vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS |
|
519 vmlsl.u16 q0, d2, d30 |
|
520 vmlal.u16 q0, d3, d30 |
|
521 vshll.u16 q10, d22, #BILINEAR_INTERPOLATION_BITS |
|
522 vmlsl.u16 q10, d22, d31 |
|
523 vmlal.u16 q10, d23, d31 |
|
524 vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
525 vshrn.u32 d1, q10, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
526 bilinear_duplicate_mask mask_fmt, 2, d4 |
|
527 vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) |
|
528 vadd.u16 q12, q12, q13 |
|
529 vmovn.u16 d0, q0 |
|
530 bilinear_interleave_src_dst \ |
|
531 mask_fmt, op, 2, d0, d1, q0, d18, d19, q9 |
|
532 bilinear_apply_mask_to_src \ |
|
533 mask_fmt, 2, d0, d1, q0, d4, \ |
|
534 q3, q8, q10, q11 |
|
535 bilinear_combine \ |
|
536 op, 2, d0, d1, q0, d18, d19, q9, \ |
|
537 q3, q8, q10, q11, d5 |
|
538 bilinear_deinterleave_dst mask_fmt, op, 2, d0, d1, q0 |
|
539 bilinear_store_&dst_fmt 2, q2, q3 |
|
540 .endm |
|
541 |
|
542 .macro bilinear_interpolate_four_pixels src_fmt, mask_fmt, dst_fmt, op |
|
543 bilinear_load_and_vertical_interpolate_four_&src_fmt \ |
|
544 q1, q11, d0, d1, d20, d21, d22, d23 \ |
|
545 q3, q9, d4, d5, d16, d17, d18, d19 |
|
546 pld [TMP1, PF_OFFS] |
|
547 sub TMP1, TMP1, STRIDE |
|
548 vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS |
|
549 vmlsl.u16 q0, d2, d30 |
|
550 vmlal.u16 q0, d3, d30 |
|
551 vshll.u16 q10, d22, #BILINEAR_INTERPOLATION_BITS |
|
552 vmlsl.u16 q10, d22, d31 |
|
553 vmlal.u16 q10, d23, d31 |
|
554 vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) |
|
555 vshll.u16 q2, d6, #BILINEAR_INTERPOLATION_BITS |
|
556 vmlsl.u16 q2, d6, d30 |
|
557 vmlal.u16 q2, d7, d30 |
|
558 vshll.u16 q8, d18, #BILINEAR_INTERPOLATION_BITS |
|
559 bilinear_load_mask mask_fmt, 4, d22 |
|
560 bilinear_load_dst dst_fmt, op, 4, d2, d3, q1 |
|
561 pld [TMP1, PF_OFFS] |
|
562 vmlsl.u16 q8, d18, d31 |
|
563 vmlal.u16 q8, d19, d31 |
|
564 vadd.u16 q12, q12, q13 |
|
565 vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
566 vshrn.u32 d1, q10, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
567 vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
568 vshrn.u32 d5, q8, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
569 bilinear_duplicate_mask mask_fmt, 4, d22 |
|
570 vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) |
|
571 vmovn.u16 d0, q0 |
|
572 vmovn.u16 d1, q2 |
|
573 vadd.u16 q12, q12, q13 |
|
574 bilinear_interleave_src_dst \ |
|
575 mask_fmt, op, 4, d0, d1, q0, d2, d3, q1 |
|
576 bilinear_apply_mask_to_src \ |
|
577 mask_fmt, 4, d0, d1, q0, d22, \ |
|
578 q3, q8, q9, q10 |
|
579 bilinear_combine \ |
|
580 op, 4, d0, d1, q0, d2, d3, q1, \ |
|
581 q3, q8, q9, q10, d23 |
|
582 bilinear_deinterleave_dst mask_fmt, op, 4, d0, d1, q0 |
|
583 bilinear_store_&dst_fmt 4, q2, q3 |
|
584 .endm |
|
585 |
|
586 .set BILINEAR_FLAG_USE_MASK, 1 |
|
587 .set BILINEAR_FLAG_USE_ALL_NEON_REGS, 2 |
|
588 |
|
589 /* |
|
590 * Main template macro for generating NEON optimized bilinear scanline functions. |
|
591 * |
|
592 * Bilinear scanline generator macro take folling arguments: |
|
593 * fname - name of the function to generate |
|
594 * src_fmt - source color format (8888 or 0565) |
|
595 * dst_fmt - destination color format (8888 or 0565) |
|
596 * src/dst_bpp_shift - (1 << bpp_shift) is the size of src/dst pixel in bytes |
|
597 * process_last_pixel - code block that interpolate one pixel and does not |
|
598 * update horizontal weight |
|
599 * process_two_pixels - code block that interpolate two pixels and update |
|
600 * horizontal weight |
|
601 * process_four_pixels - code block that interpolate four pixels and update |
|
602 * horizontal weight |
|
603 * process_pixblock_head - head part of middle loop |
|
604 * process_pixblock_tail - tail part of middle loop |
|
605 * process_pixblock_tail_head - tail_head of middle loop |
|
606 * pixblock_size - number of pixels processed in a single middle loop |
|
607 * prefetch_distance - prefetch in the source image by that many pixels ahead |
|
608 */ |
|
609 |
|
610 .macro generate_bilinear_scanline_func \ |
|
611 fname, \ |
|
612 src_fmt, dst_fmt, src_bpp_shift, dst_bpp_shift, \ |
|
613 bilinear_process_last_pixel, \ |
|
614 bilinear_process_two_pixels, \ |
|
615 bilinear_process_four_pixels, \ |
|
616 bilinear_process_pixblock_head, \ |
|
617 bilinear_process_pixblock_tail, \ |
|
618 bilinear_process_pixblock_tail_head, \ |
|
619 pixblock_size, \ |
|
620 prefetch_distance, \ |
|
621 flags |
|
622 |
|
623 pixman_asm_function fname |
|
624 .if pixblock_size == 8 |
|
625 .elseif pixblock_size == 4 |
|
626 .else |
|
627 .error unsupported pixblock size |
|
628 .endif |
|
629 |
|
630 .if ((flags) & BILINEAR_FLAG_USE_MASK) == 0 |
|
631 OUT .req r0 |
|
632 TOP .req r1 |
|
633 BOTTOM .req r2 |
|
634 WT .req r3 |
|
635 WB .req r4 |
|
636 X .req r5 |
|
637 UX .req r6 |
|
638 WIDTH .req ip |
|
639 TMP1 .req r3 |
|
640 TMP2 .req r4 |
|
641 PF_OFFS .req r7 |
|
642 TMP3 .req r8 |
|
643 TMP4 .req r9 |
|
644 STRIDE .req r2 |
|
645 |
|
646 mov ip, sp |
|
647 push {r4, r5, r6, r7, r8, r9} |
|
648 mov PF_OFFS, #prefetch_distance |
|
649 ldmia ip, {WB, X, UX, WIDTH} |
|
650 .else |
|
651 OUT .req r0 |
|
652 MASK .req r1 |
|
653 TOP .req r2 |
|
654 BOTTOM .req r3 |
|
655 WT .req r4 |
|
656 WB .req r5 |
|
657 X .req r6 |
|
658 UX .req r7 |
|
659 WIDTH .req ip |
|
660 TMP1 .req r4 |
|
661 TMP2 .req r5 |
|
662 PF_OFFS .req r8 |
|
663 TMP3 .req r9 |
|
664 TMP4 .req r10 |
|
665 STRIDE .req r3 |
|
666 |
|
667 .set prefetch_offset, prefetch_distance |
|
668 |
|
669 mov ip, sp |
|
670 push {r4, r5, r6, r7, r8, r9, r10, ip} |
|
671 mov PF_OFFS, #prefetch_distance |
|
672 ldmia ip, {WT, WB, X, UX, WIDTH} |
|
673 .endif |
|
674 |
|
675 mul PF_OFFS, PF_OFFS, UX |
|
676 |
|
677 .if ((flags) & BILINEAR_FLAG_USE_ALL_NEON_REGS) != 0 |
|
678 vpush {d8-d15} |
|
679 .endif |
|
680 |
|
681 sub STRIDE, BOTTOM, TOP |
|
682 .unreq BOTTOM |
|
683 |
|
684 cmp WIDTH, #0 |
|
685 ble 3f |
|
686 |
|
687 vdup.u16 q12, X |
|
688 vdup.u16 q13, UX |
|
689 vdup.u8 d28, WT |
|
690 vdup.u8 d29, WB |
|
691 vadd.u16 d25, d25, d26 |
|
692 |
|
693 /* ensure good destination alignment */ |
|
694 cmp WIDTH, #1 |
|
695 blt 0f |
|
696 tst OUT, #(1 << dst_bpp_shift) |
|
697 beq 0f |
|
698 vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) |
|
699 vadd.u16 q12, q12, q13 |
|
700 bilinear_process_last_pixel |
|
701 sub WIDTH, WIDTH, #1 |
|
702 0: |
|
703 vadd.u16 q13, q13, q13 |
|
704 vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) |
|
705 vadd.u16 q12, q12, q13 |
|
706 |
|
707 cmp WIDTH, #2 |
|
708 blt 0f |
|
709 tst OUT, #(1 << (dst_bpp_shift + 1)) |
|
710 beq 0f |
|
711 bilinear_process_two_pixels |
|
712 sub WIDTH, WIDTH, #2 |
|
713 0: |
|
714 .if pixblock_size == 8 |
|
715 cmp WIDTH, #4 |
|
716 blt 0f |
|
717 tst OUT, #(1 << (dst_bpp_shift + 2)) |
|
718 beq 0f |
|
719 bilinear_process_four_pixels |
|
720 sub WIDTH, WIDTH, #4 |
|
721 0: |
|
722 .endif |
|
723 subs WIDTH, WIDTH, #pixblock_size |
|
724 blt 1f |
|
725 mov PF_OFFS, PF_OFFS, asr #(16 - src_bpp_shift) |
|
726 bilinear_process_pixblock_head |
|
727 subs WIDTH, WIDTH, #pixblock_size |
|
728 blt 5f |
|
729 0: |
|
730 bilinear_process_pixblock_tail_head |
|
731 subs WIDTH, WIDTH, #pixblock_size |
|
732 bge 0b |
|
733 5: |
|
734 bilinear_process_pixblock_tail |
|
735 1: |
|
736 .if pixblock_size == 8 |
|
737 tst WIDTH, #4 |
|
738 beq 2f |
|
739 bilinear_process_four_pixels |
|
740 2: |
|
741 .endif |
|
742 /* handle the remaining trailing pixels */ |
|
743 tst WIDTH, #2 |
|
744 beq 2f |
|
745 bilinear_process_two_pixels |
|
746 2: |
|
747 tst WIDTH, #1 |
|
748 beq 3f |
|
749 bilinear_process_last_pixel |
|
750 3: |
|
751 .if ((flags) & BILINEAR_FLAG_USE_ALL_NEON_REGS) != 0 |
|
752 vpop {d8-d15} |
|
753 .endif |
|
754 |
|
755 .if ((flags) & BILINEAR_FLAG_USE_MASK) == 0 |
|
756 pop {r4, r5, r6, r7, r8, r9} |
|
757 .else |
|
758 pop {r4, r5, r6, r7, r8, r9, r10, ip} |
|
759 .endif |
|
760 bx lr |
|
761 |
|
762 .unreq OUT |
|
763 .unreq TOP |
|
764 .unreq WT |
|
765 .unreq WB |
|
766 .unreq X |
|
767 .unreq UX |
|
768 .unreq WIDTH |
|
769 .unreq TMP1 |
|
770 .unreq TMP2 |
|
771 .unreq PF_OFFS |
|
772 .unreq TMP3 |
|
773 .unreq TMP4 |
|
774 .unreq STRIDE |
|
775 .if ((flags) & BILINEAR_FLAG_USE_MASK) != 0 |
|
776 .unreq MASK |
|
777 .endif |
|
778 |
|
779 .endfunc |
|
780 |
|
781 .endm |
|
782 |
|
783 /* src_8888_8_8888 */ |
|
784 .macro bilinear_src_8888_8_8888_process_last_pixel |
|
785 bilinear_interpolate_last_pixel 8888, 8, 8888, src |
|
786 .endm |
|
787 |
|
788 .macro bilinear_src_8888_8_8888_process_two_pixels |
|
789 bilinear_interpolate_two_pixels 8888, 8, 8888, src |
|
790 .endm |
|
791 |
|
792 .macro bilinear_src_8888_8_8888_process_four_pixels |
|
793 bilinear_interpolate_four_pixels 8888, 8, 8888, src |
|
794 .endm |
|
795 |
|
796 .macro bilinear_src_8888_8_8888_process_pixblock_head |
|
797 bilinear_src_8888_8_8888_process_four_pixels |
|
798 .endm |
|
799 |
|
800 .macro bilinear_src_8888_8_8888_process_pixblock_tail |
|
801 .endm |
|
802 |
|
803 .macro bilinear_src_8888_8_8888_process_pixblock_tail_head |
|
804 bilinear_src_8888_8_8888_process_pixblock_tail |
|
805 bilinear_src_8888_8_8888_process_pixblock_head |
|
806 .endm |
|
807 |
|
808 /* src_8888_8_0565 */ |
|
809 .macro bilinear_src_8888_8_0565_process_last_pixel |
|
810 bilinear_interpolate_last_pixel 8888, 8, 0565, src |
|
811 .endm |
|
812 |
|
813 .macro bilinear_src_8888_8_0565_process_two_pixels |
|
814 bilinear_interpolate_two_pixels 8888, 8, 0565, src |
|
815 .endm |
|
816 |
|
817 .macro bilinear_src_8888_8_0565_process_four_pixels |
|
818 bilinear_interpolate_four_pixels 8888, 8, 0565, src |
|
819 .endm |
|
820 |
|
821 .macro bilinear_src_8888_8_0565_process_pixblock_head |
|
822 bilinear_src_8888_8_0565_process_four_pixels |
|
823 .endm |
|
824 |
|
825 .macro bilinear_src_8888_8_0565_process_pixblock_tail |
|
826 .endm |
|
827 |
|
828 .macro bilinear_src_8888_8_0565_process_pixblock_tail_head |
|
829 bilinear_src_8888_8_0565_process_pixblock_tail |
|
830 bilinear_src_8888_8_0565_process_pixblock_head |
|
831 .endm |
|
832 |
|
833 /* src_0565_8_x888 */ |
|
834 .macro bilinear_src_0565_8_x888_process_last_pixel |
|
835 bilinear_interpolate_last_pixel 0565, 8, 8888, src |
|
836 .endm |
|
837 |
|
838 .macro bilinear_src_0565_8_x888_process_two_pixels |
|
839 bilinear_interpolate_two_pixels 0565, 8, 8888, src |
|
840 .endm |
|
841 |
|
842 .macro bilinear_src_0565_8_x888_process_four_pixels |
|
843 bilinear_interpolate_four_pixels 0565, 8, 8888, src |
|
844 .endm |
|
845 |
|
846 .macro bilinear_src_0565_8_x888_process_pixblock_head |
|
847 bilinear_src_0565_8_x888_process_four_pixels |
|
848 .endm |
|
849 |
|
850 .macro bilinear_src_0565_8_x888_process_pixblock_tail |
|
851 .endm |
|
852 |
|
853 .macro bilinear_src_0565_8_x888_process_pixblock_tail_head |
|
854 bilinear_src_0565_8_x888_process_pixblock_tail |
|
855 bilinear_src_0565_8_x888_process_pixblock_head |
|
856 .endm |
|
857 |
|
858 /* src_0565_8_0565 */ |
|
859 .macro bilinear_src_0565_8_0565_process_last_pixel |
|
860 bilinear_interpolate_last_pixel 0565, 8, 0565, src |
|
861 .endm |
|
862 |
|
863 .macro bilinear_src_0565_8_0565_process_two_pixels |
|
864 bilinear_interpolate_two_pixels 0565, 8, 0565, src |
|
865 .endm |
|
866 |
|
867 .macro bilinear_src_0565_8_0565_process_four_pixels |
|
868 bilinear_interpolate_four_pixels 0565, 8, 0565, src |
|
869 .endm |
|
870 |
|
871 .macro bilinear_src_0565_8_0565_process_pixblock_head |
|
872 bilinear_src_0565_8_0565_process_four_pixels |
|
873 .endm |
|
874 |
|
875 .macro bilinear_src_0565_8_0565_process_pixblock_tail |
|
876 .endm |
|
877 |
|
878 .macro bilinear_src_0565_8_0565_process_pixblock_tail_head |
|
879 bilinear_src_0565_8_0565_process_pixblock_tail |
|
880 bilinear_src_0565_8_0565_process_pixblock_head |
|
881 .endm |
|
882 |
|
883 /* over_8888_8888 */ |
|
884 .macro bilinear_over_8888_8888_process_last_pixel |
|
885 bilinear_interpolate_last_pixel 8888, x, 8888, over |
|
886 .endm |
|
887 |
|
888 .macro bilinear_over_8888_8888_process_two_pixels |
|
889 bilinear_interpolate_two_pixels 8888, x, 8888, over |
|
890 .endm |
|
891 |
|
892 .macro bilinear_over_8888_8888_process_four_pixels |
|
893 bilinear_interpolate_four_pixels 8888, x, 8888, over |
|
894 .endm |
|
895 |
|
896 .macro bilinear_over_8888_8888_process_pixblock_head |
|
897 mov TMP1, X, asr #16 |
|
898 add X, X, UX |
|
899 add TMP1, TOP, TMP1, asl #2 |
|
900 mov TMP2, X, asr #16 |
|
901 add X, X, UX |
|
902 add TMP2, TOP, TMP2, asl #2 |
|
903 |
|
904 vld1.32 {d22}, [TMP1], STRIDE |
|
905 vld1.32 {d23}, [TMP1] |
|
906 mov TMP3, X, asr #16 |
|
907 add X, X, UX |
|
908 add TMP3, TOP, TMP3, asl #2 |
|
909 vmull.u8 q8, d22, d28 |
|
910 vmlal.u8 q8, d23, d29 |
|
911 |
|
912 vld1.32 {d22}, [TMP2], STRIDE |
|
913 vld1.32 {d23}, [TMP2] |
|
914 mov TMP4, X, asr #16 |
|
915 add X, X, UX |
|
916 add TMP4, TOP, TMP4, asl #2 |
|
917 vmull.u8 q9, d22, d28 |
|
918 vmlal.u8 q9, d23, d29 |
|
919 |
|
920 vld1.32 {d22}, [TMP3], STRIDE |
|
921 vld1.32 {d23}, [TMP3] |
|
922 vmull.u8 q10, d22, d28 |
|
923 vmlal.u8 q10, d23, d29 |
|
924 |
|
925 vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS |
|
926 vmlsl.u16 q0, d16, d30 |
|
927 vmlal.u16 q0, d17, d30 |
|
928 |
|
929 pld [TMP4, PF_OFFS] |
|
930 vld1.32 {d16}, [TMP4], STRIDE |
|
931 vld1.32 {d17}, [TMP4] |
|
932 pld [TMP4, PF_OFFS] |
|
933 vmull.u8 q11, d16, d28 |
|
934 vmlal.u8 q11, d17, d29 |
|
935 |
|
936 vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS |
|
937 vmlsl.u16 q1, d18, d31 |
|
938 vmlal.u16 q1, d19, d31 |
|
939 vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) |
|
940 vadd.u16 q12, q12, q13 |
|
941 .endm |
|
942 |
|
943 .macro bilinear_over_8888_8888_process_pixblock_tail |
|
944 vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS |
|
945 vmlsl.u16 q2, d20, d30 |
|
946 vmlal.u16 q2, d21, d30 |
|
947 vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS |
|
948 vmlsl.u16 q3, d22, d31 |
|
949 vmlal.u16 q3, d23, d31 |
|
950 vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
951 vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
952 vld1.32 {d2, d3}, [OUT, :128] |
|
953 pld [OUT, #(prefetch_offset * 4)] |
|
954 vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
955 vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) |
|
956 vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
957 vmovn.u16 d6, q0 |
|
958 vmovn.u16 d7, q2 |
|
959 vuzp.8 d6, d7 |
|
960 vuzp.8 d2, d3 |
|
961 vuzp.8 d6, d7 |
|
962 vuzp.8 d2, d3 |
|
963 vdup.32 d4, d7[1] |
|
964 vmvn.8 d4, d4 |
|
965 vmull.u8 q11, d2, d4 |
|
966 vmull.u8 q2, d3, d4 |
|
967 vrshr.u16 q1, q11, #8 |
|
968 vrshr.u16 q10, q2, #8 |
|
969 vraddhn.u16 d2, q1, q11 |
|
970 vraddhn.u16 d3, q10, q2 |
|
971 vqadd.u8 q3, q1, q3 |
|
972 vuzp.8 d6, d7 |
|
973 vuzp.8 d6, d7 |
|
974 vadd.u16 q12, q12, q13 |
|
975 vst1.32 {d6, d7}, [OUT, :128]! |
|
976 .endm |
|
977 |
|
978 .macro bilinear_over_8888_8888_process_pixblock_tail_head |
|
979 vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS |
|
980 mov TMP1, X, asr #16 |
|
981 add X, X, UX |
|
982 add TMP1, TOP, TMP1, asl #2 |
|
983 vmlsl.u16 q2, d20, d30 |
|
984 mov TMP2, X, asr #16 |
|
985 add X, X, UX |
|
986 add TMP2, TOP, TMP2, asl #2 |
|
987 vmlal.u16 q2, d21, d30 |
|
988 vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS |
|
989 vld1.32 {d20}, [TMP1], STRIDE |
|
990 vmlsl.u16 q3, d22, d31 |
|
991 vmlal.u16 q3, d23, d31 |
|
992 vld1.32 {d21}, [TMP1] |
|
993 vmull.u8 q8, d20, d28 |
|
994 vmlal.u8 q8, d21, d29 |
|
995 vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
996 vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
997 vld1.32 {d2, d3}, [OUT, :128] |
|
998 pld [OUT, PF_OFFS] |
|
999 vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
1000 vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) |
|
1001 vld1.32 {d22}, [TMP2], STRIDE |
|
1002 vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
1003 vmovn.u16 d6, q0 |
|
1004 vld1.32 {d23}, [TMP2] |
|
1005 vmull.u8 q9, d22, d28 |
|
1006 mov TMP3, X, asr #16 |
|
1007 add X, X, UX |
|
1008 add TMP3, TOP, TMP3, asl #2 |
|
1009 mov TMP4, X, asr #16 |
|
1010 add X, X, UX |
|
1011 add TMP4, TOP, TMP4, asl #2 |
|
1012 vmlal.u8 q9, d23, d29 |
|
1013 vmovn.u16 d7, q2 |
|
1014 vld1.32 {d22}, [TMP3], STRIDE |
|
1015 vuzp.8 d6, d7 |
|
1016 vuzp.8 d2, d3 |
|
1017 vuzp.8 d6, d7 |
|
1018 vuzp.8 d2, d3 |
|
1019 vdup.32 d4, d7[1] |
|
1020 vld1.32 {d23}, [TMP3] |
|
1021 vmvn.8 d4, d4 |
|
1022 vmull.u8 q10, d22, d28 |
|
1023 vmlal.u8 q10, d23, d29 |
|
1024 vmull.u8 q11, d2, d4 |
|
1025 vmull.u8 q2, d3, d4 |
|
1026 vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS |
|
1027 vmlsl.u16 q0, d16, d30 |
|
1028 vrshr.u16 q1, q11, #8 |
|
1029 vmlal.u16 q0, d17, d30 |
|
1030 vrshr.u16 q8, q2, #8 |
|
1031 vraddhn.u16 d2, q1, q11 |
|
1032 vraddhn.u16 d3, q8, q2 |
|
1033 pld [TMP4, PF_OFFS] |
|
1034 vld1.32 {d16}, [TMP4], STRIDE |
|
1035 vqadd.u8 q3, q1, q3 |
|
1036 vld1.32 {d17}, [TMP4] |
|
1037 pld [TMP4, PF_OFFS] |
|
1038 vmull.u8 q11, d16, d28 |
|
1039 vmlal.u8 q11, d17, d29 |
|
1040 vuzp.8 d6, d7 |
|
1041 vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS |
|
1042 vuzp.8 d6, d7 |
|
1043 vmlsl.u16 q1, d18, d31 |
|
1044 vadd.u16 q12, q12, q13 |
|
1045 vmlal.u16 q1, d19, d31 |
|
1046 vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) |
|
1047 vadd.u16 q12, q12, q13 |
|
1048 vst1.32 {d6, d7}, [OUT, :128]! |
|
1049 .endm |
|
1050 |
|
1051 /* over_8888_8_8888 */ |
|
1052 .macro bilinear_over_8888_8_8888_process_last_pixel |
|
1053 bilinear_interpolate_last_pixel 8888, 8, 8888, over |
|
1054 .endm |
|
1055 |
|
1056 .macro bilinear_over_8888_8_8888_process_two_pixels |
|
1057 bilinear_interpolate_two_pixels 8888, 8, 8888, over |
|
1058 .endm |
|
1059 |
|
1060 .macro bilinear_over_8888_8_8888_process_four_pixels |
|
1061 bilinear_interpolate_four_pixels 8888, 8, 8888, over |
|
1062 .endm |
|
1063 |
|
1064 .macro bilinear_over_8888_8_8888_process_pixblock_head |
|
1065 mov TMP1, X, asr #16 |
|
1066 add X, X, UX |
|
1067 add TMP1, TOP, TMP1, asl #2 |
|
1068 vld1.32 {d0}, [TMP1], STRIDE |
|
1069 mov TMP2, X, asr #16 |
|
1070 add X, X, UX |
|
1071 add TMP2, TOP, TMP2, asl #2 |
|
1072 vld1.32 {d1}, [TMP1] |
|
1073 mov TMP3, X, asr #16 |
|
1074 add X, X, UX |
|
1075 add TMP3, TOP, TMP3, asl #2 |
|
1076 vld1.32 {d2}, [TMP2], STRIDE |
|
1077 mov TMP4, X, asr #16 |
|
1078 add X, X, UX |
|
1079 add TMP4, TOP, TMP4, asl #2 |
|
1080 vld1.32 {d3}, [TMP2] |
|
1081 vmull.u8 q2, d0, d28 |
|
1082 vmull.u8 q3, d2, d28 |
|
1083 vmlal.u8 q2, d1, d29 |
|
1084 vmlal.u8 q3, d3, d29 |
|
1085 vshll.u16 q0, d4, #BILINEAR_INTERPOLATION_BITS |
|
1086 vshll.u16 q1, d6, #BILINEAR_INTERPOLATION_BITS |
|
1087 vmlsl.u16 q0, d4, d30 |
|
1088 vmlsl.u16 q1, d6, d31 |
|
1089 vmlal.u16 q0, d5, d30 |
|
1090 vmlal.u16 q1, d7, d31 |
|
1091 vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
1092 vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
1093 vld1.32 {d2}, [TMP3], STRIDE |
|
1094 vld1.32 {d3}, [TMP3] |
|
1095 pld [TMP4, PF_OFFS] |
|
1096 vld1.32 {d4}, [TMP4], STRIDE |
|
1097 vld1.32 {d5}, [TMP4] |
|
1098 pld [TMP4, PF_OFFS] |
|
1099 vmull.u8 q3, d2, d28 |
|
1100 vmlal.u8 q3, d3, d29 |
|
1101 vmull.u8 q1, d4, d28 |
|
1102 vmlal.u8 q1, d5, d29 |
|
1103 vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) |
|
1104 vld1.32 {d22[0]}, [MASK]! |
|
1105 pld [MASK, #prefetch_offset] |
|
1106 vadd.u16 q12, q12, q13 |
|
1107 vmovn.u16 d16, q0 |
|
1108 .endm |
|
1109 |
|
1110 .macro bilinear_over_8888_8_8888_process_pixblock_tail |
|
1111 vshll.u16 q9, d6, #BILINEAR_INTERPOLATION_BITS |
|
1112 vshll.u16 q10, d2, #BILINEAR_INTERPOLATION_BITS |
|
1113 vmlsl.u16 q9, d6, d30 |
|
1114 vmlsl.u16 q10, d2, d31 |
|
1115 vmlal.u16 q9, d7, d30 |
|
1116 vmlal.u16 q10, d3, d31 |
|
1117 vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) |
|
1118 vadd.u16 q12, q12, q13 |
|
1119 vdup.32 d22, d22[0] |
|
1120 vshrn.u32 d18, q9, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
1121 vshrn.u32 d19, q10, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
1122 vmovn.u16 d17, q9 |
|
1123 vld1.32 {d18, d19}, [OUT, :128] |
|
1124 pld [OUT, PF_OFFS] |
|
1125 vuzp.8 d16, d17 |
|
1126 vuzp.8 d18, d19 |
|
1127 vuzp.8 d16, d17 |
|
1128 vuzp.8 d18, d19 |
|
1129 vmull.u8 q10, d16, d22 |
|
1130 vmull.u8 q11, d17, d22 |
|
1131 vrsra.u16 q10, q10, #8 |
|
1132 vrsra.u16 q11, q11, #8 |
|
1133 vrshrn.u16 d16, q10, #8 |
|
1134 vrshrn.u16 d17, q11, #8 |
|
1135 vdup.32 d22, d17[1] |
|
1136 vmvn.8 d22, d22 |
|
1137 vmull.u8 q10, d18, d22 |
|
1138 vmull.u8 q11, d19, d22 |
|
1139 vrshr.u16 q9, q10, #8 |
|
1140 vrshr.u16 q0, q11, #8 |
|
1141 vraddhn.u16 d18, q9, q10 |
|
1142 vraddhn.u16 d19, q0, q11 |
|
1143 vqadd.u8 q9, q8, q9 |
|
1144 vuzp.8 d18, d19 |
|
1145 vuzp.8 d18, d19 |
|
1146 vst1.32 {d18, d19}, [OUT, :128]! |
|
1147 .endm |
|
1148 |
|
1149 .macro bilinear_over_8888_8_8888_process_pixblock_tail_head |
|
1150 vshll.u16 q9, d6, #BILINEAR_INTERPOLATION_BITS |
|
1151 mov TMP1, X, asr #16 |
|
1152 add X, X, UX |
|
1153 add TMP1, TOP, TMP1, asl #2 |
|
1154 vshll.u16 q10, d2, #BILINEAR_INTERPOLATION_BITS |
|
1155 vld1.32 {d0}, [TMP1], STRIDE |
|
1156 mov TMP2, X, asr #16 |
|
1157 add X, X, UX |
|
1158 add TMP2, TOP, TMP2, asl #2 |
|
1159 vmlsl.u16 q9, d6, d30 |
|
1160 vmlsl.u16 q10, d2, d31 |
|
1161 vld1.32 {d1}, [TMP1] |
|
1162 mov TMP3, X, asr #16 |
|
1163 add X, X, UX |
|
1164 add TMP3, TOP, TMP3, asl #2 |
|
1165 vmlal.u16 q9, d7, d30 |
|
1166 vmlal.u16 q10, d3, d31 |
|
1167 vld1.32 {d2}, [TMP2], STRIDE |
|
1168 mov TMP4, X, asr #16 |
|
1169 add X, X, UX |
|
1170 add TMP4, TOP, TMP4, asl #2 |
|
1171 vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) |
|
1172 vadd.u16 q12, q12, q13 |
|
1173 vld1.32 {d3}, [TMP2] |
|
1174 vdup.32 d22, d22[0] |
|
1175 vshrn.u32 d18, q9, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
1176 vshrn.u32 d19, q10, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
1177 vmull.u8 q2, d0, d28 |
|
1178 vmull.u8 q3, d2, d28 |
|
1179 vmovn.u16 d17, q9 |
|
1180 vld1.32 {d18, d19}, [OUT, :128] |
|
1181 pld [OUT, #(prefetch_offset * 4)] |
|
1182 vmlal.u8 q2, d1, d29 |
|
1183 vmlal.u8 q3, d3, d29 |
|
1184 vuzp.8 d16, d17 |
|
1185 vuzp.8 d18, d19 |
|
1186 vshll.u16 q0, d4, #BILINEAR_INTERPOLATION_BITS |
|
1187 vshll.u16 q1, d6, #BILINEAR_INTERPOLATION_BITS |
|
1188 vuzp.8 d16, d17 |
|
1189 vuzp.8 d18, d19 |
|
1190 vmlsl.u16 q0, d4, d30 |
|
1191 vmlsl.u16 q1, d6, d31 |
|
1192 vmull.u8 q10, d16, d22 |
|
1193 vmull.u8 q11, d17, d22 |
|
1194 vmlal.u16 q0, d5, d30 |
|
1195 vmlal.u16 q1, d7, d31 |
|
1196 vrsra.u16 q10, q10, #8 |
|
1197 vrsra.u16 q11, q11, #8 |
|
1198 vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
1199 vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS) |
|
1200 vrshrn.u16 d16, q10, #8 |
|
1201 vrshrn.u16 d17, q11, #8 |
|
1202 vld1.32 {d2}, [TMP3], STRIDE |
|
1203 vdup.32 d22, d17[1] |
|
1204 vld1.32 {d3}, [TMP3] |
|
1205 vmvn.8 d22, d22 |
|
1206 pld [TMP4, PF_OFFS] |
|
1207 vld1.32 {d4}, [TMP4], STRIDE |
|
1208 vmull.u8 q10, d18, d22 |
|
1209 vmull.u8 q11, d19, d22 |
|
1210 vld1.32 {d5}, [TMP4] |
|
1211 pld [TMP4, PF_OFFS] |
|
1212 vmull.u8 q3, d2, d28 |
|
1213 vrshr.u16 q9, q10, #8 |
|
1214 vrshr.u16 q15, q11, #8 |
|
1215 vmlal.u8 q3, d3, d29 |
|
1216 vmull.u8 q1, d4, d28 |
|
1217 vraddhn.u16 d18, q9, q10 |
|
1218 vraddhn.u16 d19, q15, q11 |
|
1219 vmlal.u8 q1, d5, d29 |
|
1220 vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) |
|
1221 vqadd.u8 q9, q8, q9 |
|
1222 vld1.32 {d22[0]}, [MASK]! |
|
1223 vuzp.8 d18, d19 |
|
1224 vadd.u16 q12, q12, q13 |
|
1225 vuzp.8 d18, d19 |
|
1226 vmovn.u16 d16, q0 |
|
1227 vst1.32 {d18, d19}, [OUT, :128]! |
|
1228 .endm |
|
1229 |
|
1230 /* add_8888_8888 */ |
|
1231 .macro bilinear_add_8888_8888_process_last_pixel |
|
1232 bilinear_interpolate_last_pixel 8888, x, 8888, add |
|
1233 .endm |
|
1234 |
|
1235 .macro bilinear_add_8888_8888_process_two_pixels |
|
1236 bilinear_interpolate_two_pixels 8888, x, 8888, add |
|
1237 .endm |
|
1238 |
|
1239 .macro bilinear_add_8888_8888_process_four_pixels |
|
1240 bilinear_interpolate_four_pixels 8888, x, 8888, add |
|
1241 .endm |
|
1242 |
|
1243 .macro bilinear_add_8888_8888_process_pixblock_head |
|
1244 bilinear_add_8888_8888_process_four_pixels |
|
1245 .endm |
|
1246 |
|
1247 .macro bilinear_add_8888_8888_process_pixblock_tail |
|
1248 .endm |
|
1249 |
|
1250 .macro bilinear_add_8888_8888_process_pixblock_tail_head |
|
1251 bilinear_add_8888_8888_process_pixblock_tail |
|
1252 bilinear_add_8888_8888_process_pixblock_head |
|
1253 .endm |
|
1254 |
|
1255 /* add_8888_8_8888 */ |
|
1256 .macro bilinear_add_8888_8_8888_process_last_pixel |
|
1257 bilinear_interpolate_last_pixel 8888, 8, 8888, add |
|
1258 .endm |
|
1259 |
|
1260 .macro bilinear_add_8888_8_8888_process_two_pixels |
|
1261 bilinear_interpolate_two_pixels 8888, 8, 8888, add |
|
1262 .endm |
|
1263 |
|
1264 .macro bilinear_add_8888_8_8888_process_four_pixels |
|
1265 bilinear_interpolate_four_pixels 8888, 8, 8888, add |
|
1266 .endm |
|
1267 |
|
1268 .macro bilinear_add_8888_8_8888_process_pixblock_head |
|
1269 bilinear_add_8888_8_8888_process_four_pixels |
|
1270 .endm |
|
1271 |
|
1272 .macro bilinear_add_8888_8_8888_process_pixblock_tail |
|
1273 .endm |
|
1274 |
|
1275 .macro bilinear_add_8888_8_8888_process_pixblock_tail_head |
|
1276 bilinear_add_8888_8_8888_process_pixblock_tail |
|
1277 bilinear_add_8888_8_8888_process_pixblock_head |
|
1278 .endm |
|
1279 |
|
1280 |
|
1281 /* Bilinear scanline functions */ |
|
1282 generate_bilinear_scanline_func \ |
|
1283 pixman_scaled_bilinear_scanline_8888_8_8888_SRC_asm_neon, \ |
|
1284 8888, 8888, 2, 2, \ |
|
1285 bilinear_src_8888_8_8888_process_last_pixel, \ |
|
1286 bilinear_src_8888_8_8888_process_two_pixels, \ |
|
1287 bilinear_src_8888_8_8888_process_four_pixels, \ |
|
1288 bilinear_src_8888_8_8888_process_pixblock_head, \ |
|
1289 bilinear_src_8888_8_8888_process_pixblock_tail, \ |
|
1290 bilinear_src_8888_8_8888_process_pixblock_tail_head, \ |
|
1291 4, 28, BILINEAR_FLAG_USE_MASK |
|
1292 |
|
1293 generate_bilinear_scanline_func \ |
|
1294 pixman_scaled_bilinear_scanline_8888_8_0565_SRC_asm_neon, \ |
|
1295 8888, 0565, 2, 1, \ |
|
1296 bilinear_src_8888_8_0565_process_last_pixel, \ |
|
1297 bilinear_src_8888_8_0565_process_two_pixels, \ |
|
1298 bilinear_src_8888_8_0565_process_four_pixels, \ |
|
1299 bilinear_src_8888_8_0565_process_pixblock_head, \ |
|
1300 bilinear_src_8888_8_0565_process_pixblock_tail, \ |
|
1301 bilinear_src_8888_8_0565_process_pixblock_tail_head, \ |
|
1302 4, 28, BILINEAR_FLAG_USE_MASK |
|
1303 |
|
1304 generate_bilinear_scanline_func \ |
|
1305 pixman_scaled_bilinear_scanline_0565_8_x888_SRC_asm_neon, \ |
|
1306 0565, 8888, 1, 2, \ |
|
1307 bilinear_src_0565_8_x888_process_last_pixel, \ |
|
1308 bilinear_src_0565_8_x888_process_two_pixels, \ |
|
1309 bilinear_src_0565_8_x888_process_four_pixels, \ |
|
1310 bilinear_src_0565_8_x888_process_pixblock_head, \ |
|
1311 bilinear_src_0565_8_x888_process_pixblock_tail, \ |
|
1312 bilinear_src_0565_8_x888_process_pixblock_tail_head, \ |
|
1313 4, 28, BILINEAR_FLAG_USE_MASK |
|
1314 |
|
1315 generate_bilinear_scanline_func \ |
|
1316 pixman_scaled_bilinear_scanline_0565_8_0565_SRC_asm_neon, \ |
|
1317 0565, 0565, 1, 1, \ |
|
1318 bilinear_src_0565_8_0565_process_last_pixel, \ |
|
1319 bilinear_src_0565_8_0565_process_two_pixels, \ |
|
1320 bilinear_src_0565_8_0565_process_four_pixels, \ |
|
1321 bilinear_src_0565_8_0565_process_pixblock_head, \ |
|
1322 bilinear_src_0565_8_0565_process_pixblock_tail, \ |
|
1323 bilinear_src_0565_8_0565_process_pixblock_tail_head, \ |
|
1324 4, 28, BILINEAR_FLAG_USE_MASK |
|
1325 |
|
1326 generate_bilinear_scanline_func \ |
|
1327 pixman_scaled_bilinear_scanline_8888_8888_OVER_asm_neon, \ |
|
1328 8888, 8888, 2, 2, \ |
|
1329 bilinear_over_8888_8888_process_last_pixel, \ |
|
1330 bilinear_over_8888_8888_process_two_pixels, \ |
|
1331 bilinear_over_8888_8888_process_four_pixels, \ |
|
1332 bilinear_over_8888_8888_process_pixblock_head, \ |
|
1333 bilinear_over_8888_8888_process_pixblock_tail, \ |
|
1334 bilinear_over_8888_8888_process_pixblock_tail_head, \ |
|
1335 4, 28, 0 |
|
1336 |
|
1337 generate_bilinear_scanline_func \ |
|
1338 pixman_scaled_bilinear_scanline_8888_8_8888_OVER_asm_neon, \ |
|
1339 8888, 8888, 2, 2, \ |
|
1340 bilinear_over_8888_8_8888_process_last_pixel, \ |
|
1341 bilinear_over_8888_8_8888_process_two_pixels, \ |
|
1342 bilinear_over_8888_8_8888_process_four_pixels, \ |
|
1343 bilinear_over_8888_8_8888_process_pixblock_head, \ |
|
1344 bilinear_over_8888_8_8888_process_pixblock_tail, \ |
|
1345 bilinear_over_8888_8_8888_process_pixblock_tail_head, \ |
|
1346 4, 28, BILINEAR_FLAG_USE_MASK |
|
1347 |
|
1348 generate_bilinear_scanline_func \ |
|
1349 pixman_scaled_bilinear_scanline_8888_8888_ADD_asm_neon, \ |
|
1350 8888, 8888, 2, 2, \ |
|
1351 bilinear_add_8888_8888_process_last_pixel, \ |
|
1352 bilinear_add_8888_8888_process_two_pixels, \ |
|
1353 bilinear_add_8888_8888_process_four_pixels, \ |
|
1354 bilinear_add_8888_8888_process_pixblock_head, \ |
|
1355 bilinear_add_8888_8888_process_pixblock_tail, \ |
|
1356 bilinear_add_8888_8888_process_pixblock_tail_head, \ |
|
1357 4, 28, 0 |
|
1358 |
|
1359 generate_bilinear_scanline_func \ |
|
1360 pixman_scaled_bilinear_scanline_8888_8_8888_ADD_asm_neon, \ |
|
1361 8888, 8888, 2, 2, \ |
|
1362 bilinear_add_8888_8_8888_process_last_pixel, \ |
|
1363 bilinear_add_8888_8_8888_process_two_pixels, \ |
|
1364 bilinear_add_8888_8_8888_process_four_pixels, \ |
|
1365 bilinear_add_8888_8_8888_process_pixblock_head, \ |
|
1366 bilinear_add_8888_8_8888_process_pixblock_tail, \ |
|
1367 bilinear_add_8888_8_8888_process_pixblock_tail_head, \ |
|
1368 4, 28, BILINEAR_FLAG_USE_MASK |