Merge commit '42cf7f91f1e9dabf494ff469d8f67ac8b33b0f63'
[ffmpeg.git] / libavcodec / mips / hpeldsp_mmi.c
1 /*
2  * Loongson SIMD optimized qpeldsp
3  *
4  * Copyright (c) 2016 Loongson Technology Corporation Limited
5  * Copyright (c) 2016 Zhou Xiaoyong <zhouxiaoyong@loongson.cn>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23
24 #include "hpeldsp_mips.h"
25 #include "libavcodec/bit_depth_template.c"
26 #include "libavutil/mips/mmiutils.h"
27 #include "constants.h"
28
29 void ff_put_pixels4_8_mmi(uint8_t *block, const uint8_t *pixels,
30     ptrdiff_t line_size, int h)
31 {
32     double ftmp[2];
33     mips_reg addr[2];
34     DECLARE_VAR_LOW32;
35     DECLARE_VAR_ADDRT;
36
37     __asm__ volatile (
38         PTR_ADDU   "%[addr1],   %[line_size],   %[line_size]            \n\t"
39         "1:                                                             \n\t"
40         PTR_ADDU   "%[addr0],   %[pixels],      %[line_size]            \n\t"
41         MMI_ULWC1(%[ftmp0], %[pixels], 0x00)
42         MMI_ULWC1(%[ftmp1], %[addr0], 0x00)
43         MMI_SWC1(%[ftmp0], %[block], 0x00)
44         MMI_SWXC1(%[ftmp1], %[block], %[line_size], 0x00)
45         PTR_ADDU   "%[pixels],  %[pixels],      %[addr1]                \n\t"
46         PTR_ADDU   "%[block],   %[block],       %[addr1]                \n\t"
47
48         PTR_ADDU   "%[addr0],   %[pixels],      %[line_size]            \n\t"
49         MMI_ULWC1(%[ftmp0], %[pixels], 0x00)
50         MMI_ULWC1(%[ftmp1], %[addr0], 0x00)
51         MMI_SWC1(%[ftmp0], %[block], 0x00)
52         MMI_SWXC1(%[ftmp1], %[block], %[line_size], 0x00)
53         PTR_ADDU   "%[pixels],  %[pixels],      %[addr1]                \n\t"
54         PTR_ADDU   "%[block],   %[block],       %[addr1]                \n\t"
55
56         PTR_ADDI   "%[h],       %[h],           -0x04                   \n\t"
57         "bnez       %[h],       1b                                      \n\t"
58         : [ftmp0]"=&f"(ftmp[0]),            [ftmp1]"=&f"(ftmp[1]),
59           RESTRICT_ASM_LOW32
60           RESTRICT_ASM_ADDRT
61           [addr0]"=&r"(addr[0]),            [addr1]"=&r"(addr[1]),
62           [block]"+&r"(block),              [pixels]"+&r"(pixels),
63           [h]"+&r"(h)
64         : [line_size]"r"((mips_reg)line_size)
65         : "memory"
66     );
67 }
68
69 void ff_put_pixels8_8_mmi(uint8_t *block, const uint8_t *pixels,
70     ptrdiff_t line_size, int h)
71 {
72     double ftmp[2];
73     mips_reg addr[3];
74     DECLARE_VAR_ALL64;
75
76     __asm__ volatile (
77         PTR_ADDU   "%[addr1],   %[line_size],   %[line_size]            \n\t"
78         "1:                                                             \n\t"
79         MMI_ULDC1(%[ftmp0], %[pixels], 0x00)
80         PTR_ADDU   "%[addr0],   %[pixels],      %[line_size]            \n\t"
81         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
82         MMI_SDC1(%[ftmp0], %[block], 0x00)
83         PTR_ADDU   "%[addr2],   %[block],       %[line_size]            \n\t"
84         MMI_SDC1(%[ftmp1], %[addr2], 0x00)
85         PTR_ADDU   "%[pixels],  %[pixels],      %[addr1]                \n\t"
86         PTR_ADDU   "%[block],   %[block],       %[addr1]                \n\t"
87
88         MMI_ULDC1(%[ftmp0], %[pixels], 0x00)
89         PTR_ADDU   "%[addr0],   %[pixels],      %[line_size]            \n\t"
90         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
91         MMI_SDC1(%[ftmp0], %[block], 0x00)
92         PTR_ADDU   "%[addr2],   %[block],       %[line_size]            \n\t"
93         MMI_SDC1(%[ftmp1], %[addr2], 0x00)
94         PTR_ADDU   "%[pixels],  %[pixels],      %[addr1]                \n\t"
95         PTR_ADDU   "%[block],   %[block],       %[addr1]                \n\t"
96
97         PTR_ADDI   "%[h],       %[h],           -0x04                   \n\t"
98         "bnez       %[h],       1b                                      \n\t"
99         : [ftmp0]"=&f"(ftmp[0]),            [ftmp1]"=&f"(ftmp[1]),
100           RESTRICT_ASM_ALL64
101           [addr0]"=&r"(addr[0]),            [addr1]"=&r"(addr[1]),
102           [addr2]"=&r"(addr[2]),
103           [block]"+&r"(block),              [pixels]"+&r"(pixels),
104           [h]"+&r"(h)
105         : [line_size]"r"((mips_reg)line_size)
106         : "memory"
107     );
108 }
109
110 void ff_put_pixels16_8_mmi(uint8_t *block, const uint8_t *pixels,
111     ptrdiff_t line_size, int h)
112 {
113     double ftmp[4];
114     mips_reg addr[2];
115     DECLARE_VAR_ALL64;
116     DECLARE_VAR_ADDRT;
117
118     __asm__ volatile (
119         PTR_ADDU   "%[addr1],   %[line_size],   %[line_size]            \n\t"
120         "1:                                                             \n\t"
121         PTR_ADDU   "%[addr0],   %[pixels],      %[line_size]            \n\t"
122         MMI_ULDC1(%[ftmp0], %[pixels], 0x00)
123         MMI_ULDC1(%[ftmp2], %[pixels], 0x08)
124         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
125         MMI_ULDC1(%[ftmp3], %[addr0], 0x08)
126         MMI_SDC1(%[ftmp0], %[block], 0x00)
127         MMI_SDXC1(%[ftmp1], %[block], %[line_size], 0x00)
128         MMI_SDC1(%[ftmp2], %[block], 0x08)
129         MMI_SDXC1(%[ftmp3], %[block], %[line_size], 0x08)
130         PTR_ADDU   "%[pixels],  %[pixels],      %[addr1]                \n\t"
131         PTR_ADDU   "%[block],   %[block],       %[addr1]                \n\t"
132
133         PTR_ADDU   "%[addr0],   %[pixels],      %[line_size]            \n\t"
134         MMI_ULDC1(%[ftmp0], %[pixels], 0x00)
135         MMI_ULDC1(%[ftmp2], %[pixels], 0x08)
136         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
137         MMI_ULDC1(%[ftmp3], %[addr0], 0x08)
138         MMI_SDC1(%[ftmp0], %[block], 0x00)
139         MMI_SDXC1(%[ftmp1], %[block], %[line_size], 0x00)
140         MMI_SDC1(%[ftmp2], %[block], 0x08)
141         MMI_SDXC1(%[ftmp3], %[block], %[line_size], 0x08)
142         PTR_ADDU   "%[pixels],  %[pixels],      %[addr1]                \n\t"
143         PTR_ADDU   "%[block],   %[block],       %[addr1]                \n\t"
144
145         PTR_ADDI   "%[h],       %[h],           -0x04                   \n\t"
146         "bnez       %[h],       1b                                      \n\t"
147         : [ftmp0]"=&f"(ftmp[0]),            [ftmp1]"=&f"(ftmp[1]),
148           [ftmp2]"=&f"(ftmp[2]),            [ftmp3]"=&f"(ftmp[3]),
149           RESTRICT_ASM_ALL64
150           RESTRICT_ASM_ADDRT
151           [addr0]"=&r"(addr[0]),            [addr1]"=&r"(addr[1]),
152           [block]"+&r"(block),              [pixels]"+&r"(pixels),
153           [h]"+&r"(h)
154         : [line_size]"r"((mips_reg)line_size)
155         : "memory"
156     );
157 }
158
159 void ff_avg_pixels4_8_mmi(uint8_t *block, const uint8_t *pixels,
160     ptrdiff_t line_size, int h)
161 {
162     double ftmp[4];
163     mips_reg addr[3];
164     DECLARE_VAR_LOW32;
165     DECLARE_VAR_ADDRT;
166
167     __asm__ volatile (
168         PTR_ADDU   "%[addr2],   %[line_size],   %[line_size]            \n\t"
169         "1:                                                             \n\t"
170         PTR_ADDU   "%[addr0],   %[pixels],      %[line_size]            \n\t"
171         MMI_ULWC1(%[ftmp0], %[pixels], 0x00)
172         MMI_ULWC1(%[ftmp1], %[addr0], 0x00)
173         PTR_ADDU   "%[addr1],   %[block],       %[line_size]            \n\t"
174         MMI_ULWC1(%[ftmp2], %[block], 0x00)
175         MMI_ULWC1(%[ftmp3], %[addr1], 0x00)
176         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
177         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
178         MMI_SWC1(%[ftmp0], %[block], 0x00)
179         MMI_SWXC1(%[ftmp1], %[block], %[line_size], 0x00)
180         PTR_ADDU   "%[pixels],  %[pixels],      %[addr2]                \n\t"
181         PTR_ADDU   "%[block],   %[block],       %[addr2]                \n\t"
182
183         PTR_ADDU   "%[addr0],   %[pixels],      %[line_size]            \n\t"
184         MMI_ULWC1(%[ftmp0], %[pixels], 0x00)
185         MMI_ULWC1(%[ftmp1], %[addr0], 0x00)
186         PTR_ADDU   "%[addr1],   %[block],       %[line_size]            \n\t"
187         MMI_ULWC1(%[ftmp2], %[block], 0x00)
188         MMI_ULWC1(%[ftmp3], %[addr1], 0x00)
189         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
190         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
191         MMI_SWC1(%[ftmp0], %[block], 0x00)
192         MMI_SWXC1(%[ftmp1], %[block], %[line_size], 0x00)
193         PTR_ADDU   "%[pixels],  %[pixels],      %[addr2]                \n\t"
194         PTR_ADDU   "%[block],   %[block],       %[addr2]                \n\t"
195
196         PTR_ADDI   "%[h],       %[h],           -0x04                   \n\t"
197         "bnez       %[h],       1b                                      \n\t"
198         : [ftmp0]"=&f"(ftmp[0]),            [ftmp1]"=&f"(ftmp[1]),
199           [ftmp2]"=&f"(ftmp[2]),            [ftmp3]"=&f"(ftmp[3]),
200           RESTRICT_ASM_LOW32
201           RESTRICT_ASM_ADDRT
202           [addr0]"=&r"(addr[0]),            [addr1]"=&r"(addr[1]),
203           [addr2]"=&r"(addr[2]),
204           [block]"+&r"(block),              [pixels]"+&r"(pixels),
205           [h]"+&r"(h)
206         : [line_size]"r"((mips_reg)line_size)
207         : "memory"
208     );
209 }
210
211 void ff_avg_pixels8_8_mmi(uint8_t *block, const uint8_t *pixels,
212     ptrdiff_t line_size, int h)
213 {
214     double ftmp[4];
215     mips_reg addr[3];
216     DECLARE_VAR_ALL64;
217     DECLARE_VAR_ADDRT;
218
219     __asm__ volatile (
220         PTR_ADDU   "%[addr2],   %[line_size],   %[line_size]            \n\t"
221         "1:                                                             \n\t"
222         MMI_ULDC1(%[ftmp0], %[pixels], 0x00)
223         PTR_ADDU   "%[addr0],   %[pixels],      %[line_size]            \n\t"
224         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
225         PTR_ADDU   "%[addr1],   %[block],       %[line_size]            \n\t"
226         MMI_ULDC1(%[ftmp2], %[block], 0x00)
227         MMI_ULDC1(%[ftmp3], %[addr1], 0x00)
228         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
229         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
230         MMI_SDC1(%[ftmp0], %[block], 0x00)
231         MMI_SDXC1(%[ftmp1], %[block], %[line_size], 0x00)
232         PTR_ADDU   "%[pixels],  %[pixels],      %[addr2]                \n\t"
233         PTR_ADDU   "%[block],   %[block],       %[addr2]                \n\t"
234
235         MMI_ULDC1(%[ftmp0], %[pixels], 0x00)
236         PTR_ADDU   "%[addr0],   %[pixels],      %[line_size]            \n\t"
237         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
238         PTR_ADDU   "%[addr1],   %[block],       %[line_size]            \n\t"
239         MMI_ULDC1(%[ftmp2], %[block], 0x00)
240         MMI_ULDC1(%[ftmp3], %[addr1], 0x00)
241         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
242         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
243         MMI_SDC1(%[ftmp0], %[block], 0x00)
244         MMI_SDXC1(%[ftmp1], %[block], %[line_size], 0x00)
245         PTR_ADDU   "%[pixels],  %[pixels],      %[addr2]                \n\t"
246         PTR_ADDU   "%[block],   %[block],       %[addr2]                \n\t"
247
248         PTR_ADDI   "%[h],       %[h],           -0x04                   \n\t"
249         "bnez       %[h],       1b                                      \n\t"
250         : [ftmp0]"=&f"(ftmp[0]),            [ftmp1]"=&f"(ftmp[1]),
251           [ftmp2]"=&f"(ftmp[2]),            [ftmp3]"=&f"(ftmp[3]),
252           RESTRICT_ASM_ALL64
253           RESTRICT_ASM_ADDRT
254           [addr0]"=&r"(addr[0]),            [addr1]"=&r"(addr[1]),
255           [addr2]"=&r"(addr[2]),
256           [block]"+&r"(block),              [pixels]"+&r"(pixels),
257           [h]"+&r"(h)
258         : [line_size]"r"((mips_reg)line_size)
259         : "memory"
260     );
261 }
262
263 void ff_avg_pixels16_8_mmi(uint8_t *block, const uint8_t *pixels,
264     ptrdiff_t line_size, int h)
265 {
266     double ftmp[8];
267     mips_reg addr[3];
268     DECLARE_VAR_ALL64;
269     DECLARE_VAR_ADDRT;
270
271     __asm__ volatile (
272         PTR_ADDU   "%[addr2],   %[line_size],   %[line_size]            \n\t"
273         "1:                                                             \n\t"
274         MMI_ULDC1(%[ftmp0], %[pixels], 0x00)
275         PTR_ADDU   "%[addr0],   %[pixels],      %[line_size]            \n\t"
276         MMI_ULDC1(%[ftmp4], %[pixels], 0x08)
277         PTR_ADDU   "%[addr1],   %[block],       %[line_size]            \n\t"
278         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
279         MMI_ULDC1(%[ftmp5], %[addr0], 0x08)
280         MMI_ULDC1(%[ftmp2], %[block], 0x00)
281         MMI_ULDC1(%[ftmp6], %[block], 0x08)
282         MMI_ULDC1(%[ftmp3], %[addr1], 0x00)
283         MMI_ULDC1(%[ftmp7], %[addr1], 0x08)
284         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
285         "pavgb      %[ftmp4],   %[ftmp4],       %[ftmp6]                \n\t"
286         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
287         "pavgb      %[ftmp5],   %[ftmp5],       %[ftmp7]                \n\t"
288         MMI_SDC1(%[ftmp0], %[block], 0x00)
289         MMI_SDXC1(%[ftmp1], %[block], %[line_size], 0x00)
290         MMI_SDC1(%[ftmp4], %[block], 0x08)
291         MMI_SDXC1(%[ftmp5], %[block], %[line_size], 0x08)
292         PTR_ADDU   "%[pixels],  %[pixels],      %[addr2]                \n\t"
293         PTR_ADDU   "%[block],   %[block],       %[addr2]                \n\t"
294
295         MMI_ULDC1(%[ftmp0], %[pixels], 0x00)
296         PTR_ADDU   "%[addr0],   %[pixels],      %[line_size]            \n\t"
297         MMI_ULDC1(%[ftmp4], %[pixels], 0x08)
298         PTR_ADDU   "%[addr1],   %[block],       %[line_size]            \n\t"
299         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
300         MMI_ULDC1(%[ftmp5], %[addr0], 0x08)
301         MMI_ULDC1(%[ftmp2], %[block], 0x00)
302         MMI_ULDC1(%[ftmp6], %[block], 0x08)
303         MMI_ULDC1(%[ftmp3], %[addr1], 0x00)
304         MMI_ULDC1(%[ftmp7], %[addr1], 0x08)
305         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
306         "pavgb      %[ftmp4],   %[ftmp4],       %[ftmp6]                \n\t"
307         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
308         "pavgb      %[ftmp5],   %[ftmp5],       %[ftmp7]                \n\t"
309         MMI_SDC1(%[ftmp0], %[block], 0x00)
310         MMI_SDXC1(%[ftmp1], %[block], %[line_size], 0x00)
311         MMI_SDC1(%[ftmp4], %[block], 0x08)
312         MMI_SDXC1(%[ftmp5], %[block], %[line_size], 0x08)
313         PTR_ADDU   "%[pixels],  %[pixels],      %[addr2]                \n\t"
314         PTR_ADDU   "%[block],   %[block],       %[addr2]                \n\t"
315
316         PTR_ADDI   "%[h],       %[h],           -0x04                   \n\t"
317         "bnez       %[h],       1b                                      \n\t"
318         : [ftmp0]"=&f"(ftmp[0]),            [ftmp1]"=&f"(ftmp[1]),
319           [ftmp2]"=&f"(ftmp[2]),            [ftmp3]"=&f"(ftmp[3]),
320           [ftmp4]"=&f"(ftmp[4]),            [ftmp5]"=&f"(ftmp[5]),
321           [ftmp6]"=&f"(ftmp[6]),            [ftmp7]"=&f"(ftmp[7]),
322           RESTRICT_ASM_ALL64
323           RESTRICT_ASM_ADDRT
324           [addr0]"=&r"(addr[0]),            [addr1]"=&r"(addr[1]),
325           [addr2]"=&r"(addr[2]),
326           [block]"+&r"(block),              [pixels]"+&r"(pixels),
327           [h]"+&r"(h)
328         : [line_size]"r"((mips_reg)line_size)
329         : "memory"
330     );
331 }
332
333 inline void ff_put_pixels4_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
334     const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
335     int h)
336 {
337     double ftmp[4];
338     mips_reg addr[5];
339     DECLARE_VAR_LOW32;
340     DECLARE_VAR_ADDRT;
341
342     __asm__ volatile (
343         PTR_ADDU   "%[addr2],   %[src_stride1], %[src_stride1]          \n\t"
344         PTR_ADDU   "%[addr3],   %[src_stride2], %[src_stride2]          \n\t"
345         PTR_ADDU   "%[addr4],   %[dst_stride],  %[dst_stride]           \n\t"
346         "1:                                                             \n\t"
347         PTR_ADDU   "%[addr0],   %[src1],        %[src_stride1]          \n\t"
348         MMI_ULWC1(%[ftmp0], %[src1], 0x00)
349         MMI_ULWC1(%[ftmp1], %[addr0], 0x00)
350         MMI_ULWC1(%[ftmp2], %[src2], 0x00)
351         PTR_ADDU   "%[addr1],   %[src2],        %[src_stride2]          \n\t"
352         MMI_ULWC1(%[ftmp3], %[addr1], 0x00)
353         PTR_ADDU   "%[src1],    %[src1],        %[addr2]                \n\t"
354         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
355         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
356         MMI_SWC1(%[ftmp0], %[dst], 0x00)
357         MMI_SWXC1(%[ftmp1], %[dst], %[dst_stride], 0x00)
358         PTR_ADDU   "%[src2],    %[src2],        %[addr3]                \n\t"
359         PTR_ADDU   "%[dst],     %[dst],         %[addr4]                \n\t"
360
361         PTR_ADDU   "%[addr0],   %[src1],        %[src_stride1]          \n\t"
362         MMI_ULWC1(%[ftmp0], %[src1], 0x00)
363         MMI_ULWC1(%[ftmp1], %[addr0], 0x00)
364         MMI_ULWC1(%[ftmp2], %[src2], 0x00)
365         PTR_ADDU   "%[addr1],   %[src2],        %[src_stride2]          \n\t"
366         MMI_ULWC1(%[ftmp3], %[addr1], 0x00)
367         PTR_ADDU   "%[src1],    %[src1],        %[addr2]                \n\t"
368         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
369         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
370         MMI_SWC1(%[ftmp0], %[dst], 0x00)
371         MMI_SWXC1(%[ftmp1], %[dst], %[dst_stride], 0x00)
372         PTR_ADDU   "%[src2],    %[src2],        %[addr3]                \n\t"
373         PTR_ADDU   "%[dst],     %[dst],         %[addr4]                \n\t"
374
375         PTR_ADDI   "%[h],       %[h],           -0x04                   \n\t"
376         "bnez       %[h],       1b                                      \n\t"
377         : [ftmp0]"=&f"(ftmp[0]),            [ftmp1]"=&f"(ftmp[1]),
378           [ftmp2]"=&f"(ftmp[2]),            [ftmp3]"=&f"(ftmp[3]),
379           RESTRICT_ASM_LOW32
380           RESTRICT_ASM_ADDRT
381           [addr0]"=&r"(addr[0]),            [addr1]"=&r"(addr[1]),
382           [addr2]"=&r"(addr[2]),            [addr3]"=&r"(addr[3]),
383           [addr4]"=&r"(addr[4]),
384           [dst]"+&r"(dst),                  [src1]"+&r"(src1),
385           [src2]"+&r"(src2),                [h]"+&r"(h)
386         : [dst_stride]"r"((mips_reg)dst_stride),
387           [src_stride1]"r"((mips_reg)src_stride1),
388           [src_stride2]"r"((mips_reg)src_stride2)
389         : "memory"
390     );
391 }
392
393 inline void ff_put_pixels8_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
394     const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
395     int h)
396 {
397     double ftmp[4];
398     mips_reg addr[5];
399     DECLARE_VAR_ALL64;
400     DECLARE_VAR_ADDRT;
401
402     __asm__ volatile (
403         PTR_ADDU   "%[addr2],   %[src_stride1], %[src_stride1]          \n\t"
404         PTR_ADDU   "%[addr3],   %[src_stride2], %[src_stride2]          \n\t"
405         PTR_ADDU   "%[addr4],   %[dst_stride],  %[dst_stride]           \n\t"
406
407         "1:                                                             \n\t"
408         MMI_ULDC1(%[ftmp0], %[src1], 0x00)
409         PTR_ADDU   "%[addr0],   %[src1],        %[src_stride1]          \n\t"
410         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
411         MMI_ULDC1(%[ftmp2], %[src2], 0x00)
412         PTR_ADDU   "%[addr1],   %[src2],        %[src_stride2]          \n\t"
413         MMI_ULDC1(%[ftmp3], %[addr1], 0x00)
414         PTR_ADDU   "%[src1],    %[src1],        %[addr2]                \n\t"
415         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
416         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
417         MMI_SDC1(%[ftmp0], %[dst], 0x00)
418         MMI_SDXC1(%[ftmp1], %[dst], %[dst_stride], 0x00)
419         PTR_ADDU   "%[src2],    %[src2],        %[addr3]                \n\t"
420         PTR_ADDU   "%[dst],     %[dst],         %[addr4]                \n\t"
421
422         MMI_ULDC1(%[ftmp0], %[src1], 0x00)
423         PTR_ADDU   "%[addr0],   %[src1],        %[src_stride1]          \n\t"
424         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
425         MMI_ULDC1(%[ftmp2], %[src2], 0x00)
426         PTR_ADDU   "%[addr1],   %[src2],        %[src_stride2]          \n\t"
427         MMI_ULDC1(%[ftmp3], %[addr1], 0x00)
428         PTR_ADDU   "%[src1],    %[src1],        %[addr2]                \n\t"
429         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
430         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
431         MMI_SDC1(%[ftmp0], %[dst], 0x00)
432         MMI_SDXC1(%[ftmp1], %[dst], %[dst_stride], 0x00)
433         PTR_ADDU   "%[src2],    %[src2],        %[addr3]                \n\t"
434         PTR_ADDU   "%[dst],     %[dst],         %[addr4]                \n\t"
435
436         PTR_ADDI   "%[h],       %[h],           -0x04                   \n\t"
437         "bnez       %[h],       1b                                      \n\t"
438         : [ftmp0]"=&f"(ftmp[0]),            [ftmp1]"=&f"(ftmp[1]),
439           [ftmp2]"=&f"(ftmp[2]),            [ftmp3]"=&f"(ftmp[3]),
440           RESTRICT_ASM_ALL64
441           RESTRICT_ASM_ADDRT
442           [addr0]"=&r"(addr[0]),            [addr1]"=&r"(addr[1]),
443           [addr2]"=&r"(addr[2]),            [addr3]"=&r"(addr[3]),
444           [addr4]"=&r"(addr[4]),
445           [dst]"+&r"(dst),                  [src1]"+&r"(src1),
446           [src2]"+&r"(src2),                [h]"+&r"(h)
447         : [dst_stride]"r"((mips_reg)dst_stride),
448           [src_stride1]"r"((mips_reg)src_stride1),
449           [src_stride2]"r"((mips_reg)src_stride2)
450         : "memory"
451     );
452 }
453
454 inline void ff_put_pixels16_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
455     const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
456     int h)
457 {
458     double ftmp[8];
459     mips_reg addr[5];
460     DECLARE_VAR_ALL64;
461     DECLARE_VAR_ADDRT;
462
463     __asm__ volatile (
464         PTR_ADDU   "%[addr2],   %[src_stride1], %[src_stride1]          \n\t"
465         PTR_ADDU   "%[addr3],   %[src_stride2], %[src_stride2]          \n\t"
466         PTR_ADDU   "%[addr4],   %[dst_stride],  %[dst_stride]           \n\t"
467
468         "1:                                                             \n\t"
469         MMI_ULDC1(%[ftmp0], %[src1], 0x00)
470         PTR_ADDU   "%[addr0],   %[src1],        %[src_stride1]          \n\t"
471         MMI_ULDC1(%[ftmp4], %[src1], 0x08)
472         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
473         MMI_ULDC1(%[ftmp5], %[addr0], 0x08)
474         MMI_ULDC1(%[ftmp2], %[src2], 0x00)
475         PTR_ADDU   "%[addr1],   %[src2],        %[src_stride2]          \n\t"
476         MMI_ULDC1(%[ftmp6], %[src2], 0x08)
477         MMI_ULDC1(%[ftmp3], %[addr1], 0x00)
478         PTR_ADDU   "%[src1],    %[src1],        %[addr2]                \n\t"
479         MMI_ULDC1(%[ftmp7], %[addr1], 0x08)
480         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
481         "pavgb      %[ftmp4],   %[ftmp4],       %[ftmp6]                \n\t"
482         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
483         "pavgb      %[ftmp5],   %[ftmp5],       %[ftmp7]                \n\t"
484         MMI_SDC1(%[ftmp0], %[dst], 0x00)
485         MMI_SDXC1(%[ftmp1], %[dst], %[dst_stride], 0x00)
486         MMI_SDC1(%[ftmp4], %[dst], 0x08)
487         MMI_SDXC1(%[ftmp5], %[dst], %[dst_stride], 0x08)
488         PTR_ADDU   "%[src2],    %[src2],        %[addr3]                \n\t"
489         PTR_ADDU   "%[dst],     %[dst],         %[addr4]                \n\t"
490
491         MMI_ULDC1(%[ftmp0], %[src1], 0x00)
492         PTR_ADDU   "%[addr0],   %[src1],        %[src_stride1]          \n\t"
493         MMI_ULDC1(%[ftmp4], %[src1], 0x08)
494         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
495         MMI_ULDC1(%[ftmp5], %[addr0], 0x08)
496         MMI_ULDC1(%[ftmp2], %[src2], 0x00)
497         PTR_ADDU   "%[addr1],   %[src2],        %[src_stride2]          \n\t"
498         MMI_ULDC1(%[ftmp6], %[src2], 0x08)
499         MMI_ULDC1(%[ftmp3], %[addr1], 0x00)
500         PTR_ADDU   "%[src1],    %[src1],        %[addr2]                \n\t"
501         MMI_ULDC1(%[ftmp7], %[addr1], 0x08)
502         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
503         "pavgb      %[ftmp4],   %[ftmp4],       %[ftmp6]                \n\t"
504         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
505         "pavgb      %[ftmp5],   %[ftmp5],       %[ftmp7]                \n\t"
506         MMI_SDC1(%[ftmp0], %[dst], 0x00)
507         MMI_SDXC1(%[ftmp1], %[dst], %[dst_stride], 0x00)
508         MMI_SDC1(%[ftmp4], %[dst], 0x08)
509         MMI_SDXC1(%[ftmp5], %[dst], %[dst_stride], 0x08)
510         PTR_ADDU   "%[src2],    %[src2],        %[addr3]                \n\t"
511         PTR_ADDU   "%[dst],     %[dst],         %[addr4]                \n\t"
512
513         PTR_ADDI   "%[h],       %[h],           -0x04                   \n\t"
514         "bnez       %[h],       1b                                      \n\t"
515         : [ftmp0]"=&f"(ftmp[0]),            [ftmp1]"=&f"(ftmp[1]),
516           [ftmp2]"=&f"(ftmp[2]),            [ftmp3]"=&f"(ftmp[3]),
517           [ftmp4]"=&f"(ftmp[4]),            [ftmp5]"=&f"(ftmp[5]),
518           [ftmp6]"=&f"(ftmp[6]),            [ftmp7]"=&f"(ftmp[7]),
519           RESTRICT_ASM_ALL64
520           RESTRICT_ASM_ADDRT
521           [addr0]"=&r"(addr[0]),            [addr1]"=&r"(addr[1]),
522           [addr2]"=&r"(addr[2]),            [addr3]"=&r"(addr[3]),
523           [addr4]"=&r"(addr[4]),
524           [dst]"+&r"(dst),                  [src1]"+&r"(src1),
525           [src2]"+&r"(src2),                [h]"+&r"(h)
526         : [dst_stride]"r"((mips_reg)dst_stride),
527           [src_stride1]"r"((mips_reg)src_stride1),
528           [src_stride2]"r"((mips_reg)src_stride2)
529         : "memory"
530     );
531 }
532
533 inline void ff_avg_pixels4_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
534     const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
535     int h)
536 {
537     double ftmp[6];
538     mips_reg addr[6];
539     DECLARE_VAR_LOW32;
540     DECLARE_VAR_ADDRT;
541
542     __asm__ volatile (
543         PTR_ADDU   "%[addr2],   %[src_stride1], %[src_stride1]          \n\t"
544         PTR_ADDU   "%[addr3],   %[src_stride2], %[src_stride2]          \n\t"
545         PTR_ADDU   "%[addr4],   %[dst_stride],  %[dst_stride]           \n\t"
546
547         "1:                                                             \n\t"
548         PTR_ADDU   "%[addr0],   %[src1],        %[src_stride1]          \n\t"
549         MMI_ULWC1(%[ftmp0], %[src1], 0x00)
550         MMI_ULWC1(%[ftmp1], %[addr0], 0x00)
551         MMI_ULWC1(%[ftmp2], %[src2], 0x00)
552         PTR_ADDU   "%[addr1],   %[src2],        %[src_stride2]          \n\t"
553         MMI_ULWC1(%[ftmp3], %[addr1], 0x00)
554         PTR_ADDU   "%[src1],    %[src1],        %[addr2]                \n\t"
555         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
556         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
557         PTR_ADDU   "%[addr5],   %[dst],         %[dst_stride]           \n\t"
558         MMI_ULWC1(%[ftmp4], %[dst], 0x00)
559         MMI_ULWC1(%[ftmp5], %[addr5], 0x00)
560         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp4]                \n\t"
561         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp5]                \n\t"
562         MMI_SWC1(%[ftmp0], %[dst], 0x00)
563         MMI_SWXC1(%[ftmp1], %[dst], %[dst_stride], 0x00)
564         PTR_ADDU   "%[src2],    %[src2],        %[addr3]                \n\t"
565         PTR_ADDU   "%[dst],     %[dst],         %[addr4]                \n\t"
566
567         PTR_ADDU   "%[addr0],   %[src1],        %[src_stride1]          \n\t"
568         MMI_ULWC1(%[ftmp0], %[src1], 0x00)
569         MMI_ULWC1(%[ftmp1], %[addr0], 0x00)
570         MMI_ULWC1(%[ftmp2], %[src2], 0x00)
571         PTR_ADDU   "%[addr1],   %[src2],        %[src_stride2]          \n\t"
572         MMI_ULWC1(%[ftmp3], %[addr1], 0x00)
573         PTR_ADDU   "%[src1],    %[src1],        %[addr2]                \n\t"
574         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
575         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
576         PTR_ADDU   "%[addr5],   %[dst],         %[dst_stride]           \n\t"
577         MMI_ULWC1(%[ftmp4], %[dst], 0x00)
578         MMI_ULWC1(%[ftmp5], %[addr5], 0x00)
579         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp4]                \n\t"
580         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp5]                \n\t"
581         MMI_SWC1(%[ftmp0], %[dst], 0x00)
582         MMI_SWXC1(%[ftmp1], %[dst], %[dst_stride], 0x00)
583         PTR_ADDU   "%[src2],    %[src2],        %[addr3]                \n\t"
584         PTR_ADDU   "%[dst],     %[dst],         %[addr4]                \n\t"
585
586         PTR_ADDI   "%[h],       %[h],           -0x04                   \n\t"
587         "bnez       %[h],       1b                                      \n\t"
588         : [ftmp0]"=&f"(ftmp[0]),            [ftmp1]"=&f"(ftmp[1]),
589           [ftmp2]"=&f"(ftmp[2]),            [ftmp3]"=&f"(ftmp[3]),
590           [ftmp4]"=&f"(ftmp[4]),            [ftmp5]"=&f"(ftmp[5]),
591           RESTRICT_ASM_LOW32
592           RESTRICT_ASM_ADDRT
593           [addr0]"=&r"(addr[0]),            [addr1]"=&r"(addr[1]),
594           [addr2]"=&r"(addr[2]),            [addr3]"=&r"(addr[3]),
595           [addr4]"=&r"(addr[4]),            [addr5]"=&r"(addr[5]),
596           [dst]"+&r"(dst),                  [src1]"+&r"(src1),
597           [src2]"+&r"(src2),                [h]"+&r"(h)
598         : [dst_stride]"r"((mips_reg)dst_stride),
599           [src_stride1]"r"((mips_reg)src_stride1),
600           [src_stride2]"r"((mips_reg)src_stride2)
601         : "memory"
602     );
603 }
604
605 inline void ff_avg_pixels8_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
606     const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
607     int h)
608 {
609     double ftmp[6];
610     mips_reg addr[6];
611     DECLARE_VAR_ALL64;
612     DECLARE_VAR_ADDRT;
613
614     __asm__ volatile (
615         PTR_ADDU   "%[addr2],   %[src_stride1], %[src_stride1]          \n\t"
616         PTR_ADDU   "%[addr3],   %[src_stride2], %[src_stride2]          \n\t"
617         PTR_ADDU   "%[addr4],   %[dst_stride],  %[dst_stride]           \n\t"
618
619         "1:                                                             \n\t"
620         MMI_ULDC1(%[ftmp0], %[src1], 0x00)
621         PTR_ADDU   "%[addr0],   %[src1],        %[src_stride1]          \n\t"
622         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
623         PTR_ADDU   "%[addr1],   %[src2],        %[src_stride2]          \n\t"
624         MMI_ULDC1(%[ftmp2], %[src2], 0x00)
625         MMI_ULDC1(%[ftmp3], %[addr1], 0x00)
626         PTR_ADDU   "%[src1],    %[src1],        %[addr2]                \n\t"
627         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
628         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
629         PTR_ADDU   "%[addr5],   %[dst],         %[dst_stride]           \n\t"
630         MMI_ULDC1(%[ftmp4], %[dst], 0x00)
631         MMI_ULDC1(%[ftmp5], %[addr5], 0x00)
632         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp4]                \n\t"
633         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp5]                \n\t"
634         MMI_SDC1(%[ftmp0], %[dst], 0x00)
635         MMI_SDXC1(%[ftmp1], %[dst], %[dst_stride], 0x00)
636         PTR_ADDU   "%[src2],    %[src2],        %[addr3]                \n\t"
637         PTR_ADDU   "%[dst],     %[dst],         %[addr4]                \n\t"
638
639         MMI_ULDC1(%[ftmp0], %[src1], 0x00)
640         PTR_ADDU   "%[addr0],   %[src1],        %[src_stride1]          \n\t"
641         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
642         PTR_ADDU   "%[addr1],   %[src2],        %[src_stride2]          \n\t"
643         MMI_ULDC1(%[ftmp2], %[src2], 0x00)
644         MMI_ULDC1(%[ftmp3], %[addr1], 0x00)
645         PTR_ADDU   "%[src1],    %[src1],        %[addr2]                \n\t"
646         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
647         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
648         PTR_ADDU   "%[addr5],   %[dst],         %[dst_stride]           \n\t"
649         MMI_ULDC1(%[ftmp4], %[dst], 0x00)
650         MMI_ULDC1(%[ftmp5], %[addr5], 0x00)
651         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp4]                \n\t"
652         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp5]                \n\t"
653         MMI_SDC1(%[ftmp0], %[dst], 0x00)
654         MMI_SDXC1(%[ftmp1], %[dst], %[dst_stride], 0x00)
655         PTR_ADDU   "%[src2],    %[src2],        %[addr3]                \n\t"
656         PTR_ADDU   "%[dst],     %[dst],         %[addr4]                \n\t"
657
658         PTR_ADDI   "%[h],       %[h],           -0x04                   \n\t"
659         "bnez       %[h],       1b                                      \n\t"
660         : [ftmp0]"=&f"(ftmp[0]),            [ftmp1]"=&f"(ftmp[1]),
661           [ftmp2]"=&f"(ftmp[2]),            [ftmp3]"=&f"(ftmp[3]),
662           [ftmp4]"=&f"(ftmp[4]),            [ftmp5]"=&f"(ftmp[5]),
663           RESTRICT_ASM_ALL64
664           RESTRICT_ASM_ADDRT
665           [addr0]"=&r"(addr[0]),            [addr1]"=&r"(addr[1]),
666           [addr2]"=&r"(addr[2]),            [addr3]"=&r"(addr[3]),
667           [addr4]"=&r"(addr[4]),            [addr5]"=&r"(addr[5]),
668           [dst]"+&r"(dst),                  [src1]"+&r"(src1),
669           [src2]"+&r"(src2),                [h]"+&r"(h)
670         : [dst_stride]"r"((mips_reg)dst_stride),
671           [src_stride1]"r"((mips_reg)src_stride1),
672           [src_stride2]"r"((mips_reg)src_stride2)
673         : "memory"
674     );
675 }
676
677 inline void ff_avg_pixels16_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
678     const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
679     int h)
680 {
681     ff_avg_pixels8_l2_8_mmi(dst, src1, src2, dst_stride, src_stride1,
682             src_stride2, h);
683     ff_avg_pixels8_l2_8_mmi(dst + 8, src1 + 8, src2 + 8, dst_stride,
684             src_stride1, src_stride2, h);
685 }
686
687 void ff_put_pixels4_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
688     ptrdiff_t line_size, int h)
689 {
690     ff_put_pixels4_l2_8_mmi(block, pixels, pixels + 1, line_size, line_size,
691             line_size, h);
692 }
693
694 void ff_put_pixels8_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
695     ptrdiff_t line_size, int h)
696 {
697     ff_put_pixels8_l2_8_mmi(block, pixels, pixels + 1, line_size, line_size,
698             line_size, h);
699 }
700
701 void ff_put_pixels16_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
702     ptrdiff_t line_size, int h)
703 {
704     ff_put_pixels16_l2_8_mmi(block, pixels, pixels + 1, line_size, line_size,
705             line_size, h);
706 }
707
708 void ff_avg_pixels4_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
709     ptrdiff_t line_size, int h)
710 {
711     ff_avg_pixels4_l2_8_mmi(block, pixels, pixels + 1, line_size, line_size,
712             line_size, h);
713 }
714
715 void ff_avg_pixels8_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
716     ptrdiff_t line_size, int h)
717 {
718     ff_avg_pixels8_l2_8_mmi(block, pixels, pixels + 1, line_size, line_size,
719             line_size, h);
720 }
721
722 void ff_avg_pixels16_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
723     ptrdiff_t line_size, int h)
724 {
725     ff_avg_pixels8_x2_8_mmi(block, pixels, line_size, h);
726     ff_avg_pixels8_x2_8_mmi(block + 8, pixels + 8, line_size, h);
727 }
728
729 inline void ff_put_no_rnd_pixels8_l2_8_mmi(uint8_t *dst, const uint8_t *src1,
730     const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2,
731     int h)
732 {
733     double ftmp[5];
734     mips_reg addr[5];
735     DECLARE_VAR_ALL64;
736     DECLARE_VAR_ADDRT;
737
738     __asm__ volatile (
739         "pcmpeqb    %[ftmp4],   %[ftmp4],       %[ftmp4]                \n\t"
740         PTR_ADDU   "%[addr2],   %[src_stride1], %[src_stride1]          \n\t"
741         PTR_ADDU   "%[addr3],   %[src_stride2], %[src_stride2]          \n\t"
742         PTR_ADDU   "%[addr4],   %[dst_stride],  %[dst_stride]           \n\t"
743
744         "1:                                                             \n\t"
745         MMI_ULDC1(%[ftmp0], %[src1], 0x00)
746         PTR_ADDU   "%[addr0],   %[src1],        %[src_stride1]          \n\t"
747         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
748         MMI_ULDC1(%[ftmp2], %[src2], 0x00)
749         PTR_ADDU   "%[addr1],   %[src2],        %[src_stride2]          \n\t"
750         MMI_ULDC1(%[ftmp3], %[addr1], 0x00)
751         PTR_ADDU   "%[src1],    %[src1],        %[addr2]                \n\t"
752         "xor        %[ftmp0],   %[ftmp0],       %[ftmp4]                \n\t"
753         "xor        %[ftmp1],   %[ftmp1],       %[ftmp4]                \n\t"
754         "xor        %[ftmp2],   %[ftmp2],       %[ftmp4]                \n\t"
755         "xor        %[ftmp3],   %[ftmp3],       %[ftmp4]                \n\t"
756         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
757         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
758         "xor        %[ftmp0],   %[ftmp0],       %[ftmp4]                \n\t"
759         "xor        %[ftmp1],   %[ftmp1],       %[ftmp4]                \n\t"
760         MMI_SDC1(%[ftmp0], %[dst], 0x00)
761         MMI_SDXC1(%[ftmp1], %[dst], %[dst_stride], 0x00)
762         PTR_ADDU   "%[src2],    %[src2],        %[addr3]                \n\t"
763         PTR_ADDU   "%[dst],     %[dst],         %[addr4]                \n\t"
764
765         MMI_ULDC1(%[ftmp0], %[src1], 0x00)
766         PTR_ADDU   "%[addr0],   %[src1],        %[src_stride1]          \n\t"
767         MMI_ULDC1(%[ftmp1], %[addr0], 0x00)
768         MMI_ULDC1(%[ftmp2], %[src2], 0x00)
769         PTR_ADDU   "%[addr1],   %[src2],        %[src_stride2]          \n\t"
770         MMI_ULDC1(%[ftmp3], %[addr1], 0x00)
771         PTR_ADDU   "%[src1],    %[src1],        %[addr2]                \n\t"
772         "xor        %[ftmp0],   %[ftmp0],       %[ftmp4]                \n\t"
773         "xor        %[ftmp1],   %[ftmp1],       %[ftmp4]                \n\t"
774         "xor        %[ftmp2],   %[ftmp2],       %[ftmp4]                \n\t"
775         "xor        %[ftmp3],   %[ftmp3],       %[ftmp4]                \n\t"
776         "pavgb      %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
777         "pavgb      %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
778         "xor        %[ftmp0],   %[ftmp0],       %[ftmp4]                \n\t"
779         "xor        %[ftmp1],   %[ftmp1],       %[ftmp4]                \n\t"
780         MMI_SDC1(%[ftmp0], %[dst], 0x00)
781         MMI_SDXC1(%[ftmp1], %[dst], %[dst_stride], 0x00)
782         PTR_ADDU   "%[src2],    %[src2],        %[addr3]                \n\t"
783         PTR_ADDU   "%[dst],     %[dst],         %[addr4]                \n\t"
784
785         PTR_ADDI   "%[h],       %[h],           -0x04                   \n\t"
786         "bnez       %[h],       1b                                      \n\t"
787         : [ftmp0]"=&f"(ftmp[0]),            [ftmp1]"=&f"(ftmp[1]),
788           [ftmp2]"=&f"(ftmp[2]),            [ftmp3]"=&f"(ftmp[3]),
789           [ftmp4]"=&f"(ftmp[4]),
790           RESTRICT_ASM_ALL64
791           RESTRICT_ASM_ADDRT
792           [addr0]"=&r"(addr[0]),            [addr1]"=&r"(addr[1]),
793           [addr2]"=&r"(addr[2]),            [addr3]"=&r"(addr[3]),
794           [addr4]"=&r"(addr[4]),
795           [dst]"+&r"(dst),                  [src1]"+&r"(src1),
796           [src2]"+&r"(src2),                [h]"+&r"(h)
797         : [dst_stride]"r"((mips_reg)dst_stride),
798           [src_stride1]"r"((mips_reg)src_stride1),
799           [src_stride2]"r"((mips_reg)src_stride2)
800         : "memory"
801     );
802 }
803
804 void ff_put_no_rnd_pixels8_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
805     ptrdiff_t line_size, int h)
806 {
807     ff_put_no_rnd_pixels8_l2_8_mmi(block, pixels, pixels + 1, line_size,
808             line_size, line_size, h);
809 }
810
811 void ff_put_no_rnd_pixels16_x2_8_mmi(uint8_t *block, const uint8_t *pixels,
812     ptrdiff_t line_size, int h)
813 {
814     ff_put_no_rnd_pixels8_x2_8_mmi(block, pixels, line_size, h);
815     ff_put_no_rnd_pixels8_x2_8_mmi(block + 8, pixels + 8, line_size, h);
816 }
817
818 void ff_put_pixels4_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
819     ptrdiff_t line_size, int h)
820 {
821     ff_put_pixels4_l2_8_mmi(block, pixels, pixels + line_size, line_size,
822             line_size, line_size, h);
823 }
824
825 void ff_put_pixels8_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
826     ptrdiff_t line_size, int h)
827 {
828     ff_put_pixels8_l2_8_mmi(block, pixels, pixels + line_size, line_size,
829             line_size, line_size, h);
830 }
831
832 void ff_put_pixels16_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
833     ptrdiff_t line_size, int h)
834 {
835     ff_put_pixels16_l2_8_mmi(block, pixels, pixels + line_size, line_size,
836             line_size, line_size, h);
837 }
838
839 void ff_avg_pixels4_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
840     ptrdiff_t line_size, int h)
841 {
842     ff_avg_pixels4_l2_8_mmi(block, pixels, pixels + line_size, line_size,
843             line_size, line_size, h);
844 }
845
846 void ff_avg_pixels8_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
847     ptrdiff_t line_size, int h)
848 {
849     ff_avg_pixels8_l2_8_mmi(block, pixels, pixels + line_size, line_size,
850             line_size, line_size, h);
851 }
852
853 void ff_avg_pixels16_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
854     ptrdiff_t line_size, int h)
855 {
856     ff_avg_pixels8_y2_8_mmi(block, pixels, line_size, h);
857     ff_avg_pixels8_y2_8_mmi(block + 8, pixels + 8, line_size, h);
858 }
859
860 void ff_put_no_rnd_pixels8_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
861     ptrdiff_t line_size, int h)
862 {
863     ff_put_no_rnd_pixels8_l2_8_mmi(block, pixels, pixels + line_size,
864             line_size, line_size, line_size, h);
865 }
866
867 void ff_put_no_rnd_pixels16_y2_8_mmi(uint8_t *block, const uint8_t *pixels,
868     ptrdiff_t line_size, int h)
869 {
870     ff_put_no_rnd_pixels8_y2_8_mmi(block, pixels, line_size, h);
871     ff_put_no_rnd_pixels8_y2_8_mmi(block + 8 , pixels + 8, line_size, h);
872 }
873
874 void ff_put_pixels4_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
875     ptrdiff_t line_size, int h)
876 {
877     /* FIXME HIGH BIT DEPTH */
878     int i;
879     const uint32_t a = AV_RN32(pixels);
880     const uint32_t b = AV_RN32(pixels + 1);
881     uint32_t l0 = (a & 0x03030303UL) +
882                   (b & 0x03030303UL) +
883                        0x02020202UL;
884     uint32_t h0 = ((a & 0xFCFCFCFCUL) >> 2) +
885                   ((b & 0xFCFCFCFCUL) >> 2);
886     uint32_t l1, h1;
887
888     pixels += line_size;
889     for (i = 0; i < h; i += 2) {
890         uint32_t a = AV_RN32(pixels);
891         uint32_t b = AV_RN32(pixels + 1);
892         l1 = (a & 0x03030303UL) +
893              (b & 0x03030303UL);
894         h1 = ((a & 0xFCFCFCFCUL) >> 2) +
895              ((b & 0xFCFCFCFCUL) >> 2);
896         *((uint32_t *) block) = h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
897         pixels += line_size;
898         block  += line_size;
899         a  = AV_RN32(pixels);
900         b  = AV_RN32(pixels + 1);
901         l0 = (a & 0x03030303UL) +
902              (b & 0x03030303UL) +
903                   0x02020202UL;
904         h0 = ((a & 0xFCFCFCFCUL) >> 2) +
905              ((b & 0xFCFCFCFCUL) >> 2);
906         *((uint32_t *) block) = h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
907         pixels += line_size;
908         block  += line_size;
909     }
910 }
911
912 void ff_put_pixels8_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
913     ptrdiff_t line_size, int h)
914 {
915 #if 1
916     double ftmp[10];
917     mips_reg addr[2];
918     DECLARE_VAR_ALL64;
919     DECLARE_VAR_ADDRT;
920
921     __asm__ volatile (
922         "xor        %[ftmp7],   %[ftmp7],       %[ftmp7]                \n\t"
923         "dli        %[addr0],   0x0f                                    \n\t"
924         "pcmpeqw    %[ftmp6],   %[ftmp6],       %[ftmp6]                \n\t"
925         "dmtc1      %[addr0],   %[ftmp8]                                \n\t"
926         "dli        %[addr0],   0x01                                    \n\t"
927         "psrlh      %[ftmp6],   %[ftmp6],       %[ftmp8]                \n\t"
928         "dmtc1      %[addr0],   %[ftmp8]                                \n\t"
929         "psllh      %[ftmp6],   %[ftmp6],       %[ftmp8]                \n\t"
930
931         "dli        %[addr0],   0x02                                    \n\t"
932         "dmtc1      %[addr0],   %[ftmp9]                                \n\t"
933         MMI_ULDC1(%[ftmp0], %[pixels], 0x00)
934         MMI_ULDC1(%[ftmp4], %[pixels], 0x01)
935         "mov.d      %[ftmp1],   %[ftmp0]                                \n\t"
936         "mov.d      %[ftmp5],   %[ftmp4]                                \n\t"
937         "punpcklbh  %[ftmp0],   %[ftmp0],       %[ftmp7]                \n\t"
938         "punpcklbh  %[ftmp4],   %[ftmp4],       %[ftmp7]                \n\t"
939         "punpckhbh  %[ftmp1],   %[ftmp1],       %[ftmp7]                \n\t"
940         "punpckhbh  %[ftmp5],   %[ftmp5],       %[ftmp7]                \n\t"
941         "paddush    %[ftmp4],   %[ftmp4],       %[ftmp0]                \n\t"
942         "paddush    %[ftmp5],   %[ftmp5],       %[ftmp1]                \n\t"
943         "xor        %[addr0],   %[addr0],       %[addr0]                \n\t"
944         PTR_ADDU   "%[pixels],  %[pixels],      %[line_size]            \n\t"
945         ".p2align   3                                                   \n\t"
946
947         "1:                                                             \n\t"
948         PTR_ADDU   "%[addr1],   %[pixels],      %[addr0]                \n\t"
949         MMI_ULDC1(%[ftmp0], %[addr1], 0x00)
950         MMI_ULDC1(%[ftmp2], %[addr1], 0x01)
951         "mov.d      %[ftmp1],   %[ftmp0]                                \n\t"
952         "mov.d      %[ftmp3],   %[ftmp2]                                \n\t"
953         "punpcklbh  %[ftmp0],   %[ftmp0],       %[ftmp7]                \n\t"
954         "punpcklbh  %[ftmp2],   %[ftmp2],       %[ftmp7]                \n\t"
955         "punpckhbh  %[ftmp1],   %[ftmp1],       %[ftmp7]                \n\t"
956         "punpckhbh  %[ftmp3],   %[ftmp3],       %[ftmp7]                \n\t"
957         "paddush    %[ftmp0],   %[ftmp0],       %[ftmp2]                \n\t"
958         "paddush    %[ftmp1],   %[ftmp1],       %[ftmp3]                \n\t"
959         "paddush    %[ftmp4],   %[ftmp4],       %[ftmp6]                \n\t"
960         "paddush    %[ftmp5],   %[ftmp5],       %[ftmp6]                \n\t"
961         "paddush    %[ftmp4],   %[ftmp4],       %[ftmp0]                \n\t"
962         "paddush    %[ftmp5],   %[ftmp5],       %[ftmp1]                \n\t"
963         "psrlh      %[ftmp4],   %[ftmp4],       %[ftmp9]                \n\t"
964         "psrlh      %[ftmp5],   %[ftmp5],       %[ftmp9]                \n\t"
965         "packushb   %[ftmp4],   %[ftmp4],       %[ftmp5]                \n\t"
966         MMI_SDXC1(%[ftmp4], %[block], %[addr0], 0x00)
967         PTR_ADDU   "%[addr0],   %[addr0],       %[line_size]            \n\t"
968         PTR_ADDU   "%[addr1],   %[pixels],      %[addr0]                \n\t"
969         MMI_ULDC1(%[ftmp2], %[addr1], 0x00)
970         MMI_ULDC1(%[ftmp4], %[addr1], 0x01)
971         "mov.d      %[ftmp3],   %[ftmp2]                                \n\t"
972         "mov.d      %[ftmp5],   %[ftmp4]                                \n\t"
973         "punpcklbh  %[ftmp2],   %[ftmp2],       %[ftmp7]                \n\t"
974         "punpcklbh  %[ftmp4],   %[ftmp4],       %[ftmp7]                \n\t"
975         "punpckhbh  %[ftmp3],   %[ftmp3],       %[ftmp7]                \n\t"
976         "punpckhbh  %[ftmp5],   %[ftmp5],       %[ftmp7]                \n\t"
977         "paddush    %[ftmp4],   %[ftmp4],       %[ftmp2]                \n\t"
978         "paddush    %[ftmp5],   %[ftmp5],       %[ftmp3]                \n\t"
979         "paddush    %[ftmp0],   %[ftmp0],       %[ftmp6]                \n\t"
980         "paddush    %[ftmp1],   %[ftmp1],       %[ftmp6]                \n\t"
981         "paddush    %[ftmp0],   %[ftmp0],       %[ftmp4]                \n\t"
982         "paddush    %[ftmp1],   %[ftmp1],       %[ftmp5]                \n\t"
983         "psrlh      %[ftmp0],   %[ftmp0],       %[ftmp9]                \n\t"
984         "psrlh      %[ftmp1],   %[ftmp1],       %[ftmp9]                \n\t"
985         "packushb   %[ftmp0],   %[ftmp0],       %[ftmp1]                \n\t"
986         MMI_SDXC1(%[ftmp0], %[block], %[addr0], 0x00)
987         PTR_ADDU   "%[addr0],   %[addr0],       %[line_size]            \n\t"
988         PTR_ADDU   "%[h],       %[h],           -0x02                   \n\t"
989         "bnez       %[h],       1b                                      \n\t"
990         : [ftmp0]"=&f"(ftmp[0]),            [ftmp1]"=&f"(ftmp[1]),
991           [ftmp2]"=&f"(ftmp[2]),            [ftmp3]"=&f"(ftmp[3]),
992           [ftmp4]"=&f"(ftmp[4]),            [ftmp5]"=&f"(ftmp[5]),
993           [ftmp6]"=&f"(ftmp[6]),            [ftmp7]"=&f"(ftmp[7]),
994           [ftmp8]"=&f"(ftmp[8]),            [ftmp9]"=&f"(ftmp[9]),
995           RESTRICT_ASM_ALL64
996           RESTRICT_ASM_ADDRT
997           [addr0]"=&r"(addr[0]),            [addr1]"=&r"(addr[1]),
998           [h]"+&r"(h),                      [pixels]"+&r"(pixels)
999         : [block]"r"(block),                [line_size]"r"((mips_reg)line_size)
1000         : "memory"
1001     );
1002 #else
1003     /* FIXME HIGH BIT DEPTH */
1004     int j;
1005
1006     for (j = 0; j < 2; j++) {
1007         int i;
1008         const uint32_t a = AV_RN32(pixels);
1009         const uint32_t b = AV_RN32(pixels + 1);
1010         uint32_t l0 = (a & 0x03030303UL) +
1011                       (b & 0x03030303UL) +
1012                            0x02020202UL;
1013         uint32_t h0 = ((a & 0xFCFCFCFCUL) >> 2) +
1014                       ((b & 0xFCFCFCFCUL) >> 2);
1015         uint32_t l1, h1;
1016
1017         pixels += line_size;
1018         for (i = 0; i < h; i += 2) {
1019             uint32_t a = AV_RN32(pixels);
1020             uint32_t b = AV_RN32(pixels + 1);
1021             l1 = (a & 0x03030303UL) +
1022                  (b & 0x03030303UL);
1023             h1 = ((a & 0xFCFCFCFCUL) >> 2) +
1024                  ((b & 0xFCFCFCFCUL) >> 2);
1025             *((uint32_t *) block) = h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
1026             pixels += line_size;
1027             block  += line_size;
1028             a  = AV_RN32(pixels);
1029             b  = AV_RN32(pixels + 1);
1030             l0 = (a & 0x03030303UL) +
1031                  (b & 0x03030303UL) +
1032                       0x02020202UL;
1033             h0 = ((a & 0xFCFCFCFCUL) >> 2) +
1034                  ((b & 0xFCFCFCFCUL) >> 2);
1035             *((uint32_t *) block) = h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
1036             pixels += line_size;
1037             block  += line_size;
1038         }
1039         pixels += 4 - line_size * (h + 1);
1040         block  += 4 - line_size * h;
1041     }
1042 #endif
1043 }
1044
1045 void ff_put_pixels16_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
1046     ptrdiff_t line_size, int h)
1047 {
1048     ff_put_pixels8_xy2_8_mmi(block, pixels, line_size, h);
1049     ff_put_pixels8_xy2_8_mmi(block + 8, pixels + 8, line_size, h);
1050 }
1051
1052 void ff_avg_pixels4_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
1053     ptrdiff_t line_size, int h)
1054 {
1055     /* FIXME HIGH BIT DEPTH */
1056     int i;
1057     const uint32_t a = AV_RN32(pixels);
1058     const uint32_t b = AV_RN32(pixels + 1);
1059     uint32_t l0 = (a & 0x03030303UL) +
1060                   (b & 0x03030303UL) +
1061                        0x02020202UL;
1062     uint32_t h0 = ((a & 0xFCFCFCFCUL) >> 2) +
1063                   ((b & 0xFCFCFCFCUL) >> 2);
1064     uint32_t l1, h1;
1065
1066     pixels += line_size;
1067     for (i = 0; i < h; i += 2) {
1068         uint32_t a = AV_RN32(pixels);
1069         uint32_t b = AV_RN32(pixels + 1);
1070         l1 = (a & 0x03030303UL) +
1071              (b & 0x03030303UL);
1072         h1 = ((a & 0xFCFCFCFCUL) >> 2) +
1073              ((b & 0xFCFCFCFCUL) >> 2);
1074         *((uint32_t *) block) = rnd_avg32(*((uint32_t *) block), h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL));
1075         pixels += line_size;
1076         block  += line_size;
1077         a  = AV_RN32(pixels);
1078         b  = AV_RN32(pixels + 1);
1079         l0 = (a & 0x03030303UL) +
1080              (b & 0x03030303UL) +
1081                   0x02020202UL;
1082         h0 = ((a & 0xFCFCFCFCUL) >> 2) +
1083              ((b & 0xFCFCFCFCUL) >> 2);
1084         *((uint32_t *) block) = rnd_avg32(*((uint32_t *) block), h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL));
1085         pixels += line_size;
1086         block  += line_size;
1087     }
1088 }
1089
1090 void ff_avg_pixels8_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
1091     ptrdiff_t line_size, int h)
1092 {
1093     /* FIXME HIGH BIT DEPTH */
1094     int j;
1095
1096     for (j = 0; j < 2; j++) {
1097         int i;
1098         const uint32_t a = AV_RN32(pixels);
1099         const uint32_t b = AV_RN32(pixels + 1);
1100         uint32_t l0 = (a & 0x03030303UL) +
1101                       (b & 0x03030303UL) +
1102                            0x02020202UL;
1103         uint32_t h0 = ((a & 0xFCFCFCFCUL) >> 2) +
1104                       ((b & 0xFCFCFCFCUL) >> 2);
1105         uint32_t l1, h1;
1106
1107         pixels += line_size;
1108         for (i = 0; i < h; i += 2) {
1109             uint32_t a = AV_RN32(pixels);
1110             uint32_t b = AV_RN32(pixels + 1);
1111             l1 = (a & 0x03030303UL) +
1112                  (b & 0x03030303UL);
1113             h1 = ((a & 0xFCFCFCFCUL) >> 2) +
1114                  ((b & 0xFCFCFCFCUL) >> 2);
1115             *((uint32_t *) block) = rnd_avg32(*((uint32_t *) block), h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL));
1116             pixels += line_size;
1117             block  += line_size;
1118             a  = AV_RN32(pixels);
1119             b  = AV_RN32(pixels + 1);
1120             l0 = (a & 0x03030303UL) +
1121                  (b & 0x03030303UL) +
1122                       0x02020202UL;
1123             h0 = ((a & 0xFCFCFCFCUL) >> 2) +
1124                  ((b & 0xFCFCFCFCUL) >> 2);
1125             *((uint32_t *) block) = rnd_avg32(*((uint32_t *) block), h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL));
1126             pixels += line_size;
1127             block  += line_size;
1128         }
1129         pixels += 4 - line_size * (h + 1);
1130         block  += 4 - line_size * h;
1131     }
1132 }
1133
1134 void ff_avg_pixels16_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
1135     ptrdiff_t line_size, int h)
1136 {
1137     ff_avg_pixels8_xy2_8_mmi(block, pixels, line_size, h);
1138     ff_avg_pixels8_xy2_8_mmi(block + 8, pixels + 8, line_size, h);
1139 }
1140
1141 void ff_put_no_rnd_pixels8_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
1142     ptrdiff_t line_size, int h)
1143 {
1144     /* FIXME HIGH BIT DEPTH */
1145     int j;
1146
1147     for (j = 0; j < 2; j++) {
1148         int i;
1149         const uint32_t a = AV_RN32(pixels);
1150         const uint32_t b = AV_RN32(pixels + 1);
1151         uint32_t l0 = (a & 0x03030303UL) +
1152                       (b & 0x03030303UL) +
1153                            0x01010101UL;
1154         uint32_t h0 = ((a & 0xFCFCFCFCUL) >> 2) +
1155                       ((b & 0xFCFCFCFCUL) >> 2);
1156         uint32_t l1, h1;
1157
1158         pixels += line_size;
1159         for (i = 0; i < h; i += 2) {
1160             uint32_t a = AV_RN32(pixels);
1161             uint32_t b = AV_RN32(pixels + 1);
1162             l1 = (a & 0x03030303UL) +
1163                  (b & 0x03030303UL);
1164             h1 = ((a & 0xFCFCFCFCUL) >> 2) +
1165                  ((b & 0xFCFCFCFCUL) >> 2);
1166             *((uint32_t *) block) = h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
1167             pixels += line_size;
1168             block  += line_size;
1169             a  = AV_RN32(pixels);
1170             b  = AV_RN32(pixels + 1);
1171             l0 = (a & 0x03030303UL) +
1172                  (b & 0x03030303UL) +
1173                       0x01010101UL;
1174             h0 = ((a & 0xFCFCFCFCUL) >> 2) +
1175                  ((b & 0xFCFCFCFCUL) >> 2);
1176             *((uint32_t *) block) = h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);
1177             pixels += line_size;
1178             block  += line_size;
1179         }
1180         pixels += 4 - line_size * (h + 1);
1181         block  += 4 - line_size * h;
1182     }
1183 }
1184
1185 void ff_put_no_rnd_pixels16_xy2_8_mmi(uint8_t *block, const uint8_t *pixels,
1186     ptrdiff_t line_size, int h)
1187 {
1188     ff_put_no_rnd_pixels8_xy2_8_mmi(block, pixels, line_size, h);
1189     ff_put_no_rnd_pixels8_xy2_8_mmi(block + 8, pixels + 8, line_size, h);
1190 }