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