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_variance_halfpixvar16x16_h_neon|
13    EXPORT  |vp8_variance_halfpixvar16x16_v_neon|
14    EXPORT  |vp8_variance_halfpixvar16x16_hv_neon|
15    EXPORT  |vp8_sub_pixel_variance16x16s_neon|
16    ARM
17    REQUIRE8
18    PRESERVE8
19
20    AREA ||.text||, CODE, READONLY, ALIGN=2
21
22;================================================
23;unsigned int vp8_variance_halfpixvar16x16_h_neon
24;(
25;    unsigned char  *src_ptr, r0
26;    int  src_pixels_per_line,  r1
27;    unsigned char *dst_ptr,  r2
28;    int dst_pixels_per_line,   r3
29;    unsigned int *sse
30;);
31;================================================
32|vp8_variance_halfpixvar16x16_h_neon| PROC
33    push            {lr}
34
35    mov             r12, #4                  ;loop counter
36    ldr             lr, [sp, #4]           ;load *sse from stack
37    vmov.i8         q8, #0                      ;q8 - sum
38    vmov.i8         q9, #0                      ;q9, q10 - sse
39    vmov.i8         q10, #0
40
41;First Pass: output_height lines x output_width columns (16x16)
42vp8_filt_fpo16x16s_4_0_loop_neon
43    vld1.u8         {d0, d1, d2, d3}, [r0], r1      ;load src data
44    vld1.8          {q11}, [r2], r3
45    vld1.u8         {d4, d5, d6, d7}, [r0], r1
46    vld1.8          {q12}, [r2], r3
47    vld1.u8         {d8, d9, d10, d11}, [r0], r1
48    vld1.8          {q13}, [r2], r3
49    vld1.u8         {d12, d13, d14, d15}, [r0], r1
50
51    ;pld                [r0]
52    ;pld                [r0, r1]
53    ;pld                [r0, r1, lsl #1]
54
55    vext.8          q1, q0, q1, #1          ;construct src_ptr[1]
56    vext.8          q3, q2, q3, #1
57    vext.8          q5, q4, q5, #1
58    vext.8          q7, q6, q7, #1
59
60    vrhadd.u8       q0, q0, q1              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
61    vld1.8          {q14}, [r2], r3
62    vrhadd.u8       q1, q2, q3
63    vrhadd.u8       q2, q4, q5
64    vrhadd.u8       q3, q6, q7
65
66    vsubl.u8        q4, d0, d22                 ;diff
67    vsubl.u8        q5, d1, d23
68    vsubl.u8        q6, d2, d24
69    vsubl.u8        q7, d3, d25
70    vsubl.u8        q0, d4, d26
71    vsubl.u8        q1, d5, d27
72    vsubl.u8        q2, d6, d28
73    vsubl.u8        q3, d7, d29
74
75    vpadal.s16      q8, q4                     ;sum
76    vmlal.s16       q9, d8, d8                ;sse
77    vmlal.s16       q10, d9, d9
78
79    subs            r12, r12, #1
80
81    vpadal.s16      q8, q5
82    vmlal.s16       q9, d10, d10
83    vmlal.s16       q10, d11, d11
84    vpadal.s16      q8, q6
85    vmlal.s16       q9, d12, d12
86    vmlal.s16       q10, d13, d13
87    vpadal.s16      q8, q7
88    vmlal.s16       q9, d14, d14
89    vmlal.s16       q10, d15, d15
90
91    vpadal.s16      q8, q0                     ;sum
92    vmlal.s16       q9, d0, d0                ;sse
93    vmlal.s16       q10, d1, d1
94    vpadal.s16      q8, q1
95    vmlal.s16       q9, d2, d2
96    vmlal.s16       q10, d3, d3
97    vpadal.s16      q8, q2
98    vmlal.s16       q9, d4, d4
99    vmlal.s16       q10, d5, d5
100    vpadal.s16      q8, q3
101    vmlal.s16       q9, d6, d6
102    vmlal.s16       q10, d7, d7
103
104    bne             vp8_filt_fpo16x16s_4_0_loop_neon
105
106    vadd.u32        q10, q9, q10                ;accumulate sse
107    vpaddl.s32      q0, q8                      ;accumulate sum
108
109    vpaddl.u32      q1, q10
110    vadd.s64        d0, d0, d1
111    vadd.u64        d1, d2, d3
112
113    vmull.s32       q5, d0, d0
114    vst1.32         {d1[0]}, [lr]               ;store sse
115    vshr.s32        d10, d10, #8
116    vsub.s32        d0, d1, d10
117
118    vmov.32         r0, d0[0]                   ;return
119    pop             {pc}
120    ENDP
121
122;================================================
123;unsigned int vp8_variance_halfpixvar16x16_v_neon
124;(
125;    unsigned char  *src_ptr, r0
126;    int  src_pixels_per_line,  r1
127;    unsigned char *dst_ptr,  r2
128;    int dst_pixels_per_line,   r3
129;    unsigned int *sse
130;);
131;================================================
132|vp8_variance_halfpixvar16x16_v_neon| PROC
133    push            {lr}
134
135    mov             r12, #4                     ;loop counter
136
137    vld1.u8         {q0}, [r0], r1              ;load src data
138    ldr             lr, [sp, #4]                ;load *sse from stack
139
140    vmov.i8         q8, #0                      ;q8 - sum
141    vmov.i8         q9, #0                      ;q9, q10 - sse
142    vmov.i8         q10, #0
143
144vp8_filt_spo16x16s_0_4_loop_neon
145    vld1.u8         {q2}, [r0], r1
146    vld1.8          {q1}, [r2], r3
147    vld1.u8         {q4}, [r0], r1
148    vld1.8          {q3}, [r2], r3
149    vld1.u8         {q6}, [r0], r1
150    vld1.8          {q5}, [r2], r3
151    vld1.u8         {q15}, [r0], r1
152
153    vrhadd.u8       q0, q0, q2
154    vld1.8          {q7}, [r2], r3
155    vrhadd.u8       q2, q2, q4
156    vrhadd.u8       q4, q4, q6
157    vrhadd.u8       q6, q6, q15
158
159    vsubl.u8        q11, d0, d2                 ;diff
160    vsubl.u8        q12, d1, d3
161    vsubl.u8        q13, d4, d6
162    vsubl.u8        q14, d5, d7
163    vsubl.u8        q0, d8, d10
164    vsubl.u8        q1, d9, d11
165    vsubl.u8        q2, d12, d14
166    vsubl.u8        q3, d13, d15
167
168    vpadal.s16      q8, q11                     ;sum
169    vmlal.s16       q9, d22, d22                ;sse
170    vmlal.s16       q10, d23, d23
171
172    subs            r12, r12, #1
173
174    vpadal.s16      q8, q12
175    vmlal.s16       q9, d24, d24
176    vmlal.s16       q10, d25, d25
177    vpadal.s16      q8, q13
178    vmlal.s16       q9, d26, d26
179    vmlal.s16       q10, d27, d27
180    vpadal.s16      q8, q14
181    vmlal.s16       q9, d28, d28
182    vmlal.s16       q10, d29, d29
183
184    vpadal.s16      q8, q0                     ;sum
185    vmlal.s16       q9, d0, d0                 ;sse
186    vmlal.s16       q10, d1, d1
187    vpadal.s16      q8, q1
188    vmlal.s16       q9, d2, d2
189    vmlal.s16       q10, d3, d3
190    vpadal.s16      q8, q2
191    vmlal.s16       q9, d4, d4
192    vmlal.s16       q10, d5, d5
193
194    vmov            q0, q15
195
196    vpadal.s16      q8, q3
197    vmlal.s16       q9, d6, d6
198    vmlal.s16       q10, d7, d7
199
200    bne             vp8_filt_spo16x16s_0_4_loop_neon
201
202    vadd.u32        q10, q9, q10                ;accumulate sse
203    vpaddl.s32      q0, q8                      ;accumulate sum
204
205    vpaddl.u32      q1, q10
206    vadd.s64        d0, d0, d1
207    vadd.u64        d1, d2, d3
208
209    vmull.s32       q5, d0, d0
210    vst1.32         {d1[0]}, [lr]               ;store sse
211    vshr.s32        d10, d10, #8
212    vsub.s32        d0, d1, d10
213
214    vmov.32         r0, d0[0]                   ;return
215    pop             {pc}
216    ENDP
217
218;================================================
219;unsigned int vp8_variance_halfpixvar16x16_hv_neon
220;(
221;    unsigned char  *src_ptr, r0
222;    int  src_pixels_per_line,  r1
223;    unsigned char *dst_ptr,  r2
224;    int dst_pixels_per_line,   r3
225;    unsigned int *sse
226;);
227;================================================
228|vp8_variance_halfpixvar16x16_hv_neon| PROC
229    push            {lr}
230
231    vld1.u8         {d0, d1, d2, d3}, [r0], r1      ;load src data
232
233    ldr             lr, [sp, #4]           ;load *sse from stack
234    vmov.i8         q13, #0                      ;q8 - sum
235    vext.8          q1, q0, q1, #1          ;construct src_ptr[1]
236
237    vmov.i8         q14, #0                      ;q9, q10 - sse
238    vmov.i8         q15, #0
239
240    mov             r12, #4                  ;loop counter
241    vrhadd.u8       q0, q0, q1              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
242
243;First Pass: output_height lines x output_width columns (17x16)
244vp8_filt16x16s_4_4_loop_neon
245    vld1.u8         {d4, d5, d6, d7}, [r0], r1
246    vld1.u8         {d8, d9, d10, d11}, [r0], r1
247    vld1.u8         {d12, d13, d14, d15}, [r0], r1
248    vld1.u8         {d16, d17, d18, d19}, [r0], r1
249
250    ;pld                [r0]
251    ;pld                [r0, r1]
252    ;pld                [r0, r1, lsl #1]
253
254    vext.8          q3, q2, q3, #1          ;construct src_ptr[1]
255    vext.8          q5, q4, q5, #1
256    vext.8          q7, q6, q7, #1
257    vext.8          q9, q8, q9, #1
258
259    vrhadd.u8       q1, q2, q3              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
260    vrhadd.u8       q2, q4, q5
261    vrhadd.u8       q3, q6, q7
262    vrhadd.u8       q4, q8, q9
263
264    vld1.8          {q5}, [r2], r3
265    vrhadd.u8       q0, q0, q1
266    vld1.8          {q6}, [r2], r3
267    vrhadd.u8       q1, q1, q2
268    vld1.8          {q7}, [r2], r3
269    vrhadd.u8       q2, q2, q3
270    vld1.8          {q8}, [r2], r3
271    vrhadd.u8       q3, q3, q4
272
273    vsubl.u8        q9, d0, d10                 ;diff
274    vsubl.u8        q10, d1, d11
275    vsubl.u8        q11, d2, d12
276    vsubl.u8        q12, d3, d13
277
278    vsubl.u8        q0, d4, d14                 ;diff
279    vsubl.u8        q1, d5, d15
280    vsubl.u8        q5, d6, d16
281    vsubl.u8        q6, d7, d17
282
283    vpadal.s16      q13, q9                     ;sum
284    vmlal.s16       q14, d18, d18                ;sse
285    vmlal.s16       q15, d19, d19
286
287    vpadal.s16      q13, q10                     ;sum
288    vmlal.s16       q14, d20, d20                ;sse
289    vmlal.s16       q15, d21, d21
290
291    vpadal.s16      q13, q11                     ;sum
292    vmlal.s16       q14, d22, d22                ;sse
293    vmlal.s16       q15, d23, d23
294
295    vpadal.s16      q13, q12                     ;sum
296    vmlal.s16       q14, d24, d24                ;sse
297    vmlal.s16       q15, d25, d25
298
299    subs            r12, r12, #1
300
301    vpadal.s16      q13, q0                     ;sum
302    vmlal.s16       q14, d0, d0                ;sse
303    vmlal.s16       q15, d1, d1
304
305    vpadal.s16      q13, q1                     ;sum
306    vmlal.s16       q14, d2, d2                ;sse
307    vmlal.s16       q15, d3, d3
308
309    vpadal.s16      q13, q5                     ;sum
310    vmlal.s16       q14, d10, d10                ;sse
311    vmlal.s16       q15, d11, d11
312
313    vmov            q0, q4
314
315    vpadal.s16      q13, q6                     ;sum
316    vmlal.s16       q14, d12, d12                ;sse
317    vmlal.s16       q15, d13, d13
318
319    bne             vp8_filt16x16s_4_4_loop_neon
320
321    vadd.u32        q15, q14, q15                ;accumulate sse
322    vpaddl.s32      q0, q13                      ;accumulate sum
323
324    vpaddl.u32      q1, q15
325    vadd.s64        d0, d0, d1
326    vadd.u64        d1, d2, d3
327
328    vmull.s32       q5, d0, d0
329    vst1.32         {d1[0]}, [lr]               ;store sse
330    vshr.s32        d10, d10, #8
331    vsub.s32        d0, d1, d10
332
333    vmov.32         r0, d0[0]                   ;return
334    pop             {pc}
335    ENDP
336
337;==============================
338; r0    unsigned char  *src_ptr,
339; r1    int  src_pixels_per_line,
340; r2    int  xoffset,
341; r3    int  yoffset,
342; stack unsigned char *dst_ptr,
343; stack int dst_pixels_per_line,
344; stack unsigned int *sse
345;note: in vp8_find_best_half_pixel_step()(called when 8<Speed<15), and first call of vp8_find_best_sub_pixel_step()
346;(called when speed<=8). xoffset/yoffset can only be 4 or 0, which means either by pass the filter,
347;or filter coeff is {64, 64}. This simplified program only works in this situation.
348;note: It happens that both xoffset and yoffset are zero. This can be handled in c code later.
349
350|vp8_sub_pixel_variance16x16s_neon| PROC
351    push            {r4, lr}
352
353    ldr             r4, [sp, #8]            ;load *dst_ptr from stack
354    ldr             r12, [sp, #12]          ;load dst_pixels_per_line from stack
355    ldr             lr, [sp, #16]           ;load *sse from stack
356
357    cmp             r2, #0                  ;skip first_pass filter if xoffset=0
358    beq             secondpass_bfilter16x16s_only
359
360    cmp             r3, #0                  ;skip second_pass filter if yoffset=0
361    beq             firstpass_bfilter16x16s_only
362
363    vld1.u8         {d0, d1, d2, d3}, [r0], r1      ;load src data
364    sub             sp, sp, #256            ;reserve space on stack for temporary storage
365    vext.8          q1, q0, q1, #1          ;construct src_ptr[1]
366    mov             r3, sp
367    mov             r2, #4                  ;loop counter
368    vrhadd.u8       q0, q0, q1              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
369
370;First Pass: output_height lines x output_width columns (17x16)
371vp8e_filt_blk2d_fp16x16s_loop_neon
372    vld1.u8         {d4, d5, d6, d7}, [r0], r1
373    vld1.u8         {d8, d9, d10, d11}, [r0], r1
374    vld1.u8         {d12, d13, d14, d15}, [r0], r1
375    vld1.u8         {d16, d17, d18, d19}, [r0], r1
376
377    ;pld                [r0]
378    ;pld                [r0, r1]
379    ;pld                [r0, r1, lsl #1]
380
381    vext.8          q3, q2, q3, #1          ;construct src_ptr[1]
382    vext.8          q5, q4, q5, #1
383    vext.8          q7, q6, q7, #1
384    vext.8          q9, q8, q9, #1
385
386    vrhadd.u8       q1, q2, q3              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
387    vrhadd.u8       q2, q4, q5
388    vrhadd.u8       q3, q6, q7
389    vrhadd.u8       q4, q8, q9
390
391    vrhadd.u8       q0, q0, q1
392    vrhadd.u8       q1, q1, q2
393    vrhadd.u8       q2, q2, q3
394    vrhadd.u8       q3, q3, q4
395
396    subs            r2, r2, #1
397    vst1.u8         {d0, d1 ,d2, d3}, [r3]!         ;store result
398    vmov            q0, q4
399    vst1.u8         {d4, d5, d6, d7}, [r3]!
400
401    bne             vp8e_filt_blk2d_fp16x16s_loop_neon
402
403    b               sub_pixel_variance16x16s_neon
404
405;--------------------
406firstpass_bfilter16x16s_only
407    mov             r2, #2                  ;loop counter
408    sub             sp, sp, #256            ;reserve space on stack for temporary storage
409    mov             r3, sp
410
411;First Pass: output_height lines x output_width columns (16x16)
412vp8e_filt_blk2d_fpo16x16s_loop_neon
413    vld1.u8         {d0, d1, d2, d3}, [r0], r1      ;load src data
414    vld1.u8         {d4, d5, d6, d7}, [r0], r1
415    vld1.u8         {d8, d9, d10, d11}, [r0], r1
416    vld1.u8         {d12, d13, d14, d15}, [r0], r1
417
418    ;pld                [r0]
419    ;pld                [r0, r1]
420    ;pld                [r0, r1, lsl #1]
421
422    vext.8          q1, q0, q1, #1          ;construct src_ptr[1]
423    vld1.u8         {d16, d17, d18, d19}, [r0], r1
424    vext.8          q3, q2, q3, #1
425    vld1.u8         {d20, d21, d22, d23}, [r0], r1
426    vext.8          q5, q4, q5, #1
427    vld1.u8         {d24, d25, d26, d27}, [r0], r1
428    vext.8          q7, q6, q7, #1
429    vld1.u8         {d28, d29, d30, d31}, [r0], r1
430    vext.8          q9, q8, q9, #1
431    vext.8          q11, q10, q11, #1
432    vext.8          q13, q12, q13, #1
433    vext.8          q15, q14, q15, #1
434
435    vrhadd.u8       q0, q0, q1              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
436    vrhadd.u8       q1, q2, q3
437    vrhadd.u8       q2, q4, q5
438    vrhadd.u8       q3, q6, q7
439    vrhadd.u8       q4, q8, q9
440    vrhadd.u8       q5, q10, q11
441    vrhadd.u8       q6, q12, q13
442    vrhadd.u8       q7, q14, q15
443
444    subs            r2, r2, #1
445
446    vst1.u8         {d0, d1, d2, d3}, [r3]!         ;store result
447    vst1.u8         {d4, d5, d6, d7}, [r3]!
448    vst1.u8         {d8, d9, d10, d11}, [r3]!
449    vst1.u8         {d12, d13, d14, d15}, [r3]!
450
451    bne             vp8e_filt_blk2d_fpo16x16s_loop_neon
452
453    b               sub_pixel_variance16x16s_neon
454
455;---------------------
456secondpass_bfilter16x16s_only
457    sub             sp, sp, #256            ;reserve space on stack for temporary storage
458
459    mov             r2, #2                  ;loop counter
460    vld1.u8         {d0, d1}, [r0], r1      ;load src data
461    mov             r3, sp
462
463vp8e_filt_blk2d_spo16x16s_loop_neon
464    vld1.u8         {d2, d3}, [r0], r1
465    vld1.u8         {d4, d5}, [r0], r1
466    vld1.u8         {d6, d7}, [r0], r1
467    vld1.u8         {d8, d9}, [r0], r1
468
469    vrhadd.u8       q0, q0, q1
470    vld1.u8         {d10, d11}, [r0], r1
471    vrhadd.u8       q1, q1, q2
472    vld1.u8         {d12, d13}, [r0], r1
473    vrhadd.u8       q2, q2, q3
474    vld1.u8         {d14, d15}, [r0], r1
475    vrhadd.u8       q3, q3, q4
476    vld1.u8         {d16, d17}, [r0], r1
477    vrhadd.u8       q4, q4, q5
478    vrhadd.u8       q5, q5, q6
479    vrhadd.u8       q6, q6, q7
480    vrhadd.u8       q7, q7, q8
481
482    subs            r2, r2, #1
483
484    vst1.u8         {d0, d1, d2, d3}, [r3]!         ;store result
485    vmov            q0, q8
486    vst1.u8         {d4, d5, d6, d7}, [r3]!
487    vst1.u8         {d8, d9, d10, d11}, [r3]!           ;store result
488    vst1.u8         {d12, d13, d14, d15}, [r3]!
489
490    bne             vp8e_filt_blk2d_spo16x16s_loop_neon
491
492    b               sub_pixel_variance16x16s_neon
493
494;----------------------------
495;variance16x16
496sub_pixel_variance16x16s_neon
497    vmov.i8         q8, #0                      ;q8 - sum
498    vmov.i8         q9, #0                      ;q9, q10 - sse
499    vmov.i8         q10, #0
500
501    sub             r3, r3, #256
502    mov             r2, #4
503
504sub_pixel_variance16x16s_neon_loop
505    vld1.8          {q0}, [r3]!                 ;Load up source and reference
506    vld1.8          {q1}, [r4], r12
507    vld1.8          {q2}, [r3]!
508    vld1.8          {q3}, [r4], r12
509    vld1.8          {q4}, [r3]!
510    vld1.8          {q5}, [r4], r12
511    vld1.8          {q6}, [r3]!
512    vld1.8          {q7}, [r4], r12
513
514    vsubl.u8        q11, d0, d2                 ;diff
515    vsubl.u8        q12, d1, d3
516    vsubl.u8        q13, d4, d6
517    vsubl.u8        q14, d5, d7
518    vsubl.u8        q0, d8, d10
519    vsubl.u8        q1, d9, d11
520    vsubl.u8        q2, d12, d14
521    vsubl.u8        q3, d13, d15
522
523    vpadal.s16      q8, q11                     ;sum
524    vmlal.s16       q9, d22, d22                ;sse
525    vmlal.s16       q10, d23, d23
526
527    subs            r2, r2, #1
528
529    vpadal.s16      q8, q12
530    vmlal.s16       q9, d24, d24
531    vmlal.s16       q10, d25, d25
532    vpadal.s16      q8, q13
533    vmlal.s16       q9, d26, d26
534    vmlal.s16       q10, d27, d27
535    vpadal.s16      q8, q14
536    vmlal.s16       q9, d28, d28
537    vmlal.s16       q10, d29, d29
538
539    vpadal.s16      q8, q0                     ;sum
540    vmlal.s16       q9, d0, d0                ;sse
541    vmlal.s16       q10, d1, d1
542    vpadal.s16      q8, q1
543    vmlal.s16       q9, d2, d2
544    vmlal.s16       q10, d3, d3
545    vpadal.s16      q8, q2
546    vmlal.s16       q9, d4, d4
547    vmlal.s16       q10, d5, d5
548    vpadal.s16      q8, q3
549    vmlal.s16       q9, d6, d6
550    vmlal.s16       q10, d7, d7
551
552    bne             sub_pixel_variance16x16s_neon_loop
553
554    vadd.u32        q10, q9, q10                ;accumulate sse
555    vpaddl.s32      q0, q8                      ;accumulate sum
556
557    vpaddl.u32      q1, q10
558    vadd.s64        d0, d0, d1
559    vadd.u64        d1, d2, d3
560
561    vmull.s32       q5, d0, d0
562    vst1.32         {d1[0]}, [lr]               ;store sse
563    vshr.s32        d10, d10, #8
564    vsub.s32        d0, d1, d10
565
566    add             sp, sp, #256
567    vmov.32         r0, d0[0]                   ;return
568
569    pop             {r4, pc}
570    ENDP
571
572    END
573