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_loop_filter_simple_horizontal_edge_neon|
13    EXPORT  |vp8_loop_filter_bhs_neon|
14    EXPORT  |vp8_loop_filter_mbhs_neon|
15    ARM
16    PRESERVE8
17
18    AREA ||.text||, CODE, READONLY, ALIGN=2
19
20; r0    unsigned char *s, PRESERVE
21; r1    int p, PRESERVE
22; q1    limit, PRESERVE
23
24|vp8_loop_filter_simple_horizontal_edge_neon| PROC
25
26    sub         r3, r0, r1, lsl #1          ; move src pointer down by 2 lines
27
28    vld1.u8     {q7}, [r0@128], r1          ; q0
29    vld1.u8     {q5}, [r3@128], r1          ; p0
30    vld1.u8     {q8}, [r0@128]              ; q1
31    vld1.u8     {q6}, [r3@128]              ; p1
32
33    vabd.u8     q15, q6, q7                 ; abs(p0 - q0)
34    vabd.u8     q14, q5, q8                 ; abs(p1 - q1)
35
36    vqadd.u8    q15, q15, q15               ; abs(p0 - q0) * 2
37    vshr.u8     q14, q14, #1                ; abs(p1 - q1) / 2
38    vmov.u8     q0, #0x80                   ; 0x80
39    vmov.s16    q13, #3
40    vqadd.u8    q15, q15, q14               ; abs(p0 - q0) * 2 + abs(p1 - q1) / 2
41
42    veor        q7, q7, q0                  ; qs0: q0 offset to convert to a signed value
43    veor        q6, q6, q0                  ; ps0: p0 offset to convert to a signed value
44    veor        q5, q5, q0                  ; ps1: p1 offset to convert to a signed value
45    veor        q8, q8, q0                  ; qs1: q1 offset to convert to a signed value
46
47    vcge.u8     q15, q1, q15                ; (abs(p0 - q0)*2 + abs(p1-q1)/2 > limit)*-1
48
49    vsubl.s8    q2, d14, d12                ; ( qs0 - ps0)
50    vsubl.s8    q3, d15, d13
51
52    vqsub.s8    q4, q5, q8                  ; q4: vp8_filter = vp8_signed_char_clamp(ps1-qs1)
53
54    vmul.s16    q2, q2, q13                 ;  3 * ( qs0 - ps0)
55    vmul.s16    q3, q3, q13
56
57    vmov.u8     q10, #0x03                  ; 0x03
58    vmov.u8     q9, #0x04                   ; 0x04
59
60    vaddw.s8    q2, q2, d8                  ; vp8_filter + 3 * ( qs0 - ps0)
61    vaddw.s8    q3, q3, d9
62
63    vqmovn.s16  d8, q2                      ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
64    vqmovn.s16  d9, q3
65
66    vand        q14, q4, q15                ; vp8_filter &= mask
67
68    vqadd.s8    q2, q14, q10                ; Filter2 = vp8_signed_char_clamp(vp8_filter+3)
69    vqadd.s8    q3, q14, q9                 ; Filter1 = vp8_signed_char_clamp(vp8_filter+4)
70    vshr.s8     q2, q2, #3                  ; Filter2 >>= 3
71    vshr.s8     q4, q3, #3                  ; Filter1 >>= 3
72
73    sub         r0, r0, r1
74
75    ;calculate output
76    vqadd.s8    q11, q6, q2                 ; u = vp8_signed_char_clamp(ps0 + Filter2)
77    vqsub.s8    q10, q7, q4                 ; u = vp8_signed_char_clamp(qs0 - Filter1)
78
79    veor        q6, q11, q0                 ; *op0 = u^0x80
80    veor        q7, q10, q0                 ; *oq0 = u^0x80
81
82    vst1.u8     {q6}, [r3@128]              ; store op0
83    vst1.u8     {q7}, [r0@128]              ; store oq0
84
85    bx          lr
86    ENDP        ; |vp8_loop_filter_simple_horizontal_edge_neon|
87
88; r0    unsigned char *y
89; r1    int ystride
90; r2    const unsigned char *blimit
91
92|vp8_loop_filter_bhs_neon| PROC
93    push        {r4, lr}
94    ldrb        r3, [r2]                    ; load blim from mem
95    vdup.s8     q1, r3                      ; duplicate blim
96
97    add         r0, r0, r1, lsl #2          ; src = y_ptr + 4 * y_stride
98    bl          vp8_loop_filter_simple_horizontal_edge_neon
99    ; vp8_loop_filter_simple_horizontal_edge_neon preserves r0, r1 and q1
100    add         r0, r0, r1, lsl #2          ; src = y_ptr + 8* y_stride
101    bl          vp8_loop_filter_simple_horizontal_edge_neon
102    add         r0, r0, r1, lsl #2          ; src = y_ptr + 12 * y_stride
103    pop         {r4, lr}
104    b           vp8_loop_filter_simple_horizontal_edge_neon
105    ENDP        ;|vp8_loop_filter_bhs_neon|
106
107; r0    unsigned char *y
108; r1    int ystride
109; r2    const unsigned char *blimit
110
111|vp8_loop_filter_mbhs_neon| PROC
112    ldrb        r3, [r2]                   ; load blim from mem
113    vdup.s8     q1, r3                     ; duplicate mblim
114    b           vp8_loop_filter_simple_horizontal_edge_neon
115    ENDP        ;|vp8_loop_filter_bhs_neon|
116
117    END
118