utilize preload in ARMv6 MC/LPF/Copy routines
[profile/ivi/libvpx.git] / vp8 / common / arm / armv6 / loopfilter_v6.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     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|
16
17     AREA    |.text|, CODE, READONLY  ; name this block of code
18
19     MACRO
20     TRANSPOSE_MATRIX $a0, $a1, $a2, $a3, $b0, $b1, $b2, $b3
21     ; input: $a0, $a1, $a2, $a3; output: $b0, $b1, $b2, $b3
22     ; a0: 03 02 01 00
23     ; a1: 13 12 11 10
24     ; a2: 23 22 21 20
25     ; a3: 33 32 31 30
26     ;     b3 b2 b1 b0
27
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
34
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
41
42     pkhtb       $b2, $b3, $b1, asr #16      ; 32 22 12 02   -- p1
43     pkhbt       $b0, $b1, $b3, lsl #16      ; 30 20 10 00   -- p3
44
45     pkhtb       $b3, $a2, $a0, asr #16      ; 33 23 13 03   -- p0
46     pkhbt       $b1, $a0, $a2, lsl #16      ; 31 21 11 01   -- p2
47     MEND
48
49
50 src         RN  r0
51 pstep       RN  r1
52 count       RN  r5
53
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,
59 ;stack  int  count
60
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.
63
64 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
65 |vp8_loop_filter_horizontal_edge_armv6| PROC
66 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
67     stmdb       sp!, {r4 - r11, lr}
68
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
73
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
83
84 |Hnext8|
85     ; vp8_filter_mask() function
86     ; calculate breakout conditions
87     ldr         r12, [src], pstep           ; p0
88
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
93
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
99     orr         lr, lr, r8
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
106     orr         lr, lr, r7
107
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)
113     ldr         r7, c0x7F7F7F7F
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
123
124     orr         lr, lr, r12
125
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
133     orr         lr, lr, r7
134     orr         lr, lr, r10
135
136     uqsub8      r10, r12, r11               ; q3 - q2
137     uqsub8      r9, r11, r12                ; q2 - q3
138
139     mvn         r11, #0                     ; r11 == -1
140
141     orr         r10, r10, r9                ; abs (q3-q2)
142     uqsub8      r10, r10, r2                ; compare to limit
143
144     mov         r12, #0
145     orr         lr, lr, r10
146     sub         src, src, pstep, lsl #2
147
148     usub8       lr, r12, lr                 ; use usub8 instead of ssub8
149     sel         lr, r11, r12                ; filter mask: lr
150
151     cmp         lr, #0
152     beq         hskip_filter                 ; skip filtering
153
154     sub         src, src, pstep, lsl #1     ; move src pointer down by 6 lines
155
156     ;vp8_hevmask() function
157     ;calculate high edge variance
158     orr         r10, r6, r8                 ; calculate vp8_hevmask
159
160     ldr         r7, [src], pstep            ; p1
161
162     usub8       r10, r12, r10               ; use usub8 instead of ssub8
163     sel         r6, r12, r11                ; obtain vp8_hevmask: r6
164
165     ;vp8_filter() function
166     ldr         r8, [src], pstep            ; p0
167     ldr         r12, c0x80808080
168     ldr         r9, [src], pstep            ; q0
169     ldr         r10, [src], pstep           ; q1
170
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
175
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
180
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))
183
184     and         r7, r7, r6                  ; vp8_filter (r7) &= hev
185
186     qadd8       r7, r7, r8
187     ldr         r9, c0x03030303             ; r9 = 3 --modified for vp8
188
189     qadd8       r7, r7, r8
190     ldr         r10, c0x04040404
191
192     qadd8       r7, r7, r8
193     and         r7, r7, lr                  ; vp8_filter &= mask;
194
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)
198
199     mov         r9, #0
200     shadd8      r8 , r8 , r9                ; Filter2 >>= 3
201     shadd8      r7 , r7 , r9                ; vp8_filter >>= 3
202     shadd8      r8 , r8 , r9
203     shadd8      r7 , r7 , r9
204     shadd8      lr , r8 , r9                ; lr: Filter2
205     shadd8      r7 , r7 , r9                ; r7: filter
206
207     ;usub8      lr, r8, r10                 ; s = (s==4)*-1
208     ;sel        lr, r11, r9
209     ;usub8      r8, r10, r8
210     ;sel        r8, r11, r9
211     ;and        r8, r8, lr                  ; -1 for each element that equals 4
212
213     ;calculate output
214     ;qadd8      lr, r8, r7                  ; u = vp8_signed_char_clamp(s + vp8_filter)
215
216     ldr         r8, [sp]                    ; load qs0
217     ldr         r9, [sp, #4]                ; load ps0
218
219     ldr         r10, c0x01010101
220
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)
223
224     ;end of modification for vp8
225
226     mov         lr, #0
227     sadd8       r7, r7 , r10                ; vp8_filter += 1
228     shadd8      r7, r7, lr                  ; vp8_filter >>= 1
229
230     ldr         r11, [sp, #12]              ; load ps1
231     ldr         r10, [sp, #8]               ; load qs1
232
233     bic         r7, r7, r6                  ; vp8_filter &= ~hev
234     sub         src, src, pstep, lsl #2
235
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)
238
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
247
248     sub         src, src, pstep, lsl #1
249
250 |hskip_filter|
251     add         src, src, #4
252     sub         src, src, pstep, lsl #2
253
254     subs        count, count, #1
255
256     ldrne       r9, [src], pstep            ; p3
257     ldrne       r10, [src], pstep           ; p2
258     ldrne       r11, [src], pstep           ; p1
259
260     bne         Hnext8
261
262     add         sp, sp, #16
263     ldmia       sp!, {r4 - r11, pc}
264     ENDP        ; |vp8_loop_filter_horizontal_edge_armv6|
265
266
267 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
268 |vp8_mbloop_filter_horizontal_edge_armv6| PROC
269 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
270     stmdb       sp!, {r4 - r11, lr}
271
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
276
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
286
287 |MBHnext8|
288
289     ; vp8_filter_mask() function
290     ; calculate breakout conditions
291     ldr         r12, [src], pstep           ; p0
292
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
297
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
302
303     uqsub8      r6, r11, r12                ; p1 - p0
304     orr         lr, lr, r8
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
311     orr         lr, lr, r7
312
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)
318     ldr         r7, c0x7F7F7F7F
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
328
329     orr         lr, lr, r12
330
331     ldr         r12, [src], pstep           ; q3
332
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
339     orr         lr, lr, r7
340     orr         lr, lr, r10
341
342     uqsub8      r10, r12, r11               ; q3 - q2
343     uqsub8      r9, r11, r12                ; q2 - q3
344
345     mvn         r11, #0                     ; r11 == -1
346
347     orr         r10, r10, r9                ; abs (q3-q2)
348     uqsub8      r10, r10, r2                ; compare to limit
349
350     mov         r12, #0
351
352     orr         lr, lr, r10
353
354     usub8       lr, r12, lr                 ; use usub8 instead of ssub8
355     sel         lr, r11, r12                ; filter mask: lr
356
357     cmp         lr, #0
358     beq         mbhskip_filter               ; skip filtering
359
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
364
365     orr         r10, r6, r8
366     ldr         r7, [src], pstep            ; p1
367
368     usub8       r10, r12, r10
369     sel         r6, r12, r11                ; hev mask: r6
370
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
374     ldr         r12, c0x80808080
375     ldr         r9, [src], pstep            ; q0
376     ldr         r10, [src]                  ; q1
377
378     eor         r7, r7, r12                 ; ps1
379     eor         r8, r8, r12                 ; ps0
380     eor         r9, r9, r12                 ; qs0
381     eor         r10, r10, r12               ; qs1
382
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
387     qadd8       r7, r7, r12
388     str         r9, [sp]                    ; store qs0 temporarily
389     qadd8       r7, r7, r12
390     str         r8, [sp, #4]                ; store ps0 temporarily
391     qadd8       r7, r7, r12                 ; vp8_filter: r7
392
393     ldr         r10, c0x03030303            ; r10 = 3 --modified for vp8
394     ldr         r9, c0x04040404
395
396     and         r7, r7, lr                  ; vp8_filter &= mask (lr is free)
397
398     mov         r12, r7                     ; Filter2: r12
399     and         r12, r12, r6                ; Filter2 &= hev
400
401     ;modify code for vp8
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)
405
406     mov         r10, #0
407     shadd8      r8 , r8 , r10               ; Filter1 >>= 3
408     shadd8      r12 , r12 , r10             ; Filter2 >>= 3
409     shadd8      r8 , r8 , r10
410     shadd8      r12 , r12 , r10
411     shadd8      r8 , r8 , r10               ; r8: Filter1
412     shadd8      r12 , r12 , r10             ; r12: Filter2
413
414     ldr         r9, [sp]                    ; load qs0
415     ldr         r11, [sp, #4]               ; load ps0
416
417     qsub8       r9 , r9, r8                 ; qs0 = vp8_signed_char_clamp(qs0 - Filter1)
418     qadd8       r11, r11, r12               ; ps0 = vp8_signed_char_clamp(ps0 + Filter2)
419
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)
423     ;mov            r10, #0
424     ;shadd8     r12 , r12 , r10             ; Filter2 >>= 3
425     ;usub8      lr, r8, r9                  ; s = (s==4)*-1
426     ;sel            lr, r11, r10
427     ;shadd8     r12 , r12 , r10
428     ;usub8      r8, r9, r8
429     ;sel            r8, r11, 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)
437
438     ;end of modification for vp8
439
440     bic         r12, r7, r6                 ; vp8_filter &= ~hev    ( r6 is free)
441     ;mov        r12, r7
442
443     ;roughly 3/7th difference across boundary
444     mov         lr, #0x1b                   ; 27
445     mov         r7, #0x3f                   ; 63
446
447     sxtb16      r6, r12
448     sxtb16      r10, r12, ror #8
449     smlabb      r8, r6, lr, r7
450     smlatb      r6, r6, lr, r7
451     smlabb      r7, r10, lr, r7
452     smultb      r10, r10, lr
453     ssat        r8, #8, r8, asr #7
454     ssat        r6, #8, r6, asr #7
455     add         r10, r10, #63
456     ssat        r7, #8, r7, asr #7
457     ssat        r10, #8, r10, asr #7
458
459     ldr         lr, c0x80808080
460
461     pkhbt       r6, r8, r6, lsl #16
462     pkhbt       r10, r7, r10, lsl #16
463     uxtb16      r6, r6
464     uxtb16      r10, r10
465
466     sub         src, src, pstep
467
468     orr         r10, r6, r10, lsl #8        ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7)
469
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
474     sub         src, src, pstep
475     eor         r10, r10, lr                ; *op0 = s^0x80
476     str         r10, [src]                  ; store *op0
477
478     ;roughly 2/7th difference across boundary
479     mov         lr, #0x12                   ; 18
480     mov         r7, #0x3f                   ; 63
481
482     sxtb16      r6, r12
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
492
493     ldr         lr, c0x80808080
494
495     pkhbt       r6, r8, r6, lsl #16
496     pkhbt       r10, r9, r10, lsl #16
497
498     ldr         r9, [sp, #8]                ; load qs1
499     ldr         r11, [sp, #12]              ; load ps1
500
501     uxtb16      r6, r6
502     uxtb16      r10, r10
503
504     sub         src, src, pstep
505
506     orr         r10, r6, r10, lsl #8        ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7)
507
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
514
515     mov         r7, #0x3f                   ; 63
516
517     str         r8, [src], pstep            ; store *oq1
518
519     ;roughly 1/7th difference across boundary
520     mov         lr, #0x9                    ; 9
521     ldr         r9, [src]                   ; load q2
522
523     sxtb16      r6, r12
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
533
534     sub         src, src, pstep, lsl #2
535
536     pkhbt       r6, r8, r6, lsl #16
537     pkhbt       r10, r12, r10, lsl #16
538
539     sub         src, src, pstep
540     ldr         lr, c0x80808080
541
542     ldr         r11, [src]                  ; load p2
543
544     uxtb16      r6, r6
545     uxtb16      r10, r10
546
547     eor         r9, r9, lr
548     eor         r11, r11, lr
549
550     orr         r10, r6, r10, lsl #8        ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7)
551
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
556     add         src, src, pstep
557     eor         r10, r10, lr                ; *oq2 = s^0x80
558     str         r10, [src], pstep, lsl #1   ; store *oq2
559
560 |mbhskip_filter|
561     add         src, src, #4
562     sub         src, src, pstep, lsl #3
563     subs        count, count, #1
564
565     ldrne       r9, [src], pstep            ; p3
566     ldrne       r10, [src], pstep           ; p2
567     ldrne       r11, [src], pstep           ; p1
568
569     bne         MBHnext8
570
571     add         sp, sp, #16
572     ldmia       sp!, {r4 - r11, pc}
573     ENDP        ; |vp8_mbloop_filter_horizontal_edge_armv6|
574
575
576 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
577 |vp8_loop_filter_vertical_edge_armv6| PROC
578 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
579     stmdb       sp!, {r4 - r11, lr}
580
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
585
586     ldr         r6, [src], pstep            ; load source data
587     ldr         r4, [r2], #4                ; flimit
588     ldr         r7, [src], pstep
589     ldr         r2, [r3], #4                ; limit
590     ldr         r8, [src], pstep
591     uadd8       r4, r4, r4                  ; flimit * 2
592     ldr         r3, [r12], #4               ; thresh
593     ldr         lr, [src], pstep
594     mov         count, count, lsl #1        ; 4-in-parallel
595     uadd8       r4, r4, r2                  ; flimit * 2 + limit
596
597 |Vnext8|
598
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
603
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
612
613     sub         src, src, pstep, lsl #2     ; move src pointer down by 4 lines
614
615     orr         lr, lr, r10
616
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
624     orr         lr, lr, r10
625
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
630     ldr         r7, [src], pstep
631     str         r12, [sp, #4]               ; save current reg before load q0 - q3 data
632     ldr         r8, [src], pstep
633     str         lr, [sp, #8]
634     ldr         lr, [src], pstep
635
636     TRANSPOSE_MATRIX r6, r7, r8, lr, r9, r10, r11, r12
637
638     ldr         lr, [sp, #8]                ; load back (f)limit accumulator
639
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
650     orr         lr, lr, r6
651     orr         lr, lr, r7
652
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)
658     ldr         r7, c0x7F7F7F7F
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
666
667     orr         r9, r11, r12                ; abs (q1-q0)
668     uqsub8      r8, r9, r2                  ; compare to limit
669     uqsub8      r10, r9, r3                 ; compare to thresh
670     orr         lr, lr, r6
671     orr         lr, lr, r8
672
673     mvn         r11, #0                     ; r11 == -1
674     mov         r12, #0
675
676     usub8       lr, r12, lr
677     ldr         r9, [sp]                    ; load the compared result
678     sel         lr, r11, r12                ; filter mask: lr
679
680     cmp         lr, #0
681     beq         vskip_filter                 ; skip filtering
682
683     ;vp8_hevmask() function
684     ;calculate high edge variance
685
686     sub         src, src, pstep, lsl #2     ; move src pointer down by 4 lines
687
688     orr         r9, r9, r10
689
690     ldrh        r7, [src, #-2]
691     ldrh        r8, [src], pstep
692
693     usub8       r9, r12, r9
694     sel         r6, r12, r11                ; hev mask: r6
695
696     ;vp8_filter() function
697     ; load soure data to r6, r11, r12, lr
698     ldrh        r9, [src, #-2]
699     ldrh        r10, [src], pstep
700
701     pkhbt       r12, r7, r8, lsl #16
702
703     ldrh        r7, [src, #-2]
704     ldrh        r8, [src], pstep
705
706     pkhbt       r11, r9, r10, lsl #16
707
708     ldrh        r9, [src, #-2]
709     ldrh        r10, [src], pstep
710
711     ; Transpose needs 8 regs(r6 - r12, and lr). Save r6 and lr first
712     str         r6, [sp]
713     str         lr, [sp, #4]
714
715     pkhbt       r6, r7, r8, lsl #16
716     pkhbt       lr, r9, r10, lsl #16
717
718     ;transpose r12, r11, r6, lr to r7, r8, r9, r10
719     TRANSPOSE_MATRIX r12, r11, r6, lr, r7, r8, r9, r10
720
721     ;load back hev_mask r6 and filter_mask lr
722     ldr         r12, c0x80808080
723     ldr         r6, [sp]
724     ldr         lr, [sp, #4]
725
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
730
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
735
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))
738
739     and         r7, r7, r6                  ;  vp8_filter (r7) &= hev (r7 : filter)
740
741     qadd8       r7, r7, r8
742     ldr         r9, c0x03030303             ; r9 = 3 --modified for vp8
743
744     qadd8       r7, r7, r8
745     ldr         r10, c0x04040404
746
747     qadd8       r7, r7, r8
748     ;mvn         r11, #0                     ; r11 == -1
749
750     and         r7, r7, lr                  ; vp8_filter &= mask
751
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)
755
756     mov         r9, #0
757     shadd8      r8 , r8 , r9                ; Filter2 >>= 3
758     shadd8      r7 , r7 , r9                ; vp8_filter >>= 3
759     shadd8      r8 , r8 , r9
760     shadd8      r7 , r7 , r9
761     shadd8      lr , r8 , r9                ; lr: filter2
762     shadd8      r7 , r7 , r9                ; r7: filter
763
764     ;usub8      lr, r8, r10                 ; s = (s==4)*-1
765     ;sel            lr, r11, r9
766     ;usub8      r8, r10, r8
767     ;sel            r8, r11, r9
768     ;and            r8, r8, lr                  ; -1 for each element that equals 4 -- r8: s
769
770     ;calculate output
771     ;qadd8      lr, r8, r7                  ; u = vp8_signed_char_clamp(s + vp8_filter)
772
773     ldr         r8, [sp]                    ; load qs0
774     ldr         r9, [sp, #4]                ; load ps0
775
776     ldr         r10, c0x01010101
777
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
781
782     eor         r8, r8, r12
783     eor         r9, r9, r12
784
785     mov         lr, #0
786
787     sadd8       r7, r7, r10
788     shadd8      r7, r7, lr
789
790     ldr         r10, [sp, #8]               ; load qs1
791     ldr         r11, [sp, #12]              ; load ps1
792
793     bic         r7, r7, r6                  ; r7: vp8_filter
794
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)
797     eor         r10, r10, r12
798     eor         r11, r11, r12
799
800     sub         src, src, pstep, lsl #2
801
802     ;we can use TRANSPOSE_MATRIX macro to transpose output - input: q1, q0, p0, p1
803     ;output is b0, b1, b2, b3
804     ;b0: 03 02 01 00
805     ;b1: 13 12 11 10
806     ;b2: 23 22 21 20
807     ;b3: 33 32 31 30
808     ;    p1 p0 q0 q1
809     ;   (a3 a2 a1 a0)
810     TRANSPOSE_MATRIX r11, r9, r8, r10, r6, r7, r12, lr
811
812     strh        r6, [src, #-2]              ; store the result
813     mov         r6, r6, lsr #16
814     strh        r6, [src], pstep
815
816     strh        r7, [src, #-2]
817     mov         r7, r7, lsr #16
818     strh        r7, [src], pstep
819
820     strh        r12, [src, #-2]
821     mov         r12, r12, lsr #16
822     strh        r12, [src], pstep
823
824     strh        lr, [src, #-2]
825     mov         lr, lr, lsr #16
826     strh        lr, [src], pstep
827
828 |vskip_filter|
829     sub         src, src, #4
830     subs        count, count, #1
831
832     ldrne       r6, [src], pstep            ; load source data
833     ldrne       r7, [src], pstep
834     ldrne       r8, [src], pstep
835     ldrne       lr, [src], pstep
836
837     bne         Vnext8
838
839     add         sp, sp, #16
840
841     ldmia       sp!, {r4 - r11, pc}
842     ENDP        ; |vp8_loop_filter_vertical_edge_armv6|
843
844
845
846 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
847 |vp8_mbloop_filter_vertical_edge_armv6| PROC
848 ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
849     stmdb       sp!, {r4 - r11, lr}
850
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
856
857     ldr         r6, [src], pstep            ; load source data
858     ldr         r4, [r2], #4                ; flimit
859     pld         [src, #23]
860     ldr         r7, [src], pstep
861     ldr         r2, [r3], #4                ; limit
862     pld         [src, #23]
863     ldr         r8, [src], pstep
864     uadd8       r4, r4, r4                  ; flimit * 2
865     ldr         r3, [r12], #4               ; thresh
866     pld         [src, #23]
867     ldr         lr, [src], pstep
868     mov         count, count, lsl #1        ; 4-in-parallel
869     uadd8       r4, r4, r2                  ; flimit * 2 + limit
870
871 |MBVnext8|
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
876
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
885
886     sub         src, src, pstep, lsl #2     ; move src pointer down by 4 lines
887
888     orr         lr, lr, r10
889
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
897     orr         lr, lr, r10
898
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
903     ldr         r7, [src], pstep
904     str         r12, [sp, #4]               ; save current reg before load q0 - q3 data
905     ldr         r8, [src], pstep
906     str         lr, [sp, #8]
907     ldr         lr, [src], pstep
908
909     TRANSPOSE_MATRIX r6, r7, r8, lr, r9, r10, r11, r12
910
911     ldr         lr, [sp, #8]                ; load back (f)limit accumulator
912
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
923     orr         lr, lr, r6
924     orr         lr, lr, r7
925
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)
931     ldr         r7, c0x7F7F7F7F
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
939
940     orr         r9, r11, r12                ; abs (q1-q0)
941     uqsub8      r8, r9, r2                  ; compare to limit
942     uqsub8      r10, r9, r3                 ; compare to thresh
943     orr         lr, lr, r6
944     orr         lr, lr, r8
945
946     mvn         r11, #0                     ; r11 == -1
947     mov         r12, #0
948
949     usub8       lr, r12, lr
950     ldr         r9, [sp]                    ; load the compared result
951     sel         lr, r11, r12                ; filter mask: lr
952
953     cmp         lr, #0
954     beq         mbvskip_filter               ; skip filtering
955
956
957     ;vp8_hevmask() function
958     ;calculate high edge variance
959
960     sub         src, src, pstep, lsl #2     ; move src pointer down by 4 lines
961
962     orr         r9, r9, r10
963
964     ldrh        r7, [src, #-2]
965     ldrh        r8, [src], pstep
966
967     usub8       r9, r12, r9
968     sel         r6, r12, r11                ; hev mask: r6
969
970
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
975     ldrh        r9, [src, #-2]
976     ldrh        r10, [src], pstep
977
978     pkhbt       r12, r7, r8, lsl #16
979
980     ldrh        r7, [src, #-2]
981     ldrh        r8, [src], pstep
982
983     pkhbt       r11, r9, r10, lsl #16
984
985     ldrh        r9, [src, #-2]
986     ldrh        r10, [src], pstep
987
988     str         r6, [sp]                    ; save r6
989     str         lr, [sp, #4]                ; save lr
990
991     pkhbt       r6, r7, r8, lsl #16
992     pkhbt       lr, r9, r10, lsl #16
993
994     ;transpose r12, r11, r6, lr to p1, p0, q0, q1
995     TRANSPOSE_MATRIX r12, r11, r6, lr, r7, r8, r9, r10
996
997     ;load back hev_mask r6 and filter_mask lr
998     ldr         r12, c0x80808080
999     ldr         r6, [sp]
1000     ldr         lr, [sp, #4]
1001
1002     eor         r7, r7, r12                 ; ps1
1003     eor         r8, r8, r12                 ; ps0
1004     eor         r9, r9, r12                 ; qs0
1005     eor         r10, r10, r12               ; qs1
1006
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
1011     qadd8       r7, r7, r12
1012     str         r9, [sp]                    ; store qs0 temporarily
1013     qadd8       r7, r7, r12
1014     str         r8, [sp, #4]                ; store ps0 temporarily
1015     qadd8       r7, r7, r12                 ; vp8_filter: r7
1016
1017     ldr         r10, c0x03030303            ; r10 = 3 --modified for vp8
1018     ldr         r9, c0x04040404
1019     ;mvn         r11, #0                     ; r11 == -1
1020
1021     and         r7, r7, lr                  ; vp8_filter &= mask (lr is free)
1022
1023     mov         r12, r7                     ; Filter2: r12
1024     and         r12, r12, r6                ; Filter2 &= hev
1025
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)
1030
1031     mov         r10, #0
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
1038
1039     ldr         r9, [sp]                    ; load qs0
1040     ldr         r11, [sp, #4]               ; load ps0
1041
1042     qsub8       r9 , r9, r8                 ; qs0 = vp8_signed_char_clamp(qs0 - Filter1)
1043     qadd8       r11, r11, r12               ; ps0 = vp8_signed_char_clamp(ps0 + Filter2)
1044
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)
1048     ;mov            r10, #0
1049     ;shadd8     r12 , r12 , r10             ; Filter2 >>= 3
1050     ;usub8      lr, r8, r9                  ; s = (s==4)*-1
1051     ;sel            lr, r11, r10
1052     ;shadd8     r12 , r12 , r10
1053     ;usub8      r8, r9, r8
1054     ;sel            r8, r11, 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)
1062
1063     ;end of modification for vp8
1064
1065     bic         r12, r7, r6                 ;vp8_filter &= ~hev    ( r6 is free)
1066     ;mov            r12, r7
1067
1068     ;roughly 3/7th difference across boundary
1069     mov         lr, #0x1b                   ; 27
1070     mov         r7, #0x3f                   ; 63
1071
1072     sxtb16      r6, r12
1073     sxtb16      r10, r12, ror #8
1074     smlabb      r8, r6, lr, r7
1075     smlatb      r6, r6, lr, r7
1076     smlabb      r7, r10, lr, r7
1077     smultb      r10, r10, lr
1078     ssat        r8, #8, r8, asr #7
1079     ssat        r6, #8, r6, asr #7
1080     add         r10, r10, #63
1081     ssat        r7, #8, r7, asr #7
1082     ssat        r10, #8, r10, asr #7
1083
1084     ldr         lr, c0x80808080
1085
1086     pkhbt       r6, r8, r6, lsl #16
1087     pkhbt       r10, r7, r10, lsl #16
1088     uxtb16      r6, r6
1089     uxtb16      r10, r10
1090
1091     sub         src, src, pstep, lsl #2     ; move src pointer down by 4 lines
1092
1093     orr         r10, r6, r10, lsl #8        ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7)
1094
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
1099
1100     strb        r10, [src, #-1]             ; store op0 result
1101     strb        r8, [src], pstep            ; store oq0 result
1102     mov         r10, r10, lsr #8
1103     mov         r8, r8, lsr #8
1104     strb        r10, [src, #-1]
1105     strb        r8, [src], pstep
1106     mov         r10, r10, lsr #8
1107     mov         r8, r8, lsr #8
1108     strb        r10, [src, #-1]
1109     strb        r8, [src], pstep
1110     mov         r10, r10, lsr #8
1111     mov         r8, r8, lsr #8
1112     strb        r10, [src, #-1]
1113     strb        r8, [src], pstep
1114
1115     ;roughly 2/7th difference across boundary
1116     mov         lr, #0x12                   ; 18
1117     mov         r7, #0x3f                   ; 63
1118
1119     sxtb16      r6, r12
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
1129
1130     sub         src, src, pstep, lsl #2     ; move src pointer down by 4 lines
1131
1132     pkhbt       r6, r8, r6, lsl #16
1133     pkhbt       r10, r9, r10, lsl #16
1134
1135     ldr         r9, [sp, #8]                ; load qs1
1136     ldr         r11, [sp, #12]              ; load ps1
1137     ldr         lr, c0x80808080
1138
1139     uxtb16      r6, r6
1140     uxtb16      r10, r10
1141
1142     add         src, src, #2
1143
1144     orr         r10, r6, r10, lsl #8        ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7)
1145
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
1150
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
1155
1156     mov         r10, r10, lsr #8
1157     mov         r8, r8, lsr #8
1158
1159     ldrb        r6, [src, #-5]
1160     strb        r10, [src, #-4]
1161     strb        r8, [src, #-1]
1162     ldrb        r7, [src], pstep
1163
1164     mov         r10, r10, lsr #8
1165     mov         r8, r8, lsr #8
1166     orr         r11, r11, r6, lsl #8
1167     orr         r9, r9, r7, lsl #8
1168
1169     ldrb        r6, [src, #-5]
1170     strb        r10, [src, #-4]
1171     strb        r8, [src, #-1]
1172     ldrb        r7, [src], pstep
1173
1174     mov         r10, r10, lsr #8
1175     mov         r8, r8, lsr #8
1176     orr         r11, r11, r6, lsl #16
1177     orr         r9, r9, r7, lsl #16
1178
1179     ldrb        r6, [src, #-5]
1180     strb        r10, [src, #-4]
1181     strb        r8, [src, #-1]
1182     ldrb        r7, [src], pstep
1183     orr         r11, r11, r6, lsl #24
1184     orr         r9, r9, r7, lsl #24
1185
1186     ;roughly 1/7th difference across boundary
1187     eor         r9, r9, lr
1188     eor         r11, r11, lr
1189
1190     mov         lr, #0x9                    ; 9
1191     mov         r7, #0x3f                   ; 63
1192
1193     sxtb16      r6, r12
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
1203
1204     sub         src, src, pstep, lsl #2
1205
1206     pkhbt       r6, r8, r6, lsl #16
1207     pkhbt       r10, r12, r10, lsl #16
1208
1209     uxtb16      r6, r6
1210     uxtb16      r10, r10
1211
1212     ldr         lr, c0x80808080
1213
1214     orr         r10, r6, r10, lsl #8        ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7)
1215
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
1220
1221     strb        r8, [src, #-5]              ; store *op2
1222     strb        r10, [src], pstep           ; store *oq2
1223     mov         r8, r8, lsr #8
1224     mov         r10, r10, lsr #8
1225     strb        r8, [src, #-5]
1226     strb        r10, [src], pstep
1227     mov         r8, r8, lsr #8
1228     mov         r10, r10, lsr #8
1229     strb        r8, [src, #-5]
1230     strb        r10, [src], pstep
1231     mov         r8, r8, lsr #8
1232     mov         r10, r10, lsr #8
1233     strb        r8, [src, #-5]
1234     strb        r10, [src], pstep
1235
1236     ;adjust src pointer for next loop
1237     sub         src, src, #2
1238
1239 |mbvskip_filter|
1240     sub         src, src, #4
1241     subs        count, count, #1
1242
1243     pld         [src, #23]                  ; preload for next block
1244     ldrne       r6, [src], pstep            ; load source data
1245     pld         [src, #23]
1246     ldrne       r7, [src], pstep
1247     pld         [src, #23]
1248     ldrne       r8, [src], pstep
1249     pld         [src, #23]
1250     ldrne       lr, [src], pstep
1251
1252     bne         MBVnext8
1253
1254     add         sp, sp, #16
1255
1256     ldmia       sp!, {r4 - r11, pc}
1257     ENDP        ; |vp8_mbloop_filter_vertical_edge_armv6|
1258
1259 ; Constant Pool
1260 c0x80808080 DCD     0x80808080
1261 c0x03030303 DCD     0x03030303
1262 c0x04040404 DCD     0x04040404
1263 c0x01010101 DCD     0x01010101
1264 c0x7F7F7F7F DCD     0x7F7F7F7F
1265
1266     END