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_loop_filter_horizontal_edge_armv6|
13 EXPORT |vp8_mbloop_filter_horizontal_edge_armv6|
14 EXPORT |vp8_loop_filter_vertical_edge_armv6|
15 EXPORT |vp8_mbloop_filter_vertical_edge_armv6|
17 AREA |.text|, CODE, READONLY ; name this block of code
20 TRANSPOSE_MATRIX $a0, $a1, $a2, $a3, $b0, $b1, $b2, $b3
21 ; input: $a0, $a1, $a2, $a3; output: $b0, $b1, $b2, $b3
28 uxtb16 $b1, $a1 ; xx 12 xx 10
29 uxtb16 $b0, $a0 ; xx 02 xx 00
30 uxtb16 $b3, $a3 ; xx 32 xx 30
31 uxtb16 $b2, $a2 ; xx 22 xx 20
32 orr $b1, $b0, $b1, lsl #8 ; 12 02 10 00
33 orr $b3, $b2, $b3, lsl #8 ; 32 22 30 20
35 uxtb16 $a1, $a1, ror #8 ; xx 13 xx 11
36 uxtb16 $a3, $a3, ror #8 ; xx 33 xx 31
37 uxtb16 $a0, $a0, ror #8 ; xx 03 xx 01
38 uxtb16 $a2, $a2, ror #8 ; xx 23 xx 21
39 orr $a0, $a0, $a1, lsl #8 ; 13 03 11 01
40 orr $a2, $a2, $a3, lsl #8 ; 33 23 31 21
42 pkhtb $b2, $b3, $b1, asr #16 ; 32 22 12 02 -- p1
43 pkhbt $b0, $b1, $b3, lsl #16 ; 30 20 10 00 -- p3
45 pkhtb $b3, $a2, $a0, asr #16 ; 33 23 13 03 -- p0
46 pkhbt $b1, $a0, $a2, lsl #16 ; 31 21 11 01 -- p2
54 ;r0 unsigned char *src_ptr,
55 ;r1 int src_pixel_step,
56 ;r2 const char *flimit,
57 ;r3 const char *limit,
58 ;stack const char *thresh,
61 ;Note: All 16 elements in flimit are equal. So, in the code, only one load is needed
62 ;for flimit. Same way applies to limit and thresh.
64 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
65 |vp8_loop_filter_horizontal_edge_armv6| PROC
66 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
67 stmdb sp!, {r4 - r11, lr}
69 sub src, src, pstep, lsl #2 ; move src pointer down by 4 lines
70 ldr count, [sp, #40] ; count for 8-in-parallel
71 ldr r6, [sp, #36] ; load thresh address
72 sub sp, sp, #16 ; create temp buffer
74 ldr r9, [src], pstep ; p3
75 ldr r4, [r2], #4 ; flimit
76 ldr r10, [src], pstep ; p2
77 ldr r2, [r3], #4 ; limit
78 ldr r11, [src], pstep ; p1
79 uadd8 r4, r4, r4 ; flimit * 2
80 ldr r3, [r6], #4 ; thresh
81 mov count, count, lsl #1 ; 4-in-parallel
82 uadd8 r4, r4, r2 ; flimit * 2 + limit
85 ; vp8_filter_mask() function
86 ; calculate breakout conditions
87 ldr r12, [src], pstep ; p0
89 uqsub8 r6, r9, r10 ; p3 - p2
90 uqsub8 r7, r10, r9 ; p2 - p3
91 uqsub8 r8, r10, r11 ; p2 - p1
92 uqsub8 r10, r11, r10 ; p1 - p2
94 orr r6, r6, r7 ; abs (p3-p2)
95 orr r8, r8, r10 ; abs (p2-p1)
96 uqsub8 lr, r6, r2 ; compare to limit. lr: vp8_filter_mask
97 uqsub8 r8, r8, r2 ; compare to limit
98 uqsub8 r6, r11, r12 ; p1 - p0
100 uqsub8 r7, r12, r11 ; p0 - p1
101 ldr r9, [src], pstep ; q0
102 ldr r10, [src], pstep ; q1
103 orr r6, r6, r7 ; abs (p1-p0)
104 uqsub8 r7, r6, r2 ; compare to limit
105 uqsub8 r8, r6, r3 ; compare to thresh -- save r8 for later
108 uqsub8 r6, r11, r10 ; p1 - q1
109 uqsub8 r7, r10, r11 ; q1 - p1
110 uqsub8 r11, r12, r9 ; p0 - q0
111 uqsub8 r12, r9, r12 ; q0 - p0
112 orr r6, r6, r7 ; abs (p1-q1)
114 orr r12, r11, r12 ; abs (p0-q0)
115 ldr r11, [src], pstep ; q2
116 uqadd8 r12, r12, r12 ; abs (p0-q0) * 2
117 and r6, r7, r6, lsr #1 ; abs (p1-q1) / 2
118 uqsub8 r7, r9, r10 ; q0 - q1
119 uqadd8 r12, r12, r6 ; abs (p0-q0)*2 + abs (p1-q1)/2
120 uqsub8 r6, r10, r9 ; q1 - q0
121 uqsub8 r12, r12, r4 ; compare to flimit
122 uqsub8 r9, r11, r10 ; q2 - q1
126 ldr r12, [src], pstep ; q3
127 uqsub8 r10, r10, r11 ; q1 - q2
128 orr r6, r7, r6 ; abs (q1-q0)
129 orr r10, r9, r10 ; abs (q2-q1)
130 uqsub8 r7, r6, r2 ; compare to limit
131 uqsub8 r10, r10, r2 ; compare to limit
132 uqsub8 r6, r6, r3 ; compare to thresh -- save r6 for later
136 uqsub8 r10, r12, r11 ; q3 - q2
137 uqsub8 r9, r11, r12 ; q2 - q3
139 mvn r11, #0 ; r11 == -1
141 orr r10, r10, r9 ; abs (q3-q2)
142 uqsub8 r10, r10, r2 ; compare to limit
146 sub src, src, pstep, lsl #2
148 usub8 lr, r12, lr ; use usub8 instead of ssub8
149 sel lr, r11, r12 ; filter mask: lr
152 beq hskip_filter ; skip filtering
154 sub src, src, pstep, lsl #1 ; move src pointer down by 6 lines
156 ;vp8_hevmask() function
157 ;calculate high edge variance
158 orr r10, r6, r8 ; calculate vp8_hevmask
160 ldr r7, [src], pstep ; p1
162 usub8 r10, r12, r10 ; use usub8 instead of ssub8
163 sel r6, r12, r11 ; obtain vp8_hevmask: r6
165 ;vp8_filter() function
166 ldr r8, [src], pstep ; p0
168 ldr r9, [src], pstep ; q0
169 ldr r10, [src], pstep ; q1
171 eor r7, r7, r12 ; p1 offset to convert to a signed value
172 eor r8, r8, r12 ; p0 offset to convert to a signed value
173 eor r9, r9, r12 ; q0 offset to convert to a signed value
174 eor r10, r10, r12 ; q1 offset to convert to a signed value
176 str r9, [sp] ; store qs0 temporarily
177 str r8, [sp, #4] ; store ps0 temporarily
178 str r10, [sp, #8] ; store qs1 temporarily
179 str r7, [sp, #12] ; store ps1 temporarily
181 qsub8 r7, r7, r10 ; vp8_signed_char_clamp(ps1-qs1)
182 qsub8 r8, r9, r8 ; vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
184 and r7, r7, r6 ; vp8_filter (r7) &= hev
187 ldr r9, c0x03030303 ; r9 = 3 --modified for vp8
193 and r7, r7, lr ; vp8_filter &= mask;
195 ;modify code for vp8 -- Filter1 = vp8_filter (r7)
196 qadd8 r8 , r7 , r9 ; Filter2 (r8) = vp8_signed_char_clamp(vp8_filter+3)
197 qadd8 r7 , r7 , r10 ; vp8_filter = vp8_signed_char_clamp(vp8_filter+4)
200 shadd8 r8 , r8 , r9 ; Filter2 >>= 3
201 shadd8 r7 , r7 , r9 ; vp8_filter >>= 3
204 shadd8 lr , r8 , r9 ; lr: Filter2
205 shadd8 r7 , r7 , r9 ; r7: filter
207 ;usub8 lr, r8, r10 ; s = (s==4)*-1
211 ;and r8, r8, lr ; -1 for each element that equals 4
214 ;qadd8 lr, r8, r7 ; u = vp8_signed_char_clamp(s + vp8_filter)
216 ldr r8, [sp] ; load qs0
217 ldr r9, [sp, #4] ; load ps0
221 qsub8 r8 ,r8, r7 ; u = vp8_signed_char_clamp(qs0 - vp8_filter)
222 qadd8 r9, r9, lr ; u = vp8_signed_char_clamp(ps0 + Filter2)
224 ;end of modification for vp8
227 sadd8 r7, r7 , r10 ; vp8_filter += 1
228 shadd8 r7, r7, lr ; vp8_filter >>= 1
230 ldr r11, [sp, #12] ; load ps1
231 ldr r10, [sp, #8] ; load qs1
233 bic r7, r7, r6 ; vp8_filter &= ~hev
234 sub src, src, pstep, lsl #2
236 qadd8 r11, r11, r7 ; u = vp8_signed_char_clamp(ps1 + vp8_filter)
237 qsub8 r10, r10,r7 ; u = vp8_signed_char_clamp(qs1 - vp8_filter)
239 eor r11, r11, r12 ; *op1 = u^0x80
240 str r11, [src], pstep ; store op1
241 eor r9, r9, r12 ; *op0 = u^0x80
242 str r9, [src], pstep ; store op0 result
243 eor r8, r8, r12 ; *oq0 = u^0x80
244 str r8, [src], pstep ; store oq0 result
245 eor r10, r10, r12 ; *oq1 = u^0x80
246 str r10, [src], pstep ; store oq1
248 sub src, src, pstep, lsl #1
252 sub src, src, pstep, lsl #2
254 subs count, count, #1
256 ldrne r9, [src], pstep ; p3
257 ldrne r10, [src], pstep ; p2
258 ldrne r11, [src], pstep ; p1
263 ldmia sp!, {r4 - r11, pc}
264 ENDP ; |vp8_loop_filter_horizontal_edge_armv6|
267 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
268 |vp8_mbloop_filter_horizontal_edge_armv6| PROC
269 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
270 stmdb sp!, {r4 - r11, lr}
272 sub src, src, pstep, lsl #2 ; move src pointer down by 4 lines
273 ldr count, [sp, #40] ; count for 8-in-parallel
274 ldr r6, [sp, #36] ; load thresh address
275 sub sp, sp, #16 ; create temp buffer
277 ldr r9, [src], pstep ; p3
278 ldr r4, [r2], #4 ; flimit
279 ldr r10, [src], pstep ; p2
280 ldr r2, [r3], #4 ; limit
281 ldr r11, [src], pstep ; p1
282 uadd8 r4, r4, r4 ; flimit * 2
283 ldr r3, [r6], #4 ; thresh
284 mov count, count, lsl #1 ; 4-in-parallel
285 uadd8 r4, r4, r2 ; flimit * 2 + limit
289 ; vp8_filter_mask() function
290 ; calculate breakout conditions
291 ldr r12, [src], pstep ; p0
293 uqsub8 r6, r9, r10 ; p3 - p2
294 uqsub8 r7, r10, r9 ; p2 - p3
295 uqsub8 r8, r10, r11 ; p2 - p1
296 uqsub8 r10, r11, r10 ; p1 - p2
298 orr r6, r6, r7 ; abs (p3-p2)
299 orr r8, r8, r10 ; abs (p2-p1)
300 uqsub8 lr, r6, r2 ; compare to limit. lr: vp8_filter_mask
301 uqsub8 r8, r8, r2 ; compare to limit
303 uqsub8 r6, r11, r12 ; p1 - p0
305 uqsub8 r7, r12, r11 ; p0 - p1
306 ldr r9, [src], pstep ; q0
307 ldr r10, [src], pstep ; q1
308 orr r6, r6, r7 ; abs (p1-p0)
309 uqsub8 r7, r6, r2 ; compare to limit
310 uqsub8 r8, r6, r3 ; compare to thresh -- save r8 for later
313 uqsub8 r6, r11, r10 ; p1 - q1
314 uqsub8 r7, r10, r11 ; q1 - p1
315 uqsub8 r11, r12, r9 ; p0 - q0
316 uqsub8 r12, r9, r12 ; q0 - p0
317 orr r6, r6, r7 ; abs (p1-q1)
319 orr r12, r11, r12 ; abs (p0-q0)
320 ldr r11, [src], pstep ; q2
321 uqadd8 r12, r12, r12 ; abs (p0-q0) * 2
322 and r6, r7, r6, lsr #1 ; abs (p1-q1) / 2
323 uqsub8 r7, r9, r10 ; q0 - q1
324 uqadd8 r12, r12, r6 ; abs (p0-q0)*2 + abs (p1-q1)/2
325 uqsub8 r6, r10, r9 ; q1 - q0
326 uqsub8 r12, r12, r4 ; compare to flimit
327 uqsub8 r9, r11, r10 ; q2 - q1
331 ldr r12, [src], pstep ; q3
333 uqsub8 r10, r10, r11 ; q1 - q2
334 orr r6, r7, r6 ; abs (q1-q0)
335 orr r10, r9, r10 ; abs (q2-q1)
336 uqsub8 r7, r6, r2 ; compare to limit
337 uqsub8 r10, r10, r2 ; compare to limit
338 uqsub8 r6, r6, r3 ; compare to thresh -- save r6 for later
342 uqsub8 r10, r12, r11 ; q3 - q2
343 uqsub8 r9, r11, r12 ; q2 - q3
345 mvn r11, #0 ; r11 == -1
347 orr r10, r10, r9 ; abs (q3-q2)
348 uqsub8 r10, r10, r2 ; compare to limit
354 usub8 lr, r12, lr ; use usub8 instead of ssub8
355 sel lr, r11, r12 ; filter mask: lr
358 beq mbhskip_filter ; skip filtering
360 ;vp8_hevmask() function
361 ;calculate high edge variance
362 sub src, src, pstep, lsl #2 ; move src pointer down by 6 lines
363 sub src, src, pstep, lsl #1
366 ldr r7, [src], pstep ; p1
369 sel r6, r12, r11 ; hev mask: r6
371 ;vp8_mbfilter() function
372 ;p2, q2 are only needed at the end. Don't need to load them in now.
373 ldr r8, [src], pstep ; p0
375 ldr r9, [src], pstep ; q0
378 eor r7, r7, r12 ; ps1
379 eor r8, r8, r12 ; ps0
380 eor r9, r9, r12 ; qs0
381 eor r10, r10, r12 ; qs1
383 qsub8 r12, r9, r8 ; vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
384 str r7, [sp, #12] ; store ps1 temporarily
385 qsub8 r7, r7, r10 ; vp8_signed_char_clamp(ps1-qs1)
386 str r10, [sp, #8] ; store qs1 temporarily
388 str r9, [sp] ; store qs0 temporarily
390 str r8, [sp, #4] ; store ps0 temporarily
391 qadd8 r7, r7, r12 ; vp8_filter: r7
393 ldr r10, c0x03030303 ; r10 = 3 --modified for vp8
396 and r7, r7, lr ; vp8_filter &= mask (lr is free)
398 mov r12, r7 ; Filter2: r12
399 and r12, r12, r6 ; Filter2 &= hev
402 ;save bottom 3 bits so that we round one side +4 and the other +3
403 qadd8 r8 , r12 , r9 ; Filter1 (r8) = vp8_signed_char_clamp(Filter2+4)
404 qadd8 r12 , r12 , r10 ; Filter2 (r12) = vp8_signed_char_clamp(Filter2+3)
407 shadd8 r8 , r8 , r10 ; Filter1 >>= 3
408 shadd8 r12 , r12 , r10 ; Filter2 >>= 3
410 shadd8 r12 , r12 , r10
411 shadd8 r8 , r8 , r10 ; r8: Filter1
412 shadd8 r12 , r12 , r10 ; r12: Filter2
414 ldr r9, [sp] ; load qs0
415 ldr r11, [sp, #4] ; load ps0
417 qsub8 r9 , r9, r8 ; qs0 = vp8_signed_char_clamp(qs0 - Filter1)
418 qadd8 r11, r11, r12 ; ps0 = vp8_signed_char_clamp(ps0 + Filter2)
420 ;save bottom 3 bits so that we round one side +4 and the other +3
421 ;and r8, r12, r10 ; s = Filter2 & 7 (s: r8)
422 ;qadd8 r12 , r12 , r9 ; Filter2 = vp8_signed_char_clamp(Filter2+4)
424 ;shadd8 r12 , r12 , r10 ; Filter2 >>= 3
425 ;usub8 lr, r8, r9 ; s = (s==4)*-1
427 ;shadd8 r12 , r12 , r10
430 ;ldr r9, [sp] ; load qs0
431 ;ldr r11, [sp, #4] ; load ps0
432 ;shadd8 r12 , r12 , r10
433 ;and r8, r8, lr ; -1 for each element that equals 4
434 ;qadd8 r10, r8, r12 ; u = vp8_signed_char_clamp(s + Filter2)
435 ;qsub8 r9 , r9, r12 ; qs0 = vp8_signed_char_clamp(qs0 - Filter2)
436 ;qadd8 r11, r11, r10 ; ps0 = vp8_signed_char_clamp(ps0 + u)
438 ;end of modification for vp8
440 bic r12, r7, r6 ; vp8_filter &= ~hev ( r6 is free)
443 ;roughly 3/7th difference across boundary
448 sxtb16 r10, r12, ror #8
449 smlabb r8, r6, lr, r7
450 smlatb r6, r6, lr, r7
451 smlabb r7, r10, lr, r7
453 ssat r8, #8, r8, asr #7
454 ssat r6, #8, r6, asr #7
456 ssat r7, #8, r7, asr #7
457 ssat r10, #8, r10, asr #7
461 pkhbt r6, r8, r6, lsl #16
462 pkhbt r10, r7, r10, lsl #16
468 orr r10, r6, r10, lsl #8 ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7)
470 qsub8 r8, r9, r10 ; s = vp8_signed_char_clamp(qs0 - u)
471 qadd8 r10, r11, r10 ; s = vp8_signed_char_clamp(ps0 + u)
472 eor r8, r8, lr ; *oq0 = s^0x80
473 str r8, [src] ; store *oq0
475 eor r10, r10, lr ; *op0 = s^0x80
476 str r10, [src] ; store *op0
478 ;roughly 2/7th difference across boundary
483 sxtb16 r10, r12, ror #8
484 smlabb r8, r6, lr, r7
485 smlatb r6, r6, lr, r7
486 smlabb r9, r10, lr, r7
487 smlatb r10, r10, lr, r7
488 ssat r8, #8, r8, asr #7
489 ssat r6, #8, r6, asr #7
490 ssat r9, #8, r9, asr #7
491 ssat r10, #8, r10, asr #7
495 pkhbt r6, r8, r6, lsl #16
496 pkhbt r10, r9, r10, lsl #16
498 ldr r9, [sp, #8] ; load qs1
499 ldr r11, [sp, #12] ; load ps1
506 orr r10, r6, r10, lsl #8 ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7)
508 qadd8 r11, r11, r10 ; s = vp8_signed_char_clamp(ps1 + u)
509 qsub8 r8, r9, r10 ; s = vp8_signed_char_clamp(qs1 - u)
510 eor r11, r11, lr ; *op1 = s^0x80
511 str r11, [src], pstep ; store *op1
512 eor r8, r8, lr ; *oq1 = s^0x80
513 add src, src, pstep, lsl #1
517 str r8, [src], pstep ; store *oq1
519 ;roughly 1/7th difference across boundary
521 ldr r9, [src] ; load q2
524 sxtb16 r10, r12, ror #8
525 smlabb r8, r6, lr, r7
526 smlatb r6, r6, lr, r7
527 smlabb r12, r10, lr, r7
528 smlatb r10, r10, lr, r7
529 ssat r8, #8, r8, asr #7
530 ssat r6, #8, r6, asr #7
531 ssat r12, #8, r12, asr #7
532 ssat r10, #8, r10, asr #7
534 sub src, src, pstep, lsl #2
536 pkhbt r6, r8, r6, lsl #16
537 pkhbt r10, r12, r10, lsl #16
542 ldr r11, [src] ; load p2
550 orr r10, r6, r10, lsl #8 ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7)
552 qadd8 r8, r11, r10 ; s = vp8_signed_char_clamp(ps2 + u)
553 qsub8 r10, r9, r10 ; s = vp8_signed_char_clamp(qs2 - u)
554 eor r8, r8, lr ; *op2 = s^0x80
555 str r8, [src], pstep, lsl #2 ; store *op2
557 eor r10, r10, lr ; *oq2 = s^0x80
558 str r10, [src], pstep, lsl #1 ; store *oq2
562 sub src, src, pstep, lsl #3
563 subs count, count, #1
565 ldrne r9, [src], pstep ; p3
566 ldrne r10, [src], pstep ; p2
567 ldrne r11, [src], pstep ; p1
572 ldmia sp!, {r4 - r11, pc}
573 ENDP ; |vp8_mbloop_filter_horizontal_edge_armv6|
576 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
577 |vp8_loop_filter_vertical_edge_armv6| PROC
578 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
579 stmdb sp!, {r4 - r11, lr}
581 sub src, src, #4 ; move src pointer down by 4
582 ldr count, [sp, #40] ; count for 8-in-parallel
583 ldr r12, [sp, #36] ; load thresh address
584 sub sp, sp, #16 ; create temp buffer
586 ldr r6, [src], pstep ; load source data
587 ldr r4, [r2], #4 ; flimit
589 ldr r2, [r3], #4 ; limit
591 uadd8 r4, r4, r4 ; flimit * 2
592 ldr r3, [r12], #4 ; thresh
594 mov count, count, lsl #1 ; 4-in-parallel
595 uadd8 r4, r4, r2 ; flimit * 2 + limit
599 ; vp8_filter_mask() function
600 ; calculate breakout conditions
601 ; transpose the source data for 4-in-parallel operation
602 TRANSPOSE_MATRIX r6, r7, r8, lr, r9, r10, r11, r12
604 uqsub8 r7, r9, r10 ; p3 - p2
605 uqsub8 r8, r10, r9 ; p2 - p3
606 uqsub8 r9, r10, r11 ; p2 - p1
607 uqsub8 r10, r11, r10 ; p1 - p2
608 orr r7, r7, r8 ; abs (p3-p2)
609 orr r10, r9, r10 ; abs (p2-p1)
610 uqsub8 lr, r7, r2 ; compare to limit. lr: vp8_filter_mask
611 uqsub8 r10, r10, r2 ; compare to limit
613 sub src, src, pstep, lsl #2 ; move src pointer down by 4 lines
617 uqsub8 r6, r11, r12 ; p1 - p0
618 uqsub8 r7, r12, r11 ; p0 - p1
619 add src, src, #4 ; move src pointer up by 4
620 orr r6, r6, r7 ; abs (p1-p0)
621 str r11, [sp, #12] ; save p1
622 uqsub8 r10, r6, r2 ; compare to limit
623 uqsub8 r11, r6, r3 ; compare to thresh
626 ; transpose uses 8 regs(r6 - r12 and lr). Need to save reg value now
627 ; transpose the source data for 4-in-parallel operation
628 ldr r6, [src], pstep ; load source data
629 str r11, [sp] ; push r11 to stack
631 str r12, [sp, #4] ; save current reg before load q0 - q3 data
636 TRANSPOSE_MATRIX r6, r7, r8, lr, r9, r10, r11, r12
638 ldr lr, [sp, #8] ; load back (f)limit accumulator
640 uqsub8 r6, r12, r11 ; q3 - q2
641 uqsub8 r7, r11, r12 ; q2 - q3
642 uqsub8 r12, r11, r10 ; q2 - q1
643 uqsub8 r11, r10, r11 ; q1 - q2
644 orr r6, r6, r7 ; abs (q3-q2)
645 orr r7, r12, r11 ; abs (q2-q1)
646 uqsub8 r6, r6, r2 ; compare to limit
647 uqsub8 r7, r7, r2 ; compare to limit
648 ldr r11, [sp, #4] ; load back p0
649 ldr r12, [sp, #12] ; load back p1
653 uqsub8 r6, r11, r9 ; p0 - q0
654 uqsub8 r7, r9, r11 ; q0 - p0
655 uqsub8 r8, r12, r10 ; p1 - q1
656 uqsub8 r11, r10, r12 ; q1 - p1
657 orr r6, r6, r7 ; abs (p0-q0)
659 orr r8, r8, r11 ; abs (p1-q1)
660 uqadd8 r6, r6, r6 ; abs (p0-q0) * 2
661 and r8, r7, r8, lsr #1 ; abs (p1-q1) / 2
662 uqsub8 r11, r10, r9 ; q1 - q0
663 uqadd8 r6, r8, r6 ; abs (p0-q0)*2 + abs (p1-q1)/2
664 uqsub8 r12, r9, r10 ; q0 - q1
665 uqsub8 r6, r6, r4 ; compare to flimit
667 orr r9, r11, r12 ; abs (q1-q0)
668 uqsub8 r8, r9, r2 ; compare to limit
669 uqsub8 r10, r9, r3 ; compare to thresh
673 mvn r11, #0 ; r11 == -1
677 ldr r9, [sp] ; load the compared result
678 sel lr, r11, r12 ; filter mask: lr
681 beq vskip_filter ; skip filtering
683 ;vp8_hevmask() function
684 ;calculate high edge variance
686 sub src, src, pstep, lsl #2 ; move src pointer down by 4 lines
691 ldrh r8, [src], pstep
694 sel r6, r12, r11 ; hev mask: r6
696 ;vp8_filter() function
697 ; load soure data to r6, r11, r12, lr
699 ldrh r10, [src], pstep
701 pkhbt r12, r7, r8, lsl #16
704 ldrh r8, [src], pstep
706 pkhbt r11, r9, r10, lsl #16
709 ldrh r10, [src], pstep
711 ; Transpose needs 8 regs(r6 - r12, and lr). Save r6 and lr first
715 pkhbt r6, r7, r8, lsl #16
716 pkhbt lr, r9, r10, lsl #16
718 ;transpose r12, r11, r6, lr to r7, r8, r9, r10
719 TRANSPOSE_MATRIX r12, r11, r6, lr, r7, r8, r9, r10
721 ;load back hev_mask r6 and filter_mask lr
726 eor r7, r7, r12 ; p1 offset to convert to a signed value
727 eor r8, r8, r12 ; p0 offset to convert to a signed value
728 eor r9, r9, r12 ; q0 offset to convert to a signed value
729 eor r10, r10, r12 ; q1 offset to convert to a signed value
731 str r9, [sp] ; store qs0 temporarily
732 str r8, [sp, #4] ; store ps0 temporarily
733 str r10, [sp, #8] ; store qs1 temporarily
734 str r7, [sp, #12] ; store ps1 temporarily
736 qsub8 r7, r7, r10 ; vp8_signed_char_clamp(ps1-qs1)
737 qsub8 r8, r9, r8 ; vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
739 and r7, r7, r6 ; vp8_filter (r7) &= hev (r7 : filter)
742 ldr r9, c0x03030303 ; r9 = 3 --modified for vp8
748 ;mvn r11, #0 ; r11 == -1
750 and r7, r7, lr ; vp8_filter &= mask
752 ;modify code for vp8 -- Filter1 = vp8_filter (r7)
753 qadd8 r8 , r7 , r9 ; Filter2 (r8) = vp8_signed_char_clamp(vp8_filter+3)
754 qadd8 r7 , r7 , r10 ; vp8_filter = vp8_signed_char_clamp(vp8_filter+4)
757 shadd8 r8 , r8 , r9 ; Filter2 >>= 3
758 shadd8 r7 , r7 , r9 ; vp8_filter >>= 3
761 shadd8 lr , r8 , r9 ; lr: filter2
762 shadd8 r7 , r7 , r9 ; r7: filter
764 ;usub8 lr, r8, r10 ; s = (s==4)*-1
768 ;and r8, r8, lr ; -1 for each element that equals 4 -- r8: s
771 ;qadd8 lr, r8, r7 ; u = vp8_signed_char_clamp(s + vp8_filter)
773 ldr r8, [sp] ; load qs0
774 ldr r9, [sp, #4] ; load ps0
778 qsub8 r8, r8, r7 ; u = vp8_signed_char_clamp(qs0 - vp8_filter)
779 qadd8 r9, r9, lr ; u = vp8_signed_char_clamp(ps0 + Filter2)
780 ;end of modification for vp8
790 ldr r10, [sp, #8] ; load qs1
791 ldr r11, [sp, #12] ; load ps1
793 bic r7, r7, r6 ; r7: vp8_filter
795 qsub8 r10 , r10, r7 ; u = vp8_signed_char_clamp(qs1 - vp8_filter)
796 qadd8 r11, r11, r7 ; u = vp8_signed_char_clamp(ps1 + vp8_filter)
800 sub src, src, pstep, lsl #2
802 ;we can use TRANSPOSE_MATRIX macro to transpose output - input: q1, q0, p0, p1
803 ;output is b0, b1, b2, b3
810 TRANSPOSE_MATRIX r11, r9, r8, r10, r6, r7, r12, lr
812 strh r6, [src, #-2] ; store the result
814 strh r6, [src], pstep
818 strh r7, [src], pstep
821 mov r12, r12, lsr #16
822 strh r12, [src], pstep
826 strh lr, [src], pstep
830 subs count, count, #1
832 ldrne r6, [src], pstep ; load source data
833 ldrne r7, [src], pstep
834 ldrne r8, [src], pstep
835 ldrne lr, [src], pstep
841 ldmia sp!, {r4 - r11, pc}
842 ENDP ; |vp8_loop_filter_vertical_edge_armv6|
846 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
847 |vp8_mbloop_filter_vertical_edge_armv6| PROC
848 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
849 stmdb sp!, {r4 - r11, lr}
851 sub src, src, #4 ; move src pointer down by 4
852 ldr count, [sp, #40] ; count for 8-in-parallel
853 ldr r12, [sp, #36] ; load thresh address
854 pld [src, #23] ; preload for next block
855 sub sp, sp, #16 ; create temp buffer
857 ldr r6, [src], pstep ; load source data
858 ldr r4, [r2], #4 ; flimit
861 ldr r2, [r3], #4 ; limit
864 uadd8 r4, r4, r4 ; flimit * 2
865 ldr r3, [r12], #4 ; thresh
868 mov count, count, lsl #1 ; 4-in-parallel
869 uadd8 r4, r4, r2 ; flimit * 2 + limit
872 ; vp8_filter_mask() function
873 ; calculate breakout conditions
874 ; transpose the source data for 4-in-parallel operation
875 TRANSPOSE_MATRIX r6, r7, r8, lr, r9, r10, r11, r12
877 uqsub8 r7, r9, r10 ; p3 - p2
878 uqsub8 r8, r10, r9 ; p2 - p3
879 uqsub8 r9, r10, r11 ; p2 - p1
880 uqsub8 r10, r11, r10 ; p1 - p2
881 orr r7, r7, r8 ; abs (p3-p2)
882 orr r10, r9, r10 ; abs (p2-p1)
883 uqsub8 lr, r7, r2 ; compare to limit. lr: vp8_filter_mask
884 uqsub8 r10, r10, r2 ; compare to limit
886 sub src, src, pstep, lsl #2 ; move src pointer down by 4 lines
890 uqsub8 r6, r11, r12 ; p1 - p0
891 uqsub8 r7, r12, r11 ; p0 - p1
892 add src, src, #4 ; move src pointer up by 4
893 orr r6, r6, r7 ; abs (p1-p0)
894 str r11, [sp, #12] ; save p1
895 uqsub8 r10, r6, r2 ; compare to limit
896 uqsub8 r11, r6, r3 ; compare to thresh
899 ; transpose uses 8 regs(r6 - r12 and lr). Need to save reg value now
900 ; transpose the source data for 4-in-parallel operation
901 ldr r6, [src], pstep ; load source data
902 str r11, [sp] ; push r11 to stack
904 str r12, [sp, #4] ; save current reg before load q0 - q3 data
909 TRANSPOSE_MATRIX r6, r7, r8, lr, r9, r10, r11, r12
911 ldr lr, [sp, #8] ; load back (f)limit accumulator
913 uqsub8 r6, r12, r11 ; q3 - q2
914 uqsub8 r7, r11, r12 ; q2 - q3
915 uqsub8 r12, r11, r10 ; q2 - q1
916 uqsub8 r11, r10, r11 ; q1 - q2
917 orr r6, r6, r7 ; abs (q3-q2)
918 orr r7, r12, r11 ; abs (q2-q1)
919 uqsub8 r6, r6, r2 ; compare to limit
920 uqsub8 r7, r7, r2 ; compare to limit
921 ldr r11, [sp, #4] ; load back p0
922 ldr r12, [sp, #12] ; load back p1
926 uqsub8 r6, r11, r9 ; p0 - q0
927 uqsub8 r7, r9, r11 ; q0 - p0
928 uqsub8 r8, r12, r10 ; p1 - q1
929 uqsub8 r11, r10, r12 ; q1 - p1
930 orr r6, r6, r7 ; abs (p0-q0)
932 orr r8, r8, r11 ; abs (p1-q1)
933 uqadd8 r6, r6, r6 ; abs (p0-q0) * 2
934 and r8, r7, r8, lsr #1 ; abs (p1-q1) / 2
935 uqsub8 r11, r10, r9 ; q1 - q0
936 uqadd8 r6, r8, r6 ; abs (p0-q0)*2 + abs (p1-q1)/2
937 uqsub8 r12, r9, r10 ; q0 - q1
938 uqsub8 r6, r6, r4 ; compare to flimit
940 orr r9, r11, r12 ; abs (q1-q0)
941 uqsub8 r8, r9, r2 ; compare to limit
942 uqsub8 r10, r9, r3 ; compare to thresh
946 mvn r11, #0 ; r11 == -1
950 ldr r9, [sp] ; load the compared result
951 sel lr, r11, r12 ; filter mask: lr
954 beq mbvskip_filter ; skip filtering
957 ;vp8_hevmask() function
958 ;calculate high edge variance
960 sub src, src, pstep, lsl #2 ; move src pointer down by 4 lines
965 ldrh r8, [src], pstep
968 sel r6, r12, r11 ; hev mask: r6
971 ; vp8_mbfilter() function
972 ; p2, q2 are only needed at the end. Don't need to load them in now.
973 ; Transpose needs 8 regs(r6 - r12, and lr). Save r6 and lr first
974 ; load soure data to r6, r11, r12, lr
976 ldrh r10, [src], pstep
978 pkhbt r12, r7, r8, lsl #16
981 ldrh r8, [src], pstep
983 pkhbt r11, r9, r10, lsl #16
986 ldrh r10, [src], pstep
988 str r6, [sp] ; save r6
989 str lr, [sp, #4] ; save lr
991 pkhbt r6, r7, r8, lsl #16
992 pkhbt lr, r9, r10, lsl #16
994 ;transpose r12, r11, r6, lr to p1, p0, q0, q1
995 TRANSPOSE_MATRIX r12, r11, r6, lr, r7, r8, r9, r10
997 ;load back hev_mask r6 and filter_mask lr
1002 eor r7, r7, r12 ; ps1
1003 eor r8, r8, r12 ; ps0
1004 eor r9, r9, r12 ; qs0
1005 eor r10, r10, r12 ; qs1
1007 qsub8 r12, r9, r8 ; vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
1008 str r7, [sp, #12] ; store ps1 temporarily
1009 qsub8 r7, r7, r10 ; vp8_signed_char_clamp(ps1-qs1)
1010 str r10, [sp, #8] ; store qs1 temporarily
1012 str r9, [sp] ; store qs0 temporarily
1014 str r8, [sp, #4] ; store ps0 temporarily
1015 qadd8 r7, r7, r12 ; vp8_filter: r7
1017 ldr r10, c0x03030303 ; r10 = 3 --modified for vp8
1019 ;mvn r11, #0 ; r11 == -1
1021 and r7, r7, lr ; vp8_filter &= mask (lr is free)
1023 mov r12, r7 ; Filter2: r12
1024 and r12, r12, r6 ; Filter2 &= hev
1026 ;modify code for vp8
1027 ;save bottom 3 bits so that we round one side +4 and the other +3
1028 qadd8 r8 , r12 , r9 ; Filter1 (r8) = vp8_signed_char_clamp(Filter2+4)
1029 qadd8 r12 , r12 , r10 ; Filter2 (r12) = vp8_signed_char_clamp(Filter2+3)
1032 shadd8 r8 , r8 , r10 ; Filter1 >>= 3
1033 shadd8 r12 , r12 , r10 ; Filter2 >>= 3
1034 shadd8 r8 , r8 , r10
1035 shadd8 r12 , r12 , r10
1036 shadd8 r8 , r8 , r10 ; r8: Filter1
1037 shadd8 r12 , r12 , r10 ; r12: Filter2
1039 ldr r9, [sp] ; load qs0
1040 ldr r11, [sp, #4] ; load ps0
1042 qsub8 r9 , r9, r8 ; qs0 = vp8_signed_char_clamp(qs0 - Filter1)
1043 qadd8 r11, r11, r12 ; ps0 = vp8_signed_char_clamp(ps0 + Filter2)
1045 ;save bottom 3 bits so that we round one side +4 and the other +3
1046 ;and r8, r12, r10 ; s = Filter2 & 7 (s: r8)
1047 ;qadd8 r12 , r12 , r9 ; Filter2 = vp8_signed_char_clamp(Filter2+4)
1049 ;shadd8 r12 , r12 , r10 ; Filter2 >>= 3
1050 ;usub8 lr, r8, r9 ; s = (s==4)*-1
1052 ;shadd8 r12 , r12 , r10
1055 ;ldr r9, [sp] ; load qs0
1056 ;ldr r11, [sp, #4] ; load ps0
1057 ;shadd8 r12 , r12 , r10
1058 ;and r8, r8, lr ; -1 for each element that equals 4
1059 ;qadd8 r10, r8, r12 ; u = vp8_signed_char_clamp(s + Filter2)
1060 ;qsub8 r9 , r9, r12 ; qs0 = vp8_signed_char_clamp(qs0 - Filter2)
1061 ;qadd8 r11, r11, r10 ; ps0 = vp8_signed_char_clamp(ps0 + u)
1063 ;end of modification for vp8
1065 bic r12, r7, r6 ;vp8_filter &= ~hev ( r6 is free)
1068 ;roughly 3/7th difference across boundary
1073 sxtb16 r10, r12, ror #8
1074 smlabb r8, r6, lr, r7
1075 smlatb r6, r6, lr, r7
1076 smlabb r7, r10, lr, r7
1078 ssat r8, #8, r8, asr #7
1079 ssat r6, #8, r6, asr #7
1081 ssat r7, #8, r7, asr #7
1082 ssat r10, #8, r10, asr #7
1086 pkhbt r6, r8, r6, lsl #16
1087 pkhbt r10, r7, r10, lsl #16
1091 sub src, src, pstep, lsl #2 ; move src pointer down by 4 lines
1093 orr r10, r6, r10, lsl #8 ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7)
1095 qsub8 r8, r9, r10 ; s = vp8_signed_char_clamp(qs0 - u)
1096 qadd8 r10, r11, r10 ; s = vp8_signed_char_clamp(ps0 + u)
1097 eor r8, r8, lr ; *oq0 = s^0x80
1098 eor r10, r10, lr ; *op0 = s^0x80
1100 strb r10, [src, #-1] ; store op0 result
1101 strb r8, [src], pstep ; store oq0 result
1102 mov r10, r10, lsr #8
1104 strb r10, [src, #-1]
1105 strb r8, [src], pstep
1106 mov r10, r10, lsr #8
1108 strb r10, [src, #-1]
1109 strb r8, [src], pstep
1110 mov r10, r10, lsr #8
1112 strb r10, [src, #-1]
1113 strb r8, [src], pstep
1115 ;roughly 2/7th difference across boundary
1120 sxtb16 r10, r12, ror #8
1121 smlabb r8, r6, lr, r7
1122 smlatb r6, r6, lr, r7
1123 smlabb r9, r10, lr, r7
1124 smlatb r10, r10, lr, r7
1125 ssat r8, #8, r8, asr #7
1126 ssat r6, #8, r6, asr #7
1127 ssat r9, #8, r9, asr #7
1128 ssat r10, #8, r10, asr #7
1130 sub src, src, pstep, lsl #2 ; move src pointer down by 4 lines
1132 pkhbt r6, r8, r6, lsl #16
1133 pkhbt r10, r9, r10, lsl #16
1135 ldr r9, [sp, #8] ; load qs1
1136 ldr r11, [sp, #12] ; load ps1
1144 orr r10, r6, r10, lsl #8 ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7)
1146 qsub8 r8, r9, r10 ; s = vp8_signed_char_clamp(qs1 - u)
1147 qadd8 r10, r11, r10 ; s = vp8_signed_char_clamp(ps1 + u)
1148 eor r8, r8, lr ; *oq1 = s^0x80
1149 eor r10, r10, lr ; *op1 = s^0x80
1151 ldrb r11, [src, #-5] ; load p2 for 1/7th difference across boundary
1152 strb r10, [src, #-4] ; store op1
1153 strb r8, [src, #-1] ; store oq1
1154 ldrb r9, [src], pstep ; load q2 for 1/7th difference across boundary
1156 mov r10, r10, lsr #8
1160 strb r10, [src, #-4]
1162 ldrb r7, [src], pstep
1164 mov r10, r10, lsr #8
1166 orr r11, r11, r6, lsl #8
1167 orr r9, r9, r7, lsl #8
1170 strb r10, [src, #-4]
1172 ldrb r7, [src], pstep
1174 mov r10, r10, lsr #8
1176 orr r11, r11, r6, lsl #16
1177 orr r9, r9, r7, lsl #16
1180 strb r10, [src, #-4]
1182 ldrb r7, [src], pstep
1183 orr r11, r11, r6, lsl #24
1184 orr r9, r9, r7, lsl #24
1186 ;roughly 1/7th difference across boundary
1194 sxtb16 r10, r12, ror #8
1195 smlabb r8, r6, lr, r7
1196 smlatb r6, r6, lr, r7
1197 smlabb r12, r10, lr, r7
1198 smlatb r10, r10, lr, r7
1199 ssat r8, #8, r8, asr #7
1200 ssat r6, #8, r6, asr #7
1201 ssat r12, #8, r12, asr #7
1202 ssat r10, #8, r10, asr #7
1204 sub src, src, pstep, lsl #2
1206 pkhbt r6, r8, r6, lsl #16
1207 pkhbt r10, r12, r10, lsl #16
1214 orr r10, r6, r10, lsl #8 ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7)
1216 qadd8 r8, r11, r10 ; s = vp8_signed_char_clamp(ps2 + u)
1217 qsub8 r10, r9, r10 ; s = vp8_signed_char_clamp(qs2 - u)
1218 eor r8, r8, lr ; *op2 = s^0x80
1219 eor r10, r10, lr ; *oq2 = s^0x80
1221 strb r8, [src, #-5] ; store *op2
1222 strb r10, [src], pstep ; store *oq2
1224 mov r10, r10, lsr #8
1226 strb r10, [src], pstep
1228 mov r10, r10, lsr #8
1230 strb r10, [src], pstep
1232 mov r10, r10, lsr #8
1234 strb r10, [src], pstep
1236 ;adjust src pointer for next loop
1241 subs count, count, #1
1243 pld [src, #23] ; preload for next block
1244 ldrne r6, [src], pstep ; load source data
1246 ldrne r7, [src], pstep
1248 ldrne r8, [src], pstep
1250 ldrne lr, [src], pstep
1256 ldmia sp!, {r4 - r11, pc}
1257 ENDP ; |vp8_mbloop_filter_vertical_edge_armv6|
1260 c0x80808080 DCD 0x80808080
1261 c0x03030303 DCD 0x03030303
1262 c0x04040404 DCD 0x04040404
1263 c0x01010101 DCD 0x01010101
1264 c0x7F7F7F7F DCD 0x7F7F7F7F