1/*
2 * Copyright (c) 2018 gxw <guxiwei-hf@loongson.cn>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include "vp3dsp_mips.h"
22#include "libavutil/intreadwrite.h"
23#include "libavutil/mips/mmiutils.h"
24#include "libavutil/common.h"
25#include "libavcodec/rnd_avg.h"
26
27#define LOAD_CONST(dst, value)                        \
28    "li     %[tmp1],      "#value"              \n\t" \
29    "dmtc1  %[tmp1],      "#dst"                \n\t" \
30    "pshufh "#dst",       "#dst",     %[ftmp10] \n\t"
31
32static void idct_row_mmi(int16_t *input)
33{
34    double ftmp[23];
35    uint64_t tmp[2];
36    __asm__ volatile (
37        "pxor       %[ftmp10],      %[ftmp10],        %[ftmp10] \n\t"
38        LOAD_CONST(%[csth_1], 1)
39        "li         %[tmp0],        0x02                        \n\t"
40        "1:                                                     \n\t"
41        /* Load input */
42        "ldc1       %[ftmp0],       0x00(%[input])              \n\t"
43        "ldc1       %[ftmp1],       0x10(%[input])              \n\t"
44        "ldc1       %[ftmp2],       0x20(%[input])              \n\t"
45        "ldc1       %[ftmp3],       0x30(%[input])              \n\t"
46        "ldc1       %[ftmp4],       0x40(%[input])              \n\t"
47        "ldc1       %[ftmp5],       0x50(%[input])              \n\t"
48        "ldc1       %[ftmp6],       0x60(%[input])              \n\t"
49        "ldc1       %[ftmp7],       0x70(%[input])              \n\t"
50        LOAD_CONST(%[ftmp8], 64277)
51        LOAD_CONST(%[ftmp9], 12785)
52        "pmulhh     %[A],           %[ftmp9],         %[ftmp7]  \n\t"
53        "pcmpgth    %[C],           %[ftmp10],        %[ftmp1]  \n\t"
54        "por        %[mask],        %[C],             %[csth_1] \n\t"
55        "pmullh     %[B],           %[ftmp1],         %[mask]   \n\t"
56        "pmulhuh    %[B],           %[ftmp8],         %[B]      \n\t"
57        "pmullh     %[B],           %[B],             %[mask]   \n\t"
58        "paddh      %[A],           %[A],             %[B]      \n\t"
59        "paddh      %[A],           %[A],             %[C]      \n\t"
60        "pcmpgth    %[D],           %[ftmp10],        %[ftmp7]  \n\t"
61        "por        %[mask],        %[D],             %[csth_1] \n\t"
62        "pmullh     %[ftmp7],       %[ftmp7],         %[mask]   \n\t"
63        "pmulhuh    %[B],           %[ftmp8],         %[ftmp7]  \n\t"
64        "pmullh     %[B],           %[B],             %[mask]   \n\t"
65        "pmulhh     %[C],           %[ftmp9],         %[ftmp1]  \n\t"
66        "psubh      %[B],           %[C],             %[B]      \n\t"
67        "psubh      %[B],           %[B],             %[D]      \n\t"
68
69        LOAD_CONST(%[ftmp8], 54491)
70        LOAD_CONST(%[ftmp9], 36410)
71        "pcmpgth    %[Ad],          %[ftmp10],        %[ftmp5]  \n\t"
72        "por        %[mask],        %[Ad],            %[csth_1] \n\t"
73        "pmullh     %[ftmp1],       %[ftmp5],         %[mask]   \n\t"
74        "pmulhuh    %[C],           %[ftmp9],         %[ftmp1]  \n\t"
75        "pmullh     %[C],           %[C],             %[mask]   \n\t"
76        "pcmpgth    %[Bd],          %[ftmp10],        %[ftmp3]  \n\t"
77        "por        %[mask],        %[Bd],            %[csth_1] \n\t"
78        "pmullh     %[D],           %[ftmp3],         %[mask]   \n\t"
79        "pmulhuh    %[D],           %[ftmp8],         %[D]      \n\t"
80        "pmullh     %[D],           %[D],             %[mask]   \n\t"
81        "paddh      %[C],           %[C],             %[D]      \n\t"
82        "paddh      %[C],           %[C],             %[Ad]     \n\t"
83        "paddh      %[C],           %[C],             %[Bd]     \n\t"
84        "pcmpgth    %[Bd],          %[ftmp10],        %[ftmp3]  \n\t"
85        "por        %[mask],        %[Bd],            %[csth_1] \n\t"
86        "pmullh     %[ftmp1],       %[ftmp3],         %[mask]   \n\t"
87        "pmulhuh    %[D],           %[ftmp9],         %[ftmp1]  \n\t"
88        "pmullh     %[D],           %[D],             %[mask]   \n\t"
89        "pcmpgth    %[Ed],          %[ftmp10],        %[ftmp5]  \n\t"
90        "por        %[mask],        %[Ed],            %[csth_1] \n\t"
91        "pmullh     %[Ad],          %[ftmp5],         %[mask]   \n\t"
92        "pmulhuh    %[Ad],          %[ftmp8],         %[Ad]     \n\t"
93        "pmullh     %[Ad],          %[Ad],            %[mask]   \n\t"
94        "psubh      %[D],           %[Ad],            %[D]      \n\t"
95        "paddh      %[D],           %[D],             %[Ed]     \n\t"
96        "psubh      %[D],           %[D],             %[Bd]     \n\t"
97
98        LOAD_CONST(%[ftmp8], 46341)
99        "psubh      %[Ad],          %[A],             %[C]      \n\t"
100        "pcmpgth    %[Bd],          %[ftmp10],        %[Ad]     \n\t"
101        "por        %[mask],        %[Bd],            %[csth_1] \n\t"
102        "pmullh     %[Ad],          %[Ad],            %[mask]   \n\t"
103        "pmulhuh    %[Ad],          %[ftmp8],         %[Ad]     \n\t"
104        "pmullh     %[Ad],          %[Ad],            %[mask]   \n\t"
105        "paddh      %[Ad],          %[Ad],            %[Bd]     \n\t"
106        "psubh      %[Bd],          %[B],             %[D]      \n\t"
107        "pcmpgth    %[Cd],          %[ftmp10],        %[Bd]     \n\t"
108        "por        %[mask],        %[Cd],            %[csth_1] \n\t"
109        "pmullh     %[Bd],          %[Bd],            %[mask]   \n\t"
110        "pmulhuh    %[Bd],          %[ftmp8],         %[Bd]     \n\t"
111        "pmullh     %[Bd],          %[Bd],            %[mask]   \n\t"
112        "paddh      %[Bd],          %[Bd],            %[Cd]     \n\t"
113        "paddh      %[Cd],          %[A],             %[C]      \n\t"
114        "paddh      %[Dd],          %[B],             %[D]      \n\t"
115        "paddh      %[A],           %[ftmp0],         %[ftmp4]  \n\t"
116        "pcmpgth    %[B],           %[ftmp10],        %[A]      \n\t"
117        "por        %[mask],        %[B],             %[csth_1] \n\t"
118        "pmullh     %[A],           %[A],             %[mask]   \n\t"
119        "pmulhuh    %[A],           %[ftmp8],         %[A]      \n\t"
120        "pmullh     %[A],           %[A],             %[mask]   \n\t"
121        "paddh      %[A],           %[A],             %[B]      \n\t"
122        "psubh      %[B],           %[ftmp0],         %[ftmp4]  \n\t"
123        "pcmpgth    %[C],           %[ftmp10],        %[B]      \n\t"
124        "por        %[mask],        %[C],             %[csth_1] \n\t"
125        "pmullh     %[B],           %[B],             %[mask]   \n\t"
126        "pmulhuh    %[B],           %[ftmp8],         %[B]      \n\t"
127        "pmullh     %[B],           %[B],             %[mask]   \n\t"
128        "paddh      %[B],           %[B],             %[C]      \n\t"
129
130        LOAD_CONST(%[ftmp8], 60547)
131        LOAD_CONST(%[ftmp9], 25080)
132        "pmulhh     %[C],           %[ftmp9],         %[ftmp6]  \n\t"
133        "pcmpgth    %[D],           %[ftmp10],        %[ftmp2]  \n\t"
134        "por        %[mask],        %[D],             %[csth_1] \n\t"
135        "pmullh     %[Ed],          %[ftmp2],         %[mask]   \n\t"
136        "pmulhuh    %[Ed],          %[ftmp8],         %[Ed]     \n\t"
137        "pmullh     %[Ed],          %[Ed],            %[mask]   \n\t"
138        "paddh      %[C],           %[C],             %[Ed]     \n\t"
139        "paddh      %[C],           %[C],             %[D]      \n\t"
140        "pcmpgth    %[Ed],          %[ftmp10],        %[ftmp6]  \n\t"
141        "por        %[mask],        %[Ed],            %[csth_1] \n\t"
142        "pmullh     %[ftmp6],       %[ftmp6],         %[mask]   \n\t"
143        "pmulhuh    %[D],           %[ftmp8],         %[ftmp6]  \n\t"
144        "pmullh     %[D],           %[D],             %[mask]   \n\t"
145        "pmulhh     %[Gd],          %[ftmp9],         %[ftmp2]  \n\t"
146        "psubh      %[D],           %[Gd],            %[D]      \n\t"
147        "psubh      %[D],           %[D],             %[Ed]     \n\t"
148        "psubh      %[Ed],          %[A],             %[C]      \n\t"
149        "paddh      %[Gd],          %[A],             %[C]      \n\t"
150        "paddh      %[A],           %[B],             %[Ad]     \n\t"
151        "psubh      %[C],           %[B],             %[Ad]     \n\t"
152        "psubh      %[B],           %[Bd],            %[D]      \n\t"
153        "paddh      %[D],           %[Bd],            %[D]      \n\t"
154        /* Final sequence of operations over-write original inputs */
155        "paddh      %[ftmp0],       %[Gd],            %[Cd]     \n\t"
156        "paddh      %[ftmp1],       %[A],             %[D]      \n\t"
157        "psubh      %[ftmp2],       %[A],             %[D]      \n\t"
158        "paddh      %[ftmp3],       %[Ed],            %[Dd]     \n\t"
159        "psubh      %[ftmp4],       %[Ed],            %[Dd]     \n\t"
160        "paddh      %[ftmp5],       %[C],             %[B]      \n\t"
161        "psubh      %[ftmp6],       %[C],             %[B]      \n\t"
162        "psubh      %[ftmp7],       %[Gd],            %[Cd]     \n\t"
163        "sdc1       %[ftmp0],       0x00(%[input])              \n\t"
164        "sdc1       %[ftmp1],       0x10(%[input])              \n\t"
165        "sdc1       %[ftmp2],       0x20(%[input])              \n\t"
166        "sdc1       %[ftmp3],       0x30(%[input])              \n\t"
167        "sdc1       %[ftmp4],       0x40(%[input])              \n\t"
168        "sdc1       %[ftmp5],       0x50(%[input])              \n\t"
169        "sdc1       %[ftmp6],       0x60(%[input])              \n\t"
170        "sdc1       %[ftmp7],       0x70(%[input])              \n\t"
171        PTR_ADDU   "%[tmp0],        %[tmp0],          -0x01     \n\t"
172        PTR_ADDIU  "%[input],       %[input],         0x08      \n\t"
173        "bnez       %[tmp0],        1b                          \n\t"
174        : [input]"+&r"(input), [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
175          [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), [ftmp2]"=&f"(ftmp[2]),
176          [ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
177          [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), [ftmp8]"=&f"(ftmp[8]),
178          [ftmp9]"=&f"(ftmp[9]), [ftmp10]"=&f"(ftmp[10]), [mask]"=&f"(ftmp[11]),
179          [A]"=&f"(ftmp[12]), [B]"=&f"(ftmp[13]), [C]"=&f"(ftmp[14]),
180          [D]"=&f"(ftmp[15]), [Ad]"=&f"(ftmp[16]), [Bd]"=&f"(ftmp[17]),
181          [Cd]"=&f"(ftmp[18]), [Dd]"=&f"(ftmp[19]), [Ed]"=&f"(ftmp[20]),
182          [Gd]"=&f"(ftmp[21]), [csth_1]"=&f"(ftmp[22])
183        :
184        : "memory"
185    );
186}
187
188static void idct_column_true_mmi(uint8_t *dst, int stride, int16_t *input)
189{
190    uint8_t temp_value[8];
191    double ftmp[23];
192    uint64_t tmp[2];
193    for (int i = 0; i < 8; ++i)
194        temp_value[i] = av_clip_uint8(128 + ((46341 * input[i << 3] + (8 << 16)) >> 20));
195    __asm__ volatile (
196        "pxor       %[ftmp10],      %[ftmp10],          %[ftmp10] \n\t"
197        "li         %[tmp0],        0x02                          \n\t"
198        "1:                                                       \n\t"
199        "ldc1       %[ftmp0],       0x00(%[input])                \n\t"
200        "ldc1       %[ftmp4],       0x08(%[input])                \n\t"
201        "ldc1       %[ftmp1],       0x10(%[input])                \n\t"
202        "ldc1       %[ftmp5],       0x18(%[input])                \n\t"
203        "ldc1       %[ftmp2],       0x20(%[input])                \n\t"
204        "ldc1       %[ftmp6],       0x28(%[input])                \n\t"
205        "ldc1       %[ftmp3],       0x30(%[input])                \n\t"
206        "ldc1       %[ftmp7],       0x38(%[input])                \n\t"
207        TRANSPOSE_4H(%[ftmp0], %[ftmp1], %[ftmp2], %[ftmp3],
208                     %[A], %[B], %[C], %[D])
209        TRANSPOSE_4H(%[ftmp4], %[ftmp5], %[ftmp6], %[ftmp7],
210                     %[A], %[B], %[C], %[D])
211        LOAD_CONST(%[ftmp8], 64277)
212        LOAD_CONST(%[ftmp9], 12785)
213        LOAD_CONST(%[Gd], 1)
214        "pmulhh     %[A],           %[ftmp9],           %[ftmp7]  \n\t"
215        "pcmpgth    %[C],           %[ftmp10],          %[ftmp1]  \n\t"
216        "por        %[mask],        %[C],               %[Gd]     \n\t"
217        "pmullh     %[B],           %[ftmp1],           %[mask]   \n\t"
218        "pmulhuh    %[B],           %[ftmp8],           %[B]      \n\t"
219        "pmullh     %[B],           %[B],               %[mask]   \n\t"
220        "paddh      %[A],           %[A],               %[B]      \n\t"
221        "paddh      %[A],           %[A],               %[C]      \n\t"
222        "pcmpgth    %[D],           %[ftmp10],          %[ftmp7]  \n\t"
223        "por        %[mask],        %[D],               %[Gd]     \n\t"
224        "pmullh     %[Ad],          %[ftmp7],           %[mask]   \n\t"
225        "pmulhuh    %[B],           %[ftmp8],           %[Ad]     \n\t"
226        "pmullh     %[B],           %[B],               %[mask]   \n\t"
227        "pmulhh     %[C],           %[ftmp9],           %[ftmp1]  \n\t"
228        "psubh      %[B],           %[C],               %[B]      \n\t"
229        "psubh      %[B],           %[B],               %[D]      \n\t"
230
231        LOAD_CONST(%[ftmp8], 54491)
232        LOAD_CONST(%[ftmp9], 36410)
233        "pcmpgth    %[Ad],          %[ftmp10],          %[ftmp5]  \n\t"
234        "por        %[mask],        %[Ad],              %[Gd]     \n\t"
235        "pmullh     %[Cd],          %[ftmp5],           %[mask]   \n\t"
236        "pmulhuh    %[C],           %[ftmp9],           %[Cd]     \n\t"
237        "pmullh     %[C],           %[C],               %[mask]   \n\t"
238        "pcmpgth    %[Bd],          %[ftmp10],          %[ftmp3]  \n\t"
239        "por        %[mask],        %[Bd],              %[Gd]     \n\t"
240        "pmullh     %[D],           %[ftmp3],           %[mask]   \n\t"
241        "pmulhuh    %[D],           %[ftmp8],           %[D]      \n\t"
242        "pmullh     %[D],           %[D],               %[mask]   \n\t"
243        "paddh      %[C],           %[C],               %[D]      \n\t"
244        "paddh      %[C],           %[C],               %[Ad]     \n\t"
245        "paddh      %[C],           %[C],               %[Bd]     \n\t"
246        "pcmpgth    %[Bd],          %[ftmp10],          %[ftmp3]  \n\t"
247        "por        %[mask],        %[Bd],              %[Gd]     \n\t"
248        "pmullh     %[Cd],          %[ftmp3],           %[mask]   \n\t"
249        "pmulhuh    %[D],           %[ftmp9],           %[Cd]     \n\t"
250        "pmullh     %[D],           %[D],               %[mask]   \n\t"
251        "pcmpgth    %[Ed],          %[ftmp10],          %[ftmp5]  \n\t"
252        "por        %[mask],        %[Ed],              %[Gd]     \n\t"
253        "pmullh     %[Ad],          %[ftmp5],           %[mask]   \n\t"
254        "pmulhuh    %[Ad],          %[ftmp8],           %[Ad]     \n\t"
255        "pmullh     %[Ad],          %[Ad],              %[mask]   \n\t"
256        "psubh      %[D],           %[Ad],              %[D]      \n\t"
257        "paddh      %[D],           %[D],               %[Ed]     \n\t"
258        "psubh      %[D],           %[D],               %[Bd]     \n\t"
259
260        LOAD_CONST(%[ftmp8], 46341)
261        "psubh      %[Ad],          %[A],             %[C]        \n\t"
262        "pcmpgth    %[Bd],          %[ftmp10],        %[Ad]       \n\t"
263        "por        %[mask],        %[Bd],            %[Gd]       \n\t"
264        "pmullh     %[Ad],          %[Ad],            %[mask]     \n\t"
265        "pmulhuh    %[Ad],          %[ftmp8],         %[Ad]       \n\t"
266        "pmullh     %[Ad],          %[Ad],            %[mask]     \n\t"
267        "paddh      %[Ad],          %[Ad],            %[Bd]       \n\t"
268        "psubh      %[Bd],          %[B],             %[D]        \n\t"
269        "pcmpgth    %[Cd],          %[ftmp10],        %[Bd]       \n\t"
270        "por        %[mask],        %[Cd],            %[Gd]       \n\t"
271        "pmullh     %[Bd],          %[Bd],            %[mask]     \n\t"
272        "pmulhuh    %[Bd],          %[ftmp8],         %[Bd]       \n\t"
273        "pmullh     %[Bd],          %[Bd],            %[mask]     \n\t"
274        "paddh      %[Bd],          %[Bd],            %[Cd]       \n\t"
275        "paddh      %[Cd],          %[A],             %[C]        \n\t"
276        "paddh      %[Dd],          %[B],             %[D]        \n\t"
277
278        LOAD_CONST(%[Ed], 2056)
279        "paddh      %[A],           %[ftmp0],         %[ftmp4]    \n\t"
280        "pcmpgth    %[B],           %[ftmp10],        %[A]        \n\t"
281        "por        %[mask],        %[B],             %[Gd]       \n\t"
282        "pmullh     %[A],           %[A],             %[mask]     \n\t"
283        "pmulhuh    %[A],           %[ftmp8],         %[A]        \n\t"
284        "pmullh     %[A],           %[A],             %[mask]     \n\t"
285        "paddh      %[A],           %[A],             %[B]        \n\t"
286        "paddh      %[A],           %[A],             %[Ed]       \n\t"
287        "psubh      %[B],           %[ftmp0],         %[ftmp4]    \n\t"
288        "pcmpgth    %[C],           %[ftmp10],        %[B]        \n\t"
289        "por        %[mask],        %[C],             %[Gd]       \n\t"
290        "pmullh     %[B],           %[B],             %[mask]     \n\t"
291        "pmulhuh    %[B],           %[ftmp8],         %[B]        \n\t"
292        "pmullh     %[B],           %[B],             %[mask]     \n\t"
293        "paddh      %[B],           %[B],             %[C]        \n\t"
294        "paddh      %[B],           %[B],             %[Ed]       \n\t"
295
296        LOAD_CONST(%[ftmp8], 60547)
297        LOAD_CONST(%[ftmp9], 25080)
298        "pmulhh     %[C],           %[ftmp9],         %[ftmp6]    \n\t"
299        "pcmpgth    %[D],           %[ftmp10],        %[ftmp2]    \n\t"
300        "por        %[mask],        %[D],             %[Gd]       \n\t"
301        "pmullh     %[Ed],          %[ftmp2],         %[mask]     \n\t"
302        "pmulhuh    %[Ed],          %[ftmp8],         %[Ed]       \n\t"
303        "pmullh     %[Ed],          %[Ed],            %[mask]     \n\t"
304        "paddh      %[C],           %[C],             %[Ed]       \n\t"
305        "paddh      %[C],           %[C],             %[D]        \n\t"
306        "pcmpgth    %[Ed],          %[ftmp10],        %[ftmp6]    \n\t"
307        "por        %[mask],        %[Ed],            %[Gd]       \n\t"
308        "pmullh     %[D],           %[ftmp6],         %[mask]     \n\t"
309        "pmulhuh    %[D],           %[ftmp8],         %[D]        \n\t"
310        "pmullh     %[D],           %[D],             %[mask]     \n\t"
311        "pmulhh     %[Gd],          %[ftmp9],         %[ftmp2]    \n\t"
312        "psubh      %[D],           %[Gd],            %[D]        \n\t"
313        "psubh      %[D],           %[D],             %[Ed]       \n\t"
314        "psubh      %[Ed],          %[A],             %[C]        \n\t"
315        "paddh      %[Gd],          %[A],             %[C]        \n\t"
316        "paddh      %[A],           %[B],             %[Ad]       \n\t"
317        "psubh      %[C],           %[B],             %[Ad]       \n\t"
318        "psubh      %[B],           %[Bd],            %[D]        \n\t"
319        "paddh      %[D],           %[Bd],            %[D]        \n\t"
320        "por        %[mask],        %[ftmp1],         %[ftmp2]    \n\t"
321        "por        %[mask],        %[mask],          %[ftmp3]    \n\t"
322        "por        %[mask],        %[mask],          %[ftmp4]    \n\t"
323        "por        %[mask],        %[mask],          %[ftmp5]    \n\t"
324        "por        %[mask],        %[mask],          %[ftmp6]    \n\t"
325        "por        %[mask],        %[mask],          %[ftmp7]    \n\t"
326        "pcmpeqh    %[mask],        %[mask],          %[ftmp10]   \n\t"
327        "packushb   %[mask],        %[mask],          %[ftmp10]   \n\t"
328        "li         %[tmp1],        0x04                          \n\t"
329        "dmtc1      %[tmp1],        %[ftmp8]                      \n\t"
330        "paddh      %[ftmp0],       %[Gd],            %[Cd]       \n\t"
331        "psrah      %[ftmp0],       %[ftmp0],         %[ftmp8]    \n\t"
332        "paddh      %[ftmp1],       %[A],             %[D]        \n\t"
333        "psrah      %[ftmp1],       %[ftmp1],         %[ftmp8]    \n\t"
334        "psubh      %[ftmp2],       %[A],             %[D]        \n\t"
335        "psrah      %[ftmp2],       %[ftmp2],         %[ftmp8]    \n\t"
336        "paddh      %[ftmp3],       %[Ed],            %[Dd]       \n\t"
337        "psrah      %[ftmp3],       %[ftmp3],         %[ftmp8]    \n\t"
338        "psubh      %[ftmp4],       %[Ed],            %[Dd]       \n\t"
339        "psrah      %[ftmp4],       %[ftmp4],         %[ftmp8]    \n\t"
340        "paddh      %[ftmp5],       %[C],             %[B]        \n\t"
341        "psrah      %[ftmp5],       %[ftmp5],         %[ftmp8]    \n\t"
342        "psubh      %[ftmp6],       %[C],             %[B]        \n\t"
343        "psrah      %[ftmp6],       %[ftmp6],         %[ftmp8]    \n\t"
344        "psubh      %[ftmp7],       %[Gd],            %[Cd]       \n\t"
345        "psrah      %[ftmp7],       %[ftmp7],         %[ftmp8]    \n\t"
346        "pmaxsh     %[ftmp0],       %[ftmp0],         %[ftmp10]   \n\t"
347        "packushb   %[ftmp0],       %[ftmp0],         %[ftmp10]   \n\t"
348        "pmaxsh     %[ftmp1],       %[ftmp1],         %[ftmp10]   \n\t"
349        "packushb   %[ftmp1],       %[ftmp1],         %[ftmp10]   \n\t"
350        "pmaxsh     %[ftmp2],       %[ftmp2],         %[ftmp10]   \n\t"
351        "packushb   %[ftmp2],       %[ftmp2],         %[ftmp10]   \n\t"
352        "pmaxsh     %[ftmp3],       %[ftmp3],         %[ftmp10]   \n\t"
353        "packushb   %[ftmp3],       %[ftmp3],         %[ftmp10]   \n\t"
354        "pmaxsh     %[ftmp4],       %[ftmp4],         %[ftmp10]   \n\t"
355        "packushb   %[ftmp4],       %[ftmp4],         %[ftmp10]   \n\t"
356        "pmaxsh     %[ftmp5],       %[ftmp5],         %[ftmp10]   \n\t"
357        "packushb   %[ftmp5],       %[ftmp5],         %[ftmp10]   \n\t"
358        "pmaxsh     %[ftmp6],       %[ftmp6],         %[ftmp10]   \n\t"
359        "packushb   %[ftmp6],       %[ftmp6],         %[ftmp10]   \n\t"
360        "pmaxsh     %[ftmp7],       %[ftmp7],         %[ftmp10]   \n\t"
361        "packushb   %[ftmp7],       %[ftmp7],         %[ftmp10]   \n\t"
362
363        "lwc1       %[Ed],          0x00(%[temp_value])           \n\t"
364        "pand       %[Ed],          %[Ed],            %[mask]     \n\t"
365        "paddb      %[ftmp0],       %[ftmp0],         %[Ed]       \n\t"
366        "paddb      %[ftmp1],       %[ftmp1],         %[Ed]       \n\t"
367        "paddb      %[ftmp2],       %[ftmp2],         %[Ed]       \n\t"
368        "paddb      %[ftmp3],       %[ftmp3],         %[Ed]       \n\t"
369        "paddb      %[ftmp4],       %[ftmp4],         %[Ed]       \n\t"
370        "paddb      %[ftmp5],       %[ftmp5],         %[Ed]       \n\t"
371        "paddb      %[ftmp6],       %[ftmp6],         %[Ed]       \n\t"
372        "paddb      %[ftmp7],       %[ftmp7],         %[Ed]       \n\t"
373        "swc1       %[ftmp0],       0x00(%[dst])                  \n\t"
374        PTR_ADDU   "%[tmp1],        %[dst],           %[stride]   \n\t"
375        "swc1       %[ftmp1],       0x00(%[tmp1])                 \n\t"
376        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
377        "swc1       %[ftmp2],       0x00(%[tmp1])                 \n\t"
378        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
379        "swc1       %[ftmp3],       0x00(%[tmp1])                 \n\t"
380        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
381        "swc1       %[ftmp4],       0x00(%[tmp1])                 \n\t"
382        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
383        "swc1       %[ftmp5],       0x00(%[tmp1])                 \n\t"
384        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
385        "swc1       %[ftmp6],       0x00(%[tmp1])                 \n\t"
386        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
387        "swc1       %[ftmp7],       0x00(%[tmp1])                 \n\t"
388        PTR_ADDIU  "%[dst],         %[dst],           0x04        \n\t"
389        PTR_ADDIU  "%[input],       %[input],         0x40        \n\t"
390        PTR_ADDIU  "%[temp_value],  %[temp_value],    0x04        \n\t"
391        PTR_ADDIU  "%[tmp0],        %[tmp0],          -0x01       \n\t"
392        "bnez       %[tmp0],        1b                            \n\t"
393        : [dst]"+&r"(dst), [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
394          [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), [ftmp2]"=&f"(ftmp[2]),
395          [ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
396          [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), [ftmp8]"=&f"(ftmp[8]),
397          [ftmp9]"=&f"(ftmp[9]), [ftmp10]"=&f"(ftmp[10]), [mask]"=&f"(ftmp[11]),
398          [A]"=&f"(ftmp[12]), [B]"=&f"(ftmp[13]), [C]"=&f"(ftmp[14]),
399          [D]"=&f"(ftmp[15]), [Ad]"=&f"(ftmp[16]), [Bd]"=&f"(ftmp[17]),
400          [Cd]"=&f"(ftmp[18]), [Dd]"=&f"(ftmp[19]), [Ed]"=&f"(ftmp[20]),
401          [Gd]"=&f"(ftmp[21]), [input]"+&r"(input)
402        : [stride]"r"(stride), [temp_value]"r"(temp_value)
403        : "memory"
404    );
405}
406
407static void idct_column_false_mmi(uint8_t *dst, int stride, int16_t *input)
408{
409    int16_t temp_value[8];
410    double ftmp[23];
411    uint64_t tmp[2];
412    for (int i = 0; i < 8; ++i)
413        temp_value[i] = (46341 * input[i << 3] + (8 << 16)) >> 20;
414    __asm__ volatile (
415        "pxor       %[ftmp10],      %[ftmp10],          %[ftmp10] \n\t"
416        "li         %[tmp0],        0x02                          \n\t"
417        "1:                                                       \n\t"
418        "ldc1       %[ftmp0],       0x00(%[input])                \n\t"
419        "ldc1       %[ftmp4],       0x08(%[input])                \n\t"
420        "ldc1       %[ftmp1],       0x10(%[input])                \n\t"
421        "ldc1       %[ftmp5],       0x18(%[input])                \n\t"
422        "ldc1       %[ftmp2],       0x20(%[input])                \n\t"
423        "ldc1       %[ftmp6],       0x28(%[input])                \n\t"
424        "ldc1       %[ftmp3],       0x30(%[input])                \n\t"
425        "ldc1       %[ftmp7],       0x38(%[input])                \n\t"
426        TRANSPOSE_4H(%[ftmp0], %[ftmp1], %[ftmp2], %[ftmp3],
427                     %[A], %[B], %[C], %[D])
428        TRANSPOSE_4H(%[ftmp4], %[ftmp5], %[ftmp6], %[ftmp7],
429                     %[A], %[B], %[C], %[D])
430        LOAD_CONST(%[ftmp8], 64277)
431        LOAD_CONST(%[ftmp9], 12785)
432        LOAD_CONST(%[Gd], 1)
433        "pmulhh     %[A],           %[ftmp9],           %[ftmp7]  \n\t"
434        "pcmpgth    %[C],           %[ftmp10],          %[ftmp1]  \n\t"
435        "por        %[mask],        %[C],               %[Gd]     \n\t"
436        "pmullh     %[B],           %[ftmp1],           %[mask]   \n\t"
437        "pmulhuh    %[B],           %[ftmp8],           %[B]      \n\t"
438        "pmullh     %[B],           %[B],               %[mask]   \n\t"
439        "paddh      %[A],           %[A],               %[B]      \n\t"
440        "paddh      %[A],           %[A],               %[C]      \n\t"
441        "pcmpgth    %[D],           %[ftmp10],          %[ftmp7]  \n\t"
442        "por        %[mask],        %[D],               %[Gd]     \n\t"
443        "pmullh     %[Ad],          %[ftmp7],           %[mask]   \n\t"
444        "pmulhuh    %[B],           %[ftmp8],           %[Ad]     \n\t"
445        "pmullh     %[B],           %[B],               %[mask]   \n\t"
446        "pmulhh     %[C],           %[ftmp9],           %[ftmp1]  \n\t"
447        "psubh      %[B],           %[C],               %[B]      \n\t"
448        "psubh      %[B],           %[B],               %[D]      \n\t"
449
450        LOAD_CONST(%[ftmp8], 54491)
451        LOAD_CONST(%[ftmp9], 36410)
452        "pcmpgth    %[Ad],          %[ftmp10],          %[ftmp5]  \n\t"
453        "por        %[mask],        %[Ad],              %[Gd]     \n\t"
454        "pmullh     %[Cd],          %[ftmp5],           %[mask]   \n\t"
455        "pmulhuh    %[C],           %[ftmp9],           %[Cd]     \n\t"
456        "pmullh     %[C],           %[C],               %[mask]   \n\t"
457        "pcmpgth    %[Bd],          %[ftmp10],          %[ftmp3]  \n\t"
458        "por        %[mask],        %[Bd],              %[Gd]     \n\t"
459        "pmullh     %[D],           %[ftmp3],           %[mask]   \n\t"
460        "pmulhuh    %[D],           %[ftmp8],           %[D]      \n\t"
461        "pmullh     %[D],           %[D],               %[mask]   \n\t"
462        "paddh      %[C],           %[C],               %[D]      \n\t"
463        "paddh      %[C],           %[C],               %[Ad]     \n\t"
464        "paddh      %[C],           %[C],               %[Bd]     \n\t"
465        "pcmpgth    %[Bd],          %[ftmp10],          %[ftmp3]  \n\t"
466        "por        %[mask],        %[Bd],              %[Gd]     \n\t"
467        "pmullh     %[Cd],          %[ftmp3],           %[mask]   \n\t"
468        "pmulhuh    %[D],           %[ftmp9],           %[Cd]     \n\t"
469        "pmullh     %[D],           %[D],               %[mask]   \n\t"
470        "pcmpgth    %[Ed],          %[ftmp10],          %[ftmp5]  \n\t"
471        "por        %[mask],        %[Ed],              %[Gd]     \n\t"
472        "pmullh     %[Ad],          %[ftmp5],           %[mask]   \n\t"
473        "pmulhuh    %[Ad],          %[ftmp8],           %[Ad]     \n\t"
474        "pmullh     %[Ad],          %[Ad],              %[mask]   \n\t"
475        "psubh      %[D],           %[Ad],              %[D]      \n\t"
476        "paddh      %[D],           %[D],               %[Ed]     \n\t"
477        "psubh      %[D],           %[D],               %[Bd]     \n\t"
478
479        LOAD_CONST(%[ftmp8], 46341)
480        "psubh      %[Ad],          %[A],             %[C]        \n\t"
481        "pcmpgth    %[Bd],          %[ftmp10],        %[Ad]       \n\t"
482        "por        %[mask],        %[Bd],            %[Gd]       \n\t"
483        "pmullh     %[Ad],          %[Ad],            %[mask]     \n\t"
484        "pmulhuh    %[Ad],          %[ftmp8],         %[Ad]       \n\t"
485        "pmullh     %[Ad],          %[Ad],            %[mask]     \n\t"
486        "paddh      %[Ad],          %[Ad],            %[Bd]       \n\t"
487        "psubh      %[Bd],          %[B],             %[D]        \n\t"
488        "pcmpgth    %[Cd],          %[ftmp10],        %[Bd]       \n\t"
489        "por        %[mask],        %[Cd],            %[Gd]       \n\t"
490        "pmullh     %[Bd],          %[Bd],            %[mask]     \n\t"
491        "pmulhuh    %[Bd],          %[ftmp8],         %[Bd]       \n\t"
492        "pmullh     %[Bd],          %[Bd],            %[mask]     \n\t"
493        "paddh      %[Bd],          %[Bd],            %[Cd]       \n\t"
494        "paddh      %[Cd],          %[A],             %[C]        \n\t"
495        "paddh      %[Dd],          %[B],             %[D]        \n\t"
496
497        LOAD_CONST(%[Ed], 8)
498        "paddh      %[A],           %[ftmp0],         %[ftmp4]    \n\t"
499        "pcmpgth    %[B],           %[ftmp10],        %[A]        \n\t"
500        "por        %[mask],        %[B],             %[Gd]       \n\t"
501        "pmullh     %[A],           %[A],             %[mask]     \n\t"
502        "pmulhuh    %[A],           %[ftmp8],         %[A]        \n\t"
503        "pmullh     %[A],           %[A],             %[mask]     \n\t"
504        "paddh      %[A],           %[A],             %[B]        \n\t"
505        "paddh      %[A],           %[A],             %[Ed]       \n\t"
506        "psubh      %[B],           %[ftmp0],         %[ftmp4]    \n\t"
507        "pcmpgth    %[C],           %[ftmp10],        %[B]        \n\t"
508        "por        %[mask],        %[C],             %[Gd]       \n\t"
509        "pmullh     %[B],           %[B],             %[mask]     \n\t"
510        "pmulhuh    %[B],           %[ftmp8],         %[B]        \n\t"
511        "pmullh     %[B],           %[B],             %[mask]     \n\t"
512        "paddh      %[B],           %[B],             %[C]        \n\t"
513        "paddh      %[B],           %[B],             %[Ed]       \n\t"
514
515        LOAD_CONST(%[ftmp8], 60547)
516        LOAD_CONST(%[ftmp9], 25080)
517        "pmulhh     %[C],           %[ftmp9],         %[ftmp6]    \n\t"
518        "pcmpgth    %[D],           %[ftmp10],        %[ftmp2]    \n\t"
519        "por        %[mask],        %[D],             %[Gd]       \n\t"
520        "pmullh     %[Ed],          %[ftmp2],         %[mask]     \n\t"
521        "pmulhuh    %[Ed],          %[ftmp8],         %[Ed]       \n\t"
522        "pmullh     %[Ed],          %[Ed],            %[mask]     \n\t"
523        "paddh      %[C],           %[C],             %[Ed]       \n\t"
524        "paddh      %[C],           %[C],             %[D]        \n\t"
525        "pcmpgth    %[Ed],          %[ftmp10],        %[ftmp6]    \n\t"
526        "por        %[mask],        %[Ed],            %[Gd]       \n\t"
527        "pmullh     %[D],           %[ftmp6],         %[mask]     \n\t"
528        "pmulhuh    %[D],           %[ftmp8],         %[D]        \n\t"
529        "pmullh     %[D],           %[D],             %[mask]     \n\t"
530        "pmulhh     %[Gd],          %[ftmp9],         %[ftmp2]    \n\t"
531        "psubh      %[D],           %[Gd],            %[D]        \n\t"
532        "psubh      %[D],           %[D],             %[Ed]       \n\t"
533        "psubh      %[Ed],          %[A],             %[C]        \n\t"
534        "paddh      %[Gd],          %[A],             %[C]        \n\t"
535        "paddh      %[A],           %[B],             %[Ad]       \n\t"
536        "psubh      %[C],           %[B],             %[Ad]       \n\t"
537        "psubh      %[B],           %[Bd],            %[D]        \n\t"
538        "paddh      %[D],           %[Bd],            %[D]        \n\t"
539        "por        %[mask],        %[ftmp1],         %[ftmp2]    \n\t"
540        "por        %[mask],        %[mask],          %[ftmp3]    \n\t"
541        "por        %[mask],        %[mask],          %[ftmp4]    \n\t"
542        "por        %[mask],        %[mask],          %[ftmp5]    \n\t"
543        "por        %[mask],        %[mask],          %[ftmp6]    \n\t"
544        "por        %[mask],        %[mask],          %[ftmp7]    \n\t"
545        "pcmpeqh    %[mask],        %[mask],          %[ftmp10]   \n\t"
546        "li         %[tmp1],        0x04                          \n\t"
547        "dmtc1      %[tmp1],        %[ftmp8]                      \n\t"
548        "paddh      %[ftmp0],       %[Gd],            %[Cd]       \n\t"
549        "psrah      %[ftmp0],       %[ftmp0],         %[ftmp8]    \n\t"
550        "paddh      %[ftmp1],       %[A],             %[D]        \n\t"
551        "psrah      %[ftmp1],       %[ftmp1],         %[ftmp8]    \n\t"
552        "psubh      %[ftmp2],       %[A],             %[D]        \n\t"
553        "psrah      %[ftmp2],       %[ftmp2],         %[ftmp8]    \n\t"
554        "paddh      %[ftmp3],       %[Ed],            %[Dd]       \n\t"
555        "psrah      %[ftmp3],       %[ftmp3],         %[ftmp8]    \n\t"
556        "psubh      %[ftmp4],       %[Ed],            %[Dd]       \n\t"
557        "psrah      %[ftmp4],       %[ftmp4],         %[ftmp8]    \n\t"
558        "paddh      %[ftmp5],       %[C],             %[B]        \n\t"
559        "psrah      %[ftmp5],       %[ftmp5],         %[ftmp8]    \n\t"
560        "psubh      %[ftmp6],       %[C],             %[B]        \n\t"
561        "psrah      %[ftmp6],       %[ftmp6],         %[ftmp8]    \n\t"
562        "psubh      %[ftmp7],       %[Gd],            %[Cd]       \n\t"
563        "psrah      %[ftmp7],       %[ftmp7],         %[ftmp8]    \n\t"
564
565        /* Load from dst */
566        "lwc1       %[A],           0x00(%[dst])                  \n\t"
567        PTR_ADDU   "%[tmp1],        %[dst],           %[stride]   \n\t"
568        "lwc1       %[B],           0x00(%[tmp1])                 \n\t"
569        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
570        "lwc1       %[C],           0x00(%[tmp1])                 \n\t"
571        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
572        "lwc1       %[D],           0x00(%[tmp1])                 \n\t"
573        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
574        "lwc1       %[Ad],          0x00(%[tmp1])                 \n\t"
575        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
576        "lwc1       %[Bd],          0x00(%[tmp1])                 \n\t"
577        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
578        "lwc1       %[Cd],          0x00(%[tmp1])                 \n\t"
579        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
580        "lwc1       %[Dd],          0x00(%[tmp1])                 \n\t"
581        "punpcklbh  %[A],           %[A],             %[ftmp10]   \n\t"
582        "punpcklbh  %[B],           %[B],             %[ftmp10]   \n\t"
583        "punpcklbh  %[C],           %[C],             %[ftmp10]   \n\t"
584        "punpcklbh  %[D],           %[D],             %[ftmp10]   \n\t"
585        "punpcklbh  %[Ad],          %[Ad],            %[ftmp10]   \n\t"
586        "punpcklbh  %[Bd],          %[Bd],            %[ftmp10]   \n\t"
587        "punpcklbh  %[Cd],          %[Cd],            %[ftmp10]   \n\t"
588        "punpcklbh  %[Dd],          %[Dd],            %[ftmp10]   \n\t"
589        "ldc1       %[Ed],          0x00(%[temp_value])           \n\t"
590        "pand       %[Ed],          %[Ed],            %[mask]     \n\t"
591        "pnor       %[mask],        %[mask],          %[mask]     \n\t"
592        "pand       %[ftmp0],       %[ftmp0],         %[mask]     \n\t"
593        "pand       %[ftmp1],       %[ftmp1],         %[mask]     \n\t"
594        "pand       %[ftmp2],       %[ftmp2],         %[mask]     \n\t"
595        "pand       %[ftmp3],       %[ftmp3],         %[mask]     \n\t"
596        "pand       %[ftmp4],       %[ftmp4],         %[mask]     \n\t"
597        "pand       %[ftmp5],       %[ftmp5],         %[mask]     \n\t"
598        "pand       %[ftmp6],       %[ftmp6],         %[mask]     \n\t"
599        "pand       %[ftmp7],       %[ftmp7],         %[mask]     \n\t"
600        "paddh      %[ftmp0],       %[ftmp0],         %[A]        \n\t"
601        "paddh      %[ftmp1],       %[ftmp1],         %[B]        \n\t"
602        "paddh      %[ftmp2],       %[ftmp2],         %[C]        \n\t"
603        "paddh      %[ftmp3],       %[ftmp3],         %[D]        \n\t"
604        "paddh      %[ftmp4],       %[ftmp4],         %[Ad]       \n\t"
605        "paddh      %[ftmp5],       %[ftmp5],         %[Bd]       \n\t"
606        "paddh      %[ftmp6],       %[ftmp6],         %[Cd]       \n\t"
607        "paddh      %[ftmp7],       %[ftmp7],         %[Dd]       \n\t"
608        "paddh      %[ftmp0],       %[ftmp0],         %[Ed]       \n\t"
609        "paddh      %[ftmp1],       %[ftmp1],         %[Ed]       \n\t"
610        "paddh      %[ftmp2],       %[ftmp2],         %[Ed]       \n\t"
611        "paddh      %[ftmp3],       %[ftmp3],         %[Ed]       \n\t"
612        "paddh      %[ftmp4],       %[ftmp4],         %[Ed]       \n\t"
613        "paddh      %[ftmp5],       %[ftmp5],         %[Ed]       \n\t"
614        "paddh      %[ftmp6],       %[ftmp6],         %[Ed]       \n\t"
615        "paddh      %[ftmp7],       %[ftmp7],         %[Ed]       \n\t"
616        "pmaxsh     %[ftmp0],       %[ftmp0],         %[ftmp10]   \n\t"
617        "packushb   %[ftmp0],       %[ftmp0],         %[ftmp10]   \n\t"
618        "pmaxsh     %[ftmp1],       %[ftmp1],         %[ftmp10]   \n\t"
619        "packushb   %[ftmp1],       %[ftmp1],         %[ftmp10]   \n\t"
620        "pmaxsh     %[ftmp2],       %[ftmp2],         %[ftmp10]   \n\t"
621        "packushb   %[ftmp2],       %[ftmp2],         %[ftmp10]   \n\t"
622        "pmaxsh     %[ftmp3],       %[ftmp3],         %[ftmp10]   \n\t"
623        "packushb   %[ftmp3],       %[ftmp3],         %[ftmp10]   \n\t"
624        "pmaxsh     %[ftmp4],       %[ftmp4],         %[ftmp10]   \n\t"
625        "packushb   %[ftmp4],       %[ftmp4],         %[ftmp10]   \n\t"
626        "pmaxsh     %[ftmp5],       %[ftmp5],         %[ftmp10]   \n\t"
627        "packushb   %[ftmp5],       %[ftmp5],         %[ftmp10]   \n\t"
628        "pmaxsh     %[ftmp6],       %[ftmp6],         %[ftmp10]   \n\t"
629        "packushb   %[ftmp6],       %[ftmp6],         %[ftmp10]   \n\t"
630        "pmaxsh     %[ftmp7],       %[ftmp7],         %[ftmp10]   \n\t"
631        "packushb   %[ftmp7],       %[ftmp7],         %[ftmp10]   \n\t"
632        "swc1       %[ftmp0],       0x00(%[dst])                  \n\t"
633        PTR_ADDU   "%[tmp1],        %[dst],           %[stride]   \n\t"
634        "swc1       %[ftmp1],       0x00(%[tmp1])                 \n\t"
635        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
636        "swc1       %[ftmp2],       0x00(%[tmp1])                 \n\t"
637        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
638        "swc1       %[ftmp3],       0x00(%[tmp1])                 \n\t"
639        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
640        "swc1       %[ftmp4],       0x00(%[tmp1])                 \n\t"
641        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
642        "swc1       %[ftmp5],       0x00(%[tmp1])                 \n\t"
643        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
644        "swc1       %[ftmp6],       0x00(%[tmp1])                 \n\t"
645        PTR_ADDU   "%[tmp1],        %[tmp1],          %[stride]   \n\t"
646        "swc1       %[ftmp7],       0x00(%[tmp1])                 \n\t"
647        PTR_ADDIU  "%[dst],         %[dst],           0x04        \n\t"
648        PTR_ADDIU  "%[input],       %[input],         0x40        \n\t"
649        PTR_ADDIU  "%[temp_value],  %[temp_value],    0x08        \n\t"
650        PTR_ADDIU  "%[tmp0],        %[tmp0],          -0x01       \n\t"
651        "bnez       %[tmp0],        1b                            \n\t"
652        : [dst]"+&r"(dst), [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1]),
653          [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), [ftmp2]"=&f"(ftmp[2]),
654          [ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
655          [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), [ftmp8]"=&f"(ftmp[8]),
656          [ftmp9]"=&f"(ftmp[9]), [ftmp10]"=&f"(ftmp[10]), [mask]"=&f"(ftmp[11]),
657          [A]"=&f"(ftmp[12]), [B]"=&f"(ftmp[13]), [C]"=&f"(ftmp[14]),
658          [D]"=&f"(ftmp[15]), [Ad]"=&f"(ftmp[16]), [Bd]"=&f"(ftmp[17]),
659          [Cd]"=&f"(ftmp[18]), [Dd]"=&f"(ftmp[19]), [Ed]"=&f"(ftmp[20]),
660          [Gd]"=&f"(ftmp[21]), [input]"+&r"(input)
661        : [stride]"r"(stride), [temp_value]"r"(temp_value)
662        : "memory"
663    );
664}
665static void idct_mmi(uint8_t *dst, int stride, int16_t *input, int type)
666{
667    idct_row_mmi(input);
668    if (type == 1)
669        idct_column_true_mmi(dst, stride, input);
670    else
671        idct_column_false_mmi(dst, stride, input);
672}
673
674void ff_vp3_idct_put_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
675{
676    idct_mmi(dest, line_size, block, 1);
677    memset(block, 0, sizeof(*block) << 6);
678}
679
680void ff_vp3_idct_add_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
681{
682    idct_mmi(dest, line_size, block, 2);
683    memset(block, 0, sizeof(*block) << 6);
684}
685void ff_vp3_idct_dc_add_mmi(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
686{
687    int dc = (block[0] + 15) >> 5;
688
689    double ftmp[7];
690    uint64_t tmp;
691    __asm__ volatile (
692        "pxor       %[ftmp0],     %[ftmp0],           %[ftmp0]      \n\t"
693        "mtc1       %[dc],        %[ftmp5]                          \n\t"
694        "pshufh     %[ftmp5],     %[ftmp5],           %[ftmp0]      \n\t"
695        "li         %[tmp0],      0x08                              \n\t"
696        "1:                                                         \n\t"
697        "ldc1       %[ftmp1],     0x00(%[dest])                     \n\t"
698        "punpcklbh  %[ftmp2],     %[ftmp1],           %[ftmp0]      \n\t"
699        "punpckhbh  %[ftmp3],     %[ftmp1],           %[ftmp0]      \n\t"
700        "paddh      %[ftmp4],     %[ftmp2],           %[ftmp5]      \n\t"
701        "paddh      %[ftmp6],     %[ftmp3],           %[ftmp5]      \n\t"
702        "packushb   %[ftmp4],     %[ftmp4],           %[ftmp0]      \n\t"
703        "packushb   %[ftmp6],     %[ftmp6],           %[ftmp0]      \n\t"
704        "swc1       %[ftmp4],     0x00(%[dest])                     \n\t"
705        "swc1       %[ftmp6],     0x04(%[dest])                     \n\t"
706        PTR_ADDU   "%[dest],      %[dest],            %[line_size]  \n\t"
707        PTR_ADDIU  "%[tmp0],      %[tmp0],            -0x01         \n\t"
708        "bnez       %[tmp0],      1b                                \n\t"
709        : [dest]"+&r"(dest), [block]"+&r"(block), [tmp0]"=&r"(tmp),
710          [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), [ftmp2]"=&f"(ftmp[2]),
711          [ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]),
712          [ftmp6]"=&f"(ftmp[6])
713        : [line_size]"r"(line_size), [dc]"r"(dc)
714        : "memory"
715    );
716    block[0] = 0;
717}
718
719void ff_put_no_rnd_pixels_l2_mmi(uint8_t *dst, const uint8_t *src1,
720                                 const uint8_t *src2, ptrdiff_t stride, int h)
721{
722    if (h == 8) {
723        double ftmp[6];
724        uint64_t tmp[2];
725        DECLARE_VAR_ALL64;
726
727        __asm__ volatile (
728            "li          %[tmp0],        0x08                            \n\t"
729            "li          %[tmp1],        0xfefefefe                      \n\t"
730            "dmtc1       %[tmp1],        %[ftmp4]                        \n\t"
731            "punpcklwd   %[ftmp4],       %[ftmp4],             %[ftmp4]  \n\t"
732            "li          %[tmp1],        0x01                            \n\t"
733            "dmtc1       %[tmp1],        %[ftmp5]                        \n\t"
734            "1:                                                          \n\t"
735            MMI_ULDC1(%[ftmp1], %[src1], 0x0)
736            MMI_ULDC1(%[ftmp2], %[src2], 0x0)
737            "pxor        %[ftmp3],       %[ftmp1],             %[ftmp2]  \n\t"
738            "pand        %[ftmp3],       %[ftmp3],             %[ftmp4]  \n\t"
739            "psrlw       %[ftmp3],       %[ftmp3],             %[ftmp5]  \n\t"
740            "pand        %[ftmp6],       %[ftmp1],             %[ftmp2]  \n\t"
741            "paddw       %[ftmp3],       %[ftmp3],             %[ftmp6]  \n\t"
742            "sdc1        %[ftmp3],       0x00(%[dst])                    \n\t"
743            PTR_ADDU    "%[src1],        %[src1],              %[stride] \n\t"
744            PTR_ADDU    "%[src2],        %[src2],              %[stride] \n\t"
745            PTR_ADDU    "%[dst],         %[dst],               %[stride] \n\t"
746            PTR_ADDIU   "%[tmp0],        %[tmp0],              -0x01     \n\t"
747            "bnez        %[tmp0],        1b                              \n\t"
748            : RESTRICT_ASM_ALL64
749              [dst]"+&r"(dst), [src1]"+&r"(src1), [src2]"+&r"(src2),
750              [ftmp1]"=&f"(ftmp[0]), [ftmp2]"=&f"(ftmp[1]), [ftmp3]"=&f"(ftmp[2]),
751              [ftmp4]"=&f"(ftmp[3]), [ftmp5]"=&f"(ftmp[4]), [ftmp6]"=&f"(ftmp[5]),
752              [tmp0]"=&r"(tmp[0]), [tmp1]"=&r"(tmp[1])
753            : [stride]"r"(stride)
754            : "memory"
755        );
756    } else {
757        int i;
758
759        for (i = 0; i < h; i++) {
760            uint32_t a, b;
761
762            a = AV_RN32(&src1[i * stride]);
763            b = AV_RN32(&src2[i * stride]);
764            AV_WN32A(&dst[i * stride], no_rnd_avg32(a, b));
765            a = AV_RN32(&src1[i * stride + 4]);
766            b = AV_RN32(&src2[i * stride + 4]);
767            AV_WN32A(&dst[i * stride + 4], no_rnd_avg32(a, b));
768        }
769    }
770}
771