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_mbloop_filter_vertical_edge_uv_neon|
17 AREA ||.text||, CODE, READONLY, ALIGN=2
18 ;Note: flimit, limit, and thresh shpuld be positive numbers. All 16 elements in flimit
19 ;are equal. So, in the code, only one load is needed
20 ;for flimit. Same way applies to limit and thresh.
21 ; r0 unsigned char *u,
23 ; r2 const signed char *flimit,
24 ; r3 const signed char *limit,
25 ; stack(r4) const signed char *thresh,
26 ; stack(r5) unsigned char *v
27 |vp8_mbloop_filter_vertical_edge_uv_neon| PROC
28 sub r0, r0, #4 ; move src pointer down by 4 columns
29 vld1.s8 {d2[], d3[]}, [r3] ; limit
30 ldr r3, [sp, #4] ; load v ptr
31 ldr r12, [sp, #0] ; load thresh pointer
33 sub r3, r3, #4 ; move v pointer down by 4 columns
35 vld1.u8 {d6}, [r0], r1 ;load u data
36 vld1.u8 {d7}, [r3], r1 ;load v data
37 vld1.u8 {d8}, [r0], r1
38 vld1.u8 {d9}, [r3], r1
39 vld1.u8 {d10}, [r0], r1
40 vld1.u8 {d11}, [r3], r1
41 vld1.u8 {d12}, [r0], r1
42 vld1.u8 {d13}, [r3], r1
43 vld1.u8 {d14}, [r0], r1
44 vld1.u8 {d15}, [r3], r1
45 vld1.u8 {d16}, [r0], r1
46 vld1.u8 {d17}, [r3], r1
47 vld1.u8 {d18}, [r0], r1
48 vld1.u8 {d19}, [r3], r1
49 vld1.u8 {d20}, [r0], r1
50 vld1.u8 {d21}, [r3], r1
52 ;transpose to 8x16 matrix
69 vld1.s8 {d4[], d5[]}, [r12] ; thresh
73 ldr r12, _mbvlfuv_coeff_
76 vabd.u8 q11, q3, q4 ; abs(p3 - p2)
77 vabd.u8 q12, q4, q5 ; abs(p2 - p1)
78 vabd.u8 q13, q5, q6 ; abs(p1 - p0)
79 vabd.u8 q14, q8, q7 ; abs(q1 - q0)
80 vabd.u8 q3, q9, q8 ; abs(q2 - q1)
81 vabd.u8 q0, q10, q9 ; abs(q3 - q2)
88 vabd.u8 q12, q6, q7 ; abs(p0 - q0)
91 vcgt.u8 q13, q13, q2 ; (abs(p1 - p0) > thresh)*-1
92 vcgt.u8 q14, q14, q2 ; (abs(q1 - q0) > thresh)*-1
95 vld1.s8 {d4[], d5[]}, [r2] ; flimit
99 vadd.u8 q2, q2, q2 ; flimit * 2
100 vadd.u8 q2, q2, q1 ; flimit * 2 + limit
103 vabd.u8 q1, q5, q8 ; abs(p1 - q1)
104 vqadd.u8 q12, q12, q12 ; abs(p0 - q0) * 2
105 vshr.u8 q1, q1, #1 ; abs(p1 - q1) / 2
106 vqadd.u8 q12, q12, q1 ; abs(p0 - q0) * 2 + abs(p1 - q1) / 2
107 vcge.u8 q12, q2, q12 ; (abs(p0 - q0)*2 + abs(p1 - q1)/2 > flimit*2 + limit)*-1
109 ;vp8_filter() function
110 veor q7, q7, q0 ; qs0: q0 offset to convert to a signed value
111 veor q6, q6, q0 ; ps0: p0 offset to convert to a signed value
112 veor q5, q5, q0 ; ps1: p1 offset to convert to a signed value
113 veor q8, q8, q0 ; qs1: q1 offset to convert to a signed value
114 veor q4, q4, q0 ; ps2: p2 offset to convert to a signed value
115 veor q9, q9, q0 ; qs2: q2 offset to convert to a signed value
117 vorr q14, q13, q14 ; q14: vp8_hevmask
119 vsubl.s8 q2, d14, d12 ; ( qs0 - ps0)
120 vsubl.s8 q13, d15, d13
122 vqsub.s8 q1, q5, q8 ; vp8_filter = vp8_signed_char_clamp(ps1-qs1)
124 vadd.s16 q10, q2, q2 ; 3 * ( qs0 - ps0)
125 vadd.s16 q11, q13, q13
126 vand q15, q15, q12 ; vp8_filter_mask
129 vadd.s16 q13, q13, q11
131 vld1.u8 {q12}, [r12]! ;#3
133 vaddw.s8 q2, q2, d2 ; vp8_filter + 3 * ( qs0 - ps0)
134 vaddw.s8 q13, q13, d3
136 vld1.u8 {q11}, [r12]! ;#4
138 vqmovn.s16 d2, q2 ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
142 vand q1, q1, q15 ; vp8_filter &= mask
144 vld1.u8 {q15}, [r12]! ;#63
146 vand q13, q1, q14 ; Filter2: q13; Filter2 &= hev
148 vld1.u8 {d7}, [r12]! ;#9
151 vqadd.s8 q2, q13, q11 ; Filter1 = vp8_signed_char_clamp(Filter2+4)
152 vqadd.s8 q13, q13, q12 ; Filter2 = vp8_signed_char_clamp(Filter2+3)
154 vld1.u8 {d6}, [r12]! ;#18
156 sub r0, r0, r1, lsl #3
157 sub r3, r3, r1, lsl #3
159 vshr.s8 q2, q2, #3 ; Filter1 >>= 3
160 vshr.s8 q13, q13, #3 ; Filter2 >>= 3
165 vqsub.s8 q7, q7, q2 ; qs0 = vp8_signed_char_clamp(qs0 - Filter1)
167 vld1.u8 {d5}, [r12]! ;#27
169 vqadd.s8 q6, q6, q13 ; ps0 = vp8_signed_char_clamp(ps0 + Filter2)
170 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
172 vbic q1, q1, q14 ; Filter2: q1; vp8_filter &= ~hev; Filter2 = vp8_filter
174 ; roughly 1/7th difference across boundary
175 ; roughly 2/7th difference across boundary
176 ; roughly 3/7th difference across boundary
181 vmlal.s8 q10, d2, d7 ; Filter2 * 9
183 vmlal.s8 q12, d2, d6 ; Filter2 * 18
185 vmlal.s8 q14, d2, d5 ; Filter2 * 27
187 vqshrn.s16 d20, q10, #7 ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7)
188 vqshrn.s16 d21, q11, #7
189 vqshrn.s16 d24, q12, #7 ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7)
190 vqshrn.s16 d25, q13, #7
191 vqshrn.s16 d28, q14, #7 ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7)
192 vqshrn.s16 d29, q15, #7
194 vqsub.s8 q11, q9, q10 ; s = vp8_signed_char_clamp(qs2 - u)
195 vqadd.s8 q10, q4, q10 ; s = vp8_signed_char_clamp(ps2 + u)
196 vqsub.s8 q13, q8, q12 ; s = vp8_signed_char_clamp(qs1 - u)
197 vqadd.s8 q12, q5, q12 ; s = vp8_signed_char_clamp(ps1 + u)
198 vqsub.s8 q15, q7, q14 ; s = vp8_signed_char_clamp(qs0 - u)
199 vqadd.s8 q14, q6, q14 ; s = vp8_signed_char_clamp(ps0 + u)
200 veor q9, q11, q0 ; *oq2 = s^0x80
201 veor q4, q10, q0 ; *op2 = s^0x80
202 veor q8, q13, q0 ; *oq1 = s^0x80
203 veor q5, q12, q0 ; *op2 = s^0x80
204 veor q7, q15, q0 ; *oq0 = s^0x80
206 veor q6, q14, q0 ; *op0 = s^0x80
209 ;transpose to 16x8 matrix
225 ;store op2, op1, op0, oq0, oq1, oq2
226 vst1.8 {d6}, [r0], r1
227 vst1.8 {d7}, [r3], r1
228 vst1.8 {d8}, [r0], r1
229 vst1.8 {d9}, [r3], r1
230 vst1.8 {d10}, [r0], r1
231 vst1.8 {d11}, [r3], r1
232 vst1.8 {d12}, [r0], r1
233 vst1.8 {d13}, [r3], r1
234 vst1.8 {d14}, [r0], r1
235 vst1.8 {d15}, [r3], r1
236 vst1.8 {d16}, [r0], r1
237 vst1.8 {d17}, [r3], r1
238 vst1.8 {d18}, [r0], r1
239 vst1.8 {d19}, [r3], r1
240 vst1.8 {d20}, [r0], r1
241 vst1.8 {d21}, [r3], r1
244 ENDP ; |vp8_mbloop_filter_vertical_edge_uv_neon|
247 AREA mbvloopfilteruv_dat, DATA, READWRITE ;read/write by default
248 ;Data section with name data_area is specified. DCD reserves space in memory for 16 data.
249 ;One word each is reserved. Label filter_coeff can be used to access the data.
250 ;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
254 DCD 0x80808080, 0x80808080, 0x80808080, 0x80808080
255 DCD 0x03030303, 0x03030303, 0x03030303, 0x03030303
256 DCD 0x04040404, 0x04040404, 0x04040404, 0x04040404
257 DCD 0x003f003f, 0x003f003f, 0x003f003f, 0x003f003f
258 DCD 0x09090909, 0x09090909, 0x12121212, 0x12121212
259 DCD 0x1b1b1b1b, 0x1b1b1b1b