Browse code

VP8: armv6 optimizations.

From 52.503s (~40fps) to 27.973sec (~80fps) decoding of 480p sintel
trailer, i.e. a ~2x speedup overall, on a Nexus S.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Ronald S. Bultje authored on 2011/08/25 05:58:37
Showing 5 changed files
... ...
@@ -11,7 +11,8 @@ ARMV6-OBJS-$(CONFIG_MPEGAUDIODSP)      += arm/mpegaudiodsp_fixed_armv6.o
11 11
 OBJS-$(CONFIG_VP5_DECODER)             += arm/vp56dsp_init_arm.o
12 12
 OBJS-$(CONFIG_VP6_DECODER)             += arm/vp56dsp_init_arm.o
13 13
 OBJS-$(CONFIG_VP8_DECODER)             += arm/vp8dsp_init_arm.o
14
-ARMV6-OBJS-$(CONFIG_VP8_DECODER)       += arm/vp8_armv6.o
14
+ARMV6-OBJS-$(CONFIG_VP8_DECODER)       += arm/vp8_armv6.o               \
15
+                                          arm/vp8dsp_armv6.o
15 16
 
16 17
 OBJS-$(CONFIG_H264DSP)                 += arm/h264dsp_init_arm.o
17 18
 OBJS-$(CONFIG_H264PRED)                += arm/h264pred_init_arm.o
... ...
@@ -97,6 +97,12 @@ T       add             \rn, \rn, \rm
97 97
 T       ldr             \rt, [\rn]
98 98
 .endm
99 99
 
100
+.macro  ldr_dpren       rt,  rn,  rm:vararg
101
+A       ldr             \rt, [\rn, -\rm]
102
+T       sub             \rt, \rn, \rm
103
+T       ldr             \rt, [\rt]
104
+.endm
105
+
100 106
 .macro  ldr_post        rt,  rn,  rm:vararg
101 107
 A       ldr             \rt, [\rn], \rm
102 108
 T       ldr             \rt, [\rn]
... ...
@@ -133,6 +139,12 @@ T       ldrh            \rt, [\rn]
133 133
 T       add             \rn, \rn, \rm
134 134
 .endm
135 135
 
136
+.macro  ldrb_post       rt,  rn,  rm
137
+A       ldrb            \rt, [\rn], \rm
138
+T       ldrb            \rt, [\rn]
139
+T       add             \rn, \rn, \rm
140
+.endm
141
+
136 142
 .macro  str_post       rt,  rn,  rm:vararg
137 143
 A       str             \rt, [\rn], \rm
138 144
 T       str             \rt, [\rn]
139 145
new file mode 100644
... ...
@@ -0,0 +1,2328 @@
0
+/**
1
+ * VP8 ARMv6 optimisations
2
+ *
3
+ * Copyright (c) 2011 The WebM project authors. All Rights Reserved.
4
+ * Copyright (c) 2010 Rob Clark <rob@ti.com>
5
+ * Copyright (c) 2011 Mans Rullgard <mans@mansr.com>
6
+ *
7
+ * This file is part of Libav.
8
+ *
9
+ * Libav is free software; you can redistribute it and/or
10
+ * modify it under the terms of the GNU Lesser General Public
11
+ * License as published by the Free Software Foundation; either
12
+ * version 2.1 of the License, or (at your option) any later version.
13
+ *
14
+ * Libav is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
+ * Lesser General Public License for more details.
18
+ *
19
+ * You should have received a copy of the GNU Lesser General Public
20
+ * License along with Libav; if not, write to the Free Software
21
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
+ *
23
+ * This code was partially ported from libvpx, which uses this license:
24
+ *
25
+ * Use of this source code is governed by a BSD-style license
26
+ * that can be found in the LICENSE file in the root of the source
27
+ * tree. An additional intellectual property rights grant can be found
28
+ * in the file PATENTS.  All contributing project authors may
29
+ * be found in the AUTHORS file in the root of the source tree.
30
+ *
31
+ * (Note that the "LICENSE", "AUTHORS" and "PATENTS" files can be
32
+ *  found in the libvpx source tree.)
33
+ */
34
+
35
+#include "asm.S"
36
+
37
+@ idct
38
+
39
+@ void vp8_luma_dc_wht(DCTELEM block[4][4][16], DCTELEM dc[16])
40
+function ff_vp8_luma_dc_wht_armv6, export=1
41
+        push           {r4 - r10, lr}
42
+
43
+        @ load dc[] and zero memory
44
+        mov             r12, #0
45
+        ldr             r2, [r1]                @ dc0[0,1]
46
+        ldr             r3, [r1,  #4]           @ dc0[2,3]
47
+        ldr             r4, [r1,  #8]           @ dc1[0,1]
48
+        ldr             r5, [r1,  #12]          @ dc1[2,3]
49
+        ldr             r6, [r1,  #16]          @ dc2[0,1]
50
+        ldr             r7, [r1,  #20]          @ dc2[2,3]
51
+        ldr             r8, [r1,  #24]          @ dc3[0,1]
52
+        ldr             r9, [r1,  #28]          @ dc3[2,3]
53
+        str             r12,[r1]
54
+        str             r12,[r1,  #4]
55
+        str             r12,[r1,  #8]
56
+        str             r12,[r1,  #12]
57
+        str             r12,[r1,  #16]
58
+        str             r12,[r1,  #20]
59
+        str             r12,[r1,  #24]
60
+        str             r12,[r1,  #28]
61
+
62
+        @ loop1
63
+        uadd16          r12, r2,  r8            @ t0[0,1]
64
+        uadd16          r14, r3,  r9            @ t0[2,3]
65
+        usub16          r2,  r2,  r8            @ t3[0,1]
66
+        usub16          r3,  r3,  r9            @ t3[2,3]
67
+        uadd16          r8,  r4,  r6            @ t1[0,1]
68
+        uadd16          r9,  r5,  r7            @ t1[2,3]
69
+        usub16          r4,  r4,  r6            @ t2[0,1]
70
+        usub16          r5,  r5,  r7            @ t2[2,3]
71
+
72
+        uadd16          r6,  r12, r8            @ dc0[0,1]
73
+        uadd16          r7,  r14, r9            @ dc0[2,3]
74
+        usub16          r12, r12, r8            @ dc2[0,1]
75
+        usub16          r14, r14, r9            @ dc2[2,3]
76
+        uadd16          r8,  r2,  r4            @ dc1[0,1]
77
+        uadd16          r9,  r3,  r5            @ dc1[2,3]
78
+        usub16          r2,  r2,  r4            @ dc3[0,1]
79
+        usub16          r3,  r3,  r5            @ dc3[2,3]
80
+
81
+        mov             r1,  #3
82
+        orr             r1,  r1,  #0x30000      @ 3 | 3 (round)
83
+
84
+        @ "transpose"
85
+        pkhbt           r4,  r6,  r8,  lsl #16  @ dc{0,1}[0]
86
+        pkhtb           r6,  r8,  r6,  asr #16  @ dc{0,1}[1]
87
+        pkhbt           r5,  r12, r2,  lsl #16  @ dc{2,3}[0]
88
+        pkhtb           r12, r2,  r12, asr #16  @ dc{2,3}[1]
89
+        pkhbt           r8,  r7,  r9,  lsl #16  @ dc{0,1}[2]
90
+        uadd16          r4,  r4,  r1
91
+        uadd16          r5,  r5,  r1
92
+        pkhtb           r7,  r9,  r7,  asr #16  @ dc{0,1}[3]
93
+        pkhbt           r2,  r14, r3,  lsl #16  @ dc{2,3}[2]
94
+        pkhtb           r14, r3,  r14, asr #16  @ dc{2,3}[3]
95
+
96
+        @ loop2
97
+        uadd16          r9,  r4,  r7            @ t0[0,1]
98
+        uadd16          r3,  r5,  r14           @ t0[2,3]
99
+        usub16          r4,  r4,  r7            @ t3[0,1]
100
+        usub16          r5,  r5,  r14           @ t3[2,3]
101
+        uadd16          r7,  r6,  r8            @ t1[0,1]
102
+        uadd16          r14, r12, r2            @ t1[2,3]
103
+        usub16          r6,  r6,  r8            @ t2[0,1]
104
+        usub16          r12, r12, r2            @ t2[2,3]
105
+
106
+        uadd16          r8,  r9,  r7            @ block[0,1][0]
107
+        uadd16          r2,  r3,  r14           @ block[2,3][0]
108
+        usub16          r9,  r9,  r7            @ block[0,1][2]
109
+        usub16          r3,  r3,  r14           @ block[2,3][2]
110
+        uadd16          r7,  r4,  r6            @ block[0,1][1]
111
+        uadd16          r14, r5,  r12           @ block[2,3][1]
112
+        usub16          r4,  r4,  r6            @ block[0,1][3]
113
+        usub16          r5,  r5,  r12           @ block[2,3][3]
114
+
115
+        @ store
116
+        mov             r6,  r8,  asr #19       @ block[1][0]
117
+        mov             r12, r7,  asr #19       @ block[1][1]
118
+        mov             r1,  r9,  asr #19       @ block[1][2]
119
+        mov             r10, r4,  asr #19       @ block[1][3]
120
+        sxth            r8,  r8
121
+        sxth            r7,  r7
122
+        sxth            r9,  r9
123
+        sxth            r4,  r4
124
+        asr             r8,  #3                 @ block[0][0]
125
+        asr             r7,  #3                 @ block[0][1]
126
+        asr             r9,  #3                 @ block[0][2]
127
+        asr             r4,  #3                 @ block[0][3]
128
+
129
+        strh            r8, [r0], #32
130
+        strh            r7, [r0], #32
131
+        strh            r9, [r0], #32
132
+        strh            r4, [r0], #32
133
+        strh            r6, [r0], #32
134
+        strh            r12,[r0], #32
135
+        strh            r1, [r0], #32
136
+        strh            r10,[r0], #32
137
+
138
+        mov             r6,  r2,  asr #19       @ block[3][0]
139
+        mov             r12, r14, asr #19       @ block[3][1]
140
+        mov             r1,  r3,  asr #19       @ block[3][2]
141
+        mov             r10, r5,  asr #19       @ block[3][3]
142
+        sxth            r2,  r2
143
+        sxth            r14, r14
144
+        sxth            r3,  r3
145
+        sxth            r5,  r5
146
+        asr             r2,  #3                 @ block[2][0]
147
+        asr             r14, #3                 @ block[2][1]
148
+        asr             r3,  #3                 @ block[2][2]
149
+        asr             r5,  #3                 @ block[2][3]
150
+
151
+        strh            r2, [r0], #32
152
+        strh            r14,[r0], #32
153
+        strh            r3, [r0], #32
154
+        strh            r5, [r0], #32
155
+        strh            r6, [r0], #32
156
+        strh            r12,[r0], #32
157
+        strh            r1, [r0], #32
158
+        strh            r10,[r0], #32
159
+
160
+        pop            {r4 - r10, pc}
161
+endfunc
162
+
163
+@ void vp8_luma_dc_wht_dc(DCTELEM block[4][4][16], DCTELEM dc[16])
164
+function ff_vp8_luma_dc_wht_dc_armv6, export=1
165
+        ldrsh           r2, [r1]
166
+        mov             r3,  #0
167
+        add             r2,  r2,  #3
168
+        strh            r3, [r1]
169
+        asr             r2,  r2,  #3
170
+    .rept 16
171
+        strh            r2, [r0], #32
172
+    .endr
173
+        bx              lr
174
+endfunc
175
+
176
+@ void vp8_idct_add(uint8_t *dst, DCTELEM block[16], int stride)
177
+function ff_vp8_idct_add_armv6, export=1
178
+        push           {r4 - r11, lr}
179
+        sub             sp,  sp,  #32
180
+
181
+        mov             r3,  #0x00004E00        @ cos
182
+        orr             r3,  r3, #0x0000007B    @ cospi8sqrt2minus1 = 20091
183
+        mov             r4,  #0x00008A00        @ sin
184
+        orr             r4,  r4, #0x0000008C    @ sinpi8sqrt2 = 35468
185
+        mov             r5,  #0x2               @ i=2
186
+1:
187
+        ldr             r6, [r1, #8]            @  i5 | i4  = block1[1] | block1[0]
188
+        ldr             r12,[r1, #24]           @ i13 | i12 = block3[1] | block3[0]
189
+        ldr             r14,[r1, #16]           @  i9 | i8  = block2[1] | block2[0]
190
+
191
+        smulwt          r9,  r3,  r6            @ (ip[5] * cospi8sqrt2minus1) >> 16
192
+        smulwb          r7,  r3,  r6            @ (ip[4] * cospi8sqrt2minus1) >> 16
193
+        smulwt          r10, r4,  r6            @ (ip[5] * sinpi8sqrt2) >> 16
194
+        smulwb          r8,  r4,  r6            @ (ip[4] * sinpi8sqrt2) >> 16
195
+        pkhbt           r7,  r7,  r9,  lsl #16  @ 5c | 4c
196
+        smulwt          r11, r3,  r12           @ (ip[13] * cospi8sqrt2minus1) >> 16
197
+        pkhbt           r8,  r8,  r10, lsl #16  @ 5s | 4s         = t2 first half
198
+        uadd16          r6,  r6,  r7            @ 5c+5 | 4c+4     = t3 first half
199
+        smulwt          r7,  r4,  r12           @ (ip[13] * sinpi8sqrt2) >> 16
200
+        smulwb          r9,  r3,  r12           @ (ip[12] * cospi8sqrt2minus1) >> 16
201
+        smulwb          r10, r4,  r12           @ (ip[12] * sinpi8sqrt2) >> 16
202
+
203
+        subs            r5,  r5,  #1            @ i--
204
+        pkhbt           r9,  r9,  r11, lsl #16  @ 13c | 12c
205
+        ldr             r11,[r1]                @  i1 | i0
206
+        pkhbt           r10, r10, r7,  lsl #16  @ 13s | 12s       = t3 second half
207
+        uadd16          r7,  r12, r9            @ 13c+13 | 12c+12 = t2 second half
208
+        usub16          r7,  r8,  r7            @ c = t2
209
+        uadd16          r6,  r6,  r10           @ d = t3
210
+        uadd16          r10, r11, r14           @ a = t0
211
+        usub16          r8,  r11, r14           @ b = t1
212
+        uadd16          r9,  r10, r6            @ a+d = tmp{0,1}[0]
213
+        usub16          r10, r10, r6            @ a-d = tmp{0,1}[3]
214
+        uadd16          r6,  r8,  r7            @ b+c = tmp{0,1}[1]
215
+        usub16          r7,  r8,  r7            @ b-c = tmp{0,1}[2]
216
+        mov             r8,  #0
217
+        str             r6, [sp,  #8]           @  o5 | o4
218
+        str             r7, [sp,  #16]          @  o9 | o8
219
+        str             r10,[sp,  #24]          @ o13 | o12
220
+        str             r9, [sp], #4            @  o1 | o0
221
+        str             r8, [r1,  #24]
222
+        str             r8, [r1,  #16]
223
+        str             r8, [r1,  #8]
224
+        str             r8, [r1], #4
225
+        bne             1b
226
+
227
+        mov             r5,  #0x2               @ i=2
228
+        sub             sp,  sp, #8
229
+2:
230
+        ldr             r6, [sp,  #8]           @ i5 | i4 = tmp{0,1}[1]
231
+        ldr             r14,[sp,  #4]           @ i3 | i2 = tmp{2,3}[0]
232
+        ldr             r12,[sp,  #12]          @ i7 | i6 = tmp{2,3}[1]
233
+        ldr             r1, [sp], #16           @ i1 | i0 = tmp{0,1}[0]
234
+        smulwt          r9,  r3,  r6            @ (ip[5] * cospi8sqrt2minus1) >> 16
235
+        smulwt          r7,  r3,  r1            @ (ip[1] * cospi8sqrt2minus1) >> 16
236
+        smulwt          r10, r4,  r6            @ (ip[5] * sinpi8sqrt2) >> 16
237
+        smulwt          r8,  r4,  r1            @ (ip[1] * sinpi8sqrt2) >> 16
238
+        pkhbt           r11, r1,  r6,  lsl #16  @ i4 | i0 = t0/t1 first half
239
+        pkhbt           r7,  r7,  r9,  lsl #16  @ 5c | 1c
240
+        pkhbt           r8,  r8,  r10, lsl #16  @ 5s | 1s = temp1 = t2 first half
241
+        pkhtb           r1,  r6,  r1,  asr #16  @ i5 | i1
242
+        uadd16          r1,  r7,  r1            @ 5c+5 | 1c+1 = temp2 (d) = t3 first half
243
+        pkhbt           r9,  r14, r12, lsl #16  @ i6 | i2 = t0/t1 second half
244
+        uadd16          r10, r11, r9            @ a = t0
245
+        usub16          r9,  r11, r9            @ b = t1
246
+        pkhtb           r6,  r12, r14, asr #16  @ i7 | i3
247
+        subs            r5,  r5,  #0x1          @ i--
248
+        smulwt          r7,  r3,  r6            @ (ip[7] * cospi8sqrt2minus1) >> 16
249
+        smulwt          r11, r4,  r6            @ (ip[7] * sinpi8sqrt2) >> 16
250
+        smulwb          r12, r3,  r6            @ (ip[3] * cospi8sqrt2minus1) >> 16
251
+        smulwb          r14, r4,  r6            @ (ip[3] * sinpi8sqrt2) >> 16
252
+
253
+        pkhbt           r7,  r12, r7,  lsl #16  @ 7c | 3c
254
+        pkhbt           r11, r14, r11, lsl #16  @ 7s | 3s = temp1 (d) = t3 second half
255
+        mov             r14, #0x4               @ set up 4's
256
+        orr             r14, r14, #0x40000      @ 4|4
257
+        uadd16          r6,  r7,  r6            @ 7c+7 | 3c+3 = temp2 (c) = t2 second half
258
+        usub16          r12, r8,  r6            @ c (o5 | o1) = t2
259
+        uadd16          r6,  r11, r1            @ d (o7 | o3) = t3
260
+        uadd16          r10, r10, r14           @ t0 + 4
261
+        uadd16          r9,  r9,  r14           @ t1 + 4
262
+        uadd16          r7,  r10, r6            @ a+d = dst{0,1}[0]
263
+        usub16          r6,  r10, r6            @ a-d = dst{0,1}[3]
264
+        uadd16          r10, r9,  r12           @ b+c = dst{0,1}[1]
265
+        usub16          r1,  r9,  r12           @ b-c = dst{0,1}[2]
266
+
267
+        mov             r9,  r6,  asr #3        @ o[1][3]
268
+        mov             r12, r1,  asr #3        @ o[1][2]
269
+        pkhtb           r8,  r12, r7,  asr #19  @ o[1][0,2]
270
+        pkhtb           r11, r9,  r10, asr #19  @ o[1][1,3]
271
+        ldr             r12,[r0]
272
+        ldr             r9, [r0,  r2]
273
+        sxth            r7,  r7
274
+        sxth            r6,  r6
275
+        sxth            r10, r10
276
+        sxth            r1,  r1
277
+        asr             r7,  #3                 @ o[0][0]
278
+        asr             r10, #3                 @ o[0][1]
279
+        pkhbt           r7,  r7,  r1,  lsl #13  @ o[0][0,2]
280
+        pkhbt           r10, r10, r6,  lsl #13  @ o[0][1,3]
281
+
282
+        uxtab16         r7,  r7,  r12
283
+        uxtab16         r10, r10, r12, ror #8
284
+        uxtab16         r8,  r8,  r9
285
+        uxtab16         r11, r11, r9,  ror #8
286
+        usat16          r7,  #8,  r7
287
+        usat16          r10, #8,  r10
288
+        usat16          r8,  #8,  r8
289
+        usat16          r11, #8,  r11
290
+        orr             r7,  r7,  r10, lsl #8
291
+        orr             r8,  r8,  r11, lsl #8
292
+        str             r8, [r0,  r2]
293
+        str_post        r7,  r0,  r2,  lsl #1
294
+
295
+        bne             2b
296
+
297
+        pop            {r4 - r11, pc}
298
+endfunc
299
+
300
+@ void vp8_idct_dc_add(uint8_t *dst, DCTELEM block[16], int stride)
301
+function ff_vp8_idct_dc_add_armv6, export=1
302
+        push           {r4 - r5,  lr}
303
+        ldrsh           r3, [r1]
304
+        mov             r4,  #0
305
+        add             r3,  r3,  #4
306
+        asr             r3,  #3
307
+        strh            r4, [r1], #32
308
+        ldr             r4, [r0,  r2]
309
+        ldr_post        r5,  r0,  r2,  lsl #1
310
+        pkhbt           r3,  r3,  r3,  lsl #16
311
+
312
+        uxtab16         lr,  r3,  r5            @ a1+2 | a1+0
313
+        uxtab16         r5,  r3,  r5,  ror #8   @ a1+3 | a1+1
314
+        uxtab16         r12, r3,  r4
315
+        uxtab16         r4,  r3,  r4,  ror #8
316
+        usat16          lr,  #8,  lr
317
+        usat16          r5,  #8,  r5
318
+        usat16          r12, #8,  r12
319
+        usat16          r4,  #8,  r4
320
+        orr             lr,  lr,  r5,  lsl #8
321
+        orr             r12, r12, r4,  lsl #8
322
+        ldr             r5, [r0]
323
+        ldr             r4, [r0,  r2]
324
+        sub             r0,  r0,  r2,  lsl #1
325
+        str             r12,[r0,  r2]
326
+        str_post        lr,  r0,  r2,  lsl #1
327
+
328
+        uxtab16         lr,  r3,  r5
329
+        uxtab16         r5,  r3,  r5,  ror #8
330
+        uxtab16         r12, r3,  r4
331
+        uxtab16         r4,  r3,  r4,  ror #8
332
+        usat16          lr,  #8,  lr
333
+        usat16          r5,  #8,  r5
334
+        usat16          r12, #8,  r12
335
+        usat16          r4,  #8,  r4
336
+        orr             lr,  lr,  r5,  lsl #8
337
+        orr             r12, r12, r4,  lsl #8
338
+
339
+        str             r12,[r0,  r2]
340
+        str_post        lr,  r0,  r2,  lsl #1
341
+
342
+        pop            {r4 - r5,  pc}
343
+endfunc
344
+
345
+@ void vp8_idct_dc_add4uv(uint8_t *dst, DCTELEM block[4][16], int stride)
346
+function ff_vp8_idct_dc_add4uv_armv6, export=1
347
+        push           {lr}
348
+
349
+        bl              ff_vp8_idct_dc_add_armv6
350
+        sub             r0,  r0,  r2,  lsl #2
351
+        add             r0,  r0,  #4
352
+        bl              ff_vp8_idct_dc_add_armv6
353
+        sub             r0,  r0,  #4
354
+        bl              ff_vp8_idct_dc_add_armv6
355
+        sub             r0,  r0,  r2,  lsl #2
356
+        add             r0,  r0,  #4
357
+        bl              ff_vp8_idct_dc_add_armv6
358
+
359
+        pop            {pc}
360
+endfunc
361
+
362
+@ void vp8_idct_dc_add4y(uint8_t *dst, DCTELEM block[4][16], int stride)
363
+function ff_vp8_idct_dc_add4y_armv6, export=1
364
+        push           {lr}
365
+
366
+        bl              ff_vp8_idct_dc_add_armv6
367
+        sub             r0,  r0,  r2,  lsl #2
368
+        add             r0,  r0,  #4
369
+        bl              ff_vp8_idct_dc_add_armv6
370
+        sub             r0,  r0,  r2,  lsl #2
371
+        add             r0,  r0,  #4
372
+        bl              ff_vp8_idct_dc_add_armv6
373
+        sub             r0,  r0,  r2,  lsl #2
374
+        add             r0,  r0,  #4
375
+        bl              ff_vp8_idct_dc_add_armv6
376
+
377
+        pop            {pc}
378
+endfunc
379
+
380
+@ loopfilter
381
+
382
+@ void vp8_v_loop_filter16_simple(uint8_t *dst, int stride, int flim)
383
+function ff_vp8_v_loop_filter16_simple_armv6, export=1
384
+        push           {r4 - r11, lr}
385
+
386
+        ldr_dpren       r3,  r0,  r1,  lsl #1   @ p1
387
+        ldr_dpren       r4,  r0,  r1            @ p0
388
+        ldr             r5, [r0]                @ q0
389
+        ldr             r6, [r0,  r1]           @ q1
390
+        orr             r2,  r2,  r2,  lsl #16
391
+        mov             r9,  #4                 @ count
392
+        mov             lr,  #0                 @ need 0 in a couple places
393
+        orr             r12, r2,  r2,  lsl #8   @ splat int -> byte
394
+        ldr             r2,  c0x80808080
395
+
396
+1:
397
+        @ vp8_simple_filter_mask()
398
+        uqsub8          r7,  r3,  r6            @ p1 - q1
399
+        uqsub8          r8,  r6,  r3            @ q1 - p1
400
+        uqsub8          r10, r4,  r5            @ p0 - q0
401
+        uqsub8          r11, r5,  r4            @ q0 - p0
402
+        orr             r8,  r8,  r7            @ abs(p1 - q1)
403
+        orr             r10, r10, r11           @ abs(p0 - q0)
404
+        uqadd8          r10, r10, r10           @ abs(p0 - q0) * 2
405
+        uhadd8          r8,  r8,  lr            @ abs(p1 - q2) >> 1
406
+        uqadd8          r10, r10, r8            @ abs(p0 - q0)*2 + abs(p1 - q1)/2
407
+        mvn             r8,  #0
408
+        usub8           r10, r12, r10           @ compare to flimit. usub8 sets GE flags
409
+        sel             r10, r8,  lr            @ filter mask: F or 0
410
+        cmp             r10, #0
411
+        beq             2f                      @ skip filtering if all masks are 0x00
412
+
413
+        @ vp8_simple_filter()
414
+        eor             r3,  r3,  r2            @ p1 offset to convert to a signed value
415
+        eor             r6,  r6,  r2            @ q1 offset to convert to a signed value
416
+        eor             r4,  r4,  r2            @ p0 offset to convert to a signed value
417
+        eor             r5,  r5,  r2            @ q0 offset to convert to a signed value
418
+
419
+        qsub8           r3,  r3,  r6            @ vp8_filter = p1 - q1
420
+        qsub8           r6,  r5,  r4            @ q0 - p0
421
+        qadd8           r3,  r3,  r6            @ += q0 - p0
422
+        ldr             r7,  c0x04040404
423
+        qadd8           r3,  r3,  r6            @ += q0 - p0
424
+        ldr             r8,  c0x03030303
425
+        qadd8           r3,  r3,  r6            @ vp8_filter = p1-q1 + 3*(q0-p0))
426
+        @STALL
427
+        and             r3,  r3,  r10           @ vp8_filter &= mask
428
+
429
+        qadd8           r7,  r3,  r7            @ Filter1 = vp8_filter + 4
430
+        qadd8           r8,  r3,  r8            @ Filter2 = vp8_filter + 3
431
+
432
+        shadd8          r7,  r7,  lr
433
+        shadd8          r8,  r8,  lr
434
+        shadd8          r7,  r7,  lr
435
+        shadd8          r8,  r8,  lr
436
+        shadd8          r7,  r7,  lr            @ Filter1 >>= 3
437
+        shadd8          r8,  r8,  lr            @ Filter2 >>= 3
438
+
439
+        qsub8           r5,  r5,  r7            @ u = q0 - Filter1
440
+        qadd8           r4,  r4,  r8            @ u = p0 + Filter2
441
+        eor             r5,  r5,  r2            @ *oq0 = u^0x80
442
+        eor             r4,  r4,  r2            @ *op0 = u^0x80
443
+T       sub             r7,  r0,  r1
444
+        str             r5, [r0]                @ store oq0 result
445
+A       str             r4, [r0, -r1]           @ store op0 result
446
+T       str             r4, [r7]
447
+
448
+2:
449
+        subs            r9,  r9,  #1            @ counter--
450
+        add             r0,  r0,  #4            @ next row
451
+T       itttt           ne
452
+A       ldrne           r3, [r0, -r1,  lsl #1]  @ p1
453
+T       subne           r3,  r0,  r1,  lsl #1
454
+T       ldrne           r3, [r3]                @ p1
455
+A       ldrne           r4, [r0, -r1]           @ p0
456
+T       subne           r4,  r0,  r1
457
+T       ldrne           r4, [r4]                @ p0
458
+T       itt             ne
459
+        ldrne           r5, [r0]                @ q0
460
+        ldrne           r6, [r0,  r1]           @ q1
461
+
462
+        bne             1b
463
+
464
+        pop            {r4 - r11, pc}
465
+endfunc
466
+
467
+c0x01010101: .long 0x01010101
468
+c0x03030303: .long 0x03030303
469
+c0x04040404: .long 0x04040404
470
+c0x7F7F7F7F: .long 0x7F7F7F7F
471
+c0x80808080: .long 0x80808080
472
+
473
+@ void vp8_v_loop_filter16_inner(uint8_t *dst, int stride,
474
+@                                int fE, int fI, int hev_thresh)
475
+@ and
476
+@ void vp8_v_loop_filter8uv_inner(uint8_t *dstU, uint8_t *dstV, int stride,
477
+@                                 int fE, int fI, int hev_thresh)
478
+@ call:
479
+@ void vp8_v_loop_filter_inner(uint8_t *dst, int stride,
480
+@                              int fE, int fI, int hev_thresh, int count)
481
+function ff_vp8_v_loop_filter_inner_armv6, export=1
482
+        push           {r4 - r11, lr}
483
+
484
+        sub             r0,  r0,  r1,  lsl #2   @ move r0 pointer down by 4 lines
485
+        ldr             r5, [sp,  #40]          @ counter
486
+        ldr             r6, [sp,  #36]          @ load thresh address
487
+        sub             sp,  sp,  #16           @ create temp buffer
488
+
489
+        ldr             r10,[r0,  r1]           @ p2
490
+        ldr_post        r9,  r0,  r1,  lsl #1   @ p3
491
+        ldr             r12,[r0,  r1]           @ p0
492
+        ldr_post        r11, r0,  r1,  lsl #1   @ p1
493
+
494
+        orr             r2,  r2,  r2,  lsl #16
495
+        orr             r3,  r3,  r3,  lsl #16
496
+        orr             r6,  r6,  r6,  lsl #16
497
+        orr             r4,  r2,  r2,  lsl #8   @ flimE  splat int -> byte
498
+        orr             r2,  r3,  r3,  lsl #8   @ flimI  splat int -> byte
499
+        orr             r3,  r6,  r6,  lsl #8   @ thresh splat int -> byte
500
+
501
+1:
502
+        @ vp8_filter_mask() function
503
+        @ calculate breakout conditions
504
+        uqsub8          r6,  r9,  r10           @ p3 - p2
505
+        uqsub8          r7,  r10, r9            @ p2 - p3
506
+        uqsub8          r8,  r10, r11           @ p2 - p1
507
+        uqsub8          r10, r11, r10           @ p1 - p2
508
+
509
+        orr             r6,  r6,  r7            @ abs (p3-p2)
510
+        orr             r8,  r8,  r10           @ abs (p2-p1)
511
+        uqsub8          lr,  r6,  r2            @ compare to limit. lr: vp8_filter_mask
512
+        uqsub8          r8,  r8,  r2            @ compare to limit
513
+        uqsub8          r6,  r11, r12           @ p1 - p0
514
+        orr             lr,  lr,  r8
515
+        uqsub8          r7,  r12, r11           @ p0 - p1
516
+        ldr             r10,[r0,  r1]           @ q1
517
+        ldr_post        r9,  r0,  r1,  lsl #1   @ q0
518
+        orr             r6,  r6,  r7            @ abs (p1-p0)
519
+        uqsub8          r7,  r6,  r2            @ compare to limit
520
+        uqsub8          r8,  r6,  r3            @ compare to thresh  -- save r8 for later
521
+        orr             lr,  lr,  r7
522
+
523
+        uqsub8          r6,  r11, r10           @ p1 - q1
524
+        uqsub8          r7,  r10, r11           @ q1 - p1
525
+        uqsub8          r11, r12, r9            @ p0 - q0
526
+        uqsub8          r12, r9,  r12           @ q0 - p0
527
+        orr             r6,  r6,  r7            @ abs (p1-q1)
528
+        ldr             r7,  c0x7F7F7F7F
529
+        orr             r12, r11, r12           @ abs (p0-q0)
530
+        ldr_post        r11, r0,  r1            @ q2
531
+        uqadd8          r12, r12, r12           @ abs (p0-q0) * 2
532
+        and             r6,  r7,  r6,  lsr #1   @ abs (p1-q1) / 2
533
+        uqsub8          r7,  r9,  r10           @ q0 - q1
534
+        uqadd8          r12, r12, r6            @ abs (p0-q0)*2 + abs (p1-q1)/2
535
+        uqsub8          r6,  r10, r9            @ q1 - q0
536
+        uqsub8          r12, r12, r4            @ compare to flimit
537
+        uqsub8          r9,  r11, r10           @ q2 - q1
538
+
539
+        orr             lr, lr, r12
540
+
541
+        ldr_post        r12, r0,  r1            @ q3
542
+        uqsub8          r10, r10, r11           @ q1 - q2
543
+        orr             r6,  r7,  r6            @ abs (q1-q0)
544
+        orr             r10, r9,  r10           @ abs (q2-q1)
545
+        uqsub8          r7,  r6,  r2            @ compare to limit
546
+        uqsub8          r10, r10, r2            @ compare to limit
547
+        uqsub8          r6,  r6,  r3            @ compare to thresh -- save r6 for later
548
+        orr             lr,  lr,  r7
549
+        orr             lr,  lr,  r10
550
+
551
+        uqsub8          r10, r12, r11           @ q3 - q2
552
+        uqsub8          r9,  r11, r12           @ q2 - q3
553
+
554
+        mvn             r11, #0                 @ r11 == -1
555
+
556
+        orr             r10, r10, r9            @ abs (q3-q2)
557
+        uqsub8          r10, r10, r2            @ compare to limit
558
+
559
+        mov             r12, #0
560
+        orr             lr,  lr,  r10
561
+        sub             r0,  r0,  r1,  lsl #2
562
+
563
+        usub8           lr,  r12, lr            @ use usub8 instead of ssub8
564
+        sel             lr,  r11, r12           @ filter mask: lr
565
+
566
+        cmp             lr,  #0
567
+        beq             2f                      @ skip filtering
568
+
569
+        sub             r0,  r0,  r1,  lsl #1   @ move r0 pointer down by 6 lines
570
+
571
+        @vp8_hevmask() function
572
+        @calculate high edge variance
573
+        orr             r10, r6,  r8            @ calculate vp8_hevmask
574
+
575
+        usub8           r10, r12, r10           @ use usub8 instead of ssub8
576
+        sel             r6,  r12, r11           @ obtain vp8_hevmask: r6
577
+
578
+        @vp8_filter() function
579
+        ldr             r8, [r0,  r1]           @ p0
580
+        ldr_post        r7,  r0,  r1,  lsl #1   @ p1
581
+        ldr             r12, c0x80808080
582
+        ldr             r10,[r0,  r1]           @ q1
583
+        ldr_post        r9,  r0,  r1,  lsl #1   @ q0
584
+
585
+        eor             r7,  r7,  r12           @ p1 offset to convert to a signed value
586
+        eor             r8,  r8,  r12           @ p0 offset to convert to a signed value
587
+        eor             r9,  r9,  r12           @ q0 offset to convert to a signed value
588
+        eor             r10, r10, r12           @ q1 offset to convert to a signed value
589
+
590
+        str             r9, [sp]                @ store qs0 temporarily
591
+        str             r8, [sp,  #4]           @ store ps0 temporarily
592
+        str             r10,[sp,  #8]           @ store qs1 temporarily
593
+        str             r7, [sp,  #12]          @ store ps1 temporarily
594
+
595
+        qsub8           r7,  r7,  r10           @ vp8_signed_char_clamp(ps1-qs1)
596
+        qsub8           r8,  r9,  r8            @ vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
597
+
598
+        and             r7,  r7,  r6            @ vp8_filter (r7) &= hev
599
+
600
+        qadd8           r7,  r7,  r8
601
+        ldr             r9,  c0x03030303        @ r9 = 3 --modified for vp8
602
+
603
+        qadd8           r7,  r7,  r8
604
+        ldr             r10, c0x04040404
605
+
606
+        qadd8           r7,  r7,  r8
607
+        and             r7,  r7,  lr            @ vp8_filter &= mask@
608
+
609
+        qadd8           r8,  r7,  r9            @ Filter2 (r8) = vp8_signed_char_clamp(vp8_filter+3)
610
+        qadd8           r7,  r7,  r10           @ vp8_filter = vp8_signed_char_clamp(vp8_filter+4)
611
+
612
+        mov             r9,  #0
613
+        shadd8          r8,  r8,  r9            @ Filter2 >>= 3
614
+        shadd8          r7,  r7,  r9            @ vp8_filter >>= 3
615
+        shadd8          r8,  r8,  r9
616
+        shadd8          r7,  r7,  r9
617
+        shadd8          lr,  r8,  r9            @ lr: Filter2
618
+        shadd8          r7,  r7,  r9            @ r7: filter
619
+
620
+        @calculate output
621
+
622
+        ldr             r8, [sp]                @ load qs0
623
+        ldr             r9, [sp,  #4]           @ load ps0
624
+
625
+        ldr             r10, c0x01010101
626
+
627
+        qsub8           r8,  r8,  r7            @ u = vp8_signed_char_clamp(qs0 - vp8_filter)
628
+        qadd8           r9,  r9,  lr            @ u = vp8_signed_char_clamp(ps0 + Filter2)
629
+
630
+        mov             lr,  #0
631
+        sadd8           r7,  r7,  r10           @ vp8_filter += 1
632
+        shadd8          r7,  r7,  lr            @ vp8_filter >>= 1
633
+
634
+        ldr             r11,[sp,  #12]          @ load ps1
635
+        ldr             r10,[sp,  #8]           @ load qs1
636
+
637
+        bic             r7,  r7,  r6            @ vp8_filter &= ~hev
638
+        sub             r0,  r0,  r1,  lsl #2
639
+
640
+        qadd8           r11, r11, r7            @ u = vp8_signed_char_clamp(ps1 + vp8_filter)
641
+        qsub8           r10, r10, r7            @ u = vp8_signed_char_clamp(qs1 - vp8_filter)
642
+
643
+        eor             r11, r11, r12           @ *op1 = u^0x80
644
+        eor             r9,  r9,  r12           @ *op0 = u^0x80
645
+        eor             r8,  r8,  r12           @ *oq0 = u^0x80
646
+        eor             r10, r10, r12           @ *oq1 = u^0x80
647
+        str             r9, [r0,  r1]           @ store op0 result
648
+        str_post        r11, r0,  r1,  lsl #1   @ store op1
649
+        str             r10,[r0,  r1]           @ store oq1
650
+        str_post        r8,  r0,  r1,  lsl #1   @ store oq0 result
651
+
652
+        sub             r0,  r0,  r1,  lsl #1
653
+
654
+2:
655
+        add             r0,  r0,  #4
656
+        sub             r0,  r0,  r1,  lsl #2
657
+
658
+        subs            r5,  r5,  #1
659
+T       ittt            ne
660
+        ldrne           r10,[r0,  r1]           @ p2
661
+A       ldrne           r9, [r0], r1,  lsl #1   @ p3
662
+T       ldrne           r9, [r0]                @ p3
663
+T       addne           r0,  r0,  r1,  lsl #1
664
+T       ittt            ne
665
+        ldrne           r12,[r0,  r1]           @ p0
666
+A       ldrne           r11,[r0], r1,  lsl #1   @ p1
667
+T       ldrne           r11,[r0]                @ p3
668
+T       addne           r0,  r0,  r1,  lsl #1
669
+
670
+        bne             1b
671
+
672
+        add             sp,  sp,  #16
673
+        pop            {r4 - r11, pc}
674
+endfunc
675
+
676
+@ void vp8_v_loop_filter16(uint8_t *dst, int stride,
677
+@                          int fE, int fI, int hev_thresh)
678
+@ and
679
+@ void vp8_v_loop_filter8uv(uint8_t *dstU, uint8_t *dstV, int stride,
680
+@                           int fE, int fI, int hev_thresh)
681
+@ call:
682
+@ void vp8_v_loop_filter(uint8_t *dst, int stride,
683
+@                        int fE, int fI, int hev_thresh, int count)
684
+function ff_vp8_v_loop_filter_armv6, export=1
685
+        push           {r4 - r11, lr}
686
+
687
+        sub             r0,  r0,  r1,  lsl #2   @ move r0 pointer down by 4 lines
688
+        ldr             r5, [sp,  #40]          @ counter
689
+        ldr             r6, [sp,  #36]          @ load thresh address
690
+        sub             sp,  sp,  #16           @ create temp buffer
691
+
692
+        ldr             r10,[r0,  r1]           @ p2
693
+        ldr_post        r9,  r0,  r1,  lsl #1   @ p3
694
+        ldr             r12,[r0,  r1]           @ p0
695
+        ldr_post        r11, r0,  r1,  lsl #1   @ p1
696
+
697
+        orr             r2,  r2,  r2,  lsl #16
698
+        orr             r3,  r3,  r3,  lsl #16
699
+        orr             r6,  r6,  r6,  lsl #16
700
+        orr             r4,  r2,  r2,  lsl #8   @ flimE  splat int -> byte
701
+        orr             r2,  r3,  r3,  lsl #8   @ flimI  splat int -> byte
702
+        orr             r3,  r6,  r6,  lsl #8   @ thresh splat int -> byte
703
+
704
+1:
705
+        @ vp8_filter_mask() function
706
+        @ calculate breakout conditions
707
+        uqsub8          r6,  r9,  r10           @ p3 - p2
708
+        uqsub8          r7,  r10, r9            @ p2 - p3
709
+        uqsub8          r8,  r10, r11           @ p2 - p1
710
+        uqsub8          r10, r11, r10           @ p1 - p2
711
+
712
+        orr             r6,  r6,  r7            @ abs (p3-p2)
713
+        orr             r8,  r8,  r10           @ abs (p2-p1)
714
+        uqsub8          lr,  r6,  r2            @ compare to limit. lr: vp8_filter_mask
715
+        uqsub8          r8,  r8,  r2            @ compare to limit
716
+
717
+        uqsub8          r6,  r11, r12           @ p1 - p0
718
+        orr             lr,  lr,  r8
719
+        uqsub8          r7,  r12, r11           @ p0 - p1
720
+        ldr             r10,[r0,  r1]           @ q1
721
+        ldr_post        r9,  r0,  r1,  lsl #1   @ q0
722
+        orr             r6,  r6,  r7            @ abs (p1-p0)
723
+        uqsub8          r7,  r6,  r2            @ compare to limit
724
+        uqsub8          r8,  r6,  r3            @ compare to thresh  -- save r8 for later
725
+        orr             lr,  lr,  r7
726
+
727
+        uqsub8          r6,  r11, r10           @ p1 - q1
728
+        uqsub8          r7,  r10, r11           @ q1 - p1
729
+        uqsub8          r11, r12, r9            @ p0 - q0
730
+        uqsub8          r12, r9,  r12           @ q0 - p0
731
+        orr             r6,  r6,  r7            @ abs (p1-q1)
732
+        ldr             r7,  c0x7F7F7F7F
733
+        orr             r12, r11, r12           @ abs (p0-q0)
734
+        ldr_post        r11, r0,  r1            @ q2
735
+        uqadd8          r12, r12, r12           @ abs (p0-q0) * 2
736
+        and             r6,  r7,  r6,  lsr #1   @ abs (p1-q1) / 2
737
+        uqsub8          r7,  r9,  r10           @ q0 - q1
738
+        uqadd8          r12, r12, r6            @ abs (p0-q0)*2 + abs (p1-q1)/2
739
+        uqsub8          r6,  r10, r9            @ q1 - q0
740
+        uqsub8          r12, r12, r4            @ compare to flimit
741
+        uqsub8          r9,  r11, r10           @ q2 - q1
742
+
743
+        orr             lr,  lr,  r12
744
+
745
+        ldr_post        r12, r0,  r1            @ q3
746
+
747
+        uqsub8          r10, r10, r11           @ q1 - q2
748
+        orr             r6,  r7,  r6            @ abs (q1-q0)
749
+        orr             r10, r9,  r10           @ abs (q2-q1)
750
+        uqsub8          r7,  r6,  r2            @ compare to limit
751
+        uqsub8          r10, r10, r2            @ compare to limit
752
+        uqsub8          r6,  r6,  r3            @ compare to thresh -- save r6 for later
753
+        orr             lr,  lr,  r7
754
+        orr             lr,  lr,  r10
755
+
756
+        uqsub8          r10, r12, r11           @ q3 - q2
757
+        uqsub8          r9,  r11, r12           @ q2 - q3
758
+
759
+        mvn             r11, #0                 @ r11 == -1
760
+
761
+        orr             r10, r10, r9            @ abs (q3-q2)
762
+        uqsub8          r10, r10, r2            @ compare to limit
763
+
764
+        mov             r12, #0
765
+
766
+        orr             lr,  lr,  r10
767
+
768
+        usub8           lr,  r12, lr            @ use usub8 instead of ssub8
769
+        sel             lr,  r11, r12           @ filter mask: lr
770
+
771
+        cmp             lr,  #0
772
+        beq             2f                      @ skip filtering
773
+
774
+        @vp8_hevmask() function
775
+        @calculate high edge variance
776
+        sub             r0,  r0,  r1,  lsl #2   @ move r0 pointer down by 6 lines
777
+        sub             r0,  r0,  r1,  lsl #1
778
+
779
+        orr             r10, r6,  r8
780
+
781
+        usub8           r10, r12, r10
782
+        sel             r6,  r12, r11           @ hev mask: r6
783
+
784
+        @vp8_mbfilter() function
785
+        @p2, q2 are only needed at the end. Do not need to load them in now.
786
+        ldr             r8, [r0,  r1]           @ p0
787
+        ldr_post        r7,  r0,  r1,  lsl #1   @ p1
788
+        ldr             r12, c0x80808080
789
+        ldr_post        r9,  r0,  r1            @ q0
790
+        ldr             r10,[r0]                @ q1
791
+
792
+        eor             r7,  r7,  r12           @ ps1
793
+        eor             r8,  r8,  r12           @ ps0
794
+        eor             r9,  r9,  r12           @ qs0
795
+        eor             r10, r10, r12           @ qs1
796
+
797
+        qsub8           r12, r9,  r8            @ vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
798
+        str             r7, [sp,  #12]          @ store ps1 temporarily
799
+        qsub8           r7,  r7,  r10           @ vp8_signed_char_clamp(ps1-qs1)
800
+        str             r10,[sp,  #8]           @ store qs1 temporarily
801
+        qadd8           r7,  r7,  r12
802
+        str             r9, [sp]                @ store qs0 temporarily
803
+        qadd8           r7,  r7,  r12
804
+        str             r8, [sp,  #4]           @ store ps0 temporarily
805
+        qadd8           r7,  r7,  r12           @ vp8_filter: r7
806
+
807
+        ldr             r10, c0x03030303        @ r10 = 3 --modified for vp8
808
+        ldr             r9,  c0x04040404
809
+
810
+        and             r7,  r7,  lr            @ vp8_filter &= mask (lr is free)
811
+
812
+        mov             r12, r7                 @ Filter2: r12
813
+        and             r12, r12, r6            @ Filter2 &= hev
814
+
815
+        @save bottom 3 bits so that we round one side +4 and the other +3
816
+        qadd8           r8,  r12, r9            @ Filter1 (r8) = vp8_signed_char_clamp(Filter2+4)
817
+        qadd8           r12, r12, r10           @ Filter2 (r12) = vp8_signed_char_clamp(Filter2+3)
818
+
819
+        mov             r10, #0
820
+        shadd8          r8,  r8,  r10           @ Filter1 >>= 3
821
+        shadd8          r12, r12, r10           @ Filter2 >>= 3
822
+        shadd8          r8,  r8,  r10
823
+        shadd8          r12, r12, r10
824
+        shadd8          r8,  r8,  r10           @ r8: Filter1
825
+        shadd8          r12, r12, r10           @ r12: Filter2
826
+
827
+        ldr             r9, [sp]                @ load qs0
828
+        ldr             r11,[sp,  #4]           @ load ps0
829
+
830
+        qsub8           r9,  r9,  r8            @ qs0 = vp8_signed_char_clamp(qs0 - Filter1)
831
+        qadd8           r11, r11, r12           @ ps0 = vp8_signed_char_clamp(ps0 + Filter2)
832
+
833
+        bic             r12, r7,  r6            @ vp8_filter &= ~hev    ( r6 is free)
834
+
835
+        @roughly 3/7th difference across boundary
836
+        mov             lr,  #0x1b              @ 27
837
+        mov             r7,  #0x3f              @ 63
838
+
839
+        sxtb16          r6,  r12
840
+        sxtb16          r10, r12, ror #8
841
+        smlabb          r8,  r6,  lr,  r7
842
+        smlatb          r6,  r6,  lr,  r7
843
+        smlabb          r7,  r10, lr,  r7
844
+        smultb          r10, r10, lr
845
+        ssat            r8,  #8,  r8,  asr #7
846
+        ssat            r6,  #8,  r6,  asr #7
847
+        add             r10, r10, #63
848
+        ssat            r7,  #8,  r7,  asr #7
849
+        ssat            r10, #8,  r10, asr #7
850
+
851
+        ldr             lr,  c0x80808080
852
+
853
+        pkhbt           r6,  r8,  r6,  lsl #16
854
+        pkhbt           r10, r7,  r10, lsl #16
855
+        uxtb16          r6,  r6
856
+        uxtb16          r10, r10
857
+
858
+        sub             r0,  r0,  r1
859
+
860
+        orr             r10, r6,  r10, lsl #8   @ u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7)
861
+
862
+        qsub8           r8,  r9,  r10           @ s = vp8_signed_char_clamp(qs0 - u)
863
+        qadd8           r10, r11, r10           @ s = vp8_signed_char_clamp(ps0 + u)
864
+        eor             r8,  r8,  lr            @ *oq0 = s^0x80
865
+        str             r8, [r0]                @ store *oq0
866
+        sub             r0,  r0,  r1
867
+        eor             r10, r10, lr            @ *op0 = s^0x80
868
+        str             r10,[r0]                @ store *op0
869
+
870
+        @roughly 2/7th difference across boundary
871
+        mov             lr,  #0x12              @ 18
872
+        mov             r7,  #0x3f              @ 63
873
+
874
+        sxtb16          r6,  r12
875
+        sxtb16          r10, r12, ror #8
876
+        smlabb          r8,  r6,  lr,  r7
877
+        smlatb          r6,  r6,  lr,  r7
878
+        smlabb          r9,  r10, lr,  r7
879
+        smlatb          r10, r10, lr,  r7
880
+        ssat            r8,  #8,  r8,  asr #7
881
+        ssat            r6,  #8,  r6,  asr #7
882
+        ssat            r9,  #8,  r9,  asr #7
883
+        ssat            r10, #8,  r10, asr #7
884
+
885
+        ldr             lr,  c0x80808080
886
+
887
+        pkhbt           r6,  r8,  r6,  lsl #16
888
+        pkhbt           r10, r9,  r10, lsl #16
889
+
890
+        ldr             r9,  [sp,  #8]          @ load qs1
891
+        ldr             r11, [sp,  #12]         @ load ps1
892
+
893
+        uxtb16          r6,  r6
894
+        uxtb16          r10, r10
895
+
896
+        sub             r0,  r0,  r1
897
+
898
+        orr             r10, r6,  r10, lsl #8   @ u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7)
899
+
900
+        qadd8           r11, r11, r10           @ s = vp8_signed_char_clamp(ps1 + u)
901
+        qsub8           r8,  r9,  r10           @ s = vp8_signed_char_clamp(qs1 - u)
902
+        eor             r11, r11, lr            @ *op1 = s^0x80
903
+        str_post        r11, r0,  r1            @ store *op1
904
+        eor             r8,  r8,  lr            @ *oq1 = s^0x80
905
+        add             r0,  r0,  r1,  lsl #1
906
+
907
+        mov             r7,  #0x3f              @ 63
908
+
909
+        str_post        r8,  r0,  r1            @ store *oq1
910
+
911
+        @roughly 1/7th difference across boundary
912
+        mov             lr,  #0x9               @ 9
913
+        ldr             r9, [r0]                @ load q2
914
+
915
+        sxtb16          r6,  r12
916
+        sxtb16          r10, r12, ror #8
917
+        smlabb          r8,  r6,  lr,  r7
918
+        smlatb          r6,  r6,  lr,  r7
919
+        smlabb          r12, r10, lr,  r7
920
+        smlatb          r10, r10, lr,  r7
921
+        ssat            r8,  #8,  r8,  asr #7
922
+        ssat            r6,  #8,  r6,  asr #7
923
+        ssat            r12, #8,  r12, asr #7
924
+        ssat            r10, #8,  r10, asr #7
925
+
926
+        sub             r0,  r0,  r1,  lsl #2
927
+
928
+        pkhbt           r6,  r8,  r6,  lsl #16
929
+        pkhbt           r10, r12, r10, lsl #16
930
+
931
+        sub             r0,  r0,  r1
932
+        ldr             lr,  c0x80808080
933
+
934
+        ldr             r11, [r0]               @ load p2
935
+
936
+        uxtb16          r6,  r6
937
+        uxtb16          r10, r10
938
+
939
+        eor             r9,  r9,  lr
940
+        eor             r11, r11, lr
941
+
942
+        orr             r10, r6,  r10, lsl #8   @ u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7)
943
+
944
+        qadd8           r8,  r11, r10           @ s = vp8_signed_char_clamp(ps2 + u)
945
+        qsub8           r10, r9,  r10           @ s = vp8_signed_char_clamp(qs2 - u)
946
+        eor             r8,  r8,  lr            @ *op2 = s^0x80
947
+        str_post        r8,  r0,  r1,  lsl #2   @ store *op2
948
+        add             r0,  r0,  r1
949
+        eor             r10, r10, lr            @ *oq2 = s^0x80
950
+        str_post        r10, r0,  r1,  lsl #1   @ store *oq2
951
+
952
+2:
953
+        add             r0,  r0,  #4
954
+        sub             r0,  r0,  r1,  lsl #3
955
+        subs            r5,  r5,  #1
956
+
957
+T       ittt            ne
958
+        ldrne           r10,[r0,  r1]           @ p2
959
+A       ldrne           r9, [r0], r1,  lsl #1   @ p3
960
+T       ldrne           r9, [r0]                @ p3
961
+T       addne           r0,  r0,  r1,  lsl #1
962
+T       ittt            ne
963
+        ldrne           r12,[r0,  r1]           @ p0
964
+A       ldrne           r11,[r0], r1,  lsl #1   @ p1
965
+T       ldrne           r11,[r0]                @ p3
966
+T       addne           r0,  r0,  r1,  lsl #1
967
+
968
+        bne             1b
969
+
970
+        add             sp,  sp,  #16
971
+        pop            {r4 - r11, pc}
972
+endfunc
973
+
974
+.macro TRANSPOSE_MATRIX i0, i1, i2, i3, o3, o2, o1, o0
975
+        @ input:  $0, $1, $2, $3
976
+        @ output: $4, $5, $6, $7
977
+        @ i0: 03 02 01 00
978
+        @ i1: 13 12 11 10
979
+        @ i2: 23 22 21 20
980
+        @ i3: 33 32 31 30
981
+        @     o3 o2 o1 o0
982
+
983
+        uxtb16          \o1, \i1                @ xx 12 xx 10
984
+        uxtb16          \o0, \i0                @ xx 02 xx 00
985
+        uxtb16          \o3, \i3                @ xx 32 xx 30
986
+        uxtb16          \o2, \i2                @ xx 22 xx 20
987
+        orr             \o1, \o0, \o1, lsl #8   @ 12 02 10 00
988
+        orr             \o3, \o2, \o3, lsl #8   @ 32 22 30 20
989
+
990
+        uxtb16          \i1, \i1, ror #8        @ xx 13 xx 11
991
+        uxtb16          \i3, \i3, ror #8        @ xx 33 xx 31
992
+        uxtb16          \i0, \i0, ror #8        @ xx 03 xx 01
993
+        uxtb16          \i2, \i2, ror #8        @ xx 23 xx 21
994
+        orr             \i0, \i0, \i1, lsl #8   @ 13 03 11 01
995
+        orr             \i2, \i2, \i3, lsl #8   @ 33 23 31 21
996
+
997
+        pkhtb           \o2, \o3, \o1, asr #16  @ 32 22 12 02   -- p1
998
+        pkhbt           \o0, \o1, \o3, lsl #16  @ 30 20 10 00   -- p3
999
+
1000
+        pkhtb           \o3, \i2, \i0, asr #16  @ 33 23 13 03   -- p0
1001
+        pkhbt           \o1, \i0, \i2, lsl #16  @ 31 21 11 01   -- p2
1002
+.endm
1003
+
1004
+@ void vp8_h_loop_filter16_simple(uint8_t *dst, int stride, int flim)
1005
+function ff_vp8_h_loop_filter16_simple_armv6, export=1
1006
+        push           {r4 - r11, lr}
1007
+        orr             r12, r2,  r2,  lsl #16
1008
+        ldr             r2,  c0x80808080
1009
+        orr             r12, r12, r12, lsl #8
1010
+
1011
+        @ load soure data to r7, r8, r9, r10
1012
+        sub             r0,  r0,  #2
1013
+        ldr             r8, [r0,  r1]
1014
+        ldr_post        r7,  r0,  r1,  lsl #1
1015
+        ldr             r10,[r0,  r1]
1016
+        ldr_post        r9,  r0,  r1,  lsl #1
1017
+        add             r0,  r0,  #2
1018
+
1019
+        mov             r11, #4                 @ count (r11) for 4-in-parallel
1020
+1:
1021
+        @transpose r7, r8, r9, r10 to r3, r4, r5, r6
1022
+        TRANSPOSE_MATRIX r7, r8, r9, r10, r6, r5, r4, r3
1023
+
1024
+        @ vp8_simple_filter_mask() function
1025
+        uqsub8          r7,  r3,  r6            @ p1 - q1
1026
+        uqsub8          r8,  r6,  r3            @ q1 - p1
1027
+        uqsub8          r9,  r4,  r5            @ p0 - q0
1028
+        uqsub8          r10, r5,  r4            @ q0 - p0
1029
+        orr             r7,  r7,  r8            @ abs(p1 - q1)
1030
+        orr             r9,  r9,  r10           @ abs(p0 - q0)
1031
+        mov             r8,  #0
1032
+        uqadd8          r9,  r9,  r9            @ abs(p0 - q0) * 2
1033
+        uhadd8          r7,  r7,  r8            @ abs(p1 - q1) / 2
1034
+        uqadd8          r7,  r7,  r9            @ abs(p0 - q0)*2 + abs(p1 - q1)/2
1035
+        mvn             r10, #0                 @ r10 == -1
1036
+
1037
+        usub8           r7,  r12, r7            @ compare to flimit
1038
+        sel             lr,  r10, r8            @ filter mask
1039
+
1040
+        cmp             lr,  #0
1041
+        beq             2f                      @ skip filtering
1042
+
1043
+        @vp8_simple_filter() function
1044
+        eor             r3,  r3,  r2            @ p1 offset to convert to a signed value
1045
+        eor             r6,  r6,  r2            @ q1 offset to convert to a signed value
1046
+        eor             r4,  r4,  r2            @ p0 offset to convert to a signed value
1047
+        eor             r5,  r5,  r2            @ q0 offset to convert to a signed value
1048
+
1049
+        qsub8           r3,  r3,  r6            @ vp8_filter = p1 - q1
1050
+        qsub8           r6,  r5,  r4            @ q0 - p0
1051
+
1052
+        qadd8           r3,  r3,  r6            @ vp8_filter += q0 - p0
1053
+        ldr             r9,  c0x03030303        @ r9 = 3
1054
+
1055
+        qadd8           r3,  r3,  r6            @ vp8_filter += q0 - p0
1056
+        ldr             r7,  c0x04040404
1057
+
1058
+        qadd8           r3,  r3,  r6            @ vp8_filter = p1-q1 + 3*(q0-p0))
1059
+        @STALL
1060
+        and             r3,  r3,  lr            @ vp8_filter &= mask
1061
+
1062
+        qadd8           r9,  r3,  r9            @ Filter2 = vp8_filter + 3
1063
+        qadd8           r3,  r3,  r7            @ Filter1 = vp8_filter + 4
1064
+
1065
+        shadd8          r9,  r9,  r8
1066
+        shadd8          r3,  r3,  r8
1067
+        shadd8          r9,  r9,  r8
1068
+        shadd8          r3,  r3,  r8
1069
+        shadd8          r9,  r9,  r8            @ Filter2 >>= 3
1070
+        shadd8          r3,  r3,  r8            @ Filter1 >>= 3
1071
+
1072
+        @calculate output
1073
+        sub             r0,  r0,  r1,  lsl #2
1074
+
1075
+        qadd8           r4,  r4,  r9            @ u = p0 + Filter2
1076
+        qsub8           r5,  r5,  r3            @ u = q0 - Filter1
1077
+        eor             r4,  r4,  r2            @ *op0 = u^0x80
1078
+        eor             r5,  r5,  r2            @ *oq0 = u^0x80
1079
+
1080
+        strb            r4, [r0,  #-1]          @ store the result
1081
+        mov             r4,  r4,  lsr #8
1082
+        strb_post       r5,  r0,  r1
1083
+        mov             r5,  r5,  lsr #8
1084
+
1085
+        strb            r4, [r0,  #-1]
1086
+        mov             r4,  r4,  lsr #8
1087
+        strb_post       r5,  r0,  r1
1088
+        mov             r5,  r5,  lsr #8
1089
+
1090
+        strb            r4, [r0,  #-1]
1091
+        mov             r4,  r4,  lsr #8
1092
+        strb_post       r5,  r0,  r1
1093
+        mov             r5,  r5,  lsr #8
1094
+
1095
+        strb            r4, [r0,  #-1]
1096
+        strb_post       r5,  r0,  r1
1097
+
1098
+2:
1099
+        subs            r11, r11, #1
1100
+
1101
+        @ load soure data to r7, r8, r9, r10
1102
+        sub             r0,  r0,  #2
1103
+T       ittt            ne
1104
+        ldrne           r8, [r0,  r1]
1105
+A       ldrne           r7, [r0], r1,  lsl #1
1106
+T       ldrne           r7, [r0]
1107
+T       addne           r0,  r0,  r1,  lsl #1
1108
+T       ittt            ne
1109
+        ldrne           r10,[r0,  r1]
1110
+A       ldrne           r9, [r0], r1,  lsl #1
1111
+T       ldrne           r9, [r0]
1112
+T       addne           r0,  r0,  r1,  lsl #1
1113
+        add             r0,  r0,  #2
1114
+
1115
+        bne             1b
1116
+
1117
+        pop            {r4 - r11, pc}
1118
+endfunc
1119
+
1120
+@ void vp8_h_loop_filter16_inner(uint8_t *dst, int stride,
1121
+@                                int fE, int fI, int hev_thresh)
1122
+@ and
1123
+@ void vp8_h_loop_filter8uv_inner(uint8_t *dstU, uint8_t *dstV, int stride,
1124
+@                          int fE, int fI, int hev_thresh)
1125
+@ call:
1126
+@ void vp8_h_loop_filter_inner(uint8_t *dst, int stride,
1127
+@                              int fE, int fI, int hev_thresh, int count)
1128
+function ff_vp8_h_loop_filter_inner_armv6, export=1
1129
+        push           {r4 - r11, lr}
1130
+
1131
+        sub             r0,  r0,  #4            @ move r0 pointer down by 4
1132
+        ldr             r5, [sp,  #40]          @ counter
1133
+        ldr             r9, [sp,  #36]          @ load thresh address
1134
+        sub             sp,  sp,  #16           @ create temp buffer
1135
+
1136
+        ldr             r7, [r0,  r1]           @ transpose will make it into p3-p0
1137
+        ldr_post        r6,  r0,  r1,  lsl #1   @ load source data
1138
+        ldr             lr, [r0,  r1]
1139
+        ldr_post        r8,  r0,  r1,  lsl #1
1140
+
1141
+        orr             r2,  r2,  r2,  lsl #16
1142
+        orr             r3,  r3,  r3,  lsl #16
1143
+        orr             r9,  r9,  r9,  lsl #16
1144
+        orr             r4,  r2,  r2,  lsl #8   @ flimE  splat int -> byte
1145
+        orr             r2,  r3,  r3,  lsl #8   @ flimI  splat int -> byte
1146
+        orr             r3,  r9,  r9,  lsl #8   @ thresh splat int -> byte
1147
+
1148
+1:
1149
+        @ vp8_filter_mask() function
1150
+        @ calculate breakout conditions
1151
+        @ transpose the source data for 4-in-parallel operation
1152
+        TRANSPOSE_MATRIX r6, r7, r8, lr, r12, r11, r10, r9
1153
+
1154
+        uqsub8          r7,  r9,  r10           @ p3 - p2
1155
+        uqsub8          r8,  r10, r9            @ p2 - p3
1156
+        uqsub8          r9,  r10, r11           @ p2 - p1
1157
+        uqsub8          r10, r11, r10           @ p1 - p2
1158
+        orr             r7,  r7,  r8            @ abs (p3-p2)
1159
+        orr             r10, r9,  r10           @ abs (p2-p1)
1160
+        uqsub8          lr,  r7,  r2            @ compare to limit. lr: vp8_filter_mask
1161
+        uqsub8          r10, r10, r2            @ compare to limit
1162
+
1163
+        sub             r0,  r0,  r1,  lsl #2   @ move r0 pointer down by 4 lines
1164
+
1165
+        orr             lr,  lr,  r10
1166
+
1167
+        uqsub8          r6,  r11, r12           @ p1 - p0
1168
+        uqsub8          r7,  r12, r11           @ p0 - p1
1169
+        add             r0,  r0,  #4            @ move r0 pointer up by 4
1170
+        orr             r6,  r6,  r7            @ abs (p1-p0)
1171
+        str             r11,[sp,  #12]          @ save p1
1172
+        uqsub8          r10, r6,  r2            @ compare to limit
1173
+        uqsub8          r11, r6,  r3            @ compare to thresh
1174
+        orr             lr,  lr,  r10
1175
+
1176
+        @ transpose uses 8 regs(r6 - r12 and lr). Need to save reg value now
1177
+        @ transpose the source data for 4-in-parallel operation
1178
+        str             r11,[sp]                @ push r11 to stack
1179
+        ldr             r7, [r0,  r1]
1180
+        ldr_post        r6,  r0,  r1,  lsl #1   @ load source data
1181
+        str             r12,[sp,  #4]           @ save current reg before load q0 - q3 data
1182
+        str             lr, [sp,  #8]
1183
+        ldr             lr, [r0,  r1]
1184
+        ldr_post        r8,  r0,  r1,  lsl #1
1185
+
1186
+        TRANSPOSE_MATRIX r6, r7, r8, lr, r12, r11, r10, r9
1187
+
1188
+        ldr             lr, [sp, #8]            @ load back (f)limit accumulator
1189
+
1190
+        uqsub8          r6,  r12, r11           @ q3 - q2
1191
+        uqsub8          r7,  r11, r12           @ q2 - q3
1192
+        uqsub8          r12, r11, r10           @ q2 - q1
1193
+        uqsub8          r11, r10, r11           @ q1 - q2
1194
+        orr             r6,  r6,  r7            @ abs (q3-q2)
1195
+        orr             r7,  r12, r11           @ abs (q2-q1)
1196
+        uqsub8          r6,  r6,  r2            @ compare to limit
1197
+        uqsub8          r7,  r7,  r2            @ compare to limit
1198
+        ldr             r11,[sp,  #4]           @ load back p0
1199
+        ldr             r12,[sp,  #12]          @ load back p1
1200
+        orr             lr,  lr,  r6
1201
+        orr             lr,  lr,  r7
1202
+
1203
+        uqsub8          r6,  r11, r9            @ p0 - q0
1204
+        uqsub8          r7,  r9,  r11           @ q0 - p0
1205
+        uqsub8          r8,  r12, r10           @ p1 - q1
1206
+        uqsub8          r11, r10, r12           @ q1 - p1
1207
+        orr             r6,  r6,  r7            @ abs (p0-q0)
1208
+        ldr             r7,  c0x7F7F7F7F
1209
+        orr             r8,  r8,  r11           @ abs (p1-q1)
1210
+        uqadd8          r6,  r6,  r6            @ abs (p0-q0) * 2
1211
+        and             r8,  r7,  r8,  lsr #1   @ abs (p1-q1) / 2
1212
+        uqsub8          r11, r10, r9            @ q1 - q0
1213
+        uqadd8          r6,  r8,  r6            @ abs (p0-q0)*2 + abs (p1-q1)/2
1214
+        uqsub8          r12, r9,  r10           @ q0 - q1
1215
+        uqsub8          r6,  r6,  r4            @ compare to flimit
1216
+
1217
+        orr             r9,  r11, r12           @ abs (q1-q0)
1218
+        uqsub8          r8,  r9,  r2            @ compare to limit
1219
+        uqsub8          r10, r9,  r3            @ compare to thresh
1220
+        orr             lr,  lr,  r6
1221
+        orr             lr,  lr,  r8
1222
+
1223
+        mvn             r11, #0                 @ r11 == -1
1224
+        mov             r12, #0
1225
+
1226
+        usub8           lr,  r12, lr
1227
+        ldr             r9, [sp]                @ load the compared result
1228
+        sel             lr,  r11, r12           @ filter mask: lr
1229
+
1230
+        cmp             lr,  #0
1231
+        beq             2f                      @ skip filtering
1232
+
1233
+        @vp8_hevmask() function
1234
+        @calculate high edge variance
1235
+        sub             r0,  r0,  r1,  lsl #2   @ move r0 pointer down by 4 lines
1236
+
1237
+        orr             r9,  r9,  r10
1238
+
1239
+        ldrh            r7, [r0,  #-2]
1240
+        ldrh_post       r8,  r0,  r1
1241
+
1242
+        usub8           r9,  r12, r9
1243
+        sel             r6,  r12, r11           @ hev mask: r6
1244
+
1245
+        @vp8_filter() function
1246
+        @ load soure data to r6, r11, r12, lr
1247
+        ldrh            r9, [r0,  #-2]
1248
+        ldrh_post       r10, r0,  r1
1249
+
1250
+        pkhbt           r12, r7,  r8,  lsl #16
1251
+
1252
+        ldrh            r7, [r0,  #-2]
1253
+        ldrh_post       r8,  r0,  r1
1254
+
1255
+        pkhbt           r11, r9,  r10, lsl #16
1256
+
1257
+        ldrh            r9, [r0,  #-2]
1258
+        ldrh_post       r10, r0,  r1
1259
+
1260
+        @ Transpose needs 8 regs(r6 - r12, and lr). Save r6 and lr first
1261
+        str             r6, [sp]
1262
+        str             lr, [sp,  #4]
1263
+
1264
+        pkhbt           r6,  r7,  r8,  lsl #16
1265
+        pkhbt           lr,  r9,  r10, lsl #16
1266
+
1267
+        @transpose r12, r11, r6, lr to r7, r8, r9, r10
1268
+        TRANSPOSE_MATRIX r12, r11, r6, lr, r10, r9, r8, r7
1269
+
1270
+        @load back hev_mask r6 and filter_mask lr
1271
+        ldr             r12, c0x80808080
1272
+        ldr             r6, [sp]
1273
+        ldr             lr, [sp,  #4]
1274
+
1275
+        eor             r7,  r7,  r12           @ p1 offset to convert to a signed value
1276
+        eor             r8,  r8,  r12           @ p0 offset to convert to a signed value
1277
+        eor             r9,  r9,  r12           @ q0 offset to convert to a signed value
1278
+        eor             r10, r10, r12           @ q1 offset to convert to a signed value
1279
+
1280
+        str             r9, [sp]                @ store qs0 temporarily
1281
+        str             r8, [sp,  #4]           @ store ps0 temporarily
1282
+        str             r10,[sp,  #8]           @ store qs1 temporarily
1283
+        str             r7, [sp,  #12]          @ store ps1 temporarily
1284
+
1285
+        qsub8           r7,  r7,  r10           @ vp8_signed_char_clamp(ps1-qs1)
1286
+        qsub8           r8,  r9,  r8            @ vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
1287
+
1288
+        and             r7,  r7,  r6            @  vp8_filter (r7) &= hev (r7 : filter)
1289
+
1290
+        qadd8           r7,  r7,  r8
1291
+        ldr             r9,  c0x03030303        @ r9 = 3 --modified for vp8
1292
+
1293
+        qadd8           r7,  r7,  r8
1294
+        ldr             r10, c0x04040404
1295
+
1296
+        qadd8           r7,  r7,  r8
1297
+
1298
+        and             r7,  r7,  lr            @ vp8_filter &= mask
1299
+
1300
+        qadd8           r8,  r7,  r9            @ Filter2 (r8) = vp8_signed_char_clamp(vp8_filter+3)
1301
+        qadd8           r7,  r7,  r10           @ vp8_filter = vp8_signed_char_clamp(vp8_filter+4)
1302
+
1303
+        mov             r9,  #0
1304
+        shadd8          r8,  r8,  r9            @ Filter2 >>= 3
1305
+        shadd8          r7,  r7,  r9            @ vp8_filter >>= 3
1306
+        shadd8          r8,  r8,  r9
1307
+        shadd8          r7,  r7,  r9
1308
+        shadd8          lr,  r8,  r9            @ lr: filter2
1309
+        shadd8          r7,  r7,  r9            @ r7: filter
1310
+
1311
+        @calculate output
1312
+        ldr             r8, [sp]                @ load qs0
1313
+        ldr             r9, [sp,  #4]           @ load ps0
1314
+
1315
+        ldr             r10, c0x01010101
1316
+
1317
+        qsub8           r8,  r8,  r7            @ u = vp8_signed_char_clamp(qs0 - vp8_filter)
1318
+        qadd8           r9,  r9,  lr            @ u = vp8_signed_char_clamp(ps0 + Filter2)
1319
+
1320
+        eor             r8,  r8,  r12
1321
+        eor             r9,  r9,  r12
1322
+
1323
+        mov             lr,  #0
1324
+
1325
+        sadd8           r7,  r7,  r10
1326
+        shadd8          r7,  r7,  lr
1327
+
1328
+        ldr             r10,[sp,  #8]           @ load qs1
1329
+        ldr             r11,[sp,  #12]          @ load ps1
1330
+
1331
+        bic             r7,  r7,  r6            @ r7: vp8_filter
1332
+
1333
+        qsub8           r10, r10, r7            @ u = vp8_signed_char_clamp(qs1 - vp8_filter)
1334
+        qadd8           r11, r11, r7            @ u = vp8_signed_char_clamp(ps1 + vp8_filter)
1335
+        eor             r10, r10, r12
1336
+        eor             r11, r11, r12
1337
+
1338
+        sub             r0,  r0,  r1,  lsl #2
1339
+
1340
+        @we can use TRANSPOSE_MATRIX macro to transpose output - input: q1, q0, p0, p1
1341
+        TRANSPOSE_MATRIX r11, r9, r8, r10, lr, r12, r7, r6
1342
+
1343
+        strh            r6, [r0,  #-2]          @ store the result
1344
+        mov             r6,  r6,  lsr #16
1345
+        strh_post       r6,  r0,  r1
1346
+
1347
+        strh            r7, [r0,  #-2]
1348
+        mov             r7,  r7,  lsr #16
1349
+        strh_post       r7,  r0,  r1
1350
+
1351
+        strh            r12, [r0,  #-2]
1352
+        mov             r12,  r12, lsr #16
1353
+        strh_post       r12,  r0,  r1
1354
+
1355
+        strh            lr, [r0,  #-2]
1356
+        mov             lr,  lr,  lsr #16
1357
+        strh_post       lr,  r0,  r1
1358
+
1359
+2:
1360
+        sub             r0,  r0,  #4
1361
+        subs            r5,  r5,  #1
1362
+
1363
+T       ittt            ne
1364
+        ldrne           r7, [r0,  r1]
1365
+A       ldrne           r6, [r0], r1,  lsl #1   @ load source data
1366
+T       ldrne           r6, [r0]                @ load source data
1367
+T       addne           r0,  r0,  r1,  lsl #1
1368
+T       ittt            ne
1369
+        ldrne           lr, [r0,  r1]
1370
+A       ldrne           r8, [r0], r1,  lsl #1
1371
+T       ldrne           r8, [r0]
1372
+T       addne           r0,  r0,  r1,  lsl #1
1373
+
1374
+        bne             1b
1375
+
1376
+        add             sp, sp, #16
1377
+        pop            {r4 - r11, pc}
1378
+endfunc
1379
+
1380
+@ void vp8_h_loop_filter16(uint8_t *dst, int stride,
1381
+@                          int fE, int fI, int hev_thresh)
1382
+@ and
1383
+@ void vp8_h_loop_filter8uv(uint8_t *dstU, uint8_t *dstV, int stride,
1384
+@                           int fE, int fI, int hev_thresh)
1385
+@ call:
1386
+@ void vp8_h_loop_filter(uint8_t *dst, int stride,
1387
+@                        int fE, int fI, int hev_thresh, int count)
1388
+function ff_vp8_h_loop_filter_armv6, export=1
1389
+        push           {r4 - r11, lr}
1390
+
1391
+        sub             r0,  r0,  #4            @ move r0 pointer down by 4
1392
+        ldr             r5, [sp,  #40]          @ counter
1393
+        ldr             r9, [sp,  #36]          @ load thresh address
1394
+        sub             sp,  sp,  #16           @ create temp buffer
1395
+
1396
+        ldr             r7, [r0,  r1]           @ transpose will make it into p3-p0
1397
+        ldr_post        r6,  r0,  r1,  lsl #1   @ load source data
1398
+        ldr             lr, [r0,  r1]
1399
+        ldr_post        r8,  r0,  r1,  lsl #1
1400
+
1401
+        orr             r2,  r2,  r2,  lsl #16
1402
+        orr             r3,  r3,  r3,  lsl #16
1403
+        orr             r9,  r9,  r9,  lsl #16
1404
+        orr             r4,  r2,  r2,  lsl #8   @ flimE  splat int -> byte
1405
+        orr             r2,  r3,  r3,  lsl #8   @ flimI  splat int -> byte
1406
+        orr             r3,  r9,  r9,  lsl #8   @ thresh splat int -> byte
1407
+
1408
+1:
1409
+        @ vp8_filter_mask() function
1410
+        @ calculate breakout conditions
1411
+        @ transpose the source data for 4-in-parallel operation
1412
+        TRANSPOSE_MATRIX r6, r7, r8, lr, r12, r11, r10, r9
1413
+
1414
+        uqsub8          r7,  r9,  r10           @ p3 - p2
1415
+        uqsub8          r8,  r10, r9            @ p2 - p3
1416
+        uqsub8          r9,  r10, r11           @ p2 - p1
1417
+        uqsub8          r10, r11, r10           @ p1 - p2
1418
+        orr             r7,  r7,  r8            @ abs (p3-p2)
1419
+        orr             r10, r9,  r10           @ abs (p2-p1)
1420
+        uqsub8          lr,  r7,  r2            @ compare to limit. lr: vp8_filter_mask
1421
+        uqsub8          r10, r10, r2            @ compare to limit
1422
+
1423
+        sub             r0,  r0,  r1,  lsl #2   @ move r0 pointer down by 4 lines
1424
+
1425
+        orr             lr,  lr,  r10
1426
+
1427
+        uqsub8          r6,  r11, r12           @ p1 - p0
1428
+        uqsub8          r7,  r12, r11           @ p0 - p1
1429
+        add             r0,  r0,  #4            @ move r0 pointer up by 4
1430
+        orr             r6,  r6,  r7            @ abs (p1-p0)
1431
+        str             r11,[sp,  #12]          @ save p1
1432
+        uqsub8          r10, r6,  r2            @ compare to limit
1433
+        uqsub8          r11, r6,  r3            @ compare to thresh
1434
+        orr             lr,  lr,  r10
1435
+
1436
+        @ transpose uses 8 regs(r6 - r12 and lr). Need to save reg value now
1437
+        @ transpose the source data for 4-in-parallel operation
1438
+        str             r11,[sp]                @ push r11 to stack
1439
+        ldr             r7, [r0,  r1]
1440
+        ldr_post        r6,  r0,  r1,  lsl #1   @ load source data
1441
+        str             r12,[sp,  #4]           @ save current reg before load q0 - q3 data
1442
+        str             lr, [sp,  #8]
1443
+        ldr             lr, [r0,  r1]
1444
+        ldr_post        r8,  r0,  r1,  lsl #1
1445
+
1446
+        TRANSPOSE_MATRIX r6, r7, r8, lr, r12, r11, r10, r9
1447
+
1448
+        ldr             lr, [sp,  #8]           @ load back (f)limit accumulator
1449
+
1450
+        uqsub8          r6,  r12, r11           @ q3 - q2
1451
+        uqsub8          r7,  r11, r12           @ q2 - q3
1452
+        uqsub8          r12, r11, r10           @ q2 - q1
1453
+        uqsub8          r11, r10, r11           @ q1 - q2
1454
+        orr             r6,  r6,  r7            @ abs (q3-q2)
1455
+        orr             r7,  r12, r11           @ abs (q2-q1)
1456
+        uqsub8          r6,  r6,  r2            @ compare to limit
1457
+        uqsub8          r7,  r7,  r2            @ compare to limit
1458
+        ldr             r11,[sp,  #4]           @ load back p0
1459
+        ldr             r12,[sp,  #12]          @ load back p1
1460
+        orr             lr,  lr,  r6
1461
+        orr             lr,  lr,  r7
1462
+
1463
+        uqsub8          r6,  r11, r9            @ p0 - q0
1464
+        uqsub8          r7,  r9,  r11           @ q0 - p0
1465
+        uqsub8          r8,  r12, r10           @ p1 - q1
1466
+        uqsub8          r11, r10, r12           @ q1 - p1
1467
+        orr             r6,  r6,  r7            @ abs (p0-q0)
1468
+        ldr             r7,  c0x7F7F7F7F
1469
+        orr             r8,  r8,  r11           @ abs (p1-q1)
1470
+        uqadd8          r6,  r6,  r6            @ abs (p0-q0) * 2
1471
+        and             r8,  r7,  r8,  lsr #1   @ abs (p1-q1) / 2
1472
+        uqsub8          r11, r10, r9            @ q1 - q0
1473
+        uqadd8          r6,  r8,  r6            @ abs (p0-q0)*2 + abs (p1-q1)/2
1474
+        uqsub8          r12, r9,  r10           @ q0 - q1
1475
+        uqsub8          r6,  r6,  r4            @ compare to flimit
1476
+
1477
+        orr             r9,  r11, r12           @ abs (q1-q0)
1478
+        uqsub8          r8,  r9,  r2            @ compare to limit
1479
+        uqsub8          r10, r9,  r3            @ compare to thresh
1480
+        orr             lr,  lr,  r6
1481
+        orr             lr,  lr,  r8
1482
+
1483
+        mvn             r11,  #0                @ r11 == -1
1484
+        mov             r12,  #0
1485
+
1486
+        usub8           lr,  r12, lr
1487
+        ldr             r9, [sp]                @ load the compared result
1488
+        sel             lr,  r11, r12           @ filter mask: lr
1489
+
1490
+        cmp             lr,  #0
1491
+        beq             2f                      @ skip filtering
1492
+
1493
+
1494
+        @vp8_hevmask() function
1495
+        @calculate high edge variance
1496
+        sub             r0,  r0,  r1,  lsl #2   @ move r0 pointer down by 4 lines
1497
+
1498
+        orr             r9,  r9,  r10
1499
+
1500
+        ldrh            r7, [r0,  #-2]
1501
+        ldrh_post       r8,  r0,  r1
1502
+
1503
+        usub8           r9,  r12, r9
1504
+        sel             r6,  r12, r11           @ hev mask: r6
1505
+
1506
+
1507
+        @ vp8_mbfilter() function
1508
+        @ p2, q2 are only needed at the end. do not need to load them in now.
1509
+        @ Transpose needs 8 regs(r6 - r12, and lr). Save r6 and lr first
1510
+        @ load soure data to r6, r11, r12, lr
1511
+        ldrh            r9, [r0,  #-2]
1512
+        ldrh_post       r10, r0,  r1
1513
+
1514
+        pkhbt           r12, r7,  r8,  lsl #16
1515
+
1516
+        ldrh            r7, [r0,  #-2]
1517
+        ldrh_post       r8,  r0,  r1
1518
+
1519
+        pkhbt           r11, r9,  r10, lsl #16
1520
+
1521
+        ldrh            r9, [r0,  #-2]
1522
+        ldrh_post       r10, r0,  r1
1523
+
1524
+        str             r6, [sp]                @ save r6
1525
+        str             lr, [sp,  #4]           @ save lr
1526
+
1527
+        pkhbt           r6,  r7,  r8,  lsl #16
1528
+        pkhbt           lr,  r9,  r10, lsl #16
1529
+
1530
+        @transpose r12, r11, r6, lr to p1, p0, q0, q1
1531
+        TRANSPOSE_MATRIX r12, r11, r6, lr, r10, r9, r8, r7
1532
+
1533
+        @load back hev_mask r6 and filter_mask lr
1534
+        ldr             r12, c0x80808080
1535
+        ldr             r6, [sp]
1536
+        ldr             lr, [sp,  #4]
1537
+
1538
+        eor             r7,  r7,  r12           @ ps1
1539
+        eor             r8,  r8,  r12           @ ps0
1540
+        eor             r9,  r9,  r12           @ qs0
1541
+        eor             r10, r10, r12           @ qs1
1542
+
1543
+        qsub8           r12, r9,  r8            @ vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
1544
+        str             r7, [sp,  #12]          @ store ps1 temporarily
1545
+        qsub8           r7,  r7,  r10           @ vp8_signed_char_clamp(ps1-qs1)
1546
+        str             r10,[sp,  #8]           @ store qs1 temporarily
1547
+        qadd8           r7,  r7,  r12
1548
+        str             r9, [sp]                @ store qs0 temporarily
1549
+        qadd8           r7,  r7,  r12
1550
+        str             r8, [sp,  #4]           @ store ps0 temporarily
1551
+        qadd8           r7,  r7,  r12           @ vp8_filter: r7
1552
+
1553
+        ldr             r10, c0x03030303        @ r10 = 3 --modified for vp8
1554
+        ldr             r9,  c0x04040404
1555
+
1556
+        and             r7,  r7,  lr            @ vp8_filter &= mask (lr is free)
1557
+
1558
+        mov             r12, r7                 @ Filter2: r12
1559
+        and             r12, r12, r6            @ Filter2 &= hev
1560
+
1561
+        @save bottom 3 bits so that we round one side +4 and the other +3
1562
+        qadd8           r8,  r12, r9            @ Filter1 (r8) = vp8_signed_char_clamp(Filter2+4)
1563
+        qadd8           r12, r12, r10           @ Filter2 (r12) = vp8_signed_char_clamp(Filter2+3)
1564
+
1565
+        mov             r10, #0
1566
+        shadd8          r8,  r8,  r10           @ Filter1 >>= 3
1567
+        shadd8          r12, r12, r10           @ Filter2 >>= 3
1568
+        shadd8          r8,  r8,  r10
1569
+        shadd8          r12, r12, r10
1570
+        shadd8          r8,  r8,  r10           @ r8: Filter1
1571
+        shadd8          r12, r12, r10           @ r12: Filter2
1572
+
1573
+        ldr             r9, [sp]                @ load qs0
1574
+        ldr             r11,[sp,  #4]           @ load ps0
1575
+
1576
+        qsub8           r9,  r9,  r8            @ qs0 = vp8_signed_char_clamp(qs0 - Filter1)
1577
+        qadd8           r11, r11, r12           @ ps0 = vp8_signed_char_clamp(ps0 + Filter2)
1578
+
1579
+        bic             r12, r7,  r6            @vp8_filter &= ~hev    ( r6 is free)
1580
+
1581
+        @roughly 3/7th difference across boundary
1582
+        mov             lr,  #0x1b              @ 27
1583
+        mov             r7,  #0x3f              @ 63
1584
+
1585
+        sxtb16          r6,  r12
1586
+        sxtb16          r10, r12, ror #8
1587
+        smlabb          r8,  r6,  lr,  r7
1588
+        smlatb          r6,  r6,  lr,  r7
1589
+        smlabb          r7,  r10, lr,  r7
1590
+        smultb          r10, r10, lr
1591
+        ssat            r8,  #8,  r8,  asr #7
1592
+        ssat            r6,  #8,  r6,  asr #7
1593
+        add             r10, r10, #63
1594
+        ssat            r7,  #8,  r7,  asr #7
1595
+        ssat            r10, #8,  r10, asr #7
1596
+
1597
+        ldr             lr, c0x80808080
1598
+
1599
+        pkhbt           r6,  r8,  r6,  lsl #16
1600
+        pkhbt           r10, r7,  r10, lsl #16
1601
+        uxtb16          r6,  r6
1602
+        uxtb16          r10, r10
1603
+
1604
+        sub             r0,  r0,  r1,  lsl #2   @ move r0 pointer down by 4 lines
1605
+
1606
+        orr             r10, r6,  r10, lsl #8   @ u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7)
1607
+
1608
+        qsub8           r8,  r9,  r10           @ s = vp8_signed_char_clamp(qs0 - u)
1609
+        qadd8           r10, r11, r10           @ s = vp8_signed_char_clamp(ps0 + u)
1610
+        eor             r8,  r8,  lr            @ *oq0 = s^0x80
1611
+        eor             r10, r10, lr            @ *op0 = s^0x80
1612
+
1613
+        strb            r10,[r0,  #-1]          @ store op0 result
1614
+        strb_post       r8,  r0,  r1            @ store oq0 result
1615
+        mov             r10, r10, lsr #8
1616
+        mov             r8,  r8,  lsr #8
1617
+        strb            r10,[r0,  #-1]
1618
+        strb_post       r8,  r0,  r1
1619
+        mov             r10, r10, lsr #8
1620
+        mov             r8,  r8,  lsr #8
1621
+        strb            r10,[r0,  #-1]
1622
+        strb_post       r8,  r0,  r1
1623
+        mov             r10, r10, lsr #8
1624
+        mov             r8,  r8,  lsr #8
1625
+        strb            r10,[r0,  #-1]
1626
+        strb_post       r8,  r0,  r1
1627
+
1628
+        @roughly 2/7th difference across boundary
1629
+        mov             lr,  #0x12              @ 18
1630
+        mov             r7,  #0x3f              @ 63
1631
+
1632
+        sxtb16          r6,  r12
1633
+        sxtb16          r10, r12, ror #8
1634
+        smlabb          r8,  r6,  lr,  r7
1635
+        smlatb          r6,  r6,  lr,  r7
1636
+        smlabb          r9,  r10, lr,  r7
1637
+        smlatb          r10, r10, lr,  r7
1638
+        ssat            r8,  #8,  r8,  asr #7
1639
+        ssat            r6,  #8,  r6,  asr #7
1640
+        ssat            r9,  #8,  r9,  asr #7
1641
+        ssat            r10, #8,  r10, asr #7
1642
+
1643
+        sub             r0,  r0,  r1,  lsl #2   @ move r0 pointer down by 4 lines
1644
+
1645
+        pkhbt           r6,  r8,  r6,  lsl #16
1646
+        pkhbt           r10, r9,  r10, lsl #16
1647
+
1648
+        ldr             r9, [sp,  #8]           @ load qs1
1649
+        ldr             r11,[sp,  #12]          @ load ps1
1650
+        ldr             lr,  c0x80808080
1651
+
1652
+        uxtb16          r6,  r6
1653
+        uxtb16          r10, r10
1654
+
1655
+        add             r0,  r0,  #2
1656
+
1657
+        orr             r10, r6,  r10, lsl #8   @ u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7)
1658
+
1659
+        qsub8           r8,  r9,  r10           @ s = vp8_signed_char_clamp(qs1 - u)
1660
+        qadd8           r10, r11, r10           @ s = vp8_signed_char_clamp(ps1 + u)
1661
+        eor             r8,  r8,  lr            @ *oq1 = s^0x80
1662
+        eor             r10, r10, lr            @ *op1 = s^0x80
1663
+
1664
+        ldrb            r11,[r0,  #-5]          @ load p2 for 1/7th difference across boundary
1665
+        strb            r10,[r0,  #-4]          @ store op1
1666
+        strb            r8, [r0,  #-1]          @ store oq1
1667
+        ldrb_post       r9,  r0,  r1            @ load q2 for 1/7th difference across boundary
1668
+
1669
+        mov             r10, r10, lsr #8
1670
+        mov             r8,  r8,  lsr #8
1671
+
1672
+        ldrb            r6, [r0,  #-5]
1673
+        strb            r10,[r0,  #-4]
1674
+        strb            r8, [r0,  #-1]
1675
+        ldrb_post       r7,  r0,  r1
1676
+
1677
+        mov             r10, r10, lsr #8
1678
+        mov             r8,  r8,  lsr #8
1679
+        orr             r11, r11, r6,  lsl #8
1680
+        orr             r9,  r9,  r7,  lsl #8
1681
+
1682
+        ldrb            r6, [r0,  #-5]
1683
+        strb            r10,[r0,  #-4]
1684
+        strb            r8, [r0,  #-1]
1685
+        ldrb_post       r7,  r0,  r1
1686
+
1687
+        mov             r10, r10, lsr #8
1688
+        mov             r8,  r8,  lsr #8
1689
+        orr             r11, r11, r6,  lsl #16
1690
+        orr             r9,  r9,  r7,  lsl #16
1691
+
1692
+        ldrb            r6, [r0,  #-5]
1693
+        strb            r10,[r0,  #-4]
1694
+        strb            r8, [r0,  #-1]
1695
+        ldrb_post       r7,  r0,  r1
1696
+        orr             r11, r11, r6,  lsl #24
1697
+        orr             r9,  r9,  r7,  lsl #24
1698
+
1699
+        @roughly 1/7th difference across boundary
1700
+        eor             r9,  r9,  lr
1701
+        eor             r11, r11, lr
1702
+
1703
+        mov             lr,  #0x9               @ 9
1704
+        mov             r7,  #0x3f              @ 63
1705
+
1706
+        sxtb16          r6,  r12
1707
+        sxtb16          r10, r12, ror #8
1708
+        smlabb          r8,  r6,  lr,  r7
1709
+        smlatb          r6,  r6,  lr,  r7
1710
+        smlabb          r12, r10, lr,  r7
1711
+        smlatb          r10, r10, lr,  r7
1712
+        ssat            r8,  #8,  r8,  asr #7
1713
+        ssat            r6,  #8,  r6,  asr #7
1714
+        ssat            r12, #8,  r12, asr #7
1715
+        ssat            r10, #8,  r10, asr #7
1716
+
1717
+        sub             r0,  r0,  r1,  lsl #2
1718
+
1719
+        pkhbt           r6,  r8,  r6,  lsl #16
1720
+        pkhbt           r10, r12, r10, lsl #16
1721
+
1722
+        uxtb16          r6,  r6
1723
+        uxtb16          r10, r10
1724
+
1725
+        ldr             lr,  c0x80808080
1726
+
1727
+        orr             r10, r6,  r10, lsl #8   @ u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7)
1728
+
1729
+        qadd8           r8,  r11, r10           @ s = vp8_signed_char_clamp(ps2 + u)
1730
+        qsub8           r10, r9,  r10           @ s = vp8_signed_char_clamp(qs2 - u)
1731
+        eor             r8,  r8,  lr            @ *op2 = s^0x80
1732
+        eor             r10, r10, lr            @ *oq2 = s^0x80
1733
+
1734
+        strb            r8, [r0,  #-5]          @ store *op2
1735
+        strb_post       r10, r0,  r1            @ store *oq2
1736
+        mov             r8,  r8,  lsr #8
1737
+        mov             r10, r10, lsr #8
1738
+        strb            r8, [r0,  #-5]
1739
+        strb_post       r10, r0,  r1
1740
+        mov             r8,  r8,  lsr #8
1741
+        mov             r10, r10, lsr #8
1742
+        strb            r8, [r0,  #-5]
1743
+        strb_post       r10, r0,  r1
1744
+        mov             r8,  r8,  lsr #8
1745
+        mov             r10, r10, lsr #8
1746
+        strb            r8, [r0,  #-5]
1747
+        strb_post       r10, r0,  r1
1748
+
1749
+        @adjust r0 pointer for next loop
1750
+        sub             r0,  r0,  #2
1751
+
1752
+2:
1753
+        sub             r0,  r0,  #4
1754
+        subs            r5,  r5,  #1
1755
+
1756
+T       ittt            ne
1757
+        ldrne           r7, [r0,  r1]
1758
+A       ldrne           r6, [r0], r1,  lsl #1   @ load source data
1759
+T       ldrne           r6, [r0]
1760
+T       addne           r0,  r0,  r1,  lsl #1
1761
+T       ittt            ne
1762
+        ldrne           lr, [r0,  r1]
1763
+A       ldrne           r8, [r0], r1,  lsl #1
1764
+T       ldrne           r8, [r0]
1765
+T       addne           r0,  r0,  r1,  lsl #1
1766
+
1767
+        bne             1b
1768
+
1769
+        add             sp,  sp,  #16
1770
+        pop            {r4 - r11, pc}
1771
+endfunc
1772
+
1773
+@ MC
1774
+
1775
+@ void put_vp8_pixels16(uint8_t *dst, int dststride, uint8_t *src,
1776
+@                       int srcstride, int h, int mx, int my)
1777
+function ff_put_vp8_pixels16_armv6, export=1
1778
+        push           {r4 - r11}
1779
+        ldr             r12,[sp,  #32]          @ h
1780
+1:
1781
+        subs            r12, r12, #2
1782
+        ldr             r5, [r2,  #4]
1783
+        ldr             r6, [r2,  #8]
1784
+        ldr             r7, [r2,  #12]
1785
+        ldr_post        r4,  r2,  r3
1786
+        ldr             r9, [r2,  #4]
1787
+        ldr             r10,[r2,  #8]
1788
+        ldr             r11,[r2,  #12]
1789
+        ldr_post        r8,  r2,  r3
1790
+        strd            r6,  r7, [r0,  #8]
1791
+        strd_post       r4,  r5,  r0,  r1
1792
+        strd            r10, r11,[r0,  #8]
1793
+        strd_post       r8,  r9,  r0,  r1
1794
+        bgt             1b
1795
+        pop            {r4 - r11}
1796
+        bx              lr
1797
+endfunc
1798
+
1799
+@ void put_vp8_pixels8(uint8_t *dst, int dststride, uint8_t *src,
1800
+@                      int srcstride, int h, int mx, int my)
1801
+function ff_put_vp8_pixels8_armv6, export=1
1802
+        push           {r4 - r11}
1803
+        ldr             r12,[sp,  #32]          @ h
1804
+1:
1805
+        subs            r12, r12, #4
1806
+        ldr             r5, [r2,  #4]
1807
+        ldr_post        r4,  r2,  r3
1808
+        ldr             r7, [r2,  #4]
1809
+        ldr_post        r6,  r2,  r3
1810
+        ldr             r9, [r2,  #4]
1811
+        ldr_post        r8,  r2,  r3
1812
+        ldr             r11,[r2,  #4]
1813
+        ldr_post        r10, r2,  r3
1814
+        strd_post       r4,  r5,  r0,  r1
1815
+        strd_post       r6,  r7,  r0,  r1
1816
+        strd_post       r8,  r9,  r0,  r1
1817
+        strd_post       r10, r11, r0,  r1
1818
+        bgt             1b
1819
+        pop            {r4 - r11}
1820
+        bx              lr
1821
+endfunc
1822
+
1823
+@ void put_vp8_pixels4(uint8_t *dst, int dststride, uint8_t *src,
1824
+@                      int srcstride, int h, int mx, int my)
1825
+function ff_put_vp8_pixels4_armv6, export=1
1826
+        ldr             r12, [sp, #0]           @ h
1827
+        push           {r4 - r6, lr}
1828
+1:
1829
+        subs            r12, r12, #4
1830
+        ldr             r5, [r2,  r3]
1831
+        ldr_post        r4,  r2,  r3,  lsl #1
1832
+        ldr             lr, [r2,  r3]
1833
+        ldr_post        r6,  r2,  r3,  lsl #1
1834
+        str             r5, [r0,  r1]
1835
+        str_post        r4,  r0,  r1,  lsl #1
1836
+        str             lr, [r0,  r1]
1837
+        str_post        r6,  r0,  r1,  lsl #1
1838
+        bgt             1b
1839
+        pop            {r4 - r6,  pc}
1840
+endfunc
1841
+
1842
+@ note: worst case sum of all 6-tap filter values * 255 is 0x7f80 so 16 bit
1843
+@ arithmatic can be used to apply filters
1844
+const sixtap_filters_13245600, align=4
1845
+        .short     2, 108, -11,  36,  -8, 1, 0, 0
1846
+        .short     3,  77, -16,  77, -16, 3, 0, 0
1847
+        .short     1,  36,  -8, 108, -11, 2, 0, 0
1848
+endconst
1849
+const fourtap_filters_1324, align=4
1850
+        .short     -6,  12, 123, -1
1851
+        .short     -9,  50,  93, -6
1852
+        .short     -6,  93,  50, -9
1853
+        .short     -1, 123,  12, -6
1854
+endconst
1855
+
1856
+@ void put_vp8_epel_h6(uint8_t *dst, int dststride, uint8_t *src,
1857
+@                      int srcstride, int w, int h, int mx)
1858
+function ff_put_vp8_epel_h6_armv6, export=1
1859
+        push           {r4 - r11, lr}
1860
+
1861
+        sub             r2,  r2,  #2
1862
+        movrel          lr,  sixtap_filters_13245600 - 16
1863
+        ldr             r12,[sp,  #44]          @ vp8_filter index
1864
+        ldr             r4, [sp,  #36]          @ width
1865
+        add             lr,  lr,  r12, lsl #3
1866
+        sub             r3,  r3,  r4            @ src_stride - block_width
1867
+        sub             r1,  r1,  r4            @ dst_stride - block_width
1868
+        lsr             r4, #2
1869
+
1870
+        str             r4, [sp,  #36]          @ "4-in-parallel" loop counter @40
1871
+        str             r3, [sp,  #44]          @ src_stride - block_width @48
1872
+        push           {r1}                     @ dst_stride - block_width @0
1873
+                                                @ height @44
1874
+
1875
+        ldr             r1, [lr], #4            @ coefficients
1876
+        ldr             r3, [lr], #4
1877
+        ldr             lr, [lr]
1878
+1:
1879
+        @ 3 loads, 10 shuffles and then mul/acc/add/shr
1880
+        @ o0: i0/i1/i2/i3/i4/i5 -> i0/i2 (ld1) | i1/i3 (ld1)   | i4/i5 (ld2)
1881
+        @ o1: i1/i2/i3/i4/i5/i6 -> i1/i3 (ld1) | i2/i4 (ld2)   | i5/i6 (ld2/3)
1882
+        @ o2: i2/i3/i4/i5/i6/i7 -> i2/i4 (ld2) | i3/i5 (ld2)   | i6/i7 (ld3)
1883
+        @ o3: i3/i4/i5/i6/i7/i8 -> i3/i5 (ld2) | i4/i6 (ld2/3) | i7/i8 (ld3)
1884
+        ldr             r7, [r2,  #5]           @ ld3 -> src[5-8]
1885
+        ldr             r6, [r2,  #2]           @ ld2 -> src[2-5]
1886
+        ldr             r5, [r2], #4            @ ld1 -> src[0-3]
1887
+
1888
+        pkhtb           r7,  r7,  r7,  asr #8   @ src[8,7,7,6]
1889
+        uxtb16          r9,  r6,  ror #8        @ src[5] | src[3]
1890
+        uxtb16          r6,  r6                 @ src[4] | src[2]
1891
+        uxtb16          r8,  r5,  ror #8        @ src[3] | src[1]
1892
+        uxtb16          r11, r7,  ror #8        @ src[8] | src[7]
1893
+        uxtb16          r7,  r7                 @ src[7] | src[6]
1894
+        pkhtb           r10, r9,  r6,  asr #16  @ src[5] | src[4]
1895
+        uxtb16          r5,  r5                 @ src[2] | src[0]
1896
+
1897
+        smuad           r11, r11, lr            @ filter[3][2] -> r11
1898
+        subs            r4,  r4,  #1
1899
+        pkhbt           r12, r10, r7,  lsl #16  @ src[6] | src[4]
1900
+        smuad           r7,  r7,  lr            @ filter[2][2] -> r7
1901
+        smuad           r5,  r5,  r1            @ filter[0][0] -> r5
1902
+        smlad           r11, r9,  r1,  r11      @ filter[3][0] -> r11
1903
+        smlad           r7,  r9,  r3,  r7       @ filter[2][1] -> r7
1904
+        smuad           r9,  r8,  r1            @ filter[1][0] -> r9
1905
+        smlad           r5,  r8,  r3,  r5       @ filter[0][1] -> r5
1906
+        pkhtb           r8,  r12, r10, asr #16  @ src[6] | src[5]
1907
+        smlad           r11, r12, r3,  r11      @ filter[3][1] -> r11
1908
+        smlad           r9,  r6,  r3,  r9       @ filter[1][1] -> r9
1909
+        smlad           r5,  r10, lr,  r5       @ filter[0][2] -> r5
1910
+        smlad           r7,  r6,  r1,  r7       @ filter[2][0] -> r7
1911
+        smlad           r9,  r8,  lr,  r9       @ filter[1][2] -> r9
1912
+
1913
+        add             r5,  r5,  #0x40         @ round_shift_and_clamp[0]
1914
+        add             r9,  r9,  #0x40         @ round_shift_and_clamp[1]
1915
+        add             r7,  r7,  #0x40         @ round_shift_and_clamp[2]
1916
+        add             r11, r11, #0x40         @ round_shift_and_clamp[3]
1917
+
1918
+        usat            r5,  #8,  r5,  asr #7
1919
+        usat            r9,  #8,  r9,  asr #7
1920
+        usat            r7,  #8,  r7,  asr #7
1921
+        usat            r11, #8,  r11, asr #7
1922
+
1923
+        strb            r5, [r0], #1            @ store res[0]
1924
+        strb            r9, [r0], #1            @ store res[1]
1925
+        strb            r7, [r0], #1            @ store res[2]
1926
+        strb            r11,[r0], #1            @ store res[3]
1927
+
1928
+        bne             1b
1929
+
1930
+        ldr             r12,[sp,  #44]          @ height = outer-loop counter
1931
+        subs            r12, r12, #1
1932
+T       itttt           ne
1933
+        ldrne           r4, [sp,  #40]          @ 4-in-parallel loop counter
1934
+        ldrne           r5, [sp,  #48]
1935
+        ldrne           r6, [sp]
1936
+        strne           r12,[sp,  #44]
1937
+        add             r2,  r2,  r5            @ move to next input/output lines
1938
+        add             r0,  r0,  r6
1939
+
1940
+        bne             1b
1941
+
1942
+        add             sp,  sp,  #4            @ restore stack after push{r1} above
1943
+        pop            {r4 - r11, pc}
1944
+endfunc
1945
+
1946
+@ void put_vp8_epel_v6(uint8_t *dst, int dststride, uint8_t *src,
1947
+@                      int srcstride, int w, int h, int my)
1948
+function ff_put_vp8_epel_v6_armv6, export=1
1949
+        push           {r4 - r11, lr}
1950
+
1951
+        movrel          lr,  sixtap_filters_13245600 - 16
1952
+        ldr             r12,[sp,  #44]          @ vp8_filter index
1953
+        ldr             r4, [sp,  #36]          @ width
1954
+        add             lr,  lr,  r12, lsl #3
1955
+        sub             r1,  r1,  r4            @ dst_stride - block_width
1956
+        lsr             r4,  #2
1957
+
1958
+        str             r4, [sp,  #36]          @ "4-in-parallel" loop counter @40
1959
+        str             r3, [sp,  #44]          @ src_stride - block_width @48
1960
+        push           {r1}                     @ dst_stride - block_width @0
1961
+                                                @ height @44
1962
+1:
1963
+        add             r1,  r3,  r3,  lsl #1   @ stride * 3
1964
+        ldr_dpren       r5,  r2,  r3            @ src[0,1,2,3 + stride * 1]
1965
+        ldr             r6, [r2,  r3]           @ src[0,1,2,3 + stride * 3]
1966
+        ldr             r7, [r2,  r3,  lsl #1]  @ src[0,1,2,3 + stride * 4]
1967
+        ldr             r8, [r2,  r1]           @ src[0,1,2,3 + stride * 5]
1968
+
1969
+        @ byte -> word and "transpose"
1970
+        uxtb16          r9,  r5,  ror #8        @ src[3 + stride*1] | src[1 + stride*1]
1971
+        uxtb16          r10, r6,  ror #8        @ src[3 + stride*3] | src[1 + stride*3]
1972
+        uxtb16          r11, r7,  ror #8        @ src[3 + stride*4] | src[1 + stride*4]
1973
+        uxtb16          r12, r8,  ror #8        @ src[3 + stride*5] | src[1 + stride*5]
1974
+        uxtb16          r5,  r5                 @ src[2 + stride*1] | src[0 + stride*1]
1975
+        uxtb16          r6,  r6                 @ src[2 + stride*3] | src[0 + stride*3]
1976
+        uxtb16          r7,  r7                 @ src[2 + stride*4] | src[0 + stride*4]
1977
+        uxtb16          r8,  r8                 @ src[2 + stride*5] | src[0 + stride*5]
1978
+        pkhbt           r1,  r9,  r10, lsl #16  @ src[1 + stride*3] | src[1 + stride*1]
1979
+        pkhtb           r9,  r10, r9,  asr #16  @ src[3 + stride*3] | src[3 + stride*1]
1980
+        pkhbt           r10, r11, r12, lsl #16  @ src[1 + stride*5] | src[1 + stride*4]
1981
+        pkhtb           r11, r12, r11, asr #16  @ src[3 + stride*5] | src[3 + stride*4]
1982
+        pkhbt           r12, r5,  r6,  lsl #16  @ src[0 + stride*3] | src[0 + stride*1]
1983
+        pkhtb           r5,  r6,  r5,  asr #16  @ src[2 + stride*3] | src[2 + stride*1]
1984
+        pkhbt           r6,  r7,  r8,  lsl #16  @ src[0 + stride*5] | src[0 + stride*4]
1985
+        pkhtb           r7,  r8,  r7,  asr #16  @ src[2 + stride*5] | src[2 + stride*4]
1986
+
1987
+        ldr             r8, [lr,  #4]           @ stall - if only I had more registers...
1988
+        smuad           r12, r12, r8            @ filter[0][1]
1989
+        smuad           r1,  r1,  r8            @ filter[1][1]
1990
+        smuad           r5,  r5,  r8            @ filter[2][1]
1991
+        smuad           r9,  r9,  r8            @ filter[3][1]
1992
+        ldr             r8, [lr,  #8]           @ stall - if only I had more registers...
1993
+        smlad           r12, r6,  r8, r12       @ filter[0][2]
1994
+        smlad           r1,  r10, r8, r1        @ filter[1][2]
1995
+        ldr_dpren       r6,  r2,  r3,  lsl #1   @ src[0,1,2,3 + stride *  0]
1996
+        ldr             r10,[r2], #4            @ src[0,1,2,3 + stride *  2]
1997
+        smlad           r5,  r7,  r8, r5        @ filter[2][2]
1998
+        smlad           r9,  r11, r8, r9        @ filter[3][2]
1999
+
2000
+        uxtb16          r7,  r6,  ror #8        @ src[3 + stride*0] | src[1 + stride*0]
2001
+        uxtb16          r11, r10, ror #8        @ src[3 + stride*2] | src[1 + stride*2]
2002
+        uxtb16          r6,  r6                 @ src[2 + stride*0] | src[0 + stride*0]
2003
+        uxtb16          r10, r10                @ src[2 + stride*2] | src[0 + stride*2]
2004
+
2005
+        pkhbt           r8,  r7,  r11, lsl #16  @ src[1 + stride*2] | src[1 + stride*0]
2006
+        pkhtb           r7,  r11, r7,  asr #16  @ src[3 + stride*2] | src[3 + stride*0]
2007
+        pkhbt           r11, r6,  r10, lsl #16  @ src[0 + stride*2] | src[0 + stride*0]
2008
+        pkhtb           r6,  r10, r6,  asr #16  @ src[2 + stride*2] | src[2 + stride*0]
2009
+
2010
+        ldr             r10,[lr]                @ stall - if only I had more registers...
2011
+        subs            r4,  r4,  #1            @ counter--
2012
+        smlad           r12, r11, r10, r12      @ filter[0][0]
2013
+        smlad           r1,  r8,  r10, r1       @ filter[1][0]
2014
+        smlad           r5,  r6,  r10, r5       @ filter[2][0]
2015
+        smlad           r9,  r7,  r10, r9       @ filter[3][0]
2016
+
2017
+        add             r12, r12, #0x40         @ round_shift_and_clamp[0]
2018
+        add             r1,  r1,  #0x40         @ round_shift_and_clamp[1]
2019
+        add             r5,  r5,  #0x40         @ round_shift_and_clamp[2]
2020
+        add             r9,  r9,  #0x40         @ round_shift_and_clamp[3]
2021
+
2022
+        usat            r12, #8,  r12, asr #7
2023
+        usat            r1,  #8,  r1,  asr #7
2024
+        usat            r5,  #8,  r5,  asr #7
2025
+        usat            r9,  #8,  r9,  asr #7
2026
+
2027
+        strb            r12,[r0], #1            @ store res[0]
2028
+        strb            r1, [r0], #1            @ store res[1]
2029
+        strb            r5, [r0], #1            @ store res[2]
2030
+        strb            r9, [r0], #1            @ store res[3]
2031
+
2032
+        bne             1b
2033
+
2034
+        ldr             r12,[sp,  #44]          @ height = outer-loop counter
2035
+        subs            r12, r12, #1
2036
+T       itttt           ne
2037
+        ldrne           r4, [sp,  #40]          @ 4-in-parallel loop counter
2038
+        ldrne           r6, [sp,  #0]
2039
+        subne           r2,  r2,  r4,  lsl #2
2040
+        strne           r12,[sp,  #44]
2041
+        add             r0,  r0,  r6
2042
+        add             r2,  r2,  r3            @ move to next input/output lines
2043
+
2044
+        bne             1b
2045
+
2046
+        add             sp,  sp,  #4            @ restore stack after push{r1} above
2047
+        pop            {r4 - r11, pc}
2048
+endfunc
2049
+
2050
+@ void put_vp8_epel_h4(uint8_t *dst, int dststride, uint8_t *src,
2051
+@                      int srcstride, int w, int h, int mx)
2052
+function ff_put_vp8_epel_h4_armv6, export=1
2053
+        push           {r4 - r11, lr}
2054
+
2055
+        subs            r2,  r2,  #1
2056
+        movrel          lr,  fourtap_filters_1324 - 4
2057
+        ldr             r4, [sp,  #36]          @ width
2058
+        ldr             r12,[sp,  #44]          @ vp8_filter index
2059
+        add             lr,  lr,  r12, lsl #2
2060
+        sub             r3,  r3,  r4            @ src_stride - block_width
2061
+        sub             r1,  r1,  r4            @ dst_stride - block_width
2062
+        ldr             r5,  [lr]
2063
+        ldr             r6,  [lr,  #4]
2064
+        asr             r4,  #2
2065
+
2066
+        ldr             lr, [sp,  #40]          @ height = outer-loop counter
2067
+        str             r4, [sp,  #36]          @ "4-in-parallel" inner loop counter
2068
+1:
2069
+        @ 3 loads, 5 uxtb16s and then mul/acc/add/shr
2070
+        @ o0: i0/i1/i2/i3 -> i0/i2(ld1) + i1/i3(ld1)
2071
+        @ o1: i1/i2/i3/i4 -> i1/i3(ld1) + i2/i4(ld2)
2072
+        @ o2: i2/i3/i4/i5 -> i2/i4(ld2) + i3/i5(ld2)
2073
+        @ o3: i3/i4/i5/i6 -> i3/i5(ld2) + i4/i6(ld3)
2074
+        ldr             r9, [r2,  #3]           @ load source data
2075
+        ldr             r8, [r2,  #2]
2076
+        ldr             r7, [r2], #4
2077
+
2078
+        uxtb16          r9,  r9,  ror #8        @ src[6] | src[4]
2079
+        uxtb16          r10, r8,  ror #8        @ src[5] | src[3]
2080
+        uxtb16          r8,  r8                 @ src[4] | src[2]
2081
+        uxtb16          r11, r7,  ror #8        @ src[3] | src[1]
2082
+        uxtb16          r7,  r7                 @ src[2] | src[0]
2083
+
2084
+        smuad           r9,  r9,  r6            @ filter[3][1] -> r9
2085
+        smuad           r12, r10, r6            @ filter[2][1] -> r12
2086
+        smuad           r7,  r7,  r5            @ filter[0][0] -> r7
2087
+        smlad           r9,  r10, r5,  r9       @ filter[3][0] -> r9
2088
+        smuad           r10, r11, r5            @ filter[1][0] -> r10
2089
+        smlad           r12, r8,  r5,  r12      @ filter[2][0] -> r12
2090
+        smlad           r7,  r11, r6,  r7       @ filter[0][1] -> r7
2091
+        smlad           r10, r8,  r6,  r10      @ filter[1][1] -> r10
2092
+
2093
+        subs            r4,  r4,  #1            @ counter--
2094
+
2095
+        add             r7,  r7,  #0x40         @ round_shift_and_clamp[0]
2096
+        add             r10, r10, #0x40         @ round_shift_and_clamp[1]
2097
+        add             r12, r12, #0x40         @ round_shift_and_clamp[2]
2098
+        add             r9,  r9,  #0x40         @ round_shift_and_clamp[3]
2099
+
2100
+        usat            r7,  #8,  r7,  asr #7
2101
+        usat            r10, #8,  r10, asr #7
2102
+        usat            r12, #8,  r12, asr #7
2103
+        usat            r9,  #8,  r9,  asr #7
2104
+
2105
+        strb            r7, [r0], #1            @ store res[0]
2106
+        strb            r10,[r0], #1            @ store res[1]
2107
+        strb            r12,[r0], #1            @ store res[2]
2108
+        strb            r9, [r0], #1            @ store res[3]
2109
+
2110
+        bne             1b
2111
+
2112
+        subs            lr,  lr,  #1
2113
+T       it              ne
2114
+        ldrne           r4, [sp,  #36]          @ 4-in-parallel loop counter
2115
+        add             r2,  r2,  r3            @ move to next input/output lines
2116
+        add             r0,  r0,  r1
2117
+
2118
+        bne             1b
2119
+
2120
+        pop            {r4 - r11, pc}
2121
+endfunc
2122
+
2123
+@ void put_vp8_epel_v4(uint8_t *dst, int dststride, uint8_t *src,
2124
+@                      int srcstride, int w, int h, int my)
2125
+function ff_put_vp8_epel_v4_armv6, export=1
2126
+        push           {r4 - r11, lr}
2127
+
2128
+        movrel          lr,  fourtap_filters_1324 - 4
2129
+        ldr             r12,[sp,  #44]          @ vp8_filter index
2130
+        ldr             r4, [sp,  #36]          @ width
2131
+        add             lr,  lr,  r12, lsl #2
2132
+        sub             r1,  r1,  r4            @ dst_stride - block_width
2133
+        asr             r4,  #2
2134
+        ldr             r5, [lr]
2135
+        ldr             r6, [lr,  #4]
2136
+
2137
+        str             r4, [sp,  #36]          @ "4-in-parallel" loop counter @40
2138
+        str             r3, [sp,  #44]          @ src_stride @48
2139
+        push           {r1}                     @ dst_stride - block_width @36
2140
+                                                @ height @44
2141
+1:
2142
+        ldr             lr, [r2,  r3, lsl #1]   @ load source pixels
2143
+        ldr             r12,[r2,  r3]
2144
+        ldr_dpren       r7,  r2,  r3
2145
+        ldr             r11,[r2], #4
2146
+
2147
+        @ byte -> word and "transpose"
2148
+        uxtb16          r8,  lr,  ror #8        @ src[3 + stride*3] | src[1 + stride*3]
2149
+        uxtb16          r9,  r12, ror #8        @ src[3 + stride*2] | src[1 + stride*2]
2150
+        uxtb16          r3,  r7,  ror #8        @ src[3 + stride*0] | src[1 + stride*0]
2151
+        uxtb16          r1,  r11, ror #8        @ src[3 + stride*1] | src[1 + stride*1]
2152
+        uxtb16          lr,  lr                 @ src[2 + stride*3] | src[0 + stride*3]
2153
+        uxtb16          r12, r12                @ src[2 + stride*2] | src[0 + stride*2]
2154
+        uxtb16          r7,  r7                 @ src[2 + stride*0] | src[0 + stride*0]
2155
+        uxtb16          r11, r11                @ src[2 + stride*1] | src[0 + stride*1]
2156
+        pkhbt           r10, r1,  r8,  lsl #16  @ src[1 + stride*3] | src[1 + stride*1]
2157
+        pkhtb           r1,  r8,  r1,  asr #16  @ src[3 + stride*3] | src[3 + stride*1]
2158
+        pkhbt           r8,  r3,  r9,  lsl #16  @ src[1 + stride*2] | src[1 + stride*0]
2159
+        pkhtb           r3,  r9,  r3,  asr #16  @ src[3 + stride*2] | src[3 + stride*0]
2160
+        pkhbt           r9,  r11, lr,  lsl #16  @ src[0 + stride*3] | src[0 + stride*1]
2161
+        pkhtb           r11, lr,  r11, asr #16  @ src[2 + stride*3] | src[2 + stride*1]
2162
+        pkhbt           lr,  r7,  r12, lsl #16  @ src[0 + stride*2] | src[0 + stride*0]
2163
+        pkhtb           r7,  r12, r7,  asr #16  @ src[2 + stride*2] | src[2 + stride*0]
2164
+
2165
+        smuad           r9,  r9,  r6            @ filter[0][1]
2166
+        smuad           r10, r10, r6            @ filter[1][1]
2167
+        smuad           r11, r11, r6            @ filter[2][1]
2168
+        smuad           r1,  r1,  r6            @ filter[3][1]
2169
+        smlad           r9,  lr,  r5, r9        @ filter[0][0]
2170
+        smlad           r10, r8,  r5, r10       @ filter[1][0]
2171
+        smlad           r11, r7,  r5, r11       @ filter[2][0]
2172
+        smlad           r1,  r3,  r5, r1        @ filter[3][0]
2173
+
2174
+        subs            r4,  r4,  #1            @ counter--
2175
+        ldr             r3, [sp,  #48]          @ FIXME prevent clobber of r3 above?
2176
+
2177
+        add             r9,  r9,  #0x40         @ round_shift_and_clamp[0]
2178
+        add             r10, r10, #0x40         @ round_shift_and_clamp[1]
2179
+        add             r11, r11, #0x40         @ round_shift_and_clamp[2]
2180
+        add             r1,  r1,  #0x40         @ round_shift_and_clamp[3]
2181
+
2182
+        usat            r9,  #8,  r9,  asr #7
2183
+        usat            r10, #8,  r10, asr #7
2184
+        usat            r11, #8,  r11, asr #7
2185
+        usat            r1,  #8,  r1,  asr #7
2186
+
2187
+        strb            r9, [r0], #1            @ store result
2188
+        strb            r10,[r0], #1
2189
+        strb            r11,[r0], #1
2190
+        strb            r1, [r0], #1
2191
+
2192
+        bne             1b
2193
+
2194
+        ldr             r12,[sp,  #44]          @ height = outer-loop counter
2195
+        subs            r12, r12, #1
2196
+T       ittt            ne
2197
+        ldrne           r4, [sp,  #40]          @ 4-in-parallel loop counter
2198
+        ldrne           r9, [sp,  #0]
2199
+        strne           r12,[sp,  #44]
2200
+        sub             r2,  r2,  r4,  lsl #2
2201
+        add             r0,  r0,  r9
2202
+        add             r2,  r2,  r3            @ move to next input/output lines
2203
+
2204
+        bne             1b
2205
+
2206
+        add             sp,  sp,  #4            @ restore stack after push{r1} above
2207
+        pop            {r4 - r11, pc}
2208
+endfunc
2209
+
2210
+@ void put_vp8_bilin_h(uint8_t *dst, int dststride, uint8_t *src,
2211
+@                      int srcstride, int w, int h, int mx)
2212
+function ff_put_vp8_bilin_h_armv6, export=1
2213
+        push           {r4 - r9,  lr}
2214
+
2215
+        ldr             r8, [sp,  #36]          @ vp8_filter index
2216
+        ldr             r12,[sp,  #32]          @ height = outer-loop counter
2217
+        ldr             r4, [sp,  #28]          @ width
2218
+        lsl             r5,  r8,  #16           @ mx << 16
2219
+        sub             r3,  r3,  r4            @ src_stride - block_width
2220
+        sub             r1,  r1,  r4            @ dst_stride - block_width
2221
+        asr             r4,  #2
2222
+        sub             r5,  r5,  r8            @ (mx << 16) | (-mx)
2223
+        str             r4, [sp,  #28]          @ "4-in-parallel" loop counter
2224
+        add             r5,  r5,  #8            @ (8 - mx) | (mx << 16) = filter coefficients
2225
+1:
2226
+        ldrb            r6, [r2], #1            @ load source data
2227
+        ldrb            r7, [r2], #1
2228
+        ldrb            r8, [r2], #1
2229
+        ldrb            r9, [r2], #1
2230
+        ldrb            lr, [r2]
2231
+
2232
+        pkhbt           r6,  r6,  r7,  lsl #16  @ src[1] | src[0]
2233
+        pkhbt           r7,  r7,  r8,  lsl #16  @ src[2] | src[1]
2234
+        pkhbt           r8,  r8,  r9,  lsl #16  @ src[3] | src[2]
2235
+        pkhbt           r9,  r9,  lr,  lsl #16  @ src[4] | src[3]
2236
+
2237
+        smuad           r6,  r6,  r5            @ apply the filter
2238
+        smuad           r7,  r7,  r5
2239
+        smuad           r8,  r8,  r5
2240
+        smuad           r9,  r9,  r5
2241
+
2242
+        subs            r4,  r4,  #1            @ counter--
2243
+
2244
+        add             r6,  r6,  #0x4          @ round_shift_and_clamp
2245
+        add             r7,  r7,  #0x4
2246
+        add             r8,  r8,  #0x4
2247
+        add             r9,  r9,  #0x4
2248
+
2249
+        asr             r6,  #3
2250
+        asr             r7,  #3
2251
+        pkhbt           r6,  r6,  r8,  lsl #13
2252
+        pkhbt           r7,  r7,  r9,  lsl #13
2253
+        orr             r6,  r6,  r7,  lsl #8
2254
+        str             r6, [r0], #4            @ store result
2255
+
2256
+        bne             1b
2257
+
2258
+        ldr             r4, [sp,  #28]          @ 4-in-parallel loop counter
2259
+        subs            r12, r12, #1
2260
+
2261
+        add             r2,  r2,  r3            @ move to next input/output lines
2262
+        add             r0,  r0,  r1
2263
+
2264
+        bne             1b
2265
+
2266
+        pop            {r4 - r9,  pc}
2267
+endfunc
2268
+
2269
+@ void put_vp8_bilin_v(uint8_t *dst, int dststride, uint8_t *src,
2270
+@                      int srcstride, int w, int h, int my)
2271
+function ff_put_vp8_bilin_v_armv6, export=1
2272
+        push           {r4 - r11, lr}
2273
+
2274
+        ldr             r11,[sp,  #44]          @ vp8_filter index
2275
+        ldr             r4, [sp,  #36]          @ width
2276
+        mov             r5,  r11, lsl #16       @ mx << 16
2277
+        ldr             r12,[sp,  #40]          @ height = outer-loop counter
2278
+        sub             r1,  r1,  r4
2279
+        sub             r5,  r5,  r11           @ (mx << 16) | (-mx)
2280
+        asr             r4,  #2
2281
+        add             r5,  r5,  #8            @ (8 - mx) | (mx << 16) = filter coefficients
2282
+        str             r4, [sp,  #36]          @ "4-in-parallel" loop counter
2283
+1:
2284
+        ldrb            r10,[r2,  r3]           @ load the data
2285
+        ldrb            r6, [r2], #1
2286
+        ldrb            r11,[r2,  r3]
2287
+        ldrb            r7, [r2], #1
2288
+        ldrb            lr, [r2,  r3]
2289
+        ldrb            r8, [r2], #1
2290
+        ldrb            r9, [r2,  r3]
2291
+        pkhbt           r6,  r6,  r10, lsl #16
2292
+        ldrb            r10,[r2], #1
2293
+        pkhbt           r7,  r7,  r11, lsl #16
2294
+        pkhbt           r8,  r8,  lr,  lsl #16
2295
+        pkhbt           r9,  r10, r9,  lsl #16
2296
+
2297
+        smuad           r6,  r6,  r5            @ apply the filter
2298
+        smuad           r7,  r7,  r5
2299
+        smuad           r8,  r8,  r5
2300
+        smuad           r9,  r9,  r5
2301
+
2302
+        subs            r4,  r4,  #1            @ counter--
2303
+
2304
+        add             r6,  r6,  #0x4          @ round_shift_and_clamp
2305
+        add             r7,  r7,  #0x4
2306
+        add             r8,  r8,  #0x4
2307
+        add             r9,  r9,  #0x4
2308
+
2309
+        asr             r6,  #3
2310
+        asr             r7,  #3
2311
+        pkhbt           r6,  r6,  r8,  lsl #13
2312
+        pkhbt           r7,  r7,  r9,  lsl #13
2313
+        orr             r6,  r6,  r7,  lsl #8
2314
+        str             r6, [r0], #4            @ store result
2315
+
2316
+        bne             1b
2317
+
2318
+        ldr             r4, [sp,  #36]          @ 4-in-parallel loop counter
2319
+        subs            r12, r12, #1
2320
+
2321
+        add             r2,  r2,  r3            @ move to next input/output lines
2322
+        add             r0,  r0,  r1
2323
+        sub             r2,  r2,  r4,  lsl #2
2324
+
2325
+        bne             1b
2326
+        pop            {r4 - r11, pc}
2327
+endfunc
... ...
@@ -19,13 +19,17 @@
19 19
 #include <stdint.h>
20 20
 #include "libavcodec/vp8dsp.h"
21 21
 
22
-void ff_vp8_luma_dc_wht_neon(DCTELEM block[4][4][16], DCTELEM dc[16]);
23
-void ff_vp8_luma_dc_wht_dc_neon(DCTELEM block[4][4][16], DCTELEM dc[16]);
22
+void ff_vp8_luma_dc_wht_dc_armv6(DCTELEM block[4][4][16], DCTELEM dc[16]);
24 23
 
25
-void ff_vp8_idct_add_neon(uint8_t *dst, DCTELEM block[16], int stride);
26
-void ff_vp8_idct_dc_add_neon(uint8_t *dst, DCTELEM block[16], int stride);
27
-void ff_vp8_idct_dc_add4y_neon(uint8_t *dst, DCTELEM block[4][16], int stride);
28
-void ff_vp8_idct_dc_add4uv_neon(uint8_t *dst, DCTELEM block[4][16], int stride);
24
+#define idct_funcs(opt) \
25
+void ff_vp8_luma_dc_wht_ ## opt(DCTELEM block[4][4][16], DCTELEM dc[16]); \
26
+void ff_vp8_idct_add_ ## opt(uint8_t *dst, DCTELEM block[16], int stride); \
27
+void ff_vp8_idct_dc_add_ ## opt(uint8_t *dst, DCTELEM block[16], int stride); \
28
+void ff_vp8_idct_dc_add4y_ ## opt(uint8_t *dst, DCTELEM block[4][16], int stride); \
29
+void ff_vp8_idct_dc_add4uv_ ## opt(uint8_t *dst, DCTELEM block[4][16], int stride)
30
+
31
+idct_funcs(neon);
32
+idct_funcs(armv6);
29 33
 
30 34
 void ff_vp8_v_loop_filter16_neon(uint8_t *dst, int stride,
31 35
                                  int flim_E, int flim_I, int hev_thresh);
... ...
@@ -47,29 +51,106 @@ void ff_vp8_h_loop_filter8uv_inner_neon(uint8_t *dstU, uint8_t *dstV,
47 47
                                         int stride, int flim_E, int flim_I,
48 48
                                         int hev_thresh);
49 49
 
50
-void ff_vp8_v_loop_filter16_simple_neon(uint8_t *dst, int stride, int flim);
51
-void ff_vp8_h_loop_filter16_simple_neon(uint8_t *dst, int stride, int flim);
50
+void ff_vp8_v_loop_filter_inner_armv6(uint8_t *dst, int stride,
51
+                                      int flim_E, int flim_I,
52
+                                      int hev_thresh, int count);
53
+void ff_vp8_h_loop_filter_inner_armv6(uint8_t *dst, int stride,
54
+                                      int flim_E, int flim_I,
55
+                                      int hev_thresh, int count);
56
+void ff_vp8_v_loop_filter_armv6(uint8_t *dst, int stride,
57
+                                int flim_E, int flim_I,
58
+                                int hev_thresh, int count);
59
+void ff_vp8_h_loop_filter_armv6(uint8_t *dst, int stride,
60
+                                int flim_E, int flim_I,
61
+                                int hev_thresh, int count);
52 62
 
63
+static void ff_vp8_v_loop_filter16_armv6(uint8_t *dst, int stride,
64
+                                         int flim_E, int flim_I, int hev_thresh)
65
+{
66
+    ff_vp8_v_loop_filter_armv6(dst, stride, flim_E, flim_I, hev_thresh, 4);
67
+}
68
+
69
+static void ff_vp8_h_loop_filter16_armv6(uint8_t *dst, int stride,
70
+                                         int flim_E, int flim_I, int hev_thresh)
71
+{
72
+    ff_vp8_h_loop_filter_armv6(dst, stride, flim_E, flim_I, hev_thresh, 4);
73
+}
53 74
 
54
-#define VP8_MC(n)                                                       \
55
-    void ff_put_vp8_##n##_neon(uint8_t *dst, int dststride,             \
56
-                               uint8_t *src, int srcstride,             \
57
-                               int h, int x, int y)
75
+static void ff_vp8_v_loop_filter8uv_armv6(uint8_t *dstU, uint8_t *dstV, int stride,
76
+                                          int flim_E, int flim_I, int hev_thresh)
77
+{
78
+    ff_vp8_v_loop_filter_armv6(dstU, stride, flim_E, flim_I, hev_thresh, 2);
79
+    ff_vp8_v_loop_filter_armv6(dstV, stride, flim_E, flim_I, hev_thresh, 2);
80
+}
81
+
82
+static void ff_vp8_h_loop_filter8uv_armv6(uint8_t *dstU, uint8_t *dstV, int stride,
83
+                                          int flim_E, int flim_I, int hev_thresh)
84
+{
85
+    ff_vp8_h_loop_filter_armv6(dstU, stride, flim_E, flim_I, hev_thresh, 2);
86
+    ff_vp8_h_loop_filter_armv6(dstV, stride, flim_E, flim_I, hev_thresh, 2);
87
+}
88
+
89
+static void ff_vp8_v_loop_filter16_inner_armv6(uint8_t *dst, int stride,
90
+                                               int flim_E, int flim_I, int hev_thresh)
91
+{
92
+    ff_vp8_v_loop_filter_inner_armv6(dst, stride, flim_E, flim_I, hev_thresh, 4);
93
+}
94
+
95
+static void ff_vp8_h_loop_filter16_inner_armv6(uint8_t *dst, int stride,
96
+                                               int flim_E, int flim_I, int hev_thresh)
97
+{
98
+    ff_vp8_h_loop_filter_inner_armv6(dst, stride, flim_E, flim_I, hev_thresh, 4);
99
+}
100
+
101
+static void ff_vp8_v_loop_filter8uv_inner_armv6(uint8_t *dstU, uint8_t *dstV,
102
+                                                int stride, int flim_E, int flim_I,
103
+                                                int hev_thresh)
104
+{
105
+    ff_vp8_v_loop_filter_inner_armv6(dstU, stride, flim_E, flim_I, hev_thresh, 2);
106
+    ff_vp8_v_loop_filter_inner_armv6(dstV, stride, flim_E, flim_I, hev_thresh, 2);
107
+}
108
+
109
+static void ff_vp8_h_loop_filter8uv_inner_armv6(uint8_t *dstU, uint8_t *dstV,
110
+                                                int stride, int flim_E, int flim_I,
111
+                                                int hev_thresh)
112
+{
113
+    ff_vp8_h_loop_filter_inner_armv6(dstU, stride, flim_E, flim_I, hev_thresh, 2);
114
+    ff_vp8_h_loop_filter_inner_armv6(dstV, stride, flim_E, flim_I, hev_thresh, 2);
115
+}
116
+
117
+#define simple_lf_funcs(opt) \
118
+void ff_vp8_v_loop_filter16_simple_ ## opt(uint8_t *dst, int stride, int flim); \
119
+void ff_vp8_h_loop_filter16_simple_ ## opt(uint8_t *dst, int stride, int flim)
120
+
121
+simple_lf_funcs(neon);
122
+simple_lf_funcs(armv6);
123
+
124
+#define VP8_MC_OPT(n, opt)                                              \
125
+    void ff_put_vp8_##n##_##opt(uint8_t *dst, int dststride,            \
126
+                                uint8_t *src, int srcstride,            \
127
+                                int h, int x, int y)
128
+
129
+#define VP8_MC(n) \
130
+    VP8_MC_OPT(n, neon)
58 131
 
59 132
 #define VP8_EPEL(w)                             \
60
-    VP8_MC(pixels ## w);                        \
61 133
     VP8_MC(epel ## w ## _h4);                   \
62 134
     VP8_MC(epel ## w ## _h6);                   \
63
-    VP8_MC(epel ## w ## _v4);                   \
64 135
     VP8_MC(epel ## w ## _h4v4);                 \
65 136
     VP8_MC(epel ## w ## _h6v4);                 \
137
+    VP8_MC(epel ## w ## _v4);                   \
66 138
     VP8_MC(epel ## w ## _v6);                   \
67 139
     VP8_MC(epel ## w ## _h4v6);                 \
68 140
     VP8_MC(epel ## w ## _h6v6)
69 141
 
70 142
 VP8_EPEL(16);
143
+VP8_MC(pixels16);
144
+VP8_MC_OPT(pixels16, armv6);
71 145
 VP8_EPEL(8);
146
+VP8_MC(pixels8);
147
+VP8_MC_OPT(pixels8,  armv6);
72 148
 VP8_EPEL(4);
149
+VP8_MC_OPT(pixels4,  armv6);
73 150
 
74 151
 VP8_MC(bilin16_h);
75 152
 VP8_MC(bilin16_v);
... ...
@@ -81,83 +162,148 @@ VP8_MC(bilin4_h);
81 81
 VP8_MC(bilin4_v);
82 82
 VP8_MC(bilin4_hv);
83 83
 
84
+#define VP8_V6_MC(n) \
85
+void ff_put_vp8_##n##_armv6(uint8_t *dst, int dststride, uint8_t *src, \
86
+                            int srcstride, int w, int h, int mxy)
87
+
88
+VP8_V6_MC(epel_v6);
89
+VP8_V6_MC(epel_h6);
90
+VP8_V6_MC(epel_v4);
91
+VP8_V6_MC(epel_h4);
92
+VP8_V6_MC(bilin_v);
93
+VP8_V6_MC(bilin_h);
94
+
95
+#define VP8_EPEL_HV(SIZE, TAPNUMX, TAPNUMY, NAME, HNAME, VNAME, MAXHEIGHT) \
96
+static void ff_put_vp8_##NAME##SIZE##_##HNAME##VNAME##_armv6( \
97
+                                        uint8_t *dst, int dststride, uint8_t *src, \
98
+                                        int srcstride, int h, int mx, int my) \
99
+{ \
100
+    DECLARE_ALIGNED(4, uint8_t, tmp)[SIZE * (MAXHEIGHT + TAPNUMY - 1)]; \
101
+    uint8_t *tmpptr = tmp + SIZE * (TAPNUMY / 2 - 1); \
102
+    src -= srcstride * (TAPNUMY / 2 - 1); \
103
+    ff_put_vp8_ ## NAME ## _ ## HNAME ## _armv6(tmp, SIZE,      src,    srcstride, \
104
+                                                SIZE, h + TAPNUMY - 1,  mx); \
105
+    ff_put_vp8_ ## NAME ## _ ## VNAME ## _armv6(dst, dststride, tmpptr, SIZE, \
106
+                                                SIZE, h,                my); \
107
+}
108
+
109
+VP8_EPEL_HV(16, 6, 6, epel,  h6, v6, 16);
110
+VP8_EPEL_HV(16, 2, 2, bilin, h,  v,  16);
111
+VP8_EPEL_HV(8,  6, 6, epel,  h6, v6, 16);
112
+VP8_EPEL_HV(8,  4, 6, epel,  h4, v6, 16);
113
+VP8_EPEL_HV(8,  6, 4, epel,  h6, v4, 16);
114
+VP8_EPEL_HV(8,  4, 4, epel,  h4, v4, 16);
115
+VP8_EPEL_HV(8,  2, 2, bilin, h,  v,  16);
116
+VP8_EPEL_HV(4,  6, 6, epel,  h6, v6, 8);
117
+VP8_EPEL_HV(4,  4, 6, epel,  h4, v6, 8);
118
+VP8_EPEL_HV(4,  6, 4, epel,  h6, v4, 8);
119
+VP8_EPEL_HV(4,  4, 4, epel,  h4, v4, 8);
120
+VP8_EPEL_HV(4,  2, 2, bilin, h,  v,  8);
121
+
122
+extern void put_vp8_epel4_v6_c(uint8_t *dst, int d, uint8_t *src, int s, int h, int mx, int my);
123
+#undef printf
124
+#define VP8_EPEL_H_OR_V(SIZE, NAME, HV) \
125
+static void ff_put_vp8_##NAME##SIZE##_##HV##_armv6( \
126
+                                        uint8_t *dst, int dststride, uint8_t *src, \
127
+                                        int srcstride, int h, int mx, int my) \
128
+{ \
129
+    ff_put_vp8_## NAME ## _ ## HV ## _armv6(dst, dststride, src, srcstride, \
130
+                                            SIZE, h, mx | my); \
131
+}
132
+
133
+VP8_EPEL_H_OR_V(4,  epel,  h6);
134
+VP8_EPEL_H_OR_V(4,  epel,  h4);
135
+VP8_EPEL_H_OR_V(4,  epel,  v6);
136
+VP8_EPEL_H_OR_V(4,  epel,  v4);
137
+VP8_EPEL_H_OR_V(4,  bilin, v);
138
+VP8_EPEL_H_OR_V(4,  bilin, h);
139
+VP8_EPEL_H_OR_V(8,  epel,  h6);
140
+VP8_EPEL_H_OR_V(8,  epel,  h4);
141
+VP8_EPEL_H_OR_V(8,  epel,  v6);
142
+VP8_EPEL_H_OR_V(8,  epel,  v4);
143
+VP8_EPEL_H_OR_V(8,  bilin, v);
144
+VP8_EPEL_H_OR_V(8,  bilin, h);
145
+VP8_EPEL_H_OR_V(16, epel,  h6);
146
+VP8_EPEL_H_OR_V(16, epel,  v6);
147
+VP8_EPEL_H_OR_V(16, bilin, v);
148
+VP8_EPEL_H_OR_V(16, bilin, h);
149
+
84 150
 av_cold void ff_vp8dsp_init_arm(VP8DSPContext *dsp)
85 151
 {
152
+#define set_func_ptrs(opt) \
153
+        dsp->vp8_luma_dc_wht    = ff_vp8_luma_dc_wht_##opt; \
154
+        dsp->vp8_luma_dc_wht_dc = ff_vp8_luma_dc_wht_dc_armv6; \
155
+ \
156
+        dsp->vp8_idct_add       = ff_vp8_idct_add_##opt; \
157
+        dsp->vp8_idct_dc_add    = ff_vp8_idct_dc_add_##opt; \
158
+        dsp->vp8_idct_dc_add4y  = ff_vp8_idct_dc_add4y_##opt; \
159
+        dsp->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_##opt; \
160
+ \
161
+        dsp->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16_##opt; \
162
+        dsp->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16_##opt; \
163
+        dsp->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_##opt; \
164
+        dsp->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_##opt; \
165
+ \
166
+        dsp->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16_inner_##opt; \
167
+        dsp->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16_inner_##opt; \
168
+        dsp->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_##opt; \
169
+        dsp->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_##opt; \
170
+ \
171
+        dsp->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter16_simple_##opt; \
172
+        dsp->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter16_simple_##opt; \
173
+ \
174
+        dsp->put_vp8_epel_pixels_tab[0][0][0] = ff_put_vp8_pixels16_##opt; \
175
+        dsp->put_vp8_epel_pixels_tab[0][0][2] = ff_put_vp8_epel16_h6_##opt; \
176
+        dsp->put_vp8_epel_pixels_tab[0][2][0] = ff_put_vp8_epel16_v6_##opt; \
177
+        dsp->put_vp8_epel_pixels_tab[0][2][2] = ff_put_vp8_epel16_h6v6_##opt; \
178
+ \
179
+        dsp->put_vp8_epel_pixels_tab[1][0][0] = ff_put_vp8_pixels8_##opt; \
180
+        dsp->put_vp8_epel_pixels_tab[1][0][1] = ff_put_vp8_epel8_h4_##opt; \
181
+        dsp->put_vp8_epel_pixels_tab[1][0][2] = ff_put_vp8_epel8_h6_##opt; \
182
+        dsp->put_vp8_epel_pixels_tab[1][1][0] = ff_put_vp8_epel8_v4_##opt; \
183
+        dsp->put_vp8_epel_pixels_tab[1][1][1] = ff_put_vp8_epel8_h4v4_##opt; \
184
+        dsp->put_vp8_epel_pixels_tab[1][1][2] = ff_put_vp8_epel8_h6v4_##opt; \
185
+        dsp->put_vp8_epel_pixels_tab[1][2][0] = ff_put_vp8_epel8_v6_##opt; \
186
+        dsp->put_vp8_epel_pixels_tab[1][2][1] = ff_put_vp8_epel8_h4v6_##opt; \
187
+        dsp->put_vp8_epel_pixels_tab[1][2][2] = ff_put_vp8_epel8_h6v6_##opt; \
188
+ \
189
+        dsp->put_vp8_epel_pixels_tab[2][0][0] = ff_put_vp8_pixels4_armv6; \
190
+        dsp->put_vp8_epel_pixels_tab[2][0][1] = ff_put_vp8_epel4_h4_##opt; \
191
+        dsp->put_vp8_epel_pixels_tab[2][0][2] = ff_put_vp8_epel4_h6_##opt; \
192
+        dsp->put_vp8_epel_pixels_tab[2][1][0] = ff_put_vp8_epel4_v4_##opt; \
193
+        dsp->put_vp8_epel_pixels_tab[2][1][1] = ff_put_vp8_epel4_h4v4_##opt; \
194
+        dsp->put_vp8_epel_pixels_tab[2][1][2] = ff_put_vp8_epel4_h6v4_##opt; \
195
+        dsp->put_vp8_epel_pixels_tab[2][2][0] = ff_put_vp8_epel4_v6_##opt; \
196
+        dsp->put_vp8_epel_pixels_tab[2][2][1] = ff_put_vp8_epel4_h4v6_##opt; \
197
+        dsp->put_vp8_epel_pixels_tab[2][2][2] = ff_put_vp8_epel4_h6v6_##opt; \
198
+ \
199
+        dsp->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_##opt; \
200
+        dsp->put_vp8_bilinear_pixels_tab[0][0][2] = ff_put_vp8_bilin16_h_##opt; \
201
+        dsp->put_vp8_bilinear_pixels_tab[0][2][0] = ff_put_vp8_bilin16_v_##opt; \
202
+        dsp->put_vp8_bilinear_pixels_tab[0][2][2] = ff_put_vp8_bilin16_hv_##opt; \
203
+ \
204
+        dsp->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_##opt; \
205
+        dsp->put_vp8_bilinear_pixels_tab[1][0][1] = ff_put_vp8_bilin8_h_##opt; \
206
+        dsp->put_vp8_bilinear_pixels_tab[1][0][2] = ff_put_vp8_bilin8_h_##opt; \
207
+        dsp->put_vp8_bilinear_pixels_tab[1][1][0] = ff_put_vp8_bilin8_v_##opt; \
208
+        dsp->put_vp8_bilinear_pixels_tab[1][1][1] = ff_put_vp8_bilin8_hv_##opt; \
209
+        dsp->put_vp8_bilinear_pixels_tab[1][1][2] = ff_put_vp8_bilin8_hv_##opt; \
210
+        dsp->put_vp8_bilinear_pixels_tab[1][2][0] = ff_put_vp8_bilin8_v_##opt; \
211
+        dsp->put_vp8_bilinear_pixels_tab[1][2][1] = ff_put_vp8_bilin8_hv_##opt; \
212
+        dsp->put_vp8_bilinear_pixels_tab[1][2][2] = ff_put_vp8_bilin8_hv_##opt; \
213
+ \
214
+        dsp->put_vp8_bilinear_pixels_tab[2][0][0] = ff_put_vp8_pixels4_armv6; \
215
+        dsp->put_vp8_bilinear_pixels_tab[2][0][1] = ff_put_vp8_bilin4_h_##opt; \
216
+        dsp->put_vp8_bilinear_pixels_tab[2][0][2] = ff_put_vp8_bilin4_h_##opt; \
217
+        dsp->put_vp8_bilinear_pixels_tab[2][1][0] = ff_put_vp8_bilin4_v_##opt; \
218
+        dsp->put_vp8_bilinear_pixels_tab[2][1][1] = ff_put_vp8_bilin4_hv_##opt; \
219
+        dsp->put_vp8_bilinear_pixels_tab[2][1][2] = ff_put_vp8_bilin4_hv_##opt; \
220
+        dsp->put_vp8_bilinear_pixels_tab[2][2][0] = ff_put_vp8_bilin4_v_##opt; \
221
+        dsp->put_vp8_bilinear_pixels_tab[2][2][1] = ff_put_vp8_bilin4_hv_##opt; \
222
+        dsp->put_vp8_bilinear_pixels_tab[2][2][2] = ff_put_vp8_bilin4_hv_##opt
86 223
     if (HAVE_NEON) {
87
-        dsp->vp8_luma_dc_wht    = ff_vp8_luma_dc_wht_neon;
88
-        dsp->vp8_luma_dc_wht_dc = ff_vp8_luma_dc_wht_dc_neon;
89
-
90
-        dsp->vp8_idct_add       = ff_vp8_idct_add_neon;
91
-        dsp->vp8_idct_dc_add    = ff_vp8_idct_dc_add_neon;
92
-        dsp->vp8_idct_dc_add4y  = ff_vp8_idct_dc_add4y_neon;
93
-        dsp->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_neon;
94
-
95
-        dsp->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16_neon;
96
-        dsp->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16_neon;
97
-        dsp->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_neon;
98
-        dsp->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_neon;
99
-
100
-        dsp->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16_inner_neon;
101
-        dsp->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16_inner_neon;
102
-        dsp->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_neon;
103
-        dsp->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_neon;
104
-
105
-        dsp->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter16_simple_neon;
106
-        dsp->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter16_simple_neon;
107
-
108
-        dsp->put_vp8_epel_pixels_tab[0][0][0] = ff_put_vp8_pixels16_neon;
109
-        dsp->put_vp8_epel_pixels_tab[0][0][2] = ff_put_vp8_epel16_h6_neon;
110
-        dsp->put_vp8_epel_pixels_tab[0][2][0] = ff_put_vp8_epel16_v6_neon;
111
-        dsp->put_vp8_epel_pixels_tab[0][2][2] = ff_put_vp8_epel16_h6v6_neon;
112
-
113
-        dsp->put_vp8_epel_pixels_tab[1][0][0] = ff_put_vp8_pixels8_neon;
114
-        dsp->put_vp8_epel_pixels_tab[1][0][1] = ff_put_vp8_epel8_h4_neon;
115
-        dsp->put_vp8_epel_pixels_tab[1][0][2] = ff_put_vp8_epel8_h6_neon;
116
-        dsp->put_vp8_epel_pixels_tab[1][1][0] = ff_put_vp8_epel8_v4_neon;
117
-        dsp->put_vp8_epel_pixels_tab[1][1][1] = ff_put_vp8_epel8_h4v4_neon;
118
-        dsp->put_vp8_epel_pixels_tab[1][1][2] = ff_put_vp8_epel8_h6v4_neon;
119
-        dsp->put_vp8_epel_pixels_tab[1][2][0] = ff_put_vp8_epel8_v6_neon;
120
-        dsp->put_vp8_epel_pixels_tab[1][2][1] = ff_put_vp8_epel8_h4v6_neon;
121
-        dsp->put_vp8_epel_pixels_tab[1][2][2] = ff_put_vp8_epel8_h6v6_neon;
122
-
123
-        dsp->put_vp8_epel_pixels_tab[2][0][0] = ff_put_vp8_pixels4_neon;
124
-        dsp->put_vp8_epel_pixels_tab[2][0][1] = ff_put_vp8_epel4_h4_neon;
125
-        dsp->put_vp8_epel_pixels_tab[2][0][2] = ff_put_vp8_epel4_h6_neon;
126
-        dsp->put_vp8_epel_pixels_tab[2][1][0] = ff_put_vp8_epel4_v4_neon;
127
-        dsp->put_vp8_epel_pixels_tab[2][1][1] = ff_put_vp8_epel4_h4v4_neon;
128
-        dsp->put_vp8_epel_pixels_tab[2][1][2] = ff_put_vp8_epel4_h6v4_neon;
129
-        dsp->put_vp8_epel_pixels_tab[2][2][0] = ff_put_vp8_epel4_v6_neon;
130
-        dsp->put_vp8_epel_pixels_tab[2][2][1] = ff_put_vp8_epel4_h4v6_neon;
131
-        dsp->put_vp8_epel_pixels_tab[2][2][2] = ff_put_vp8_epel4_h6v6_neon;
132
-
133
-        dsp->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_neon;
134
-        dsp->put_vp8_bilinear_pixels_tab[0][0][1] = ff_put_vp8_bilin16_h_neon;
135
-        dsp->put_vp8_bilinear_pixels_tab[0][0][2] = ff_put_vp8_bilin16_h_neon;
136
-        dsp->put_vp8_bilinear_pixels_tab[0][1][0] = ff_put_vp8_bilin16_v_neon;
137
-        dsp->put_vp8_bilinear_pixels_tab[0][1][1] = ff_put_vp8_bilin16_hv_neon;
138
-        dsp->put_vp8_bilinear_pixels_tab[0][1][2] = ff_put_vp8_bilin16_hv_neon;
139
-        dsp->put_vp8_bilinear_pixels_tab[0][2][0] = ff_put_vp8_bilin16_v_neon;
140
-        dsp->put_vp8_bilinear_pixels_tab[0][2][1] = ff_put_vp8_bilin16_hv_neon;
141
-        dsp->put_vp8_bilinear_pixels_tab[0][2][2] = ff_put_vp8_bilin16_hv_neon;
142
-
143
-        dsp->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_neon;
144
-        dsp->put_vp8_bilinear_pixels_tab[1][0][1] = ff_put_vp8_bilin8_h_neon;
145
-        dsp->put_vp8_bilinear_pixels_tab[1][0][2] = ff_put_vp8_bilin8_h_neon;
146
-        dsp->put_vp8_bilinear_pixels_tab[1][1][0] = ff_put_vp8_bilin8_v_neon;
147
-        dsp->put_vp8_bilinear_pixels_tab[1][1][1] = ff_put_vp8_bilin8_hv_neon;
148
-        dsp->put_vp8_bilinear_pixels_tab[1][1][2] = ff_put_vp8_bilin8_hv_neon;
149
-        dsp->put_vp8_bilinear_pixels_tab[1][2][0] = ff_put_vp8_bilin8_v_neon;
150
-        dsp->put_vp8_bilinear_pixels_tab[1][2][1] = ff_put_vp8_bilin8_hv_neon;
151
-        dsp->put_vp8_bilinear_pixels_tab[1][2][2] = ff_put_vp8_bilin8_hv_neon;
152
-
153
-        dsp->put_vp8_bilinear_pixels_tab[2][0][0] = ff_put_vp8_pixels4_neon;
154
-        dsp->put_vp8_bilinear_pixels_tab[2][0][1] = ff_put_vp8_bilin4_h_neon;
155
-        dsp->put_vp8_bilinear_pixels_tab[2][0][2] = ff_put_vp8_bilin4_h_neon;
156
-        dsp->put_vp8_bilinear_pixels_tab[2][1][0] = ff_put_vp8_bilin4_v_neon;
157
-        dsp->put_vp8_bilinear_pixels_tab[2][1][1] = ff_put_vp8_bilin4_hv_neon;
158
-        dsp->put_vp8_bilinear_pixels_tab[2][1][2] = ff_put_vp8_bilin4_hv_neon;
159
-        dsp->put_vp8_bilinear_pixels_tab[2][2][0] = ff_put_vp8_bilin4_v_neon;
160
-        dsp->put_vp8_bilinear_pixels_tab[2][2][1] = ff_put_vp8_bilin4_hv_neon;
161
-        dsp->put_vp8_bilinear_pixels_tab[2][2][2] = ff_put_vp8_bilin4_hv_neon;
224
+        set_func_ptrs(neon);
225
+    } else if (HAVE_ARMV6) {
226
+        set_func_ptrs(armv6);
162 227
     }
163 228
 }
... ...
@@ -76,18 +76,6 @@ function ff_vp8_luma_dc_wht_neon, export=1
76 76
         bx              lr
77 77
 endfunc
78 78
 
79
-function ff_vp8_luma_dc_wht_dc_neon, export=1
80
-        ldrsh           r2,  [r1]
81
-        mov             r3,  #0
82
-        add             r2,  r2,  #3
83
-        strh            r3,  [r1]
84
-        asr             r2,  r2,  #3
85
-    .rept 16
86
-        strh            r2,  [r0], #32
87
-    .endr
88
-        bx              lr
89
-endfunc
90
-
91 79
 function ff_vp8_idct_add_neon, export=1
92 80
         vld1.16         {q0-q1},  [r1,:128]
93 81
         movw            r3,  #20091
... ...
@@ -741,23 +729,6 @@ function ff_put_vp8_pixels8_neon, export=1
741 741
         bx              lr
742 742
 endfunc
743 743
 
744
-function ff_put_vp8_pixels4_neon, export=1
745
-        ldr             r12, [sp, #0]           @ h
746
-        push            {r4-r6,lr}
747
-1:
748
-        subs            r12, r12, #4
749
-        ldr_post        r4,  r2,  r3
750
-        ldr_post        r5,  r2,  r3
751
-        ldr_post        r6,  r2,  r3
752
-        ldr_post        lr,  r2,  r3
753
-        str_post        r4,  r0,  r1
754
-        str_post        r5,  r0,  r1
755
-        str_post        r6,  r0,  r1
756
-        str_post        lr,  r0,  r1
757
-        bgt             1b
758
-        pop             {r4-r6,pc}
759
-endfunc
760
-
761 744
 /* 4/6-tap 8th-pel MC */
762 745
 
763 746
 .macro  vp8_epel8_h6    d,   a,   b