]> Git Repo - qemu.git/blob - target/mips/msa_helper.c
target/arm: Convert PMUL.8 to gvec
[qemu.git] / target / mips / msa_helper.c
1 /*
2  * MIPS SIMD Architecture Module Instruction emulation helpers for QEMU.
3  *
4  * Copyright (c) 2014 Imagination Technologies
5  *
6  * This library 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 of the License, or (at your option) any later version.
10  *
11  * This library 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 this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "qemu/osdep.h"
21 #include "cpu.h"
22 #include "internal.h"
23 #include "exec/exec-all.h"
24 #include "exec/helper-proto.h"
25 #include "fpu/softfloat.h"
26
27 /* Data format min and max values */
28 #define DF_BITS(df) (1 << ((df) + 3))
29
30 #define DF_MAX_INT(df)  (int64_t)((1LL << (DF_BITS(df) - 1)) - 1)
31 #define M_MAX_INT(m)    (int64_t)((1LL << ((m)         - 1)) - 1)
32
33 #define DF_MIN_INT(df)  (int64_t)(-(1LL << (DF_BITS(df) - 1)))
34 #define M_MIN_INT(m)    (int64_t)(-(1LL << ((m)         - 1)))
35
36 #define DF_MAX_UINT(df) (uint64_t)(-1ULL >> (64 - DF_BITS(df)))
37 #define M_MAX_UINT(m)   (uint64_t)(-1ULL >> (64 - (m)))
38
39 #define UNSIGNED(x, df) ((x) & DF_MAX_UINT(df))
40 #define SIGNED(x, df)                                                   \
41     ((((int64_t)x) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df)))
42
43 /* Element-by-element access macros */
44 #define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df))
45
46
47
48 /*
49  * Bit Count
50  * ---------
51  *
52  * +---------------+----------------------------------------------------------+
53  * | NLOC.B        | Vector Leading Ones Count (byte)                         |
54  * | NLOC.H        | Vector Leading Ones Count (halfword)                     |
55  * | NLOC.W        | Vector Leading Ones Count (word)                         |
56  * | NLOC.D        | Vector Leading Ones Count (doubleword)                   |
57  * | NLZC.B        | Vector Leading Zeros Count (byte)                        |
58  * | NLZC.H        | Vector Leading Zeros Count (halfword)                    |
59  * | NLZC.W        | Vector Leading Zeros Count (word)                        |
60  * | NLZC.D        | Vector Leading Zeros Count (doubleword)                  |
61  * | PCNT.B        | Vector Population Count (byte)                           |
62  * | PCNT.H        | Vector Population Count (halfword)                       |
63  * | PCNT.W        | Vector Population Count (word)                           |
64  * | PCNT.D        | Vector Population Count (doubleword)                     |
65  * +---------------+----------------------------------------------------------+
66  */
67
68 static inline int64_t msa_nlzc_df(uint32_t df, int64_t arg)
69 {
70     uint64_t x, y;
71     int n, c;
72
73     x = UNSIGNED(arg, df);
74     n = DF_BITS(df);
75     c = DF_BITS(df) / 2;
76
77     do {
78         y = x >> c;
79         if (y != 0) {
80             n = n - c;
81             x = y;
82         }
83         c = c >> 1;
84     } while (c != 0);
85
86     return n - x;
87 }
88
89 static inline int64_t msa_nloc_df(uint32_t df, int64_t arg)
90 {
91     return msa_nlzc_df(df, UNSIGNED((~arg), df));
92 }
93
94 void helper_msa_nloc_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
95 {
96     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
97     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
98
99     pwd->b[0]  = msa_nloc_df(DF_BYTE, pws->b[0]);
100     pwd->b[1]  = msa_nloc_df(DF_BYTE, pws->b[1]);
101     pwd->b[2]  = msa_nloc_df(DF_BYTE, pws->b[2]);
102     pwd->b[3]  = msa_nloc_df(DF_BYTE, pws->b[3]);
103     pwd->b[4]  = msa_nloc_df(DF_BYTE, pws->b[4]);
104     pwd->b[5]  = msa_nloc_df(DF_BYTE, pws->b[5]);
105     pwd->b[6]  = msa_nloc_df(DF_BYTE, pws->b[6]);
106     pwd->b[7]  = msa_nloc_df(DF_BYTE, pws->b[7]);
107     pwd->b[8]  = msa_nloc_df(DF_BYTE, pws->b[8]);
108     pwd->b[9]  = msa_nloc_df(DF_BYTE, pws->b[9]);
109     pwd->b[10] = msa_nloc_df(DF_BYTE, pws->b[10]);
110     pwd->b[11] = msa_nloc_df(DF_BYTE, pws->b[11]);
111     pwd->b[12] = msa_nloc_df(DF_BYTE, pws->b[12]);
112     pwd->b[13] = msa_nloc_df(DF_BYTE, pws->b[13]);
113     pwd->b[14] = msa_nloc_df(DF_BYTE, pws->b[14]);
114     pwd->b[15] = msa_nloc_df(DF_BYTE, pws->b[15]);
115 }
116
117 void helper_msa_nloc_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
118 {
119     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
120     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
121
122     pwd->h[0]  = msa_nloc_df(DF_HALF, pws->h[0]);
123     pwd->h[1]  = msa_nloc_df(DF_HALF, pws->h[1]);
124     pwd->h[2]  = msa_nloc_df(DF_HALF, pws->h[2]);
125     pwd->h[3]  = msa_nloc_df(DF_HALF, pws->h[3]);
126     pwd->h[4]  = msa_nloc_df(DF_HALF, pws->h[4]);
127     pwd->h[5]  = msa_nloc_df(DF_HALF, pws->h[5]);
128     pwd->h[6]  = msa_nloc_df(DF_HALF, pws->h[6]);
129     pwd->h[7]  = msa_nloc_df(DF_HALF, pws->h[7]);
130 }
131
132 void helper_msa_nloc_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
133 {
134     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
135     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
136
137     pwd->w[0]  = msa_nloc_df(DF_WORD, pws->w[0]);
138     pwd->w[1]  = msa_nloc_df(DF_WORD, pws->w[1]);
139     pwd->w[2]  = msa_nloc_df(DF_WORD, pws->w[2]);
140     pwd->w[3]  = msa_nloc_df(DF_WORD, pws->w[3]);
141 }
142
143 void helper_msa_nloc_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
144 {
145     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
146     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
147
148     pwd->d[0]  = msa_nloc_df(DF_DOUBLE, pws->d[0]);
149     pwd->d[1]  = msa_nloc_df(DF_DOUBLE, pws->d[1]);
150 }
151
152 void helper_msa_nlzc_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
153 {
154     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
155     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
156
157     pwd->b[0]  = msa_nlzc_df(DF_BYTE, pws->b[0]);
158     pwd->b[1]  = msa_nlzc_df(DF_BYTE, pws->b[1]);
159     pwd->b[2]  = msa_nlzc_df(DF_BYTE, pws->b[2]);
160     pwd->b[3]  = msa_nlzc_df(DF_BYTE, pws->b[3]);
161     pwd->b[4]  = msa_nlzc_df(DF_BYTE, pws->b[4]);
162     pwd->b[5]  = msa_nlzc_df(DF_BYTE, pws->b[5]);
163     pwd->b[6]  = msa_nlzc_df(DF_BYTE, pws->b[6]);
164     pwd->b[7]  = msa_nlzc_df(DF_BYTE, pws->b[7]);
165     pwd->b[8]  = msa_nlzc_df(DF_BYTE, pws->b[8]);
166     pwd->b[9]  = msa_nlzc_df(DF_BYTE, pws->b[9]);
167     pwd->b[10] = msa_nlzc_df(DF_BYTE, pws->b[10]);
168     pwd->b[11] = msa_nlzc_df(DF_BYTE, pws->b[11]);
169     pwd->b[12] = msa_nlzc_df(DF_BYTE, pws->b[12]);
170     pwd->b[13] = msa_nlzc_df(DF_BYTE, pws->b[13]);
171     pwd->b[14] = msa_nlzc_df(DF_BYTE, pws->b[14]);
172     pwd->b[15] = msa_nlzc_df(DF_BYTE, pws->b[15]);
173 }
174
175 void helper_msa_nlzc_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
176 {
177     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
178     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
179
180     pwd->h[0]  = msa_nlzc_df(DF_HALF, pws->h[0]);
181     pwd->h[1]  = msa_nlzc_df(DF_HALF, pws->h[1]);
182     pwd->h[2]  = msa_nlzc_df(DF_HALF, pws->h[2]);
183     pwd->h[3]  = msa_nlzc_df(DF_HALF, pws->h[3]);
184     pwd->h[4]  = msa_nlzc_df(DF_HALF, pws->h[4]);
185     pwd->h[5]  = msa_nlzc_df(DF_HALF, pws->h[5]);
186     pwd->h[6]  = msa_nlzc_df(DF_HALF, pws->h[6]);
187     pwd->h[7]  = msa_nlzc_df(DF_HALF, pws->h[7]);
188 }
189
190 void helper_msa_nlzc_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
191 {
192     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
193     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
194
195     pwd->w[0]  = msa_nlzc_df(DF_WORD, pws->w[0]);
196     pwd->w[1]  = msa_nlzc_df(DF_WORD, pws->w[1]);
197     pwd->w[2]  = msa_nlzc_df(DF_WORD, pws->w[2]);
198     pwd->w[3]  = msa_nlzc_df(DF_WORD, pws->w[3]);
199 }
200
201 void helper_msa_nlzc_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
202 {
203     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
204     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
205
206     pwd->d[0]  = msa_nlzc_df(DF_DOUBLE, pws->d[0]);
207     pwd->d[1]  = msa_nlzc_df(DF_DOUBLE, pws->d[1]);
208 }
209
210 static inline int64_t msa_pcnt_df(uint32_t df, int64_t arg)
211 {
212     uint64_t x;
213
214     x = UNSIGNED(arg, df);
215
216     x = (x & 0x5555555555555555ULL) + ((x >>  1) & 0x5555555555555555ULL);
217     x = (x & 0x3333333333333333ULL) + ((x >>  2) & 0x3333333333333333ULL);
218     x = (x & 0x0F0F0F0F0F0F0F0FULL) + ((x >>  4) & 0x0F0F0F0F0F0F0F0FULL);
219     x = (x & 0x00FF00FF00FF00FFULL) + ((x >>  8) & 0x00FF00FF00FF00FFULL);
220     x = (x & 0x0000FFFF0000FFFFULL) + ((x >> 16) & 0x0000FFFF0000FFFFULL);
221     x = (x & 0x00000000FFFFFFFFULL) + ((x >> 32));
222
223     return x;
224 }
225
226 void helper_msa_pcnt_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
227 {
228     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
229     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
230
231     pwd->b[0]  = msa_pcnt_df(DF_BYTE, pws->b[0]);
232     pwd->b[1]  = msa_pcnt_df(DF_BYTE, pws->b[1]);
233     pwd->b[2]  = msa_pcnt_df(DF_BYTE, pws->b[2]);
234     pwd->b[3]  = msa_pcnt_df(DF_BYTE, pws->b[3]);
235     pwd->b[4]  = msa_pcnt_df(DF_BYTE, pws->b[4]);
236     pwd->b[5]  = msa_pcnt_df(DF_BYTE, pws->b[5]);
237     pwd->b[6]  = msa_pcnt_df(DF_BYTE, pws->b[6]);
238     pwd->b[7]  = msa_pcnt_df(DF_BYTE, pws->b[7]);
239     pwd->b[8]  = msa_pcnt_df(DF_BYTE, pws->b[8]);
240     pwd->b[9]  = msa_pcnt_df(DF_BYTE, pws->b[9]);
241     pwd->b[10] = msa_pcnt_df(DF_BYTE, pws->b[10]);
242     pwd->b[11] = msa_pcnt_df(DF_BYTE, pws->b[11]);
243     pwd->b[12] = msa_pcnt_df(DF_BYTE, pws->b[12]);
244     pwd->b[13] = msa_pcnt_df(DF_BYTE, pws->b[13]);
245     pwd->b[14] = msa_pcnt_df(DF_BYTE, pws->b[14]);
246     pwd->b[15] = msa_pcnt_df(DF_BYTE, pws->b[15]);
247 }
248
249 void helper_msa_pcnt_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
250 {
251     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
252     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
253
254     pwd->h[0]  = msa_pcnt_df(DF_HALF, pws->h[0]);
255     pwd->h[1]  = msa_pcnt_df(DF_HALF, pws->h[1]);
256     pwd->h[2]  = msa_pcnt_df(DF_HALF, pws->h[2]);
257     pwd->h[3]  = msa_pcnt_df(DF_HALF, pws->h[3]);
258     pwd->h[4]  = msa_pcnt_df(DF_HALF, pws->h[4]);
259     pwd->h[5]  = msa_pcnt_df(DF_HALF, pws->h[5]);
260     pwd->h[6]  = msa_pcnt_df(DF_HALF, pws->h[6]);
261     pwd->h[7]  = msa_pcnt_df(DF_HALF, pws->h[7]);
262 }
263
264 void helper_msa_pcnt_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
265 {
266     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
267     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
268
269     pwd->w[0]  = msa_pcnt_df(DF_WORD, pws->w[0]);
270     pwd->w[1]  = msa_pcnt_df(DF_WORD, pws->w[1]);
271     pwd->w[2]  = msa_pcnt_df(DF_WORD, pws->w[2]);
272     pwd->w[3]  = msa_pcnt_df(DF_WORD, pws->w[3]);
273 }
274
275 void helper_msa_pcnt_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
276 {
277     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
278     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
279
280     pwd->d[0]  = msa_pcnt_df(DF_DOUBLE, pws->d[0]);
281     pwd->d[1]  = msa_pcnt_df(DF_DOUBLE, pws->d[1]);
282 }
283
284
285 /*
286  * Bit Move
287  * --------
288  *
289  * +---------------+----------------------------------------------------------+
290  * | BINSL.B       | Vector Bit Insert Left (byte)                            |
291  * | BINSL.H       | Vector Bit Insert Left (halfword)                        |
292  * | BINSL.W       | Vector Bit Insert Left (word)                            |
293  * | BINSL.D       | Vector Bit Insert Left (doubleword)                      |
294  * | BINSR.B       | Vector Bit Insert Right (byte)                           |
295  * | BINSR.H       | Vector Bit Insert Right (halfword)                       |
296  * | BINSR.W       | Vector Bit Insert Right (word)                           |
297  * | BINSR.D       | Vector Bit Insert Right (doubleword)                     |
298  * | BMNZ.V        | Vector Bit Move If Not Zero                              |
299  * | BMZ.V         | Vector Bit Move If Zero                                  |
300  * | BSEL.V        | Vector Bit Select                                        |
301  * +---------------+----------------------------------------------------------+
302  */
303
304 /* Data format bit position and unsigned values */
305 #define BIT_POSITION(x, df) ((uint64_t)(x) % DF_BITS(df))
306
307 static inline int64_t msa_binsl_df(uint32_t df,
308                                    int64_t dest, int64_t arg1, int64_t arg2)
309 {
310     uint64_t u_arg1 = UNSIGNED(arg1, df);
311     uint64_t u_dest = UNSIGNED(dest, df);
312     int32_t sh_d = BIT_POSITION(arg2, df) + 1;
313     int32_t sh_a = DF_BITS(df) - sh_d;
314     if (sh_d == DF_BITS(df)) {
315         return u_arg1;
316     } else {
317         return UNSIGNED(UNSIGNED(u_dest << sh_d, df) >> sh_d, df) |
318                UNSIGNED(UNSIGNED(u_arg1 >> sh_a, df) << sh_a, df);
319     }
320 }
321
322 void helper_msa_binsl_b(CPUMIPSState *env,
323                         uint32_t wd, uint32_t ws, uint32_t wt)
324 {
325     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
326     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
327     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
328
329     pwd->b[0]  = msa_binsl_df(DF_BYTE, pwd->b[0],  pws->b[0],  pwt->b[0]);
330     pwd->b[1]  = msa_binsl_df(DF_BYTE, pwd->b[1],  pws->b[1],  pwt->b[1]);
331     pwd->b[2]  = msa_binsl_df(DF_BYTE, pwd->b[2],  pws->b[2],  pwt->b[2]);
332     pwd->b[3]  = msa_binsl_df(DF_BYTE, pwd->b[3],  pws->b[3],  pwt->b[3]);
333     pwd->b[4]  = msa_binsl_df(DF_BYTE, pwd->b[4],  pws->b[4],  pwt->b[4]);
334     pwd->b[5]  = msa_binsl_df(DF_BYTE, pwd->b[5],  pws->b[5],  pwt->b[5]);
335     pwd->b[6]  = msa_binsl_df(DF_BYTE, pwd->b[6],  pws->b[6],  pwt->b[6]);
336     pwd->b[7]  = msa_binsl_df(DF_BYTE, pwd->b[7],  pws->b[7],  pwt->b[7]);
337     pwd->b[8]  = msa_binsl_df(DF_BYTE, pwd->b[8],  pws->b[8],  pwt->b[8]);
338     pwd->b[9]  = msa_binsl_df(DF_BYTE, pwd->b[9],  pws->b[9],  pwt->b[9]);
339     pwd->b[10] = msa_binsl_df(DF_BYTE, pwd->b[10], pws->b[10], pwt->b[10]);
340     pwd->b[11] = msa_binsl_df(DF_BYTE, pwd->b[11], pws->b[11], pwt->b[11]);
341     pwd->b[12] = msa_binsl_df(DF_BYTE, pwd->b[12], pws->b[12], pwt->b[12]);
342     pwd->b[13] = msa_binsl_df(DF_BYTE, pwd->b[13], pws->b[13], pwt->b[13]);
343     pwd->b[14] = msa_binsl_df(DF_BYTE, pwd->b[14], pws->b[14], pwt->b[14]);
344     pwd->b[15] = msa_binsl_df(DF_BYTE, pwd->b[15], pws->b[15], pwt->b[15]);
345 }
346
347 void helper_msa_binsl_h(CPUMIPSState *env,
348                         uint32_t wd, uint32_t ws, uint32_t wt)
349 {
350     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
351     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
352     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
353
354     pwd->h[0]  = msa_binsl_df(DF_HALF, pwd->h[0],  pws->h[0],  pwt->h[0]);
355     pwd->h[1]  = msa_binsl_df(DF_HALF, pwd->h[1],  pws->h[1],  pwt->h[1]);
356     pwd->h[2]  = msa_binsl_df(DF_HALF, pwd->h[2],  pws->h[2],  pwt->h[2]);
357     pwd->h[3]  = msa_binsl_df(DF_HALF, pwd->h[3],  pws->h[3],  pwt->h[3]);
358     pwd->h[4]  = msa_binsl_df(DF_HALF, pwd->h[4],  pws->h[4],  pwt->h[4]);
359     pwd->h[5]  = msa_binsl_df(DF_HALF, pwd->h[5],  pws->h[5],  pwt->h[5]);
360     pwd->h[6]  = msa_binsl_df(DF_HALF, pwd->h[6],  pws->h[6],  pwt->h[6]);
361     pwd->h[7]  = msa_binsl_df(DF_HALF, pwd->h[7],  pws->h[7],  pwt->h[7]);
362 }
363
364 void helper_msa_binsl_w(CPUMIPSState *env,
365                         uint32_t wd, uint32_t ws, uint32_t wt)
366 {
367     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
368     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
369     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
370
371     pwd->w[0]  = msa_binsl_df(DF_WORD, pwd->w[0],  pws->w[0],  pwt->w[0]);
372     pwd->w[1]  = msa_binsl_df(DF_WORD, pwd->w[1],  pws->w[1],  pwt->w[1]);
373     pwd->w[2]  = msa_binsl_df(DF_WORD, pwd->w[2],  pws->w[2],  pwt->w[2]);
374     pwd->w[3]  = msa_binsl_df(DF_WORD, pwd->w[3],  pws->w[3],  pwt->w[3]);
375 }
376
377 void helper_msa_binsl_d(CPUMIPSState *env,
378                         uint32_t wd, uint32_t ws, uint32_t wt)
379 {
380     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
381     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
382     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
383
384     pwd->d[0]  = msa_binsl_df(DF_DOUBLE, pwd->d[0],  pws->d[0],  pwt->d[0]);
385     pwd->d[1]  = msa_binsl_df(DF_DOUBLE, pwd->d[1],  pws->d[1],  pwt->d[1]);
386 }
387
388 static inline int64_t msa_binsr_df(uint32_t df,
389                                    int64_t dest, int64_t arg1, int64_t arg2)
390 {
391     uint64_t u_arg1 = UNSIGNED(arg1, df);
392     uint64_t u_dest = UNSIGNED(dest, df);
393     int32_t sh_d = BIT_POSITION(arg2, df) + 1;
394     int32_t sh_a = DF_BITS(df) - sh_d;
395     if (sh_d == DF_BITS(df)) {
396         return u_arg1;
397     } else {
398         return UNSIGNED(UNSIGNED(u_dest >> sh_d, df) << sh_d, df) |
399                UNSIGNED(UNSIGNED(u_arg1 << sh_a, df) >> sh_a, df);
400     }
401 }
402
403 void helper_msa_binsr_b(CPUMIPSState *env,
404                         uint32_t wd, uint32_t ws, uint32_t wt)
405 {
406     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
407     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
408     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
409
410     pwd->b[0]  = msa_binsr_df(DF_BYTE, pwd->b[0],  pws->b[0],  pwt->b[0]);
411     pwd->b[1]  = msa_binsr_df(DF_BYTE, pwd->b[1],  pws->b[1],  pwt->b[1]);
412     pwd->b[2]  = msa_binsr_df(DF_BYTE, pwd->b[2],  pws->b[2],  pwt->b[2]);
413     pwd->b[3]  = msa_binsr_df(DF_BYTE, pwd->b[3],  pws->b[3],  pwt->b[3]);
414     pwd->b[4]  = msa_binsr_df(DF_BYTE, pwd->b[4],  pws->b[4],  pwt->b[4]);
415     pwd->b[5]  = msa_binsr_df(DF_BYTE, pwd->b[5],  pws->b[5],  pwt->b[5]);
416     pwd->b[6]  = msa_binsr_df(DF_BYTE, pwd->b[6],  pws->b[6],  pwt->b[6]);
417     pwd->b[7]  = msa_binsr_df(DF_BYTE, pwd->b[7],  pws->b[7],  pwt->b[7]);
418     pwd->b[8]  = msa_binsr_df(DF_BYTE, pwd->b[8],  pws->b[8],  pwt->b[8]);
419     pwd->b[9]  = msa_binsr_df(DF_BYTE, pwd->b[9],  pws->b[9],  pwt->b[9]);
420     pwd->b[10] = msa_binsr_df(DF_BYTE, pwd->b[10], pws->b[10], pwt->b[10]);
421     pwd->b[11] = msa_binsr_df(DF_BYTE, pwd->b[11], pws->b[11], pwt->b[11]);
422     pwd->b[12] = msa_binsr_df(DF_BYTE, pwd->b[12], pws->b[12], pwt->b[12]);
423     pwd->b[13] = msa_binsr_df(DF_BYTE, pwd->b[13], pws->b[13], pwt->b[13]);
424     pwd->b[14] = msa_binsr_df(DF_BYTE, pwd->b[14], pws->b[14], pwt->b[14]);
425     pwd->b[15] = msa_binsr_df(DF_BYTE, pwd->b[15], pws->b[15], pwt->b[15]);
426 }
427
428 void helper_msa_binsr_h(CPUMIPSState *env,
429                         uint32_t wd, uint32_t ws, uint32_t wt)
430 {
431     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
432     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
433     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
434
435     pwd->h[0]  = msa_binsr_df(DF_HALF, pwd->h[0],  pws->h[0],  pwt->h[0]);
436     pwd->h[1]  = msa_binsr_df(DF_HALF, pwd->h[1],  pws->h[1],  pwt->h[1]);
437     pwd->h[2]  = msa_binsr_df(DF_HALF, pwd->h[2],  pws->h[2],  pwt->h[2]);
438     pwd->h[3]  = msa_binsr_df(DF_HALF, pwd->h[3],  pws->h[3],  pwt->h[3]);
439     pwd->h[4]  = msa_binsr_df(DF_HALF, pwd->h[4],  pws->h[4],  pwt->h[4]);
440     pwd->h[5]  = msa_binsr_df(DF_HALF, pwd->h[5],  pws->h[5],  pwt->h[5]);
441     pwd->h[6]  = msa_binsr_df(DF_HALF, pwd->h[6],  pws->h[6],  pwt->h[6]);
442     pwd->h[7]  = msa_binsr_df(DF_HALF, pwd->h[7],  pws->h[7],  pwt->h[7]);
443 }
444
445 void helper_msa_binsr_w(CPUMIPSState *env,
446                         uint32_t wd, uint32_t ws, uint32_t wt)
447 {
448     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
449     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
450     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
451
452     pwd->w[0]  = msa_binsr_df(DF_WORD, pwd->w[0],  pws->w[0],  pwt->w[0]);
453     pwd->w[1]  = msa_binsr_df(DF_WORD, pwd->w[1],  pws->w[1],  pwt->w[1]);
454     pwd->w[2]  = msa_binsr_df(DF_WORD, pwd->w[2],  pws->w[2],  pwt->w[2]);
455     pwd->w[3]  = msa_binsr_df(DF_WORD, pwd->w[3],  pws->w[3],  pwt->w[3]);
456 }
457
458 void helper_msa_binsr_d(CPUMIPSState *env,
459                         uint32_t wd, uint32_t ws, uint32_t wt)
460 {
461     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
462     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
463     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
464
465     pwd->d[0]  = msa_binsr_df(DF_DOUBLE, pwd->d[0],  pws->d[0],  pwt->d[0]);
466     pwd->d[1]  = msa_binsr_df(DF_DOUBLE, pwd->d[1],  pws->d[1],  pwt->d[1]);
467 }
468
469 void helper_msa_bmnz_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
470 {
471     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
472     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
473     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
474
475     pwd->d[0] = UNSIGNED(                                                     \
476         ((pwd->d[0] & (~pwt->d[0])) | (pws->d[0] & pwt->d[0])), DF_DOUBLE);
477     pwd->d[1] = UNSIGNED(                                                     \
478         ((pwd->d[1] & (~pwt->d[1])) | (pws->d[1] & pwt->d[1])), DF_DOUBLE);
479 }
480
481 void helper_msa_bmz_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
482 {
483     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
484     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
485     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
486
487     pwd->d[0] = UNSIGNED(                                                     \
488         ((pwd->d[0] & pwt->d[0]) | (pws->d[0] & (~pwt->d[0]))), DF_DOUBLE);
489     pwd->d[1] = UNSIGNED(                                                     \
490         ((pwd->d[1] & pwt->d[1]) | (pws->d[1] & (~pwt->d[1]))), DF_DOUBLE);
491 }
492
493 void helper_msa_bsel_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
494 {
495     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
496     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
497     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
498
499     pwd->d[0] = UNSIGNED(                                                     \
500         (pws->d[0] & (~pwd->d[0])) | (pwt->d[0] & pwd->d[0]), DF_DOUBLE);
501     pwd->d[1] = UNSIGNED(                                                     \
502         (pws->d[1] & (~pwd->d[1])) | (pwt->d[1] & pwd->d[1]), DF_DOUBLE);
503 }
504
505
506 /*
507  * Bit Set
508  * -------
509  *
510  * +---------------+----------------------------------------------------------+
511  * | BCLR.B        | Vector Bit Clear (byte)                                  |
512  * | BCLR.H        | Vector Bit Clear (halfword)                              |
513  * | BCLR.W        | Vector Bit Clear (word)                                  |
514  * | BCLR.D        | Vector Bit Clear (doubleword)                            |
515  * | BNEG.B        | Vector Bit Negate (byte)                                 |
516  * | BNEG.H        | Vector Bit Negate (halfword)                             |
517  * | BNEG.W        | Vector Bit Negate (word)                                 |
518  * | BNEG.D        | Vector Bit Negate (doubleword)                           |
519  * | BSET.B        | Vector Bit Set (byte)                                    |
520  * | BSET.H        | Vector Bit Set (halfword)                                |
521  * | BSET.W        | Vector Bit Set (word)                                    |
522  * | BSET.D        | Vector Bit Set (doubleword)                              |
523  * +---------------+----------------------------------------------------------+
524  */
525
526 static inline int64_t msa_bclr_df(uint32_t df, int64_t arg1, int64_t arg2)
527 {
528     int32_t b_arg2 = BIT_POSITION(arg2, df);
529     return UNSIGNED(arg1 & (~(1LL << b_arg2)), df);
530 }
531
532 void helper_msa_bclr_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
533 {
534     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
535     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
536     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
537
538     pwd->b[0]  = msa_bclr_df(DF_BYTE, pws->b[0],  pwt->b[0]);
539     pwd->b[1]  = msa_bclr_df(DF_BYTE, pws->b[1],  pwt->b[1]);
540     pwd->b[2]  = msa_bclr_df(DF_BYTE, pws->b[2],  pwt->b[2]);
541     pwd->b[3]  = msa_bclr_df(DF_BYTE, pws->b[3],  pwt->b[3]);
542     pwd->b[4]  = msa_bclr_df(DF_BYTE, pws->b[4],  pwt->b[4]);
543     pwd->b[5]  = msa_bclr_df(DF_BYTE, pws->b[5],  pwt->b[5]);
544     pwd->b[6]  = msa_bclr_df(DF_BYTE, pws->b[6],  pwt->b[6]);
545     pwd->b[7]  = msa_bclr_df(DF_BYTE, pws->b[7],  pwt->b[7]);
546     pwd->b[8]  = msa_bclr_df(DF_BYTE, pws->b[8],  pwt->b[8]);
547     pwd->b[9]  = msa_bclr_df(DF_BYTE, pws->b[9],  pwt->b[9]);
548     pwd->b[10] = msa_bclr_df(DF_BYTE, pws->b[10], pwt->b[10]);
549     pwd->b[11] = msa_bclr_df(DF_BYTE, pws->b[11], pwt->b[11]);
550     pwd->b[12] = msa_bclr_df(DF_BYTE, pws->b[12], pwt->b[12]);
551     pwd->b[13] = msa_bclr_df(DF_BYTE, pws->b[13], pwt->b[13]);
552     pwd->b[14] = msa_bclr_df(DF_BYTE, pws->b[14], pwt->b[14]);
553     pwd->b[15] = msa_bclr_df(DF_BYTE, pws->b[15], pwt->b[15]);
554 }
555
556 void helper_msa_bclr_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
557 {
558     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
559     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
560     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
561
562     pwd->h[0]  = msa_bclr_df(DF_HALF, pws->h[0],  pwt->h[0]);
563     pwd->h[1]  = msa_bclr_df(DF_HALF, pws->h[1],  pwt->h[1]);
564     pwd->h[2]  = msa_bclr_df(DF_HALF, pws->h[2],  pwt->h[2]);
565     pwd->h[3]  = msa_bclr_df(DF_HALF, pws->h[3],  pwt->h[3]);
566     pwd->h[4]  = msa_bclr_df(DF_HALF, pws->h[4],  pwt->h[4]);
567     pwd->h[5]  = msa_bclr_df(DF_HALF, pws->h[5],  pwt->h[5]);
568     pwd->h[6]  = msa_bclr_df(DF_HALF, pws->h[6],  pwt->h[6]);
569     pwd->h[7]  = msa_bclr_df(DF_HALF, pws->h[7],  pwt->h[7]);
570 }
571
572 void helper_msa_bclr_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
573 {
574     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
575     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
576     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
577
578     pwd->w[0]  = msa_bclr_df(DF_WORD, pws->w[0],  pwt->w[0]);
579     pwd->w[1]  = msa_bclr_df(DF_WORD, pws->w[1],  pwt->w[1]);
580     pwd->w[2]  = msa_bclr_df(DF_WORD, pws->w[2],  pwt->w[2]);
581     pwd->w[3]  = msa_bclr_df(DF_WORD, pws->w[3],  pwt->w[3]);
582 }
583
584 void helper_msa_bclr_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
585 {
586     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
587     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
588     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
589
590     pwd->d[0]  = msa_bclr_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
591     pwd->d[1]  = msa_bclr_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
592 }
593
594 static inline int64_t msa_bneg_df(uint32_t df, int64_t arg1, int64_t arg2)
595 {
596     int32_t b_arg2 = BIT_POSITION(arg2, df);
597     return UNSIGNED(arg1 ^ (1LL << b_arg2), df);
598 }
599
600 void helper_msa_bneg_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
601 {
602     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
603     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
604     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
605
606     pwd->b[0]  = msa_bneg_df(DF_BYTE, pws->b[0],  pwt->b[0]);
607     pwd->b[1]  = msa_bneg_df(DF_BYTE, pws->b[1],  pwt->b[1]);
608     pwd->b[2]  = msa_bneg_df(DF_BYTE, pws->b[2],  pwt->b[2]);
609     pwd->b[3]  = msa_bneg_df(DF_BYTE, pws->b[3],  pwt->b[3]);
610     pwd->b[4]  = msa_bneg_df(DF_BYTE, pws->b[4],  pwt->b[4]);
611     pwd->b[5]  = msa_bneg_df(DF_BYTE, pws->b[5],  pwt->b[5]);
612     pwd->b[6]  = msa_bneg_df(DF_BYTE, pws->b[6],  pwt->b[6]);
613     pwd->b[7]  = msa_bneg_df(DF_BYTE, pws->b[7],  pwt->b[7]);
614     pwd->b[8]  = msa_bneg_df(DF_BYTE, pws->b[8],  pwt->b[8]);
615     pwd->b[9]  = msa_bneg_df(DF_BYTE, pws->b[9],  pwt->b[9]);
616     pwd->b[10] = msa_bneg_df(DF_BYTE, pws->b[10], pwt->b[10]);
617     pwd->b[11] = msa_bneg_df(DF_BYTE, pws->b[11], pwt->b[11]);
618     pwd->b[12] = msa_bneg_df(DF_BYTE, pws->b[12], pwt->b[12]);
619     pwd->b[13] = msa_bneg_df(DF_BYTE, pws->b[13], pwt->b[13]);
620     pwd->b[14] = msa_bneg_df(DF_BYTE, pws->b[14], pwt->b[14]);
621     pwd->b[15] = msa_bneg_df(DF_BYTE, pws->b[15], pwt->b[15]);
622 }
623
624 void helper_msa_bneg_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
625 {
626     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
627     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
628     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
629
630     pwd->h[0]  = msa_bneg_df(DF_HALF, pws->h[0],  pwt->h[0]);
631     pwd->h[1]  = msa_bneg_df(DF_HALF, pws->h[1],  pwt->h[1]);
632     pwd->h[2]  = msa_bneg_df(DF_HALF, pws->h[2],  pwt->h[2]);
633     pwd->h[3]  = msa_bneg_df(DF_HALF, pws->h[3],  pwt->h[3]);
634     pwd->h[4]  = msa_bneg_df(DF_HALF, pws->h[4],  pwt->h[4]);
635     pwd->h[5]  = msa_bneg_df(DF_HALF, pws->h[5],  pwt->h[5]);
636     pwd->h[6]  = msa_bneg_df(DF_HALF, pws->h[6],  pwt->h[6]);
637     pwd->h[7]  = msa_bneg_df(DF_HALF, pws->h[7],  pwt->h[7]);
638 }
639
640 void helper_msa_bneg_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
641 {
642     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
643     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
644     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
645
646     pwd->w[0]  = msa_bneg_df(DF_WORD, pws->w[0],  pwt->w[0]);
647     pwd->w[1]  = msa_bneg_df(DF_WORD, pws->w[1],  pwt->w[1]);
648     pwd->w[2]  = msa_bneg_df(DF_WORD, pws->w[2],  pwt->w[2]);
649     pwd->w[3]  = msa_bneg_df(DF_WORD, pws->w[3],  pwt->w[3]);
650 }
651
652 void helper_msa_bneg_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
653 {
654     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
655     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
656     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
657
658     pwd->d[0]  = msa_bneg_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
659     pwd->d[1]  = msa_bneg_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
660 }
661
662 static inline int64_t msa_bset_df(uint32_t df, int64_t arg1,
663         int64_t arg2)
664 {
665     int32_t b_arg2 = BIT_POSITION(arg2, df);
666     return UNSIGNED(arg1 | (1LL << b_arg2), df);
667 }
668
669 void helper_msa_bset_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
670 {
671     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
672     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
673     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
674
675     pwd->b[0]  = msa_bset_df(DF_BYTE, pws->b[0],  pwt->b[0]);
676     pwd->b[1]  = msa_bset_df(DF_BYTE, pws->b[1],  pwt->b[1]);
677     pwd->b[2]  = msa_bset_df(DF_BYTE, pws->b[2],  pwt->b[2]);
678     pwd->b[3]  = msa_bset_df(DF_BYTE, pws->b[3],  pwt->b[3]);
679     pwd->b[4]  = msa_bset_df(DF_BYTE, pws->b[4],  pwt->b[4]);
680     pwd->b[5]  = msa_bset_df(DF_BYTE, pws->b[5],  pwt->b[5]);
681     pwd->b[6]  = msa_bset_df(DF_BYTE, pws->b[6],  pwt->b[6]);
682     pwd->b[7]  = msa_bset_df(DF_BYTE, pws->b[7],  pwt->b[7]);
683     pwd->b[8]  = msa_bset_df(DF_BYTE, pws->b[8],  pwt->b[8]);
684     pwd->b[9]  = msa_bset_df(DF_BYTE, pws->b[9],  pwt->b[9]);
685     pwd->b[10] = msa_bset_df(DF_BYTE, pws->b[10], pwt->b[10]);
686     pwd->b[11] = msa_bset_df(DF_BYTE, pws->b[11], pwt->b[11]);
687     pwd->b[12] = msa_bset_df(DF_BYTE, pws->b[12], pwt->b[12]);
688     pwd->b[13] = msa_bset_df(DF_BYTE, pws->b[13], pwt->b[13]);
689     pwd->b[14] = msa_bset_df(DF_BYTE, pws->b[14], pwt->b[14]);
690     pwd->b[15] = msa_bset_df(DF_BYTE, pws->b[15], pwt->b[15]);
691 }
692
693 void helper_msa_bset_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
694 {
695     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
696     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
697     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
698
699     pwd->h[0]  = msa_bset_df(DF_HALF, pws->h[0],  pwt->h[0]);
700     pwd->h[1]  = msa_bset_df(DF_HALF, pws->h[1],  pwt->h[1]);
701     pwd->h[2]  = msa_bset_df(DF_HALF, pws->h[2],  pwt->h[2]);
702     pwd->h[3]  = msa_bset_df(DF_HALF, pws->h[3],  pwt->h[3]);
703     pwd->h[4]  = msa_bset_df(DF_HALF, pws->h[4],  pwt->h[4]);
704     pwd->h[5]  = msa_bset_df(DF_HALF, pws->h[5],  pwt->h[5]);
705     pwd->h[6]  = msa_bset_df(DF_HALF, pws->h[6],  pwt->h[6]);
706     pwd->h[7]  = msa_bset_df(DF_HALF, pws->h[7],  pwt->h[7]);
707 }
708
709 void helper_msa_bset_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
710 {
711     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
712     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
713     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
714
715     pwd->w[0]  = msa_bset_df(DF_WORD, pws->w[0],  pwt->w[0]);
716     pwd->w[1]  = msa_bset_df(DF_WORD, pws->w[1],  pwt->w[1]);
717     pwd->w[2]  = msa_bset_df(DF_WORD, pws->w[2],  pwt->w[2]);
718     pwd->w[3]  = msa_bset_df(DF_WORD, pws->w[3],  pwt->w[3]);
719 }
720
721 void helper_msa_bset_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
722 {
723     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
724     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
725     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
726
727     pwd->d[0]  = msa_bset_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
728     pwd->d[1]  = msa_bset_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
729 }
730
731
732 /*
733  * Fixed Multiply
734  * --------------
735  *
736  * +---------------+----------------------------------------------------------+
737  * | MADD_Q.H      | Vector Fixed-Point Multiply and Add (halfword)           |
738  * | MADD_Q.W      | Vector Fixed-Point Multiply and Add (word)               |
739  * | MADDR_Q.H     | Vector Fixed-Point Multiply and Add Rounded (halfword)   |
740  * | MADDR_Q.W     | Vector Fixed-Point Multiply and Add Rounded (word)       |
741  * | MSUB_Q.H      | Vector Fixed-Point Multiply and Subtr. (halfword)        |
742  * | MSUB_Q.W      | Vector Fixed-Point Multiply and Subtr. (word)            |
743  * | MSUBR_Q.H     | Vector Fixed-Point Multiply and Subtr. Rounded (halfword)|
744  * | MSUBR_Q.W     | Vector Fixed-Point Multiply and Subtr. Rounded (word)    |
745  * | MUL_Q.H       | Vector Fixed-Point Multiply (halfword)                   |
746  * | MUL_Q.W       | Vector Fixed-Point Multiply (word)                       |
747  * | MULR_Q.H      | Vector Fixed-Point Multiply Rounded (halfword)           |
748  * | MULR_Q.W      | Vector Fixed-Point Multiply Rounded (word)               |
749  * +---------------+----------------------------------------------------------+
750  */
751
752 /* TODO: insert Fixed Multiply group helpers here */
753
754
755 /*
756  * Float Max Min
757  * -------------
758  *
759  * +---------------+----------------------------------------------------------+
760  * | FMAX_A.W      | Vector Floating-Point Maximum (Absolute) (word)          |
761  * | FMAX_A.D      | Vector Floating-Point Maximum (Absolute) (doubleword)    |
762  * | FMAX.W        | Vector Floating-Point Maximum (word)                     |
763  * | FMAX.D        | Vector Floating-Point Maximum (doubleword)               |
764  * | FMIN_A.W      | Vector Floating-Point Minimum (Absolute) (word)          |
765  * | FMIN_A.D      | Vector Floating-Point Minimum (Absolute) (doubleword)    |
766  * | FMIN.W        | Vector Floating-Point Minimum (word)                     |
767  * | FMIN.D        | Vector Floating-Point Minimum (doubleword)               |
768  * +---------------+----------------------------------------------------------+
769  */
770
771 /* TODO: insert Float Max Min group helpers here */
772
773
774 /*
775  * Int Add
776  * -------
777  *
778  * +---------------+----------------------------------------------------------+
779  * | ADD_A.B       | Vector Add Absolute Values (byte)                        |
780  * | ADD_A.H       | Vector Add Absolute Values (halfword)                    |
781  * | ADD_A.W       | Vector Add Absolute Values (word)                        |
782  * | ADD_A.D       | Vector Add Absolute Values (doubleword)                  |
783  * | ADDS_A.B      | Vector Signed Saturated Add (of Absolute) (byte)         |
784  * | ADDS_A.H      | Vector Signed Saturated Add (of Absolute) (halfword)     |
785  * | ADDS_A.W      | Vector Signed Saturated Add (of Absolute) (word)         |
786  * | ADDS_A.D      | Vector Signed Saturated Add (of Absolute) (doubleword)   |
787  * | ADDS_S.B      | Vector Signed Saturated Add (of Signed) (byte)           |
788  * | ADDS_S.H      | Vector Signed Saturated Add (of Signed) (halfword)       |
789  * | ADDS_S.W      | Vector Signed Saturated Add (of Signed) (word)           |
790  * | ADDS_S.D      | Vector Signed Saturated Add (of Signed) (doubleword)     |
791  * | ADDS_U.B      | Vector Unsigned Saturated Add (of Unsigned) (byte)       |
792  * | ADDS_U.H      | Vector Unsigned Saturated Add (of Unsigned) (halfword)   |
793  * | ADDS_U.W      | Vector Unsigned Saturated Add (of Unsigned) (word)       |
794  * | ADDS_U.D      | Vector Unsigned Saturated Add (of Unsigned) (doubleword) |
795  * | ADDV.B        | Vector Add (byte)                                        |
796  * | ADDV.H        | Vector Add (halfword)                                    |
797  * | ADDV.W        | Vector Add (word)                                        |
798  * | ADDV.D        | Vector Add (doubleword)                                  |
799  * | HADD_S.H      | Vector Signed Horizontal Add (halfword)                  |
800  * | HADD_S.W      | Vector Signed Horizontal Add (word)                      |
801  * | HADD_S.D      | Vector Signed Horizontal Add (doubleword)                |
802  * | HADD_U.H      | Vector Unigned Horizontal Add (halfword)                 |
803  * | HADD_U.W      | Vector Unigned Horizontal Add (word)                     |
804  * | HADD_U.D      | Vector Unigned Horizontal Add (doubleword)               |
805  * +---------------+----------------------------------------------------------+
806  */
807
808
809 static inline int64_t msa_add_a_df(uint32_t df, int64_t arg1, int64_t arg2)
810 {
811     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
812     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
813     return abs_arg1 + abs_arg2;
814 }
815
816 void helper_msa_add_a_b(CPUMIPSState *env,
817                         uint32_t wd, uint32_t ws, uint32_t wt)
818 {
819     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
820     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
821     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
822
823     pwd->b[0]  = msa_add_a_df(DF_BYTE, pws->b[0],  pwt->b[0]);
824     pwd->b[1]  = msa_add_a_df(DF_BYTE, pws->b[1],  pwt->b[1]);
825     pwd->b[2]  = msa_add_a_df(DF_BYTE, pws->b[2],  pwt->b[2]);
826     pwd->b[3]  = msa_add_a_df(DF_BYTE, pws->b[3],  pwt->b[3]);
827     pwd->b[4]  = msa_add_a_df(DF_BYTE, pws->b[4],  pwt->b[4]);
828     pwd->b[5]  = msa_add_a_df(DF_BYTE, pws->b[5],  pwt->b[5]);
829     pwd->b[6]  = msa_add_a_df(DF_BYTE, pws->b[6],  pwt->b[6]);
830     pwd->b[7]  = msa_add_a_df(DF_BYTE, pws->b[7],  pwt->b[7]);
831     pwd->b[8]  = msa_add_a_df(DF_BYTE, pws->b[8],  pwt->b[8]);
832     pwd->b[9]  = msa_add_a_df(DF_BYTE, pws->b[9],  pwt->b[9]);
833     pwd->b[10] = msa_add_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
834     pwd->b[11] = msa_add_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
835     pwd->b[12] = msa_add_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
836     pwd->b[13] = msa_add_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
837     pwd->b[14] = msa_add_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
838     pwd->b[15] = msa_add_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
839 }
840
841 void helper_msa_add_a_h(CPUMIPSState *env,
842                         uint32_t wd, uint32_t ws, uint32_t wt)
843 {
844     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
845     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
846     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
847
848     pwd->h[0]  = msa_add_a_df(DF_HALF, pws->h[0],  pwt->h[0]);
849     pwd->h[1]  = msa_add_a_df(DF_HALF, pws->h[1],  pwt->h[1]);
850     pwd->h[2]  = msa_add_a_df(DF_HALF, pws->h[2],  pwt->h[2]);
851     pwd->h[3]  = msa_add_a_df(DF_HALF, pws->h[3],  pwt->h[3]);
852     pwd->h[4]  = msa_add_a_df(DF_HALF, pws->h[4],  pwt->h[4]);
853     pwd->h[5]  = msa_add_a_df(DF_HALF, pws->h[5],  pwt->h[5]);
854     pwd->h[6]  = msa_add_a_df(DF_HALF, pws->h[6],  pwt->h[6]);
855     pwd->h[7]  = msa_add_a_df(DF_HALF, pws->h[7],  pwt->h[7]);
856 }
857
858 void helper_msa_add_a_w(CPUMIPSState *env,
859                         uint32_t wd, uint32_t ws, uint32_t wt)
860 {
861     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
862     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
863     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
864
865     pwd->w[0]  = msa_add_a_df(DF_WORD, pws->w[0],  pwt->w[0]);
866     pwd->w[1]  = msa_add_a_df(DF_WORD, pws->w[1],  pwt->w[1]);
867     pwd->w[2]  = msa_add_a_df(DF_WORD, pws->w[2],  pwt->w[2]);
868     pwd->w[3]  = msa_add_a_df(DF_WORD, pws->w[3],  pwt->w[3]);
869 }
870
871 void helper_msa_add_a_d(CPUMIPSState *env,
872                         uint32_t wd, uint32_t ws, uint32_t wt)
873 {
874     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
875     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
876     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
877
878     pwd->d[0]  = msa_add_a_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
879     pwd->d[1]  = msa_add_a_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
880 }
881
882
883 static inline int64_t msa_adds_a_df(uint32_t df, int64_t arg1, int64_t arg2)
884 {
885     uint64_t max_int = (uint64_t)DF_MAX_INT(df);
886     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
887     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
888     if (abs_arg1 > max_int || abs_arg2 > max_int) {
889         return (int64_t)max_int;
890     } else {
891         return (abs_arg1 < max_int - abs_arg2) ? abs_arg1 + abs_arg2 : max_int;
892     }
893 }
894
895 void helper_msa_adds_a_b(CPUMIPSState *env,
896                          uint32_t wd, uint32_t ws, uint32_t wt)
897 {
898     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
899     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
900     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
901
902     pwd->b[0]  = msa_adds_a_df(DF_BYTE, pws->b[0],  pwt->b[0]);
903     pwd->b[1]  = msa_adds_a_df(DF_BYTE, pws->b[1],  pwt->b[1]);
904     pwd->b[2]  = msa_adds_a_df(DF_BYTE, pws->b[2],  pwt->b[2]);
905     pwd->b[3]  = msa_adds_a_df(DF_BYTE, pws->b[3],  pwt->b[3]);
906     pwd->b[4]  = msa_adds_a_df(DF_BYTE, pws->b[4],  pwt->b[4]);
907     pwd->b[5]  = msa_adds_a_df(DF_BYTE, pws->b[5],  pwt->b[5]);
908     pwd->b[6]  = msa_adds_a_df(DF_BYTE, pws->b[6],  pwt->b[6]);
909     pwd->b[7]  = msa_adds_a_df(DF_BYTE, pws->b[7],  pwt->b[7]);
910     pwd->b[8]  = msa_adds_a_df(DF_BYTE, pws->b[8],  pwt->b[8]);
911     pwd->b[9]  = msa_adds_a_df(DF_BYTE, pws->b[9],  pwt->b[9]);
912     pwd->b[10] = msa_adds_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
913     pwd->b[11] = msa_adds_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
914     pwd->b[12] = msa_adds_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
915     pwd->b[13] = msa_adds_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
916     pwd->b[14] = msa_adds_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
917     pwd->b[15] = msa_adds_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
918 }
919
920 void helper_msa_adds_a_h(CPUMIPSState *env,
921                          uint32_t wd, uint32_t ws, uint32_t wt)
922 {
923     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
924     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
925     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
926
927     pwd->h[0]  = msa_adds_a_df(DF_HALF, pws->h[0],  pwt->h[0]);
928     pwd->h[1]  = msa_adds_a_df(DF_HALF, pws->h[1],  pwt->h[1]);
929     pwd->h[2]  = msa_adds_a_df(DF_HALF, pws->h[2],  pwt->h[2]);
930     pwd->h[3]  = msa_adds_a_df(DF_HALF, pws->h[3],  pwt->h[3]);
931     pwd->h[4]  = msa_adds_a_df(DF_HALF, pws->h[4],  pwt->h[4]);
932     pwd->h[5]  = msa_adds_a_df(DF_HALF, pws->h[5],  pwt->h[5]);
933     pwd->h[6]  = msa_adds_a_df(DF_HALF, pws->h[6],  pwt->h[6]);
934     pwd->h[7]  = msa_adds_a_df(DF_HALF, pws->h[7],  pwt->h[7]);
935 }
936
937 void helper_msa_adds_a_w(CPUMIPSState *env,
938                          uint32_t wd, uint32_t ws, uint32_t wt)
939 {
940     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
941     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
942     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
943
944     pwd->w[0]  = msa_adds_a_df(DF_WORD, pws->w[0],  pwt->w[0]);
945     pwd->w[1]  = msa_adds_a_df(DF_WORD, pws->w[1],  pwt->w[1]);
946     pwd->w[2]  = msa_adds_a_df(DF_WORD, pws->w[2],  pwt->w[2]);
947     pwd->w[3]  = msa_adds_a_df(DF_WORD, pws->w[3],  pwt->w[3]);
948 }
949
950 void helper_msa_adds_a_d(CPUMIPSState *env,
951                          uint32_t wd, uint32_t ws, uint32_t wt)
952 {
953     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
954     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
955     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
956
957     pwd->d[0]  = msa_adds_a_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
958     pwd->d[1]  = msa_adds_a_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
959 }
960
961
962 static inline int64_t msa_adds_s_df(uint32_t df, int64_t arg1, int64_t arg2)
963 {
964     int64_t max_int = DF_MAX_INT(df);
965     int64_t min_int = DF_MIN_INT(df);
966     if (arg1 < 0) {
967         return (min_int - arg1 < arg2) ? arg1 + arg2 : min_int;
968     } else {
969         return (arg2 < max_int - arg1) ? arg1 + arg2 : max_int;
970     }
971 }
972
973 void helper_msa_adds_s_b(CPUMIPSState *env,
974                          uint32_t wd, uint32_t ws, uint32_t wt)
975 {
976     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
977     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
978     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
979
980     pwd->b[0]  = msa_adds_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
981     pwd->b[1]  = msa_adds_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
982     pwd->b[2]  = msa_adds_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
983     pwd->b[3]  = msa_adds_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
984     pwd->b[4]  = msa_adds_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
985     pwd->b[5]  = msa_adds_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
986     pwd->b[6]  = msa_adds_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
987     pwd->b[7]  = msa_adds_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
988     pwd->b[8]  = msa_adds_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
989     pwd->b[9]  = msa_adds_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
990     pwd->b[10] = msa_adds_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
991     pwd->b[11] = msa_adds_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
992     pwd->b[12] = msa_adds_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
993     pwd->b[13] = msa_adds_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
994     pwd->b[14] = msa_adds_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
995     pwd->b[15] = msa_adds_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
996 }
997
998 void helper_msa_adds_s_h(CPUMIPSState *env,
999                          uint32_t wd, uint32_t ws, uint32_t wt)
1000 {
1001     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1002     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1003     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1004
1005     pwd->h[0]  = msa_adds_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1006     pwd->h[1]  = msa_adds_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1007     pwd->h[2]  = msa_adds_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1008     pwd->h[3]  = msa_adds_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1009     pwd->h[4]  = msa_adds_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1010     pwd->h[5]  = msa_adds_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1011     pwd->h[6]  = msa_adds_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1012     pwd->h[7]  = msa_adds_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1013 }
1014
1015 void helper_msa_adds_s_w(CPUMIPSState *env,
1016                          uint32_t wd, uint32_t ws, uint32_t wt)
1017 {
1018     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1019     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1020     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1021
1022     pwd->w[0]  = msa_adds_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1023     pwd->w[1]  = msa_adds_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1024     pwd->w[2]  = msa_adds_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1025     pwd->w[3]  = msa_adds_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1026 }
1027
1028 void helper_msa_adds_s_d(CPUMIPSState *env,
1029                          uint32_t wd, uint32_t ws, uint32_t wt)
1030 {
1031     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1032     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1033     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1034
1035     pwd->d[0]  = msa_adds_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1036     pwd->d[1]  = msa_adds_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1037 }
1038
1039
1040 static inline uint64_t msa_adds_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1041 {
1042     uint64_t max_uint = DF_MAX_UINT(df);
1043     uint64_t u_arg1 = UNSIGNED(arg1, df);
1044     uint64_t u_arg2 = UNSIGNED(arg2, df);
1045     return (u_arg1 < max_uint - u_arg2) ? u_arg1 + u_arg2 : max_uint;
1046 }
1047
1048 void helper_msa_adds_u_b(CPUMIPSState *env,
1049                          uint32_t wd, uint32_t ws, uint32_t wt)
1050 {
1051     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1052     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1053     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1054
1055     pwd->b[0]  = msa_adds_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1056     pwd->b[1]  = msa_adds_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1057     pwd->b[2]  = msa_adds_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1058     pwd->b[3]  = msa_adds_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1059     pwd->b[4]  = msa_adds_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1060     pwd->b[5]  = msa_adds_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1061     pwd->b[6]  = msa_adds_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1062     pwd->b[7]  = msa_adds_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1063     pwd->b[8]  = msa_adds_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1064     pwd->b[9]  = msa_adds_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1065     pwd->b[10] = msa_adds_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1066     pwd->b[11] = msa_adds_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1067     pwd->b[12] = msa_adds_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1068     pwd->b[13] = msa_adds_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1069     pwd->b[14] = msa_adds_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1070     pwd->b[15] = msa_adds_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1071 }
1072
1073 void helper_msa_adds_u_h(CPUMIPSState *env,
1074                          uint32_t wd, uint32_t ws, uint32_t wt)
1075 {
1076     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1077     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1078     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1079
1080     pwd->h[0]  = msa_adds_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1081     pwd->h[1]  = msa_adds_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1082     pwd->h[2]  = msa_adds_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1083     pwd->h[3]  = msa_adds_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1084     pwd->h[4]  = msa_adds_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1085     pwd->h[5]  = msa_adds_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1086     pwd->h[6]  = msa_adds_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1087     pwd->h[7]  = msa_adds_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1088 }
1089
1090 void helper_msa_adds_u_w(CPUMIPSState *env,
1091                          uint32_t wd, uint32_t ws, uint32_t wt)
1092 {
1093     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1094     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1095     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1096
1097     pwd->w[0]  = msa_adds_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1098     pwd->w[1]  = msa_adds_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1099     pwd->w[2]  = msa_adds_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1100     pwd->w[3]  = msa_adds_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1101 }
1102
1103 void helper_msa_adds_u_d(CPUMIPSState *env,
1104                          uint32_t wd, uint32_t ws, uint32_t wt)
1105 {
1106     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1107     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1108     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1109
1110     pwd->d[0]  = msa_adds_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1111     pwd->d[1]  = msa_adds_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1112 }
1113
1114
1115 static inline int64_t msa_addv_df(uint32_t df, int64_t arg1, int64_t arg2)
1116 {
1117     return arg1 + arg2;
1118 }
1119
1120 void helper_msa_addv_b(CPUMIPSState *env,
1121                        uint32_t wd, uint32_t ws, uint32_t wt)
1122 {
1123     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1124     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1125     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1126
1127     pwd->b[0]  = msa_addv_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1128     pwd->b[1]  = msa_addv_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1129     pwd->b[2]  = msa_addv_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1130     pwd->b[3]  = msa_addv_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1131     pwd->b[4]  = msa_addv_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1132     pwd->b[5]  = msa_addv_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1133     pwd->b[6]  = msa_addv_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1134     pwd->b[7]  = msa_addv_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1135     pwd->b[8]  = msa_addv_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1136     pwd->b[9]  = msa_addv_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1137     pwd->b[10] = msa_addv_df(DF_BYTE, pws->b[10], pwt->b[10]);
1138     pwd->b[11] = msa_addv_df(DF_BYTE, pws->b[11], pwt->b[11]);
1139     pwd->b[12] = msa_addv_df(DF_BYTE, pws->b[12], pwt->b[12]);
1140     pwd->b[13] = msa_addv_df(DF_BYTE, pws->b[13], pwt->b[13]);
1141     pwd->b[14] = msa_addv_df(DF_BYTE, pws->b[14], pwt->b[14]);
1142     pwd->b[15] = msa_addv_df(DF_BYTE, pws->b[15], pwt->b[15]);
1143 }
1144
1145 void helper_msa_addv_h(CPUMIPSState *env,
1146                        uint32_t wd, uint32_t ws, uint32_t wt)
1147 {
1148     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1149     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1150     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1151
1152     pwd->h[0]  = msa_addv_df(DF_HALF, pws->h[0],  pwt->h[0]);
1153     pwd->h[1]  = msa_addv_df(DF_HALF, pws->h[1],  pwt->h[1]);
1154     pwd->h[2]  = msa_addv_df(DF_HALF, pws->h[2],  pwt->h[2]);
1155     pwd->h[3]  = msa_addv_df(DF_HALF, pws->h[3],  pwt->h[3]);
1156     pwd->h[4]  = msa_addv_df(DF_HALF, pws->h[4],  pwt->h[4]);
1157     pwd->h[5]  = msa_addv_df(DF_HALF, pws->h[5],  pwt->h[5]);
1158     pwd->h[6]  = msa_addv_df(DF_HALF, pws->h[6],  pwt->h[6]);
1159     pwd->h[7]  = msa_addv_df(DF_HALF, pws->h[7],  pwt->h[7]);
1160 }
1161
1162 void helper_msa_addv_w(CPUMIPSState *env,
1163                        uint32_t wd, uint32_t ws, uint32_t wt)
1164 {
1165     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1166     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1167     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1168
1169     pwd->w[0]  = msa_addv_df(DF_WORD, pws->w[0],  pwt->w[0]);
1170     pwd->w[1]  = msa_addv_df(DF_WORD, pws->w[1],  pwt->w[1]);
1171     pwd->w[2]  = msa_addv_df(DF_WORD, pws->w[2],  pwt->w[2]);
1172     pwd->w[3]  = msa_addv_df(DF_WORD, pws->w[3],  pwt->w[3]);
1173 }
1174
1175 void helper_msa_addv_d(CPUMIPSState *env,
1176                        uint32_t wd, uint32_t ws, uint32_t wt)
1177 {
1178     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1179     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1180     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1181
1182     pwd->d[0]  = msa_addv_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1183     pwd->d[1]  = msa_addv_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1184 }
1185
1186
1187 #define SIGNED_EVEN(a, df) \
1188         ((((int64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2))
1189
1190 #define UNSIGNED_EVEN(a, df) \
1191         ((((uint64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2))
1192
1193 #define SIGNED_ODD(a, df) \
1194         ((((int64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
1195
1196 #define UNSIGNED_ODD(a, df) \
1197         ((((uint64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
1198
1199
1200 static inline int64_t msa_hadd_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1201 {
1202     return SIGNED_ODD(arg1, df) + SIGNED_EVEN(arg2, df);
1203 }
1204
1205 void helper_msa_hadd_s_h(CPUMIPSState *env,
1206                          uint32_t wd, uint32_t ws, uint32_t wt)
1207 {
1208     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1209     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1210     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1211
1212     pwd->h[0]  = msa_hadd_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1213     pwd->h[1]  = msa_hadd_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1214     pwd->h[2]  = msa_hadd_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1215     pwd->h[3]  = msa_hadd_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1216     pwd->h[4]  = msa_hadd_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1217     pwd->h[5]  = msa_hadd_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1218     pwd->h[6]  = msa_hadd_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1219     pwd->h[7]  = msa_hadd_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1220 }
1221
1222 void helper_msa_hadd_s_w(CPUMIPSState *env,
1223                          uint32_t wd, uint32_t ws, uint32_t wt)
1224 {
1225     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1226     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1227     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1228
1229     pwd->w[0]  = msa_hadd_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1230     pwd->w[1]  = msa_hadd_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1231     pwd->w[2]  = msa_hadd_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1232     pwd->w[3]  = msa_hadd_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1233 }
1234
1235 void helper_msa_hadd_s_d(CPUMIPSState *env,
1236                          uint32_t wd, uint32_t ws, uint32_t wt)
1237 {
1238     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1239     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1240     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1241
1242     pwd->d[0]  = msa_hadd_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1243     pwd->d[1]  = msa_hadd_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1244 }
1245
1246
1247 static inline int64_t msa_hadd_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1248 {
1249     return UNSIGNED_ODD(arg1, df) + UNSIGNED_EVEN(arg2, df);
1250 }
1251
1252 void helper_msa_hadd_u_h(CPUMIPSState *env,
1253                          uint32_t wd, uint32_t ws, uint32_t wt)
1254 {
1255     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1256     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1257     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1258
1259     pwd->h[0]  = msa_hadd_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1260     pwd->h[1]  = msa_hadd_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1261     pwd->h[2]  = msa_hadd_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1262     pwd->h[3]  = msa_hadd_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1263     pwd->h[4]  = msa_hadd_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1264     pwd->h[5]  = msa_hadd_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1265     pwd->h[6]  = msa_hadd_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1266     pwd->h[7]  = msa_hadd_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1267 }
1268
1269 void helper_msa_hadd_u_w(CPUMIPSState *env,
1270                          uint32_t wd, uint32_t ws, uint32_t wt)
1271 {
1272     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1273     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1274     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1275
1276     pwd->w[0]  = msa_hadd_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1277     pwd->w[1]  = msa_hadd_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1278     pwd->w[2]  = msa_hadd_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1279     pwd->w[3]  = msa_hadd_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1280 }
1281
1282 void helper_msa_hadd_u_d(CPUMIPSState *env,
1283                          uint32_t wd, uint32_t ws, uint32_t wt)
1284 {
1285     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1286     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1287     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1288
1289     pwd->d[0]  = msa_hadd_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1290     pwd->d[1]  = msa_hadd_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1291 }
1292
1293
1294 /*
1295  * Int Average
1296  * -----------
1297  *
1298  * +---------------+----------------------------------------------------------+
1299  * | AVE_S.B       | Vector Signed Average (byte)                             |
1300  * | AVE_S.H       | Vector Signed Average (halfword)                         |
1301  * | AVE_S.W       | Vector Signed Average (word)                             |
1302  * | AVE_S.D       | Vector Signed Average (doubleword)                       |
1303  * | AVE_U.B       | Vector Unsigned Average (byte)                           |
1304  * | AVE_U.H       | Vector Unsigned Average (halfword)                       |
1305  * | AVE_U.W       | Vector Unsigned Average (word)                           |
1306  * | AVE_U.D       | Vector Unsigned Average (doubleword)                     |
1307  * | AVER_S.B      | Vector Signed Average Rounded (byte)                     |
1308  * | AVER_S.H      | Vector Signed Average Rounded (halfword)                 |
1309  * | AVER_S.W      | Vector Signed Average Rounded (word)                     |
1310  * | AVER_S.D      | Vector Signed Average Rounded (doubleword)               |
1311  * | AVER_U.B      | Vector Unsigned Average Rounded (byte)                   |
1312  * | AVER_U.H      | Vector Unsigned Average Rounded (halfword)               |
1313  * | AVER_U.W      | Vector Unsigned Average Rounded (word)                   |
1314  * | AVER_U.D      | Vector Unsigned Average Rounded (doubleword)             |
1315  * +---------------+----------------------------------------------------------+
1316  */
1317
1318 static inline int64_t msa_ave_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1319 {
1320     /* signed shift */
1321     return (arg1 >> 1) + (arg2 >> 1) + (arg1 & arg2 & 1);
1322 }
1323
1324 void helper_msa_ave_s_b(CPUMIPSState *env,
1325                         uint32_t wd, uint32_t ws, uint32_t wt)
1326 {
1327     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1328     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1329     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1330
1331     pwd->b[0]  = msa_ave_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1332     pwd->b[1]  = msa_ave_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1333     pwd->b[2]  = msa_ave_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1334     pwd->b[3]  = msa_ave_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1335     pwd->b[4]  = msa_ave_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1336     pwd->b[5]  = msa_ave_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1337     pwd->b[6]  = msa_ave_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1338     pwd->b[7]  = msa_ave_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1339     pwd->b[8]  = msa_ave_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1340     pwd->b[9]  = msa_ave_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1341     pwd->b[10] = msa_ave_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
1342     pwd->b[11] = msa_ave_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
1343     pwd->b[12] = msa_ave_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
1344     pwd->b[13] = msa_ave_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
1345     pwd->b[14] = msa_ave_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
1346     pwd->b[15] = msa_ave_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
1347 }
1348
1349 void helper_msa_ave_s_h(CPUMIPSState *env,
1350                         uint32_t wd, uint32_t ws, uint32_t wt)
1351 {
1352     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1353     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1354     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1355
1356     pwd->h[0]  = msa_ave_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1357     pwd->h[1]  = msa_ave_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1358     pwd->h[2]  = msa_ave_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1359     pwd->h[3]  = msa_ave_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1360     pwd->h[4]  = msa_ave_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1361     pwd->h[5]  = msa_ave_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1362     pwd->h[6]  = msa_ave_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1363     pwd->h[7]  = msa_ave_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1364 }
1365
1366 void helper_msa_ave_s_w(CPUMIPSState *env,
1367                         uint32_t wd, uint32_t ws, uint32_t wt)
1368 {
1369     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1370     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1371     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1372
1373     pwd->w[0]  = msa_ave_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1374     pwd->w[1]  = msa_ave_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1375     pwd->w[2]  = msa_ave_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1376     pwd->w[3]  = msa_ave_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1377 }
1378
1379 void helper_msa_ave_s_d(CPUMIPSState *env,
1380                         uint32_t wd, uint32_t ws, uint32_t wt)
1381 {
1382     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1383     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1384     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1385
1386     pwd->d[0]  = msa_ave_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1387     pwd->d[1]  = msa_ave_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1388 }
1389
1390 static inline uint64_t msa_ave_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1391 {
1392     uint64_t u_arg1 = UNSIGNED(arg1, df);
1393     uint64_t u_arg2 = UNSIGNED(arg2, df);
1394     /* unsigned shift */
1395     return (u_arg1 >> 1) + (u_arg2 >> 1) + (u_arg1 & u_arg2 & 1);
1396 }
1397
1398 void helper_msa_ave_u_b(CPUMIPSState *env,
1399                         uint32_t wd, uint32_t ws, uint32_t wt)
1400 {
1401     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1402     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1403     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1404
1405     pwd->b[0]  = msa_ave_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1406     pwd->b[1]  = msa_ave_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1407     pwd->b[2]  = msa_ave_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1408     pwd->b[3]  = msa_ave_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1409     pwd->b[4]  = msa_ave_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1410     pwd->b[5]  = msa_ave_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1411     pwd->b[6]  = msa_ave_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1412     pwd->b[7]  = msa_ave_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1413     pwd->b[8]  = msa_ave_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1414     pwd->b[9]  = msa_ave_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1415     pwd->b[10] = msa_ave_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1416     pwd->b[11] = msa_ave_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1417     pwd->b[12] = msa_ave_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1418     pwd->b[13] = msa_ave_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1419     pwd->b[14] = msa_ave_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1420     pwd->b[15] = msa_ave_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1421 }
1422
1423 void helper_msa_ave_u_h(CPUMIPSState *env,
1424                         uint32_t wd, uint32_t ws, uint32_t wt)
1425 {
1426     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1427     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1428     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1429
1430     pwd->h[0]  = msa_ave_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1431     pwd->h[1]  = msa_ave_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1432     pwd->h[2]  = msa_ave_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1433     pwd->h[3]  = msa_ave_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1434     pwd->h[4]  = msa_ave_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1435     pwd->h[5]  = msa_ave_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1436     pwd->h[6]  = msa_ave_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1437     pwd->h[7]  = msa_ave_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1438 }
1439
1440 void helper_msa_ave_u_w(CPUMIPSState *env,
1441                         uint32_t wd, uint32_t ws, uint32_t wt)
1442 {
1443     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1444     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1445     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1446
1447     pwd->w[0]  = msa_ave_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1448     pwd->w[1]  = msa_ave_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1449     pwd->w[2]  = msa_ave_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1450     pwd->w[3]  = msa_ave_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1451 }
1452
1453 void helper_msa_ave_u_d(CPUMIPSState *env,
1454                         uint32_t wd, uint32_t ws, uint32_t wt)
1455 {
1456     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1457     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1458     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1459
1460     pwd->d[0]  = msa_ave_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1461     pwd->d[1]  = msa_ave_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1462 }
1463
1464 static inline int64_t msa_aver_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1465 {
1466     /* signed shift */
1467     return (arg1 >> 1) + (arg2 >> 1) + ((arg1 | arg2) & 1);
1468 }
1469
1470 void helper_msa_aver_s_b(CPUMIPSState *env,
1471                          uint32_t wd, uint32_t ws, uint32_t wt)
1472 {
1473     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1474     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1475     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1476
1477     pwd->b[0]  = msa_aver_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1478     pwd->b[1]  = msa_aver_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1479     pwd->b[2]  = msa_aver_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1480     pwd->b[3]  = msa_aver_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1481     pwd->b[4]  = msa_aver_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1482     pwd->b[5]  = msa_aver_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1483     pwd->b[6]  = msa_aver_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1484     pwd->b[7]  = msa_aver_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1485     pwd->b[8]  = msa_aver_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1486     pwd->b[9]  = msa_aver_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1487     pwd->b[10] = msa_aver_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
1488     pwd->b[11] = msa_aver_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
1489     pwd->b[12] = msa_aver_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
1490     pwd->b[13] = msa_aver_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
1491     pwd->b[14] = msa_aver_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
1492     pwd->b[15] = msa_aver_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
1493 }
1494
1495 void helper_msa_aver_s_h(CPUMIPSState *env,
1496                          uint32_t wd, uint32_t ws, uint32_t wt)
1497 {
1498     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1499     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1500     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1501
1502     pwd->h[0]  = msa_aver_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1503     pwd->h[1]  = msa_aver_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1504     pwd->h[2]  = msa_aver_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1505     pwd->h[3]  = msa_aver_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1506     pwd->h[4]  = msa_aver_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1507     pwd->h[5]  = msa_aver_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1508     pwd->h[6]  = msa_aver_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1509     pwd->h[7]  = msa_aver_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1510 }
1511
1512 void helper_msa_aver_s_w(CPUMIPSState *env,
1513                          uint32_t wd, uint32_t ws, uint32_t wt)
1514 {
1515     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1516     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1517     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1518
1519     pwd->w[0]  = msa_aver_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1520     pwd->w[1]  = msa_aver_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1521     pwd->w[2]  = msa_aver_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1522     pwd->w[3]  = msa_aver_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1523 }
1524
1525 void helper_msa_aver_s_d(CPUMIPSState *env,
1526                          uint32_t wd, uint32_t ws, uint32_t wt)
1527 {
1528     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1529     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1530     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1531
1532     pwd->d[0]  = msa_aver_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1533     pwd->d[1]  = msa_aver_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1534 }
1535
1536 static inline uint64_t msa_aver_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1537 {
1538     uint64_t u_arg1 = UNSIGNED(arg1, df);
1539     uint64_t u_arg2 = UNSIGNED(arg2, df);
1540     /* unsigned shift */
1541     return (u_arg1 >> 1) + (u_arg2 >> 1) + ((u_arg1 | u_arg2) & 1);
1542 }
1543
1544 void helper_msa_aver_u_b(CPUMIPSState *env,
1545                          uint32_t wd, uint32_t ws, uint32_t wt)
1546 {
1547     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1548     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1549     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1550
1551     pwd->b[0]  = msa_aver_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1552     pwd->b[1]  = msa_aver_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1553     pwd->b[2]  = msa_aver_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1554     pwd->b[3]  = msa_aver_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1555     pwd->b[4]  = msa_aver_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1556     pwd->b[5]  = msa_aver_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1557     pwd->b[6]  = msa_aver_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1558     pwd->b[7]  = msa_aver_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1559     pwd->b[8]  = msa_aver_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1560     pwd->b[9]  = msa_aver_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1561     pwd->b[10] = msa_aver_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1562     pwd->b[11] = msa_aver_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1563     pwd->b[12] = msa_aver_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1564     pwd->b[13] = msa_aver_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1565     pwd->b[14] = msa_aver_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1566     pwd->b[15] = msa_aver_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1567 }
1568
1569 void helper_msa_aver_u_h(CPUMIPSState *env,
1570                          uint32_t wd, uint32_t ws, uint32_t wt)
1571 {
1572     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1573     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1574     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1575
1576     pwd->h[0]  = msa_aver_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1577     pwd->h[1]  = msa_aver_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1578     pwd->h[2]  = msa_aver_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1579     pwd->h[3]  = msa_aver_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1580     pwd->h[4]  = msa_aver_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1581     pwd->h[5]  = msa_aver_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1582     pwd->h[6]  = msa_aver_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1583     pwd->h[7]  = msa_aver_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1584 }
1585
1586 void helper_msa_aver_u_w(CPUMIPSState *env,
1587                          uint32_t wd, uint32_t ws, uint32_t wt)
1588 {
1589     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1590     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1591     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1592
1593     pwd->w[0]  = msa_aver_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1594     pwd->w[1]  = msa_aver_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1595     pwd->w[2]  = msa_aver_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1596     pwd->w[3]  = msa_aver_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1597 }
1598
1599 void helper_msa_aver_u_d(CPUMIPSState *env,
1600                          uint32_t wd, uint32_t ws, uint32_t wt)
1601 {
1602     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1603     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1604     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1605
1606     pwd->d[0]  = msa_aver_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1607     pwd->d[1]  = msa_aver_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1608 }
1609
1610
1611 /*
1612  * Int Compare
1613  * -----------
1614  *
1615  * +---------------+----------------------------------------------------------+
1616  * | CEQ.B         | Vector Compare Equal (byte)                              |
1617  * | CEQ.H         | Vector Compare Equal (halfword)                          |
1618  * | CEQ.W         | Vector Compare Equal (word)                              |
1619  * | CEQ.D         | Vector Compare Equal (doubleword)                        |
1620  * | CLE_S.B       | Vector Compare Signed Less Than or Equal (byte)          |
1621  * | CLE_S.H       | Vector Compare Signed Less Than or Equal (halfword)      |
1622  * | CLE_S.W       | Vector Compare Signed Less Than or Equal (word)          |
1623  * | CLE_S.D       | Vector Compare Signed Less Than or Equal (doubleword)    |
1624  * | CLE_U.B       | Vector Compare Unsigned Less Than or Equal (byte)        |
1625  * | CLE_U.H       | Vector Compare Unsigned Less Than or Equal (halfword)    |
1626  * | CLE_U.W       | Vector Compare Unsigned Less Than or Equal (word)        |
1627  * | CLE_U.D       | Vector Compare Unsigned Less Than or Equal (doubleword)  |
1628  * | CLT_S.B       | Vector Compare Signed Less Than (byte)                   |
1629  * | CLT_S.H       | Vector Compare Signed Less Than (halfword)               |
1630  * | CLT_S.W       | Vector Compare Signed Less Than (word)                   |
1631  * | CLT_S.D       | Vector Compare Signed Less Than (doubleword)             |
1632  * | CLT_U.B       | Vector Compare Unsigned Less Than (byte)                 |
1633  * | CLT_U.H       | Vector Compare Unsigned Less Than (halfword)             |
1634  * | CLT_U.W       | Vector Compare Unsigned Less Than (word)                 |
1635  * | CLT_U.D       | Vector Compare Unsigned Less Than (doubleword)           |
1636  * +---------------+----------------------------------------------------------+
1637  */
1638
1639 static inline int64_t msa_ceq_df(uint32_t df, int64_t arg1, int64_t arg2)
1640 {
1641     return arg1 == arg2 ? -1 : 0;
1642 }
1643
1644 static inline int8_t msa_ceq_b(int8_t arg1, int8_t arg2)
1645 {
1646     return arg1 == arg2 ? -1 : 0;
1647 }
1648
1649 void helper_msa_ceq_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1650 {
1651     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1652     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1653     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1654
1655     pwd->b[0]  = msa_ceq_b(pws->b[0],  pwt->b[0]);
1656     pwd->b[1]  = msa_ceq_b(pws->b[1],  pwt->b[1]);
1657     pwd->b[2]  = msa_ceq_b(pws->b[2],  pwt->b[2]);
1658     pwd->b[3]  = msa_ceq_b(pws->b[3],  pwt->b[3]);
1659     pwd->b[4]  = msa_ceq_b(pws->b[4],  pwt->b[4]);
1660     pwd->b[5]  = msa_ceq_b(pws->b[5],  pwt->b[5]);
1661     pwd->b[6]  = msa_ceq_b(pws->b[6],  pwt->b[6]);
1662     pwd->b[7]  = msa_ceq_b(pws->b[7],  pwt->b[7]);
1663     pwd->b[8]  = msa_ceq_b(pws->b[8],  pwt->b[8]);
1664     pwd->b[9]  = msa_ceq_b(pws->b[9],  pwt->b[9]);
1665     pwd->b[10] = msa_ceq_b(pws->b[10], pwt->b[10]);
1666     pwd->b[11] = msa_ceq_b(pws->b[11], pwt->b[11]);
1667     pwd->b[12] = msa_ceq_b(pws->b[12], pwt->b[12]);
1668     pwd->b[13] = msa_ceq_b(pws->b[13], pwt->b[13]);
1669     pwd->b[14] = msa_ceq_b(pws->b[14], pwt->b[14]);
1670     pwd->b[15] = msa_ceq_b(pws->b[15], pwt->b[15]);
1671 }
1672
1673 static inline int16_t msa_ceq_h(int16_t arg1, int16_t arg2)
1674 {
1675     return arg1 == arg2 ? -1 : 0;
1676 }
1677
1678 void helper_msa_ceq_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1679 {
1680     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1681     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1682     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1683
1684     pwd->h[0]  = msa_ceq_h(pws->h[0],  pwt->h[0]);
1685     pwd->h[1]  = msa_ceq_h(pws->h[1],  pwt->h[1]);
1686     pwd->h[2]  = msa_ceq_h(pws->h[2],  pwt->h[2]);
1687     pwd->h[3]  = msa_ceq_h(pws->h[3],  pwt->h[3]);
1688     pwd->h[4]  = msa_ceq_h(pws->h[4],  pwt->h[4]);
1689     pwd->h[5]  = msa_ceq_h(pws->h[5],  pwt->h[5]);
1690     pwd->h[6]  = msa_ceq_h(pws->h[6],  pwt->h[6]);
1691     pwd->h[7]  = msa_ceq_h(pws->h[7],  pwt->h[7]);
1692 }
1693
1694 static inline int32_t msa_ceq_w(int32_t arg1, int32_t arg2)
1695 {
1696     return arg1 == arg2 ? -1 : 0;
1697 }
1698
1699 void helper_msa_ceq_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1700 {
1701     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1702     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1703     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1704
1705     pwd->w[0]  = msa_ceq_w(pws->w[0],  pwt->w[0]);
1706     pwd->w[1]  = msa_ceq_w(pws->w[1],  pwt->w[1]);
1707     pwd->w[2]  = msa_ceq_w(pws->w[2],  pwt->w[2]);
1708     pwd->w[3]  = msa_ceq_w(pws->w[3],  pwt->w[3]);
1709 }
1710
1711 static inline int64_t msa_ceq_d(int64_t arg1, int64_t arg2)
1712 {
1713     return arg1 == arg2 ? -1 : 0;
1714 }
1715
1716 void helper_msa_ceq_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1717 {
1718     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1719     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1720     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1721
1722     pwd->d[0]  = msa_ceq_d(pws->d[0],  pwt->d[0]);
1723     pwd->d[1]  = msa_ceq_d(pws->d[1],  pwt->d[1]);
1724 }
1725
1726 static inline int64_t msa_cle_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1727 {
1728     return arg1 <= arg2 ? -1 : 0;
1729 }
1730
1731 void helper_msa_cle_s_b(CPUMIPSState *env,
1732                         uint32_t wd, uint32_t ws, uint32_t wt)
1733 {
1734     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1735     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1736     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1737
1738     pwd->b[0]  = msa_cle_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1739     pwd->b[1]  = msa_cle_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1740     pwd->b[2]  = msa_cle_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1741     pwd->b[3]  = msa_cle_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1742     pwd->b[4]  = msa_cle_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1743     pwd->b[5]  = msa_cle_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1744     pwd->b[6]  = msa_cle_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1745     pwd->b[7]  = msa_cle_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1746     pwd->b[8]  = msa_cle_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1747     pwd->b[9]  = msa_cle_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1748     pwd->b[10] = msa_cle_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
1749     pwd->b[11] = msa_cle_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
1750     pwd->b[12] = msa_cle_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
1751     pwd->b[13] = msa_cle_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
1752     pwd->b[14] = msa_cle_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
1753     pwd->b[15] = msa_cle_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
1754 }
1755
1756 void helper_msa_cle_s_h(CPUMIPSState *env,
1757                         uint32_t wd, uint32_t ws, uint32_t wt)
1758 {
1759     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1760     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1761     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1762
1763     pwd->h[0]  = msa_cle_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1764     pwd->h[1]  = msa_cle_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1765     pwd->h[2]  = msa_cle_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1766     pwd->h[3]  = msa_cle_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1767     pwd->h[4]  = msa_cle_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1768     pwd->h[5]  = msa_cle_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1769     pwd->h[6]  = msa_cle_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1770     pwd->h[7]  = msa_cle_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1771 }
1772
1773 void helper_msa_cle_s_w(CPUMIPSState *env,
1774                         uint32_t wd, uint32_t ws, uint32_t wt)
1775 {
1776     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1777     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1778     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1779
1780     pwd->w[0]  = msa_cle_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1781     pwd->w[1]  = msa_cle_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1782     pwd->w[2]  = msa_cle_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1783     pwd->w[3]  = msa_cle_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1784 }
1785
1786 void helper_msa_cle_s_d(CPUMIPSState *env,
1787                         uint32_t wd, uint32_t ws, uint32_t wt)
1788 {
1789     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1790     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1791     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1792
1793     pwd->d[0]  = msa_cle_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1794     pwd->d[1]  = msa_cle_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1795 }
1796
1797 static inline int64_t msa_cle_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1798 {
1799     uint64_t u_arg1 = UNSIGNED(arg1, df);
1800     uint64_t u_arg2 = UNSIGNED(arg2, df);
1801     return u_arg1 <= u_arg2 ? -1 : 0;
1802 }
1803
1804 void helper_msa_cle_u_b(CPUMIPSState *env,
1805                         uint32_t wd, uint32_t ws, uint32_t wt)
1806 {
1807     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1808     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1809     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1810
1811     pwd->b[0]  = msa_cle_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1812     pwd->b[1]  = msa_cle_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1813     pwd->b[2]  = msa_cle_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1814     pwd->b[3]  = msa_cle_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1815     pwd->b[4]  = msa_cle_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1816     pwd->b[5]  = msa_cle_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1817     pwd->b[6]  = msa_cle_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1818     pwd->b[7]  = msa_cle_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1819     pwd->b[8]  = msa_cle_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1820     pwd->b[9]  = msa_cle_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1821     pwd->b[10] = msa_cle_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1822     pwd->b[11] = msa_cle_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1823     pwd->b[12] = msa_cle_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1824     pwd->b[13] = msa_cle_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1825     pwd->b[14] = msa_cle_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1826     pwd->b[15] = msa_cle_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1827 }
1828
1829 void helper_msa_cle_u_h(CPUMIPSState *env,
1830                         uint32_t wd, uint32_t ws, uint32_t wt)
1831 {
1832     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1833     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1834     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1835
1836     pwd->h[0]  = msa_cle_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1837     pwd->h[1]  = msa_cle_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1838     pwd->h[2]  = msa_cle_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1839     pwd->h[3]  = msa_cle_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1840     pwd->h[4]  = msa_cle_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1841     pwd->h[5]  = msa_cle_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1842     pwd->h[6]  = msa_cle_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1843     pwd->h[7]  = msa_cle_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1844 }
1845
1846 void helper_msa_cle_u_w(CPUMIPSState *env,
1847                         uint32_t wd, uint32_t ws, uint32_t wt)
1848 {
1849     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1850     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1851     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1852
1853     pwd->w[0]  = msa_cle_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1854     pwd->w[1]  = msa_cle_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1855     pwd->w[2]  = msa_cle_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1856     pwd->w[3]  = msa_cle_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1857 }
1858
1859 void helper_msa_cle_u_d(CPUMIPSState *env,
1860                         uint32_t wd, uint32_t ws, uint32_t wt)
1861 {
1862     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1863     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1864     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1865
1866     pwd->d[0]  = msa_cle_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1867     pwd->d[1]  = msa_cle_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1868 }
1869
1870 static inline int64_t msa_clt_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1871 {
1872     return arg1 < arg2 ? -1 : 0;
1873 }
1874
1875 static inline int8_t msa_clt_s_b(int8_t arg1, int8_t arg2)
1876 {
1877     return arg1 < arg2 ? -1 : 0;
1878 }
1879
1880 void helper_msa_clt_s_b(CPUMIPSState *env,
1881                         uint32_t wd, uint32_t ws, uint32_t wt)
1882 {
1883     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1884     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1885     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1886
1887     pwd->b[0]  = msa_clt_s_b(pws->b[0],  pwt->b[0]);
1888     pwd->b[1]  = msa_clt_s_b(pws->b[1],  pwt->b[1]);
1889     pwd->b[2]  = msa_clt_s_b(pws->b[2],  pwt->b[2]);
1890     pwd->b[3]  = msa_clt_s_b(pws->b[3],  pwt->b[3]);
1891     pwd->b[4]  = msa_clt_s_b(pws->b[4],  pwt->b[4]);
1892     pwd->b[5]  = msa_clt_s_b(pws->b[5],  pwt->b[5]);
1893     pwd->b[6]  = msa_clt_s_b(pws->b[6],  pwt->b[6]);
1894     pwd->b[7]  = msa_clt_s_b(pws->b[7],  pwt->b[7]);
1895     pwd->b[8]  = msa_clt_s_b(pws->b[8],  pwt->b[8]);
1896     pwd->b[9]  = msa_clt_s_b(pws->b[9],  pwt->b[9]);
1897     pwd->b[10] = msa_clt_s_b(pws->b[10], pwt->b[10]);
1898     pwd->b[11] = msa_clt_s_b(pws->b[11], pwt->b[11]);
1899     pwd->b[12] = msa_clt_s_b(pws->b[12], pwt->b[12]);
1900     pwd->b[13] = msa_clt_s_b(pws->b[13], pwt->b[13]);
1901     pwd->b[14] = msa_clt_s_b(pws->b[14], pwt->b[14]);
1902     pwd->b[15] = msa_clt_s_b(pws->b[15], pwt->b[15]);
1903 }
1904
1905 static inline int16_t msa_clt_s_h(int16_t arg1, int16_t arg2)
1906 {
1907     return arg1 < arg2 ? -1 : 0;
1908 }
1909
1910 void helper_msa_clt_s_h(CPUMIPSState *env,
1911                         uint32_t wd, uint32_t ws, uint32_t wt)
1912 {
1913     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1914     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1915     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1916
1917     pwd->h[0]  = msa_clt_s_h(pws->h[0],  pwt->h[0]);
1918     pwd->h[1]  = msa_clt_s_h(pws->h[1],  pwt->h[1]);
1919     pwd->h[2]  = msa_clt_s_h(pws->h[2],  pwt->h[2]);
1920     pwd->h[3]  = msa_clt_s_h(pws->h[3],  pwt->h[3]);
1921     pwd->h[4]  = msa_clt_s_h(pws->h[4],  pwt->h[4]);
1922     pwd->h[5]  = msa_clt_s_h(pws->h[5],  pwt->h[5]);
1923     pwd->h[6]  = msa_clt_s_h(pws->h[6],  pwt->h[6]);
1924     pwd->h[7]  = msa_clt_s_h(pws->h[7],  pwt->h[7]);
1925 }
1926
1927 static inline int32_t msa_clt_s_w(int32_t arg1, int32_t arg2)
1928 {
1929     return arg1 < arg2 ? -1 : 0;
1930 }
1931
1932 void helper_msa_clt_s_w(CPUMIPSState *env,
1933                         uint32_t wd, uint32_t ws, uint32_t wt)
1934 {
1935     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1936     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1937     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1938
1939     pwd->w[0]  = msa_clt_s_w(pws->w[0],  pwt->w[0]);
1940     pwd->w[1]  = msa_clt_s_w(pws->w[1],  pwt->w[1]);
1941     pwd->w[2]  = msa_clt_s_w(pws->w[2],  pwt->w[2]);
1942     pwd->w[3]  = msa_clt_s_w(pws->w[3],  pwt->w[3]);
1943 }
1944
1945 static inline int64_t msa_clt_s_d(int64_t arg1, int64_t arg2)
1946 {
1947     return arg1 < arg2 ? -1 : 0;
1948 }
1949
1950 void helper_msa_clt_s_d(CPUMIPSState *env,
1951                         uint32_t wd, uint32_t ws, uint32_t wt)
1952 {
1953     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1954     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1955     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1956
1957     pwd->d[0]  = msa_clt_s_d(pws->d[0],  pwt->d[0]);
1958     pwd->d[1]  = msa_clt_s_d(pws->d[1],  pwt->d[1]);
1959 }
1960
1961 static inline int64_t msa_clt_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1962 {
1963     uint64_t u_arg1 = UNSIGNED(arg1, df);
1964     uint64_t u_arg2 = UNSIGNED(arg2, df);
1965     return u_arg1 < u_arg2 ? -1 : 0;
1966 }
1967
1968 void helper_msa_clt_u_b(CPUMIPSState *env,
1969                         uint32_t wd, uint32_t ws, uint32_t wt)
1970 {
1971     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1972     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1973     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1974
1975     pwd->b[0]  = msa_clt_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1976     pwd->b[1]  = msa_clt_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1977     pwd->b[2]  = msa_clt_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1978     pwd->b[3]  = msa_clt_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1979     pwd->b[4]  = msa_clt_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1980     pwd->b[5]  = msa_clt_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1981     pwd->b[6]  = msa_clt_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1982     pwd->b[7]  = msa_clt_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1983     pwd->b[8]  = msa_clt_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1984     pwd->b[9]  = msa_clt_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1985     pwd->b[10] = msa_clt_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1986     pwd->b[11] = msa_clt_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1987     pwd->b[12] = msa_clt_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1988     pwd->b[13] = msa_clt_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1989     pwd->b[14] = msa_clt_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1990     pwd->b[15] = msa_clt_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1991 }
1992
1993 void helper_msa_clt_u_h(CPUMIPSState *env,
1994                         uint32_t wd, uint32_t ws, uint32_t wt)
1995 {
1996     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1997     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1998     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1999
2000     pwd->h[0]  = msa_clt_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
2001     pwd->h[1]  = msa_clt_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
2002     pwd->h[2]  = msa_clt_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
2003     pwd->h[3]  = msa_clt_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
2004     pwd->h[4]  = msa_clt_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
2005     pwd->h[5]  = msa_clt_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
2006     pwd->h[6]  = msa_clt_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
2007     pwd->h[7]  = msa_clt_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
2008 }
2009
2010 void helper_msa_clt_u_w(CPUMIPSState *env,
2011                         uint32_t wd, uint32_t ws, uint32_t wt)
2012 {
2013     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2014     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2015     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2016
2017     pwd->w[0]  = msa_clt_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
2018     pwd->w[1]  = msa_clt_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
2019     pwd->w[2]  = msa_clt_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
2020     pwd->w[3]  = msa_clt_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
2021 }
2022
2023 void helper_msa_clt_u_d(CPUMIPSState *env,
2024                         uint32_t wd, uint32_t ws, uint32_t wt)
2025 {
2026     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2027     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2028     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2029
2030     pwd->d[0]  = msa_clt_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2031     pwd->d[1]  = msa_clt_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2032 }
2033
2034
2035 /*
2036  * Int Divide
2037  * ----------
2038  *
2039  * +---------------+----------------------------------------------------------+
2040  * | DIV_S.B       | Vector Signed Divide (byte)                              |
2041  * | DIV_S.H       | Vector Signed Divide (halfword)                          |
2042  * | DIV_S.W       | Vector Signed Divide (word)                              |
2043  * | DIV_S.D       | Vector Signed Divide (doubleword)                        |
2044  * | DIV_U.B       | Vector Unsigned Divide (byte)                            |
2045  * | DIV_U.H       | Vector Unsigned Divide (halfword)                        |
2046  * | DIV_U.W       | Vector Unsigned Divide (word)                            |
2047  * | DIV_U.D       | Vector Unsigned Divide (doubleword)                      |
2048  * +---------------+----------------------------------------------------------+
2049  */
2050
2051
2052 static inline int64_t msa_div_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2053 {
2054     if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
2055         return DF_MIN_INT(df);
2056     }
2057     return arg2 ? arg1 / arg2
2058                 : arg1 >= 0 ? -1 : 1;
2059 }
2060
2061 void helper_msa_div_s_b(CPUMIPSState *env,
2062                         uint32_t wd, uint32_t ws, uint32_t wt)
2063 {
2064     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2065     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2066     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2067
2068     pwd->b[0]  = msa_div_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2069     pwd->b[1]  = msa_div_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2070     pwd->b[2]  = msa_div_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2071     pwd->b[3]  = msa_div_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2072     pwd->b[4]  = msa_div_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2073     pwd->b[5]  = msa_div_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2074     pwd->b[6]  = msa_div_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2075     pwd->b[7]  = msa_div_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2076     pwd->b[8]  = msa_div_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2077     pwd->b[9]  = msa_div_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2078     pwd->b[10] = msa_div_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2079     pwd->b[11] = msa_div_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2080     pwd->b[12] = msa_div_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2081     pwd->b[13] = msa_div_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2082     pwd->b[14] = msa_div_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2083     pwd->b[15] = msa_div_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2084 }
2085
2086 void helper_msa_div_s_h(CPUMIPSState *env,
2087                         uint32_t wd, uint32_t ws, uint32_t wt)
2088 {
2089     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2090     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2091     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2092
2093     pwd->h[0]  = msa_div_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
2094     pwd->h[1]  = msa_div_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
2095     pwd->h[2]  = msa_div_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
2096     pwd->h[3]  = msa_div_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
2097     pwd->h[4]  = msa_div_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
2098     pwd->h[5]  = msa_div_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
2099     pwd->h[6]  = msa_div_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
2100     pwd->h[7]  = msa_div_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
2101 }
2102
2103 void helper_msa_div_s_w(CPUMIPSState *env,
2104                         uint32_t wd, uint32_t ws, uint32_t wt)
2105 {
2106     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2107     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2108     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2109
2110     pwd->w[0]  = msa_div_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
2111     pwd->w[1]  = msa_div_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
2112     pwd->w[2]  = msa_div_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
2113     pwd->w[3]  = msa_div_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
2114 }
2115
2116 void helper_msa_div_s_d(CPUMIPSState *env,
2117                         uint32_t wd, uint32_t ws, uint32_t wt)
2118 {
2119     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2120     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2121     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2122
2123     pwd->d[0]  = msa_div_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2124     pwd->d[1]  = msa_div_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2125 }
2126
2127 static inline int64_t msa_div_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2128 {
2129     uint64_t u_arg1 = UNSIGNED(arg1, df);
2130     uint64_t u_arg2 = UNSIGNED(arg2, df);
2131     return arg2 ? u_arg1 / u_arg2 : -1;
2132 }
2133
2134 void helper_msa_div_u_b(CPUMIPSState *env,
2135                         uint32_t wd, uint32_t ws, uint32_t wt)
2136 {
2137     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2138     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2139     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2140
2141     pwd->b[0]  = msa_div_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2142     pwd->b[1]  = msa_div_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2143     pwd->b[2]  = msa_div_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2144     pwd->b[3]  = msa_div_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2145     pwd->b[4]  = msa_div_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2146     pwd->b[5]  = msa_div_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2147     pwd->b[6]  = msa_div_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2148     pwd->b[7]  = msa_div_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2149     pwd->b[8]  = msa_div_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2150     pwd->b[9]  = msa_div_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2151     pwd->b[10] = msa_div_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2152     pwd->b[11] = msa_div_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2153     pwd->b[12] = msa_div_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2154     pwd->b[13] = msa_div_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2155     pwd->b[14] = msa_div_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2156     pwd->b[15] = msa_div_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2157 }
2158
2159 void helper_msa_div_u_h(CPUMIPSState *env,
2160                         uint32_t wd, uint32_t ws, uint32_t wt)
2161 {
2162     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2163     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2164     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2165
2166     pwd->h[0]  = msa_div_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
2167     pwd->h[1]  = msa_div_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
2168     pwd->h[2]  = msa_div_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
2169     pwd->h[3]  = msa_div_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
2170     pwd->h[4]  = msa_div_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
2171     pwd->h[5]  = msa_div_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
2172     pwd->h[6]  = msa_div_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
2173     pwd->h[7]  = msa_div_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
2174 }
2175
2176 void helper_msa_div_u_w(CPUMIPSState *env,
2177                         uint32_t wd, uint32_t ws, uint32_t wt)
2178 {
2179     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2180     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2181     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2182
2183     pwd->w[0]  = msa_div_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
2184     pwd->w[1]  = msa_div_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
2185     pwd->w[2]  = msa_div_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
2186     pwd->w[3]  = msa_div_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
2187 }
2188
2189 void helper_msa_div_u_d(CPUMIPSState *env,
2190                         uint32_t wd, uint32_t ws, uint32_t wt)
2191 {
2192     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2193     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2194     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2195
2196     pwd->d[0]  = msa_div_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2197     pwd->d[1]  = msa_div_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2198 }
2199
2200
2201 /*
2202  * Int Dot Product
2203  * ---------------
2204  *
2205  * +---------------+----------------------------------------------------------+
2206  * | DOTP_S.H      | Vector Signed Dot Product (halfword)                     |
2207  * | DOTP_S.W      | Vector Signed Dot Product (word)                         |
2208  * | DOTP_S.D      | Vector Signed Dot Product (doubleword)                   |
2209  * | DOTP_U.H      | Vector Unsigned Dot Product (halfword)                   |
2210  * | DOTP_U.W      | Vector Unsigned Dot Product (word)                       |
2211  * | DOTP_U.D      | Vector Unsigned Dot Product (doubleword)                 |
2212  * | DPADD_S.H     | Vector Signed Dot Product (halfword)                     |
2213  * | DPADD_S.W     | Vector Signed Dot Product (word)                         |
2214  * | DPADD_S.D     | Vector Signed Dot Product (doubleword)                   |
2215  * | DPADD_U.H     | Vector Unsigned Dot Product (halfword)                   |
2216  * | DPADD_U.W     | Vector Unsigned Dot Product (word)                       |
2217  * | DPADD_U.D     | Vector Unsigned Dot Product (doubleword)                 |
2218  * | DPSUB_S.H     | Vector Signed Dot Product (halfword)                     |
2219  * | DPSUB_S.W     | Vector Signed Dot Product (word)                         |
2220  * | DPSUB_S.D     | Vector Signed Dot Product (doubleword)                   |
2221  * | DPSUB_U.H     | Vector Unsigned Dot Product (halfword)                   |
2222  * | DPSUB_U.W     | Vector Unsigned Dot Product (word)                       |
2223  * | DPSUB_U.D     | Vector Unsigned Dot Product (doubleword)                 |
2224  * +---------------+----------------------------------------------------------+
2225  */
2226
2227 /* TODO: insert Int Dot Product group helpers here */
2228
2229
2230 /*
2231  * Int Max Min
2232  * -----------
2233  *
2234  * +---------------+----------------------------------------------------------+
2235  * | MAX_A.B       | Vector Maximum Based on Absolute Value (byte)            |
2236  * | MAX_A.H       | Vector Maximum Based on Absolute Value (halfword)        |
2237  * | MAX_A.W       | Vector Maximum Based on Absolute Value (word)            |
2238  * | MAX_A.D       | Vector Maximum Based on Absolute Value (doubleword)      |
2239  * | MAX_S.B       | Vector Signed Maximum (byte)                             |
2240  * | MAX_S.H       | Vector Signed Maximum (halfword)                         |
2241  * | MAX_S.W       | Vector Signed Maximum (word)                             |
2242  * | MAX_S.D       | Vector Signed Maximum (doubleword)                       |
2243  * | MAX_U.B       | Vector Unsigned Maximum (byte)                           |
2244  * | MAX_U.H       | Vector Unsigned Maximum (halfword)                       |
2245  * | MAX_U.W       | Vector Unsigned Maximum (word)                           |
2246  * | MAX_U.D       | Vector Unsigned Maximum (doubleword)                     |
2247  * | MIN_A.B       | Vector Minimum Based on Absolute Value (byte)            |
2248  * | MIN_A.H       | Vector Minimum Based on Absolute Value (halfword)        |
2249  * | MIN_A.W       | Vector Minimum Based on Absolute Value (word)            |
2250  * | MIN_A.D       | Vector Minimum Based on Absolute Value (doubleword)      |
2251  * | MIN_S.B       | Vector Signed Minimum (byte)                             |
2252  * | MIN_S.H       | Vector Signed Minimum (halfword)                         |
2253  * | MIN_S.W       | Vector Signed Minimum (word)                             |
2254  * | MIN_S.D       | Vector Signed Minimum (doubleword)                       |
2255  * | MIN_U.B       | Vector Unsigned Minimum (byte)                           |
2256  * | MIN_U.H       | Vector Unsigned Minimum (halfword)                       |
2257  * | MIN_U.W       | Vector Unsigned Minimum (word)                           |
2258  * | MIN_U.D       | Vector Unsigned Minimum (doubleword)                     |
2259  * +---------------+----------------------------------------------------------+
2260  */
2261
2262 static inline int64_t msa_max_a_df(uint32_t df, int64_t arg1, int64_t arg2)
2263 {
2264     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
2265     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
2266     return abs_arg1 > abs_arg2 ? arg1 : arg2;
2267 }
2268
2269 void helper_msa_max_a_b(CPUMIPSState *env,
2270                         uint32_t wd, uint32_t ws, uint32_t wt)
2271 {
2272     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2273     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2274     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2275
2276     pwd->b[0]  = msa_max_a_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2277     pwd->b[1]  = msa_max_a_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2278     pwd->b[2]  = msa_max_a_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2279     pwd->b[3]  = msa_max_a_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2280     pwd->b[4]  = msa_max_a_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2281     pwd->b[5]  = msa_max_a_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2282     pwd->b[6]  = msa_max_a_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2283     pwd->b[7]  = msa_max_a_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2284     pwd->b[8]  = msa_max_a_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2285     pwd->b[9]  = msa_max_a_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2286     pwd->b[10] = msa_max_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
2287     pwd->b[11] = msa_max_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
2288     pwd->b[12] = msa_max_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
2289     pwd->b[13] = msa_max_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
2290     pwd->b[14] = msa_max_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
2291     pwd->b[15] = msa_max_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
2292 }
2293
2294 void helper_msa_max_a_h(CPUMIPSState *env,
2295                         uint32_t wd, uint32_t ws, uint32_t wt)
2296 {
2297     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2298     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2299     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2300
2301     pwd->h[0]  = msa_max_a_df(DF_HALF, pws->h[0],  pwt->h[0]);
2302     pwd->h[1]  = msa_max_a_df(DF_HALF, pws->h[1],  pwt->h[1]);
2303     pwd->h[2]  = msa_max_a_df(DF_HALF, pws->h[2],  pwt->h[2]);
2304     pwd->h[3]  = msa_max_a_df(DF_HALF, pws->h[3],  pwt->h[3]);
2305     pwd->h[4]  = msa_max_a_df(DF_HALF, pws->h[4],  pwt->h[4]);
2306     pwd->h[5]  = msa_max_a_df(DF_HALF, pws->h[5],  pwt->h[5]);
2307     pwd->h[6]  = msa_max_a_df(DF_HALF, pws->h[6],  pwt->h[6]);
2308     pwd->h[7]  = msa_max_a_df(DF_HALF, pws->h[7],  pwt->h[7]);
2309 }
2310
2311 void helper_msa_max_a_w(CPUMIPSState *env,
2312                         uint32_t wd, uint32_t ws, uint32_t wt)
2313 {
2314     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2315     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2316     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2317
2318     pwd->w[0]  = msa_max_a_df(DF_WORD, pws->w[0],  pwt->w[0]);
2319     pwd->w[1]  = msa_max_a_df(DF_WORD, pws->w[1],  pwt->w[1]);
2320     pwd->w[2]  = msa_max_a_df(DF_WORD, pws->w[2],  pwt->w[2]);
2321     pwd->w[3]  = msa_max_a_df(DF_WORD, pws->w[3],  pwt->w[3]);
2322 }
2323
2324 void helper_msa_max_a_d(CPUMIPSState *env,
2325                         uint32_t wd, uint32_t ws, uint32_t wt)
2326 {
2327     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2328     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2329     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2330
2331     pwd->d[0]  = msa_max_a_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2332     pwd->d[1]  = msa_max_a_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2333 }
2334
2335
2336 static inline int64_t msa_max_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2337 {
2338     return arg1 > arg2 ? arg1 : arg2;
2339 }
2340
2341 void helper_msa_max_s_b(CPUMIPSState *env,
2342                         uint32_t wd, uint32_t ws, uint32_t wt)
2343 {
2344     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2345     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2346     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2347
2348     pwd->b[0]  = msa_max_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2349     pwd->b[1]  = msa_max_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2350     pwd->b[2]  = msa_max_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2351     pwd->b[3]  = msa_max_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2352     pwd->b[4]  = msa_max_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2353     pwd->b[5]  = msa_max_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2354     pwd->b[6]  = msa_max_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2355     pwd->b[7]  = msa_max_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2356     pwd->b[8]  = msa_max_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2357     pwd->b[9]  = msa_max_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2358     pwd->b[10] = msa_max_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2359     pwd->b[11] = msa_max_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2360     pwd->b[12] = msa_max_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2361     pwd->b[13] = msa_max_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2362     pwd->b[14] = msa_max_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2363     pwd->b[15] = msa_max_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2364 }
2365
2366 void helper_msa_max_s_h(CPUMIPSState *env,
2367                         uint32_t wd, uint32_t ws, uint32_t wt)
2368 {
2369     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2370     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2371     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2372
2373     pwd->h[0]  = msa_max_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
2374     pwd->h[1]  = msa_max_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
2375     pwd->h[2]  = msa_max_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
2376     pwd->h[3]  = msa_max_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
2377     pwd->h[4]  = msa_max_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
2378     pwd->h[5]  = msa_max_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
2379     pwd->h[6]  = msa_max_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
2380     pwd->h[7]  = msa_max_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
2381 }
2382
2383 void helper_msa_max_s_w(CPUMIPSState *env,
2384                         uint32_t wd, uint32_t ws, uint32_t wt)
2385 {
2386     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2387     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2388     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2389
2390     pwd->w[0]  = msa_max_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
2391     pwd->w[1]  = msa_max_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
2392     pwd->w[2]  = msa_max_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
2393     pwd->w[3]  = msa_max_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
2394 }
2395
2396 void helper_msa_max_s_d(CPUMIPSState *env,
2397                         uint32_t wd, uint32_t ws, uint32_t wt)
2398 {
2399     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2400     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2401     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2402
2403     pwd->d[0]  = msa_max_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2404     pwd->d[1]  = msa_max_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2405 }
2406
2407
2408 static inline int64_t msa_max_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2409 {
2410     uint64_t u_arg1 = UNSIGNED(arg1, df);
2411     uint64_t u_arg2 = UNSIGNED(arg2, df);
2412     return u_arg1 > u_arg2 ? arg1 : arg2;
2413 }
2414
2415 void helper_msa_max_u_b(CPUMIPSState *env,
2416                         uint32_t wd, uint32_t ws, uint32_t wt)
2417 {
2418     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2419     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2420     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2421
2422     pwd->b[0]  = msa_max_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2423     pwd->b[1]  = msa_max_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2424     pwd->b[2]  = msa_max_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2425     pwd->b[3]  = msa_max_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2426     pwd->b[4]  = msa_max_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2427     pwd->b[5]  = msa_max_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2428     pwd->b[6]  = msa_max_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2429     pwd->b[7]  = msa_max_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2430     pwd->b[8]  = msa_max_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2431     pwd->b[9]  = msa_max_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2432     pwd->b[10] = msa_max_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2433     pwd->b[11] = msa_max_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2434     pwd->b[12] = msa_max_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2435     pwd->b[13] = msa_max_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2436     pwd->b[14] = msa_max_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2437     pwd->b[15] = msa_max_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2438 }
2439
2440 void helper_msa_max_u_h(CPUMIPSState *env,
2441                         uint32_t wd, uint32_t ws, uint32_t wt)
2442 {
2443     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2444     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2445     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2446
2447     pwd->h[0]  = msa_max_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
2448     pwd->h[1]  = msa_max_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
2449     pwd->h[2]  = msa_max_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
2450     pwd->h[3]  = msa_max_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
2451     pwd->h[4]  = msa_max_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
2452     pwd->h[5]  = msa_max_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
2453     pwd->h[6]  = msa_max_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
2454     pwd->h[7]  = msa_max_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
2455 }
2456
2457 void helper_msa_max_u_w(CPUMIPSState *env,
2458                         uint32_t wd, uint32_t ws, uint32_t wt)
2459 {
2460     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2461     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2462     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2463
2464     pwd->w[0]  = msa_max_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
2465     pwd->w[1]  = msa_max_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
2466     pwd->w[2]  = msa_max_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
2467     pwd->w[3]  = msa_max_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
2468 }
2469
2470 void helper_msa_max_u_d(CPUMIPSState *env,
2471                         uint32_t wd, uint32_t ws, uint32_t wt)
2472 {
2473     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2474     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2475     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2476
2477     pwd->d[0]  = msa_max_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2478     pwd->d[1]  = msa_max_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2479 }
2480
2481
2482 static inline int64_t msa_min_a_df(uint32_t df, int64_t arg1, int64_t arg2)
2483 {
2484     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
2485     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
2486     return abs_arg1 < abs_arg2 ? arg1 : arg2;
2487 }
2488
2489 void helper_msa_min_a_b(CPUMIPSState *env,
2490                         uint32_t wd, uint32_t ws, uint32_t wt)
2491 {
2492     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2493     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2494     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2495
2496     pwd->b[0]  = msa_min_a_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2497     pwd->b[1]  = msa_min_a_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2498     pwd->b[2]  = msa_min_a_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2499     pwd->b[3]  = msa_min_a_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2500     pwd->b[4]  = msa_min_a_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2501     pwd->b[5]  = msa_min_a_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2502     pwd->b[6]  = msa_min_a_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2503     pwd->b[7]  = msa_min_a_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2504     pwd->b[8]  = msa_min_a_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2505     pwd->b[9]  = msa_min_a_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2506     pwd->b[10] = msa_min_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
2507     pwd->b[11] = msa_min_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
2508     pwd->b[12] = msa_min_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
2509     pwd->b[13] = msa_min_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
2510     pwd->b[14] = msa_min_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
2511     pwd->b[15] = msa_min_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
2512 }
2513
2514 void helper_msa_min_a_h(CPUMIPSState *env,
2515                         uint32_t wd, uint32_t ws, uint32_t wt)
2516 {
2517     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2518     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2519     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2520
2521     pwd->h[0]  = msa_min_a_df(DF_HALF, pws->h[0],  pwt->h[0]);
2522     pwd->h[1]  = msa_min_a_df(DF_HALF, pws->h[1],  pwt->h[1]);
2523     pwd->h[2]  = msa_min_a_df(DF_HALF, pws->h[2],  pwt->h[2]);
2524     pwd->h[3]  = msa_min_a_df(DF_HALF, pws->h[3],  pwt->h[3]);
2525     pwd->h[4]  = msa_min_a_df(DF_HALF, pws->h[4],  pwt->h[4]);
2526     pwd->h[5]  = msa_min_a_df(DF_HALF, pws->h[5],  pwt->h[5]);
2527     pwd->h[6]  = msa_min_a_df(DF_HALF, pws->h[6],  pwt->h[6]);
2528     pwd->h[7]  = msa_min_a_df(DF_HALF, pws->h[7],  pwt->h[7]);
2529 }
2530
2531 void helper_msa_min_a_w(CPUMIPSState *env,
2532                         uint32_t wd, uint32_t ws, uint32_t wt)
2533 {
2534     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2535     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2536     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2537
2538     pwd->w[0]  = msa_min_a_df(DF_WORD, pws->w[0],  pwt->w[0]);
2539     pwd->w[1]  = msa_min_a_df(DF_WORD, pws->w[1],  pwt->w[1]);
2540     pwd->w[2]  = msa_min_a_df(DF_WORD, pws->w[2],  pwt->w[2]);
2541     pwd->w[3]  = msa_min_a_df(DF_WORD, pws->w[3],  pwt->w[3]);
2542 }
2543
2544 void helper_msa_min_a_d(CPUMIPSState *env,
2545                         uint32_t wd, uint32_t ws, uint32_t wt)
2546 {
2547     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2548     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2549     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2550
2551     pwd->d[0]  = msa_min_a_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2552     pwd->d[1]  = msa_min_a_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2553 }
2554
2555
2556 static inline int64_t msa_min_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2557 {
2558     return arg1 < arg2 ? arg1 : arg2;
2559 }
2560
2561 void helper_msa_min_s_b(CPUMIPSState *env,
2562                         uint32_t wd, uint32_t ws, uint32_t wt)
2563 {
2564     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2565     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2566     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2567
2568     pwd->b[0]  = msa_min_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2569     pwd->b[1]  = msa_min_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2570     pwd->b[2]  = msa_min_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2571     pwd->b[3]  = msa_min_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2572     pwd->b[4]  = msa_min_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2573     pwd->b[5]  = msa_min_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2574     pwd->b[6]  = msa_min_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2575     pwd->b[7]  = msa_min_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2576     pwd->b[8]  = msa_min_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2577     pwd->b[9]  = msa_min_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2578     pwd->b[10] = msa_min_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2579     pwd->b[11] = msa_min_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2580     pwd->b[12] = msa_min_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2581     pwd->b[13] = msa_min_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2582     pwd->b[14] = msa_min_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2583     pwd->b[15] = msa_min_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2584 }
2585
2586 void helper_msa_min_s_h(CPUMIPSState *env,
2587                         uint32_t wd, uint32_t ws, uint32_t wt)
2588 {
2589     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2590     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2591     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2592
2593     pwd->h[0]  = msa_min_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
2594     pwd->h[1]  = msa_min_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
2595     pwd->h[2]  = msa_min_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
2596     pwd->h[3]  = msa_min_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
2597     pwd->h[4]  = msa_min_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
2598     pwd->h[5]  = msa_min_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
2599     pwd->h[6]  = msa_min_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
2600     pwd->h[7]  = msa_min_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
2601 }
2602
2603 void helper_msa_min_s_w(CPUMIPSState *env,
2604                         uint32_t wd, uint32_t ws, uint32_t wt)
2605 {
2606     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2607     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2608     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2609
2610     pwd->w[0]  = msa_min_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
2611     pwd->w[1]  = msa_min_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
2612     pwd->w[2]  = msa_min_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
2613     pwd->w[3]  = msa_min_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
2614 }
2615
2616 void helper_msa_min_s_d(CPUMIPSState *env,
2617                         uint32_t wd, uint32_t ws, uint32_t wt)
2618 {
2619     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2620     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2621     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2622
2623     pwd->d[0]  = msa_min_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2624     pwd->d[1]  = msa_min_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2625 }
2626
2627
2628 static inline int64_t msa_min_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2629 {
2630     uint64_t u_arg1 = UNSIGNED(arg1, df);
2631     uint64_t u_arg2 = UNSIGNED(arg2, df);
2632     return u_arg1 < u_arg2 ? arg1 : arg2;
2633 }
2634
2635 void helper_msa_min_u_b(CPUMIPSState *env,
2636                         uint32_t wd, uint32_t ws, uint32_t wt)
2637 {
2638     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2639     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2640     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2641
2642     pwd->b[0]  = msa_min_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2643     pwd->b[1]  = msa_min_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2644     pwd->b[2]  = msa_min_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2645     pwd->b[3]  = msa_min_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2646     pwd->b[4]  = msa_min_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2647     pwd->b[5]  = msa_min_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2648     pwd->b[6]  = msa_min_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2649     pwd->b[7]  = msa_min_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2650     pwd->b[8]  = msa_min_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2651     pwd->b[9]  = msa_min_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2652     pwd->b[10] = msa_min_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2653     pwd->b[11] = msa_min_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2654     pwd->b[12] = msa_min_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2655     pwd->b[13] = msa_min_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2656     pwd->b[14] = msa_min_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2657     pwd->b[15] = msa_min_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2658 }
2659
2660 void helper_msa_min_u_h(CPUMIPSState *env,
2661                         uint32_t wd, uint32_t ws, uint32_t wt)
2662 {
2663     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2664     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2665     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2666
2667     pwd->h[0]  = msa_min_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
2668     pwd->h[1]  = msa_min_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
2669     pwd->h[2]  = msa_min_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
2670     pwd->h[3]  = msa_min_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
2671     pwd->h[4]  = msa_min_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
2672     pwd->h[5]  = msa_min_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
2673     pwd->h[6]  = msa_min_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
2674     pwd->h[7]  = msa_min_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
2675 }
2676
2677 void helper_msa_min_u_w(CPUMIPSState *env,
2678                         uint32_t wd, uint32_t ws, uint32_t wt)
2679 {
2680     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2681     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2682     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2683
2684     pwd->w[0]  = msa_min_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
2685     pwd->w[1]  = msa_min_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
2686     pwd->w[2]  = msa_min_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
2687     pwd->w[3]  = msa_min_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
2688 }
2689
2690 void helper_msa_min_u_d(CPUMIPSState *env,
2691                         uint32_t wd, uint32_t ws, uint32_t wt)
2692 {
2693     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2694     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2695     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2696
2697     pwd->d[0]  = msa_min_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2698     pwd->d[1]  = msa_min_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2699 }
2700
2701
2702 /*
2703  * Int Modulo
2704  * ----------
2705  *
2706  * +---------------+----------------------------------------------------------+
2707  * | MOD_S.B       | Vector Signed Modulo (byte)                              |
2708  * | MOD_S.H       | Vector Signed Modulo (halfword)                          |
2709  * | MOD_S.W       | Vector Signed Modulo (word)                              |
2710  * | MOD_S.D       | Vector Signed Modulo (doubleword)                        |
2711  * | MOD_U.B       | Vector Unsigned Modulo (byte)                            |
2712  * | MOD_U.H       | Vector Unsigned Modulo (halfword)                        |
2713  * | MOD_U.W       | Vector Unsigned Modulo (word)                            |
2714  * | MOD_U.D       | Vector Unsigned Modulo (doubleword)                      |
2715  * +---------------+----------------------------------------------------------+
2716  */
2717
2718 static inline int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2719 {
2720     if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
2721         return 0;
2722     }
2723     return arg2 ? arg1 % arg2 : arg1;
2724 }
2725
2726 void helper_msa_mod_s_b(CPUMIPSState *env,
2727                         uint32_t wd, uint32_t ws, uint32_t wt)
2728 {
2729     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2730     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2731     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2732
2733     pwd->b[0]  = msa_mod_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2734     pwd->b[1]  = msa_mod_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2735     pwd->b[2]  = msa_mod_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2736     pwd->b[3]  = msa_mod_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2737     pwd->b[4]  = msa_mod_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2738     pwd->b[5]  = msa_mod_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2739     pwd->b[6]  = msa_mod_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2740     pwd->b[7]  = msa_mod_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2741     pwd->b[8]  = msa_mod_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2742     pwd->b[9]  = msa_mod_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2743     pwd->b[10] = msa_mod_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2744     pwd->b[11] = msa_mod_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2745     pwd->b[12] = msa_mod_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2746     pwd->b[13] = msa_mod_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2747     pwd->b[14] = msa_mod_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2748     pwd->b[15] = msa_mod_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2749 }
2750
2751 void helper_msa_mod_s_h(CPUMIPSState *env,
2752                         uint32_t wd, uint32_t ws, uint32_t wt)
2753 {
2754     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2755     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2756     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2757
2758     pwd->h[0]  = msa_mod_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
2759     pwd->h[1]  = msa_mod_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
2760     pwd->h[2]  = msa_mod_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
2761     pwd->h[3]  = msa_mod_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
2762     pwd->h[4]  = msa_mod_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
2763     pwd->h[5]  = msa_mod_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
2764     pwd->h[6]  = msa_mod_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
2765     pwd->h[7]  = msa_mod_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
2766 }
2767
2768 void helper_msa_mod_s_w(CPUMIPSState *env,
2769                         uint32_t wd, uint32_t ws, uint32_t wt)
2770 {
2771     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2772     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2773     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2774
2775     pwd->w[0]  = msa_mod_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
2776     pwd->w[1]  = msa_mod_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
2777     pwd->w[2]  = msa_mod_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
2778     pwd->w[3]  = msa_mod_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
2779 }
2780
2781 void helper_msa_mod_s_d(CPUMIPSState *env,
2782                         uint32_t wd, uint32_t ws, uint32_t wt)
2783 {
2784     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2785     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2786     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2787
2788     pwd->d[0]  = msa_mod_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2789     pwd->d[1]  = msa_mod_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2790 }
2791
2792 static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2793 {
2794     uint64_t u_arg1 = UNSIGNED(arg1, df);
2795     uint64_t u_arg2 = UNSIGNED(arg2, df);
2796     return u_arg2 ? u_arg1 % u_arg2 : u_arg1;
2797 }
2798
2799 void helper_msa_mod_u_b(CPUMIPSState *env,
2800                         uint32_t wd, uint32_t ws, uint32_t wt)
2801 {
2802     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2803     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2804     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2805
2806     pwd->b[0]  = msa_mod_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2807     pwd->b[1]  = msa_mod_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2808     pwd->b[2]  = msa_mod_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2809     pwd->b[3]  = msa_mod_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2810     pwd->b[4]  = msa_mod_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2811     pwd->b[5]  = msa_mod_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2812     pwd->b[6]  = msa_mod_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2813     pwd->b[7]  = msa_mod_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2814     pwd->b[8]  = msa_mod_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2815     pwd->b[9]  = msa_mod_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2816     pwd->b[10] = msa_mod_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2817     pwd->b[11] = msa_mod_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2818     pwd->b[12] = msa_mod_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2819     pwd->b[13] = msa_mod_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2820     pwd->b[14] = msa_mod_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2821     pwd->b[15] = msa_mod_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2822 }
2823
2824 void helper_msa_mod_u_h(CPUMIPSState *env,
2825                         uint32_t wd, uint32_t ws, uint32_t wt)
2826 {
2827     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2828     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2829     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2830
2831     pwd->h[0]  = msa_mod_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
2832     pwd->h[1]  = msa_mod_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
2833     pwd->h[2]  = msa_mod_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
2834     pwd->h[3]  = msa_mod_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
2835     pwd->h[4]  = msa_mod_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
2836     pwd->h[5]  = msa_mod_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
2837     pwd->h[6]  = msa_mod_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
2838     pwd->h[7]  = msa_mod_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
2839 }
2840
2841 void helper_msa_mod_u_w(CPUMIPSState *env,
2842                         uint32_t wd, uint32_t ws, uint32_t wt)
2843 {
2844     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2845     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2846     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2847
2848     pwd->w[0]  = msa_mod_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
2849     pwd->w[1]  = msa_mod_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
2850     pwd->w[2]  = msa_mod_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
2851     pwd->w[3]  = msa_mod_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
2852 }
2853
2854 void helper_msa_mod_u_d(CPUMIPSState *env,
2855                         uint32_t wd, uint32_t ws, uint32_t wt)
2856 {
2857     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2858     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2859     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2860
2861     pwd->d[0]  = msa_mod_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2862     pwd->d[1]  = msa_mod_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2863 }
2864
2865
2866 /*
2867  * Int Multiply
2868  * ------------
2869  *
2870  * +---------------+----------------------------------------------------------+
2871  * | MADDV.B       | Vector Multiply and Add (byte)                           |
2872  * | MADDV.H       | Vector Multiply and Add (halfword)                       |
2873  * | MADDV.W       | Vector Multiply and Add (word)                           |
2874  * | MADDV.D       | Vector Multiply and Add (doubleword)                     |
2875  * | MSUBV.B       | Vector Multiply and Subtract (byte)                      |
2876  * | MSUBV.H       | Vector Multiply and Subtract (halfword)                  |
2877  * | MSUBV.W       | Vector Multiply and Subtract (word)                      |
2878  * | MSUBV.D       | Vector Multiply and Subtract (doubleword)                |
2879  * | MULV.B        | Vector Multiply (byte)                                   |
2880  * | MULV.H        | Vector Multiply (halfword)                               |
2881  * | MULV.W        | Vector Multiply (word)                                   |
2882  * | MULV.D        | Vector Multiply (doubleword)                             |
2883  * +---------------+----------------------------------------------------------+
2884  */
2885
2886 /* TODO: insert Int Multiply group helpers here */
2887
2888
2889 /*
2890  * Int Subtract
2891  * ------------
2892  *
2893  * +---------------+----------------------------------------------------------+
2894  * | ASUB_S.B      | Vector Absolute Values of Signed Subtract (byte)         |
2895  * | ASUB_S.H      | Vector Absolute Values of Signed Subtract (halfword)     |
2896  * | ASUB_S.W      | Vector Absolute Values of Signed Subtract (word)         |
2897  * | ASUB_S.D      | Vector Absolute Values of Signed Subtract (doubleword)   |
2898  * | ASUB_U.B      | Vector Absolute Values of Unsigned Subtract (byte)       |
2899  * | ASUB_U.H      | Vector Absolute Values of Unsigned Subtract (halfword)   |
2900  * | ASUB_U.W      | Vector Absolute Values of Unsigned Subtract (word)       |
2901  * | ASUB_U.D      | Vector Absolute Values of Unsigned Subtract (doubleword) |
2902  * | HSUB_S.H      | Vector Signed Horizontal Subtract (halfword)             |
2903  * | HSUB_S.W      | Vector Signed Horizontal Subtract (word)                 |
2904  * | HSUB_S.D      | Vector Signed Horizontal Subtract (doubleword)           |
2905  * | HSUB_U.H      | Vector Unigned Horizontal Subtract (halfword)            |
2906  * | HSUB_U.W      | Vector Unigned Horizontal Subtract (word)                |
2907  * | HSUB_U.D      | Vector Unigned Horizontal Subtract (doubleword)          |
2908  * | SUBS_S.B      | Vector Signed Saturated Subtract (of Signed) (byte)      |
2909  * | SUBS_S.H      | Vector Signed Saturated Subtract (of Signed) (halfword)  |
2910  * | SUBS_S.W      | Vector Signed Saturated Subtract (of Signed) (word)      |
2911  * | SUBS_S.D      | Vector Signed Saturated Subtract (of Signed) (doubleword)|
2912  * | SUBS_U.B      | Vector Unsigned Saturated Subtract (of Uns.) (byte)      |
2913  * | SUBS_U.H      | Vector Unsigned Saturated Subtract (of Uns.) (halfword)  |
2914  * | SUBS_U.W      | Vector Unsigned Saturated Subtract (of Uns.) (word)      |
2915  * | SUBS_U.D      | Vector Unsigned Saturated Subtract (of Uns.) (doubleword)|
2916  * | SUBSUS_U.B    | Vector Uns. Sat. Subtract (of S. from Uns.) (byte)       |
2917  * | SUBSUS_U.H    | Vector Uns. Sat. Subtract (of S. from Uns.) (halfword)   |
2918  * | SUBSUS_U.W    | Vector Uns. Sat. Subtract (of S. from Uns.) (word)       |
2919  * | SUBSUS_U.D    | Vector Uns. Sat. Subtract (of S. from Uns.) (doubleword) |
2920  * | SUBSUU_S.B    | Vector Signed Saturated Subtract (of Uns.) (byte)        |
2921  * | SUBSUU_S.H    | Vector Signed Saturated Subtract (of Uns.) (halfword)    |
2922  * | SUBSUU_S.W    | Vector Signed Saturated Subtract (of Uns.) (word)        |
2923  * | SUBSUU_S.D    | Vector Signed Saturated Subtract (of Uns.) (doubleword)  |
2924  * | SUBV.B        | Vector Subtract (byte)                                   |
2925  * | SUBV.H        | Vector Subtract (halfword)                               |
2926  * | SUBV.W        | Vector Subtract (word)                                   |
2927  * | SUBV.D        | Vector Subtract (doubleword)                             |
2928  * +---------------+----------------------------------------------------------+
2929  */
2930
2931
2932 static inline int64_t msa_asub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2933 {
2934     /* signed compare */
2935     return (arg1 < arg2) ?
2936         (uint64_t)(arg2 - arg1) : (uint64_t)(arg1 - arg2);
2937 }
2938
2939 void helper_msa_asub_s_b(CPUMIPSState *env,
2940                          uint32_t wd, uint32_t ws, uint32_t wt)
2941 {
2942     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2943     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2944     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2945
2946     pwd->b[0]  = msa_asub_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2947     pwd->b[1]  = msa_asub_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2948     pwd->b[2]  = msa_asub_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2949     pwd->b[3]  = msa_asub_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2950     pwd->b[4]  = msa_asub_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2951     pwd->b[5]  = msa_asub_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2952     pwd->b[6]  = msa_asub_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2953     pwd->b[7]  = msa_asub_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2954     pwd->b[8]  = msa_asub_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2955     pwd->b[9]  = msa_asub_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2956     pwd->b[10] = msa_asub_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2957     pwd->b[11] = msa_asub_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2958     pwd->b[12] = msa_asub_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2959     pwd->b[13] = msa_asub_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2960     pwd->b[14] = msa_asub_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2961     pwd->b[15] = msa_asub_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2962 }
2963
2964 void helper_msa_asub_s_h(CPUMIPSState *env,
2965                          uint32_t wd, uint32_t ws, uint32_t wt)
2966 {
2967     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2968     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2969     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2970
2971     pwd->h[0]  = msa_asub_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
2972     pwd->h[1]  = msa_asub_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
2973     pwd->h[2]  = msa_asub_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
2974     pwd->h[3]  = msa_asub_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
2975     pwd->h[4]  = msa_asub_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
2976     pwd->h[5]  = msa_asub_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
2977     pwd->h[6]  = msa_asub_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
2978     pwd->h[7]  = msa_asub_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
2979 }
2980
2981 void helper_msa_asub_s_w(CPUMIPSState *env,
2982                          uint32_t wd, uint32_t ws, uint32_t wt)
2983 {
2984     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2985     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2986     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2987
2988     pwd->w[0]  = msa_asub_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
2989     pwd->w[1]  = msa_asub_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
2990     pwd->w[2]  = msa_asub_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
2991     pwd->w[3]  = msa_asub_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
2992 }
2993
2994 void helper_msa_asub_s_d(CPUMIPSState *env,
2995                          uint32_t wd, uint32_t ws, uint32_t wt)
2996 {
2997     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2998     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2999     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3000
3001     pwd->d[0]  = msa_asub_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3002     pwd->d[1]  = msa_asub_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3003 }
3004
3005
3006 static inline uint64_t msa_asub_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
3007 {
3008     uint64_t u_arg1 = UNSIGNED(arg1, df);
3009     uint64_t u_arg2 = UNSIGNED(arg2, df);
3010     /* unsigned compare */
3011     return (u_arg1 < u_arg2) ?
3012         (uint64_t)(u_arg2 - u_arg1) : (uint64_t)(u_arg1 - u_arg2);
3013 }
3014
3015 void helper_msa_asub_u_b(CPUMIPSState *env,
3016                          uint32_t wd, uint32_t ws, uint32_t wt)
3017 {
3018     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3019     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3020     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3021
3022     pwd->b[0]  = msa_asub_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
3023     pwd->b[1]  = msa_asub_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
3024     pwd->b[2]  = msa_asub_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
3025     pwd->b[3]  = msa_asub_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
3026     pwd->b[4]  = msa_asub_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
3027     pwd->b[5]  = msa_asub_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
3028     pwd->b[6]  = msa_asub_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
3029     pwd->b[7]  = msa_asub_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
3030     pwd->b[8]  = msa_asub_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
3031     pwd->b[9]  = msa_asub_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
3032     pwd->b[10] = msa_asub_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
3033     pwd->b[11] = msa_asub_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
3034     pwd->b[12] = msa_asub_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
3035     pwd->b[13] = msa_asub_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
3036     pwd->b[14] = msa_asub_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
3037     pwd->b[15] = msa_asub_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
3038 }
3039
3040 void helper_msa_asub_u_h(CPUMIPSState *env,
3041                          uint32_t wd, uint32_t ws, uint32_t wt)
3042 {
3043     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3044     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3045     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3046
3047     pwd->h[0]  = msa_asub_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
3048     pwd->h[1]  = msa_asub_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
3049     pwd->h[2]  = msa_asub_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
3050     pwd->h[3]  = msa_asub_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
3051     pwd->h[4]  = msa_asub_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
3052     pwd->h[5]  = msa_asub_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
3053     pwd->h[6]  = msa_asub_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
3054     pwd->h[7]  = msa_asub_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
3055 }
3056
3057 void helper_msa_asub_u_w(CPUMIPSState *env,
3058                          uint32_t wd, uint32_t ws, uint32_t wt)
3059 {
3060     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3061     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3062     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3063
3064     pwd->w[0]  = msa_asub_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
3065     pwd->w[1]  = msa_asub_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
3066     pwd->w[2]  = msa_asub_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
3067     pwd->w[3]  = msa_asub_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
3068 }
3069
3070 void helper_msa_asub_u_d(CPUMIPSState *env,
3071                          uint32_t wd, uint32_t ws, uint32_t wt)
3072 {
3073     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3074     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3075     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3076
3077     pwd->d[0]  = msa_asub_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3078     pwd->d[1]  = msa_asub_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3079 }
3080
3081
3082 /* TODO: insert the rest of Int Subtract group helpers here */
3083
3084
3085 static inline int64_t msa_hsub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
3086 {
3087     return SIGNED_ODD(arg1, df) - SIGNED_EVEN(arg2, df);
3088 }
3089
3090 void helper_msa_hsub_s_h(CPUMIPSState *env,
3091                          uint32_t wd, uint32_t ws, uint32_t wt)
3092 {
3093     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3094     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3095     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3096
3097     pwd->h[0]  = msa_hsub_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
3098     pwd->h[1]  = msa_hsub_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
3099     pwd->h[2]  = msa_hsub_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
3100     pwd->h[3]  = msa_hsub_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
3101     pwd->h[4]  = msa_hsub_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
3102     pwd->h[5]  = msa_hsub_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
3103     pwd->h[6]  = msa_hsub_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
3104     pwd->h[7]  = msa_hsub_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
3105 }
3106
3107 void helper_msa_hsub_s_w(CPUMIPSState *env,
3108                          uint32_t wd, uint32_t ws, uint32_t wt)
3109 {
3110     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3111     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3112     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3113
3114     pwd->w[0]  = msa_hsub_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
3115     pwd->w[1]  = msa_hsub_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
3116     pwd->w[2]  = msa_hsub_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
3117     pwd->w[3]  = msa_hsub_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
3118 }
3119
3120 void helper_msa_hsub_s_d(CPUMIPSState *env,
3121                          uint32_t wd, uint32_t ws, uint32_t wt)
3122 {
3123     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3124     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3125     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3126
3127     pwd->d[0]  = msa_hsub_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3128     pwd->d[1]  = msa_hsub_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3129 }
3130
3131
3132 static inline int64_t msa_hsub_u_df(uint32_t df, int64_t arg1, int64_t arg2)
3133 {
3134     return UNSIGNED_ODD(arg1, df) - UNSIGNED_EVEN(arg2, df);
3135 }
3136
3137 void helper_msa_hsub_u_h(CPUMIPSState *env,
3138                          uint32_t wd, uint32_t ws, uint32_t wt)
3139 {
3140     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3141     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3142     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3143
3144     pwd->h[0]  = msa_hsub_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
3145     pwd->h[1]  = msa_hsub_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
3146     pwd->h[2]  = msa_hsub_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
3147     pwd->h[3]  = msa_hsub_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
3148     pwd->h[4]  = msa_hsub_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
3149     pwd->h[5]  = msa_hsub_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
3150     pwd->h[6]  = msa_hsub_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
3151     pwd->h[7]  = msa_hsub_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
3152 }
3153
3154 void helper_msa_hsub_u_w(CPUMIPSState *env,
3155                          uint32_t wd, uint32_t ws, uint32_t wt)
3156 {
3157     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3158     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3159     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3160
3161     pwd->w[0]  = msa_hsub_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
3162     pwd->w[1]  = msa_hsub_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
3163     pwd->w[2]  = msa_hsub_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
3164     pwd->w[3]  = msa_hsub_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
3165 }
3166
3167 void helper_msa_hsub_u_d(CPUMIPSState *env,
3168                          uint32_t wd, uint32_t ws, uint32_t wt)
3169 {
3170     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3171     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3172     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3173
3174     pwd->d[0]  = msa_hsub_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3175     pwd->d[1]  = msa_hsub_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3176 }
3177
3178
3179 /*
3180  * Interleave
3181  * ----------
3182  *
3183  * +---------------+----------------------------------------------------------+
3184  * | ILVEV.B       | Vector Interleave Even (byte)                            |
3185  * | ILVEV.H       | Vector Interleave Even (halfword)                        |
3186  * | ILVEV.W       | Vector Interleave Even (word)                            |
3187  * | ILVEV.D       | Vector Interleave Even (doubleword)                      |
3188  * | ILVOD.B       | Vector Interleave Odd (byte)                             |
3189  * | ILVOD.H       | Vector Interleave Odd (halfword)                         |
3190  * | ILVOD.W       | Vector Interleave Odd (word)                             |
3191  * | ILVOD.D       | Vector Interleave Odd (doubleword)                       |
3192  * | ILVL.B        | Vector Interleave Left (byte)                            |
3193  * | ILVL.H        | Vector Interleave Left (halfword)                        |
3194  * | ILVL.W        | Vector Interleave Left (word)                            |
3195  * | ILVL.D        | Vector Interleave Left (doubleword)                      |
3196  * | ILVR.B        | Vector Interleave Right (byte)                           |
3197  * | ILVR.H        | Vector Interleave Right (halfword)                       |
3198  * | ILVR.W        | Vector Interleave Right (word)                           |
3199  * | ILVR.D        | Vector Interleave Right (doubleword)                     |
3200  * +---------------+----------------------------------------------------------+
3201  */
3202
3203
3204 void helper_msa_ilvev_b(CPUMIPSState *env,
3205                         uint32_t wd, uint32_t ws, uint32_t wt)
3206 {
3207     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3208     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3209     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3210
3211 #if defined(HOST_WORDS_BIGENDIAN)
3212     pwd->b[8]  = pws->b[9];
3213     pwd->b[9]  = pwt->b[9];
3214     pwd->b[10] = pws->b[11];
3215     pwd->b[11] = pwt->b[11];
3216     pwd->b[12] = pws->b[13];
3217     pwd->b[13] = pwt->b[13];
3218     pwd->b[14] = pws->b[15];
3219     pwd->b[15] = pwt->b[15];
3220     pwd->b[0]  = pws->b[1];
3221     pwd->b[1]  = pwt->b[1];
3222     pwd->b[2]  = pws->b[3];
3223     pwd->b[3]  = pwt->b[3];
3224     pwd->b[4]  = pws->b[5];
3225     pwd->b[5]  = pwt->b[5];
3226     pwd->b[6]  = pws->b[7];
3227     pwd->b[7]  = pwt->b[7];
3228 #else
3229     pwd->b[15] = pws->b[14];
3230     pwd->b[14] = pwt->b[14];
3231     pwd->b[13] = pws->b[12];
3232     pwd->b[12] = pwt->b[12];
3233     pwd->b[11] = pws->b[10];
3234     pwd->b[10] = pwt->b[10];
3235     pwd->b[9]  = pws->b[8];
3236     pwd->b[8]  = pwt->b[8];
3237     pwd->b[7]  = pws->b[6];
3238     pwd->b[6]  = pwt->b[6];
3239     pwd->b[5]  = pws->b[4];
3240     pwd->b[4]  = pwt->b[4];
3241     pwd->b[3]  = pws->b[2];
3242     pwd->b[2]  = pwt->b[2];
3243     pwd->b[1]  = pws->b[0];
3244     pwd->b[0]  = pwt->b[0];
3245 #endif
3246 }
3247
3248 void helper_msa_ilvev_h(CPUMIPSState *env,
3249                         uint32_t wd, uint32_t ws, uint32_t wt)
3250 {
3251     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3252     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3253     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3254
3255 #if defined(HOST_WORDS_BIGENDIAN)
3256     pwd->h[4] = pws->h[5];
3257     pwd->h[5] = pwt->h[5];
3258     pwd->h[6] = pws->h[7];
3259     pwd->h[7] = pwt->h[7];
3260     pwd->h[0] = pws->h[1];
3261     pwd->h[1] = pwt->h[1];
3262     pwd->h[2] = pws->h[3];
3263     pwd->h[3] = pwt->h[3];
3264 #else
3265     pwd->h[7] = pws->h[6];
3266     pwd->h[6] = pwt->h[6];
3267     pwd->h[5] = pws->h[4];
3268     pwd->h[4] = pwt->h[4];
3269     pwd->h[3] = pws->h[2];
3270     pwd->h[2] = pwt->h[2];
3271     pwd->h[1] = pws->h[0];
3272     pwd->h[0] = pwt->h[0];
3273 #endif
3274 }
3275
3276 void helper_msa_ilvev_w(CPUMIPSState *env,
3277                         uint32_t wd, uint32_t ws, uint32_t wt)
3278 {
3279     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3280     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3281     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3282
3283 #if defined(HOST_WORDS_BIGENDIAN)
3284     pwd->w[2] = pws->w[3];
3285     pwd->w[3] = pwt->w[3];
3286     pwd->w[0] = pws->w[1];
3287     pwd->w[1] = pwt->w[1];
3288 #else
3289     pwd->w[3] = pws->w[2];
3290     pwd->w[2] = pwt->w[2];
3291     pwd->w[1] = pws->w[0];
3292     pwd->w[0] = pwt->w[0];
3293 #endif
3294 }
3295
3296 void helper_msa_ilvev_d(CPUMIPSState *env,
3297                         uint32_t wd, uint32_t ws, uint32_t wt)
3298 {
3299     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3300     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3301     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3302
3303     pwd->d[1] = pws->d[0];
3304     pwd->d[0] = pwt->d[0];
3305 }
3306
3307
3308 void helper_msa_ilvod_b(CPUMIPSState *env,
3309                         uint32_t wd, uint32_t ws, uint32_t wt)
3310 {
3311     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3312     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3313     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3314
3315 #if defined(HOST_WORDS_BIGENDIAN)
3316     pwd->b[7]  = pwt->b[6];
3317     pwd->b[6]  = pws->b[6];
3318     pwd->b[5]  = pwt->b[4];
3319     pwd->b[4]  = pws->b[4];
3320     pwd->b[3]  = pwt->b[2];
3321     pwd->b[2]  = pws->b[2];
3322     pwd->b[1]  = pwt->b[0];
3323     pwd->b[0]  = pws->b[0];
3324     pwd->b[15] = pwt->b[14];
3325     pwd->b[14] = pws->b[14];
3326     pwd->b[13] = pwt->b[12];
3327     pwd->b[12] = pws->b[12];
3328     pwd->b[11] = pwt->b[10];
3329     pwd->b[10] = pws->b[10];
3330     pwd->b[9]  = pwt->b[8];
3331     pwd->b[8]  = pws->b[8];
3332 #else
3333     pwd->b[0]  = pwt->b[1];
3334     pwd->b[1]  = pws->b[1];
3335     pwd->b[2]  = pwt->b[3];
3336     pwd->b[3]  = pws->b[3];
3337     pwd->b[4]  = pwt->b[5];
3338     pwd->b[5]  = pws->b[5];
3339     pwd->b[6]  = pwt->b[7];
3340     pwd->b[7]  = pws->b[7];
3341     pwd->b[8]  = pwt->b[9];
3342     pwd->b[9]  = pws->b[9];
3343     pwd->b[10] = pwt->b[11];
3344     pwd->b[11] = pws->b[11];
3345     pwd->b[12] = pwt->b[13];
3346     pwd->b[13] = pws->b[13];
3347     pwd->b[14] = pwt->b[15];
3348     pwd->b[15] = pws->b[15];
3349 #endif
3350 }
3351
3352 void helper_msa_ilvod_h(CPUMIPSState *env,
3353                         uint32_t wd, uint32_t ws, uint32_t wt)
3354 {
3355     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3356     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3357     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3358
3359 #if defined(HOST_WORDS_BIGENDIAN)
3360     pwd->h[3] = pwt->h[2];
3361     pwd->h[2] = pws->h[2];
3362     pwd->h[1] = pwt->h[0];
3363     pwd->h[0] = pws->h[0];
3364     pwd->h[7] = pwt->h[6];
3365     pwd->h[6] = pws->h[6];
3366     pwd->h[5] = pwt->h[4];
3367     pwd->h[4] = pws->h[4];
3368 #else
3369     pwd->h[0] = pwt->h[1];
3370     pwd->h[1] = pws->h[1];
3371     pwd->h[2] = pwt->h[3];
3372     pwd->h[3] = pws->h[3];
3373     pwd->h[4] = pwt->h[5];
3374     pwd->h[5] = pws->h[5];
3375     pwd->h[6] = pwt->h[7];
3376     pwd->h[7] = pws->h[7];
3377 #endif
3378 }
3379
3380 void helper_msa_ilvod_w(CPUMIPSState *env,
3381                         uint32_t wd, uint32_t ws, uint32_t wt)
3382 {
3383     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3384     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3385     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3386
3387 #if defined(HOST_WORDS_BIGENDIAN)
3388     pwd->w[1] = pwt->w[0];
3389     pwd->w[0] = pws->w[0];
3390     pwd->w[3] = pwt->w[2];
3391     pwd->w[2] = pws->w[2];
3392 #else
3393     pwd->w[0] = pwt->w[1];
3394     pwd->w[1] = pws->w[1];
3395     pwd->w[2] = pwt->w[3];
3396     pwd->w[3] = pws->w[3];
3397 #endif
3398 }
3399
3400 void helper_msa_ilvod_d(CPUMIPSState *env,
3401                         uint32_t wd, uint32_t ws, uint32_t wt)
3402 {
3403     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3404     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3405     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3406
3407     pwd->d[0] = pwt->d[1];
3408     pwd->d[1] = pws->d[1];
3409 }
3410
3411
3412 void helper_msa_ilvl_b(CPUMIPSState *env,
3413                        uint32_t wd, uint32_t ws, uint32_t wt)
3414 {
3415     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3416     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3417     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3418
3419 #if defined(HOST_WORDS_BIGENDIAN)
3420     pwd->b[7]  = pwt->b[15];
3421     pwd->b[6]  = pws->b[15];
3422     pwd->b[5]  = pwt->b[14];
3423     pwd->b[4]  = pws->b[14];
3424     pwd->b[3]  = pwt->b[13];
3425     pwd->b[2]  = pws->b[13];
3426     pwd->b[1]  = pwt->b[12];
3427     pwd->b[0]  = pws->b[12];
3428     pwd->b[15] = pwt->b[11];
3429     pwd->b[14] = pws->b[11];
3430     pwd->b[13] = pwt->b[10];
3431     pwd->b[12] = pws->b[10];
3432     pwd->b[11] = pwt->b[9];
3433     pwd->b[10] = pws->b[9];
3434     pwd->b[9]  = pwt->b[8];
3435     pwd->b[8]  = pws->b[8];
3436 #else
3437     pwd->b[0]  = pwt->b[8];
3438     pwd->b[1]  = pws->b[8];
3439     pwd->b[2]  = pwt->b[9];
3440     pwd->b[3]  = pws->b[9];
3441     pwd->b[4]  = pwt->b[10];
3442     pwd->b[5]  = pws->b[10];
3443     pwd->b[6]  = pwt->b[11];
3444     pwd->b[7]  = pws->b[11];
3445     pwd->b[8]  = pwt->b[12];
3446     pwd->b[9]  = pws->b[12];
3447     pwd->b[10] = pwt->b[13];
3448     pwd->b[11] = pws->b[13];
3449     pwd->b[12] = pwt->b[14];
3450     pwd->b[13] = pws->b[14];
3451     pwd->b[14] = pwt->b[15];
3452     pwd->b[15] = pws->b[15];
3453 #endif
3454 }
3455
3456 void helper_msa_ilvl_h(CPUMIPSState *env,
3457                        uint32_t wd, uint32_t ws, uint32_t wt)
3458 {
3459     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3460     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3461     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3462
3463 #if defined(HOST_WORDS_BIGENDIAN)
3464     pwd->h[3] = pwt->h[7];
3465     pwd->h[2] = pws->h[7];
3466     pwd->h[1] = pwt->h[6];
3467     pwd->h[0] = pws->h[6];
3468     pwd->h[7] = pwt->h[5];
3469     pwd->h[6] = pws->h[5];
3470     pwd->h[5] = pwt->h[4];
3471     pwd->h[4] = pws->h[4];
3472 #else
3473     pwd->h[0] = pwt->h[4];
3474     pwd->h[1] = pws->h[4];
3475     pwd->h[2] = pwt->h[5];
3476     pwd->h[3] = pws->h[5];
3477     pwd->h[4] = pwt->h[6];
3478     pwd->h[5] = pws->h[6];
3479     pwd->h[6] = pwt->h[7];
3480     pwd->h[7] = pws->h[7];
3481 #endif
3482 }
3483
3484 void helper_msa_ilvl_w(CPUMIPSState *env,
3485                        uint32_t wd, uint32_t ws, uint32_t wt)
3486 {
3487     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3488     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3489     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3490
3491 #if defined(HOST_WORDS_BIGENDIAN)
3492     pwd->w[1] = pwt->w[3];
3493     pwd->w[0] = pws->w[3];
3494     pwd->w[3] = pwt->w[2];
3495     pwd->w[2] = pws->w[2];
3496 #else
3497     pwd->w[0] = pwt->w[2];
3498     pwd->w[1] = pws->w[2];
3499     pwd->w[2] = pwt->w[3];
3500     pwd->w[3] = pws->w[3];
3501 #endif
3502 }
3503
3504 void helper_msa_ilvl_d(CPUMIPSState *env,
3505                        uint32_t wd, uint32_t ws, uint32_t wt)
3506 {
3507     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3508     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3509     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3510
3511     pwd->d[0] = pwt->d[1];
3512     pwd->d[1] = pws->d[1];
3513 }
3514
3515
3516 void helper_msa_ilvr_b(CPUMIPSState *env,
3517                        uint32_t wd, uint32_t ws, uint32_t wt)
3518 {
3519     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3520     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3521     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3522
3523 #if defined(HOST_WORDS_BIGENDIAN)
3524     pwd->b[8]  = pws->b[0];
3525     pwd->b[9]  = pwt->b[0];
3526     pwd->b[10] = pws->b[1];
3527     pwd->b[11] = pwt->b[1];
3528     pwd->b[12] = pws->b[2];
3529     pwd->b[13] = pwt->b[2];
3530     pwd->b[14] = pws->b[3];
3531     pwd->b[15] = pwt->b[3];
3532     pwd->b[0]  = pws->b[4];
3533     pwd->b[1]  = pwt->b[4];
3534     pwd->b[2]  = pws->b[5];
3535     pwd->b[3]  = pwt->b[5];
3536     pwd->b[4]  = pws->b[6];
3537     pwd->b[5]  = pwt->b[6];
3538     pwd->b[6]  = pws->b[7];
3539     pwd->b[7]  = pwt->b[7];
3540 #else
3541     pwd->b[15] = pws->b[7];
3542     pwd->b[14] = pwt->b[7];
3543     pwd->b[13] = pws->b[6];
3544     pwd->b[12] = pwt->b[6];
3545     pwd->b[11] = pws->b[5];
3546     pwd->b[10] = pwt->b[5];
3547     pwd->b[9]  = pws->b[4];
3548     pwd->b[8]  = pwt->b[4];
3549     pwd->b[7]  = pws->b[3];
3550     pwd->b[6]  = pwt->b[3];
3551     pwd->b[5]  = pws->b[2];
3552     pwd->b[4]  = pwt->b[2];
3553     pwd->b[3]  = pws->b[1];
3554     pwd->b[2]  = pwt->b[1];
3555     pwd->b[1]  = pws->b[0];
3556     pwd->b[0]  = pwt->b[0];
3557 #endif
3558 }
3559
3560 void helper_msa_ilvr_h(CPUMIPSState *env,
3561                        uint32_t wd, uint32_t ws, uint32_t wt)
3562 {
3563     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3564     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3565     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3566
3567 #if defined(HOST_WORDS_BIGENDIAN)
3568     pwd->h[4] = pws->h[0];
3569     pwd->h[5] = pwt->h[0];
3570     pwd->h[6] = pws->h[1];
3571     pwd->h[7] = pwt->h[1];
3572     pwd->h[0] = pws->h[2];
3573     pwd->h[1] = pwt->h[2];
3574     pwd->h[2] = pws->h[3];
3575     pwd->h[3] = pwt->h[3];
3576 #else
3577     pwd->h[7] = pws->h[3];
3578     pwd->h[6] = pwt->h[3];
3579     pwd->h[5] = pws->h[2];
3580     pwd->h[4] = pwt->h[2];
3581     pwd->h[3] = pws->h[1];
3582     pwd->h[2] = pwt->h[1];
3583     pwd->h[1] = pws->h[0];
3584     pwd->h[0] = pwt->h[0];
3585 #endif
3586 }
3587
3588 void helper_msa_ilvr_w(CPUMIPSState *env,
3589                        uint32_t wd, uint32_t ws, uint32_t wt)
3590 {
3591     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3592     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3593     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3594
3595 #if defined(HOST_WORDS_BIGENDIAN)
3596     pwd->w[2] = pws->w[0];
3597     pwd->w[3] = pwt->w[0];
3598     pwd->w[0] = pws->w[1];
3599     pwd->w[1] = pwt->w[1];
3600 #else
3601     pwd->w[3] = pws->w[1];
3602     pwd->w[2] = pwt->w[1];
3603     pwd->w[1] = pws->w[0];
3604     pwd->w[0] = pwt->w[0];
3605 #endif
3606 }
3607
3608 void helper_msa_ilvr_d(CPUMIPSState *env,
3609                        uint32_t wd, uint32_t ws, uint32_t wt)
3610 {
3611     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3612     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3613     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3614
3615     pwd->d[1] = pws->d[0];
3616     pwd->d[0] = pwt->d[0];
3617 }
3618
3619
3620 /*
3621  * Logic
3622  * -----
3623  *
3624  * +---------------+----------------------------------------------------------+
3625  * | AND.V         | Vector Logical And                                       |
3626  * | NOR.V         | Vector Logical Negated Or                                |
3627  * | OR.V          | Vector Logical Or                                        |
3628  * | XOR.V         | Vector Logical Exclusive Or                              |
3629  * +---------------+----------------------------------------------------------+
3630  */
3631
3632
3633 void helper_msa_and_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
3634 {
3635     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3636     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3637     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3638
3639     pwd->d[0] = pws->d[0] & pwt->d[0];
3640     pwd->d[1] = pws->d[1] & pwt->d[1];
3641 }
3642
3643 void helper_msa_nor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
3644 {
3645     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3646     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3647     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3648
3649     pwd->d[0] = ~(pws->d[0] | pwt->d[0]);
3650     pwd->d[1] = ~(pws->d[1] | pwt->d[1]);
3651 }
3652
3653 void helper_msa_or_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
3654 {
3655     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3656     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3657     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3658
3659     pwd->d[0] = pws->d[0] | pwt->d[0];
3660     pwd->d[1] = pws->d[1] | pwt->d[1];
3661 }
3662
3663 void helper_msa_xor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
3664 {
3665     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3666     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3667     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3668
3669     pwd->d[0] = pws->d[0] ^ pwt->d[0];
3670     pwd->d[1] = pws->d[1] ^ pwt->d[1];
3671 }
3672
3673
3674 /*
3675  * Move
3676  * ----
3677  *
3678  * +---------------+----------------------------------------------------------+
3679  * | MOVE.V        | Vector Move                                              |
3680  * +---------------+----------------------------------------------------------+
3681  */
3682
3683 static inline void msa_move_v(wr_t *pwd, wr_t *pws)
3684 {
3685     pwd->d[0] = pws->d[0];
3686     pwd->d[1] = pws->d[1];
3687 }
3688
3689 void helper_msa_move_v(CPUMIPSState *env, uint32_t wd, uint32_t ws)
3690 {
3691     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3692     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3693
3694     msa_move_v(pwd, pws);
3695 }
3696
3697
3698 /*
3699  * Pack
3700  * ----
3701  *
3702  * +---------------+----------------------------------------------------------+
3703  * | PCKEV.B       | Vector Pack Even (byte)                                  |
3704  * | PCKEV.H       | Vector Pack Even (halfword)                              |
3705  * | PCKEV.W       | Vector Pack Even (word)                                  |
3706  * | PCKEV.D       | Vector Pack Even (doubleword)                            |
3707  * | PCKOD.B       | Vector Pack Odd (byte)                                   |
3708  * | PCKOD.H       | Vector Pack Odd (halfword)                               |
3709  * | PCKOD.W       | Vector Pack Odd (word)                                   |
3710  * | PCKOD.D       | Vector Pack Odd (doubleword)                             |
3711  * | VSHF.B        | Vector Data Preserving Shuffle (byte)                    |
3712  * | VSHF.H        | Vector Data Preserving Shuffle (halfword)                |
3713  * | VSHF.W        | Vector Data Preserving Shuffle (word)                    |
3714  * | VSHF.D        | Vector Data Preserving Shuffle (doubleword)              |
3715  * +---------------+----------------------------------------------------------+
3716  */
3717
3718
3719 void helper_msa_pckev_b(CPUMIPSState *env,
3720                         uint32_t wd, uint32_t ws, uint32_t wt)
3721 {
3722     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3723     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3724     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3725
3726 #if defined(HOST_WORDS_BIGENDIAN)
3727     pwd->b[8]  = pws->b[9];
3728     pwd->b[10] = pws->b[13];
3729     pwd->b[12] = pws->b[1];
3730     pwd->b[14] = pws->b[5];
3731     pwd->b[0]  = pwt->b[9];
3732     pwd->b[2]  = pwt->b[13];
3733     pwd->b[4]  = pwt->b[1];
3734     pwd->b[6]  = pwt->b[5];
3735     pwd->b[9]  = pws->b[11];
3736     pwd->b[13] = pws->b[3];
3737     pwd->b[1]  = pwt->b[11];
3738     pwd->b[5]  = pwt->b[3];
3739     pwd->b[11] = pws->b[15];
3740     pwd->b[3]  = pwt->b[15];
3741     pwd->b[15] = pws->b[7];
3742     pwd->b[7]  = pwt->b[7];
3743 #else
3744     pwd->b[15] = pws->b[14];
3745     pwd->b[13] = pws->b[10];
3746     pwd->b[11] = pws->b[6];
3747     pwd->b[9]  = pws->b[2];
3748     pwd->b[7]  = pwt->b[14];
3749     pwd->b[5]  = pwt->b[10];
3750     pwd->b[3]  = pwt->b[6];
3751     pwd->b[1]  = pwt->b[2];
3752     pwd->b[14] = pws->b[12];
3753     pwd->b[10] = pws->b[4];
3754     pwd->b[6]  = pwt->b[12];
3755     pwd->b[2]  = pwt->b[4];
3756     pwd->b[12] = pws->b[8];
3757     pwd->b[4]  = pwt->b[8];
3758     pwd->b[8]  = pws->b[0];
3759     pwd->b[0]  = pwt->b[0];
3760 #endif
3761 }
3762
3763 void helper_msa_pckev_h(CPUMIPSState *env,
3764                         uint32_t wd, uint32_t ws, uint32_t wt)
3765 {
3766     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3767     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3768     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3769
3770 #if defined(HOST_WORDS_BIGENDIAN)
3771     pwd->h[4] = pws->h[5];
3772     pwd->h[6] = pws->h[1];
3773     pwd->h[0] = pwt->h[5];
3774     pwd->h[2] = pwt->h[1];
3775     pwd->h[5] = pws->h[7];
3776     pwd->h[1] = pwt->h[7];
3777     pwd->h[7] = pws->h[3];
3778     pwd->h[3] = pwt->h[3];
3779 #else
3780     pwd->h[7] = pws->h[6];
3781     pwd->h[5] = pws->h[2];
3782     pwd->h[3] = pwt->h[6];
3783     pwd->h[1] = pwt->h[2];
3784     pwd->h[6] = pws->h[4];
3785     pwd->h[2] = pwt->h[4];
3786     pwd->h[4] = pws->h[0];
3787     pwd->h[0] = pwt->h[0];
3788 #endif
3789 }
3790
3791 void helper_msa_pckev_w(CPUMIPSState *env,
3792                         uint32_t wd, uint32_t ws, uint32_t wt)
3793 {
3794     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3795     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3796     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3797
3798 #if defined(HOST_WORDS_BIGENDIAN)
3799     pwd->w[2] = pws->w[3];
3800     pwd->w[0] = pwt->w[3];
3801     pwd->w[3] = pws->w[1];
3802     pwd->w[1] = pwt->w[1];
3803 #else
3804     pwd->w[3] = pws->w[2];
3805     pwd->w[1] = pwt->w[2];
3806     pwd->w[2] = pws->w[0];
3807     pwd->w[0] = pwt->w[0];
3808 #endif
3809 }
3810
3811 void helper_msa_pckev_d(CPUMIPSState *env,
3812                         uint32_t wd, uint32_t ws, uint32_t wt)
3813 {
3814     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3815     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3816     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3817
3818     pwd->d[1] = pws->d[0];
3819     pwd->d[0] = pwt->d[0];
3820 }
3821
3822
3823 void helper_msa_pckod_b(CPUMIPSState *env,
3824                         uint32_t wd, uint32_t ws, uint32_t wt)
3825 {
3826     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3827     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3828     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3829
3830 #if defined(HOST_WORDS_BIGENDIAN)
3831     pwd->b[7]  = pwt->b[6];
3832     pwd->b[5]  = pwt->b[2];
3833     pwd->b[3]  = pwt->b[14];
3834     pwd->b[1]  = pwt->b[10];
3835     pwd->b[15] = pws->b[6];
3836     pwd->b[13] = pws->b[2];
3837     pwd->b[11] = pws->b[14];
3838     pwd->b[9]  = pws->b[10];
3839     pwd->b[6]  = pwt->b[4];
3840     pwd->b[2]  = pwt->b[12];
3841     pwd->b[14] = pws->b[4];
3842     pwd->b[10] = pws->b[12];
3843     pwd->b[4]  = pwt->b[0];
3844     pwd->b[12] = pws->b[0];
3845     pwd->b[0]  = pwt->b[8];
3846     pwd->b[8]  = pws->b[8];
3847 #else
3848     pwd->b[0]  = pwt->b[1];
3849     pwd->b[2]  = pwt->b[5];
3850     pwd->b[4]  = pwt->b[9];
3851     pwd->b[6]  = pwt->b[13];
3852     pwd->b[8]  = pws->b[1];
3853     pwd->b[10] = pws->b[5];
3854     pwd->b[12] = pws->b[9];
3855     pwd->b[14] = pws->b[13];
3856     pwd->b[1]  = pwt->b[3];
3857     pwd->b[5]  = pwt->b[11];
3858     pwd->b[9]  = pws->b[3];
3859     pwd->b[13] = pws->b[11];
3860     pwd->b[3]  = pwt->b[7];
3861     pwd->b[11] = pws->b[7];
3862     pwd->b[7]  = pwt->b[15];
3863     pwd->b[15] = pws->b[15];
3864 #endif
3865
3866 }
3867
3868 void helper_msa_pckod_h(CPUMIPSState *env,
3869                         uint32_t wd, uint32_t ws, uint32_t wt)
3870 {
3871     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3872     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3873     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3874
3875 #if defined(HOST_WORDS_BIGENDIAN)
3876     pwd->h[3] = pwt->h[2];
3877     pwd->h[1] = pwt->h[6];
3878     pwd->h[7] = pws->h[2];
3879     pwd->h[5] = pws->h[6];
3880     pwd->h[2] = pwt->h[0];
3881     pwd->h[6] = pws->h[0];
3882     pwd->h[0] = pwt->h[4];
3883     pwd->h[4] = pws->h[4];
3884 #else
3885     pwd->h[0] = pwt->h[1];
3886     pwd->h[2] = pwt->h[5];
3887     pwd->h[4] = pws->h[1];
3888     pwd->h[6] = pws->h[5];
3889     pwd->h[1] = pwt->h[3];
3890     pwd->h[5] = pws->h[3];
3891     pwd->h[3] = pwt->h[7];
3892     pwd->h[7] = pws->h[7];
3893 #endif
3894 }
3895
3896 void helper_msa_pckod_w(CPUMIPSState *env,
3897                         uint32_t wd, uint32_t ws, uint32_t wt)
3898 {
3899     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3900     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3901     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3902
3903 #if defined(HOST_WORDS_BIGENDIAN)
3904     pwd->w[1] = pwt->w[0];
3905     pwd->w[3] = pws->w[0];
3906     pwd->w[0] = pwt->w[2];
3907     pwd->w[2] = pws->w[2];
3908 #else
3909     pwd->w[0] = pwt->w[1];
3910     pwd->w[2] = pws->w[1];
3911     pwd->w[1] = pwt->w[3];
3912     pwd->w[3] = pws->w[3];
3913 #endif
3914 }
3915
3916 void helper_msa_pckod_d(CPUMIPSState *env,
3917                         uint32_t wd, uint32_t ws, uint32_t wt)
3918 {
3919     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3920     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3921     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3922
3923     pwd->d[0] = pwt->d[1];
3924     pwd->d[1] = pws->d[1];
3925 }
3926
3927
3928 /*
3929  * Shift
3930  * -----
3931  *
3932  * +---------------+----------------------------------------------------------+
3933  * | SLL.B         | Vector Shift Left (byte)                                 |
3934  * | SLL.H         | Vector Shift Left (halfword)                             |
3935  * | SLL.W         | Vector Shift Left (word)                                 |
3936  * | SLL.D         | Vector Shift Left (doubleword)                           |
3937  * | SRA.B         | Vector Shift Right Arithmetic (byte)                     |
3938  * | SRA.H         | Vector Shift Right Arithmetic (halfword)                 |
3939  * | SRA.W         | Vector Shift Right Arithmetic (word)                     |
3940  * | SRA.D         | Vector Shift Right Arithmetic (doubleword)               |
3941  * | SRAR.B        | Vector Shift Right Arithmetic Rounded (byte)             |
3942  * | SRAR.H        | Vector Shift Right Arithmetic Rounded (halfword)         |
3943  * | SRAR.W        | Vector Shift Right Arithmetic Rounded (word)             |
3944  * | SRAR.D        | Vector Shift Right Arithmetic Rounded (doubleword)       |
3945  * | SRL.B         | Vector Shift Right Logical (byte)                        |
3946  * | SRL.H         | Vector Shift Right Logical (halfword)                    |
3947  * | SRL.W         | Vector Shift Right Logical (word)                        |
3948  * | SRL.D         | Vector Shift Right Logical (doubleword)                  |
3949  * | SRLR.B        | Vector Shift Right Logical Rounded (byte)                |
3950  * | SRLR.H        | Vector Shift Right Logical Rounded (halfword)            |
3951  * | SRLR.W        | Vector Shift Right Logical Rounded (word)                |
3952  * | SRLR.D        | Vector Shift Right Logical Rounded (doubleword)          |
3953  * +---------------+----------------------------------------------------------+
3954  */
3955
3956
3957 static inline int64_t msa_sll_df(uint32_t df, int64_t arg1, int64_t arg2)
3958 {
3959     int32_t b_arg2 = BIT_POSITION(arg2, df);
3960     return arg1 << b_arg2;
3961 }
3962
3963 void helper_msa_sll_b(CPUMIPSState *env,
3964                       uint32_t wd, uint32_t ws, uint32_t wt)
3965 {
3966     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3967     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3968     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3969
3970     pwd->b[0]  = msa_sll_df(DF_BYTE, pws->b[0],  pwt->b[0]);
3971     pwd->b[1]  = msa_sll_df(DF_BYTE, pws->b[1],  pwt->b[1]);
3972     pwd->b[2]  = msa_sll_df(DF_BYTE, pws->b[2],  pwt->b[2]);
3973     pwd->b[3]  = msa_sll_df(DF_BYTE, pws->b[3],  pwt->b[3]);
3974     pwd->b[4]  = msa_sll_df(DF_BYTE, pws->b[4],  pwt->b[4]);
3975     pwd->b[5]  = msa_sll_df(DF_BYTE, pws->b[5],  pwt->b[5]);
3976     pwd->b[6]  = msa_sll_df(DF_BYTE, pws->b[6],  pwt->b[6]);
3977     pwd->b[7]  = msa_sll_df(DF_BYTE, pws->b[7],  pwt->b[7]);
3978     pwd->b[8]  = msa_sll_df(DF_BYTE, pws->b[8],  pwt->b[8]);
3979     pwd->b[9]  = msa_sll_df(DF_BYTE, pws->b[9],  pwt->b[9]);
3980     pwd->b[10] = msa_sll_df(DF_BYTE, pws->b[10], pwt->b[10]);
3981     pwd->b[11] = msa_sll_df(DF_BYTE, pws->b[11], pwt->b[11]);
3982     pwd->b[12] = msa_sll_df(DF_BYTE, pws->b[12], pwt->b[12]);
3983     pwd->b[13] = msa_sll_df(DF_BYTE, pws->b[13], pwt->b[13]);
3984     pwd->b[14] = msa_sll_df(DF_BYTE, pws->b[14], pwt->b[14]);
3985     pwd->b[15] = msa_sll_df(DF_BYTE, pws->b[15], pwt->b[15]);
3986 }
3987
3988 void helper_msa_sll_h(CPUMIPSState *env,
3989                       uint32_t wd, uint32_t ws, uint32_t wt)
3990 {
3991     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3992     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3993     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3994
3995     pwd->h[0]  = msa_sll_df(DF_HALF, pws->h[0],  pwt->h[0]);
3996     pwd->h[1]  = msa_sll_df(DF_HALF, pws->h[1],  pwt->h[1]);
3997     pwd->h[2]  = msa_sll_df(DF_HALF, pws->h[2],  pwt->h[2]);
3998     pwd->h[3]  = msa_sll_df(DF_HALF, pws->h[3],  pwt->h[3]);
3999     pwd->h[4]  = msa_sll_df(DF_HALF, pws->h[4],  pwt->h[4]);
4000     pwd->h[5]  = msa_sll_df(DF_HALF, pws->h[5],  pwt->h[5]);
4001     pwd->h[6]  = msa_sll_df(DF_HALF, pws->h[6],  pwt->h[6]);
4002     pwd->h[7]  = msa_sll_df(DF_HALF, pws->h[7],  pwt->h[7]);
4003 }
4004
4005 void helper_msa_sll_w(CPUMIPSState *env,
4006                       uint32_t wd, uint32_t ws, uint32_t wt)
4007 {
4008     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4009     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4010     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4011
4012     pwd->w[0]  = msa_sll_df(DF_WORD, pws->w[0],  pwt->w[0]);
4013     pwd->w[1]  = msa_sll_df(DF_WORD, pws->w[1],  pwt->w[1]);
4014     pwd->w[2]  = msa_sll_df(DF_WORD, pws->w[2],  pwt->w[2]);
4015     pwd->w[3]  = msa_sll_df(DF_WORD, pws->w[3],  pwt->w[3]);
4016 }
4017
4018 void helper_msa_sll_d(CPUMIPSState *env,
4019                       uint32_t wd, uint32_t ws, uint32_t wt)
4020 {
4021     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4022     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4023     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4024
4025     pwd->d[0]  = msa_sll_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
4026     pwd->d[1]  = msa_sll_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
4027 }
4028
4029
4030 static inline int64_t msa_sra_df(uint32_t df, int64_t arg1, int64_t arg2)
4031 {
4032     int32_t b_arg2 = BIT_POSITION(arg2, df);
4033     return arg1 >> b_arg2;
4034 }
4035
4036 void helper_msa_sra_b(CPUMIPSState *env,
4037                       uint32_t wd, uint32_t ws, uint32_t wt)
4038 {
4039     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4040     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4041     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4042
4043     pwd->b[0]  = msa_sra_df(DF_BYTE, pws->b[0],  pwt->b[0]);
4044     pwd->b[1]  = msa_sra_df(DF_BYTE, pws->b[1],  pwt->b[1]);
4045     pwd->b[2]  = msa_sra_df(DF_BYTE, pws->b[2],  pwt->b[2]);
4046     pwd->b[3]  = msa_sra_df(DF_BYTE, pws->b[3],  pwt->b[3]);
4047     pwd->b[4]  = msa_sra_df(DF_BYTE, pws->b[4],  pwt->b[4]);
4048     pwd->b[5]  = msa_sra_df(DF_BYTE, pws->b[5],  pwt->b[5]);
4049     pwd->b[6]  = msa_sra_df(DF_BYTE, pws->b[6],  pwt->b[6]);
4050     pwd->b[7]  = msa_sra_df(DF_BYTE, pws->b[7],  pwt->b[7]);
4051     pwd->b[8]  = msa_sra_df(DF_BYTE, pws->b[8],  pwt->b[8]);
4052     pwd->b[9]  = msa_sra_df(DF_BYTE, pws->b[9],  pwt->b[9]);
4053     pwd->b[10] = msa_sra_df(DF_BYTE, pws->b[10], pwt->b[10]);
4054     pwd->b[11] = msa_sra_df(DF_BYTE, pws->b[11], pwt->b[11]);
4055     pwd->b[12] = msa_sra_df(DF_BYTE, pws->b[12], pwt->b[12]);
4056     pwd->b[13] = msa_sra_df(DF_BYTE, pws->b[13], pwt->b[13]);
4057     pwd->b[14] = msa_sra_df(DF_BYTE, pws->b[14], pwt->b[14]);
4058     pwd->b[15] = msa_sra_df(DF_BYTE, pws->b[15], pwt->b[15]);
4059 }
4060
4061 void helper_msa_sra_h(CPUMIPSState *env,
4062                       uint32_t wd, uint32_t ws, uint32_t wt)
4063 {
4064     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4065     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4066     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4067
4068     pwd->h[0]  = msa_sra_df(DF_HALF, pws->h[0],  pwt->h[0]);
4069     pwd->h[1]  = msa_sra_df(DF_HALF, pws->h[1],  pwt->h[1]);
4070     pwd->h[2]  = msa_sra_df(DF_HALF, pws->h[2],  pwt->h[2]);
4071     pwd->h[3]  = msa_sra_df(DF_HALF, pws->h[3],  pwt->h[3]);
4072     pwd->h[4]  = msa_sra_df(DF_HALF, pws->h[4],  pwt->h[4]);
4073     pwd->h[5]  = msa_sra_df(DF_HALF, pws->h[5],  pwt->h[5]);
4074     pwd->h[6]  = msa_sra_df(DF_HALF, pws->h[6],  pwt->h[6]);
4075     pwd->h[7]  = msa_sra_df(DF_HALF, pws->h[7],  pwt->h[7]);
4076 }
4077
4078 void helper_msa_sra_w(CPUMIPSState *env,
4079                       uint32_t wd, uint32_t ws, uint32_t wt)
4080 {
4081     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4082     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4083     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4084
4085     pwd->w[0]  = msa_sra_df(DF_WORD, pws->w[0],  pwt->w[0]);
4086     pwd->w[1]  = msa_sra_df(DF_WORD, pws->w[1],  pwt->w[1]);
4087     pwd->w[2]  = msa_sra_df(DF_WORD, pws->w[2],  pwt->w[2]);
4088     pwd->w[3]  = msa_sra_df(DF_WORD, pws->w[3],  pwt->w[3]);
4089 }
4090
4091 void helper_msa_sra_d(CPUMIPSState *env,
4092                       uint32_t wd, uint32_t ws, uint32_t wt)
4093 {
4094     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4095     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4096     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4097
4098     pwd->d[0]  = msa_sra_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
4099     pwd->d[1]  = msa_sra_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
4100 }
4101
4102
4103 static inline int64_t msa_srar_df(uint32_t df, int64_t arg1, int64_t arg2)
4104 {
4105     int32_t b_arg2 = BIT_POSITION(arg2, df);
4106     if (b_arg2 == 0) {
4107         return arg1;
4108     } else {
4109         int64_t r_bit = (arg1 >> (b_arg2 - 1)) & 1;
4110         return (arg1 >> b_arg2) + r_bit;
4111     }
4112 }
4113
4114 void helper_msa_srar_b(CPUMIPSState *env,
4115                        uint32_t wd, uint32_t ws, uint32_t wt)
4116 {
4117     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4118     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4119     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4120
4121     pwd->b[0]  = msa_srar_df(DF_BYTE, pws->b[0],  pwt->b[0]);
4122     pwd->b[1]  = msa_srar_df(DF_BYTE, pws->b[1],  pwt->b[1]);
4123     pwd->b[2]  = msa_srar_df(DF_BYTE, pws->b[2],  pwt->b[2]);
4124     pwd->b[3]  = msa_srar_df(DF_BYTE, pws->b[3],  pwt->b[3]);
4125     pwd->b[4]  = msa_srar_df(DF_BYTE, pws->b[4],  pwt->b[4]);
4126     pwd->b[5]  = msa_srar_df(DF_BYTE, pws->b[5],  pwt->b[5]);
4127     pwd->b[6]  = msa_srar_df(DF_BYTE, pws->b[6],  pwt->b[6]);
4128     pwd->b[7]  = msa_srar_df(DF_BYTE, pws->b[7],  pwt->b[7]);
4129     pwd->b[8]  = msa_srar_df(DF_BYTE, pws->b[8],  pwt->b[8]);
4130     pwd->b[9]  = msa_srar_df(DF_BYTE, pws->b[9],  pwt->b[9]);
4131     pwd->b[10] = msa_srar_df(DF_BYTE, pws->b[10], pwt->b[10]);
4132     pwd->b[11] = msa_srar_df(DF_BYTE, pws->b[11], pwt->b[11]);
4133     pwd->b[12] = msa_srar_df(DF_BYTE, pws->b[12], pwt->b[12]);
4134     pwd->b[13] = msa_srar_df(DF_BYTE, pws->b[13], pwt->b[13]);
4135     pwd->b[14] = msa_srar_df(DF_BYTE, pws->b[14], pwt->b[14]);
4136     pwd->b[15] = msa_srar_df(DF_BYTE, pws->b[15], pwt->b[15]);
4137 }
4138
4139 void helper_msa_srar_h(CPUMIPSState *env,
4140                        uint32_t wd, uint32_t ws, uint32_t wt)
4141 {
4142     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4143     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4144     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4145
4146     pwd->h[0]  = msa_srar_df(DF_HALF, pws->h[0],  pwt->h[0]);
4147     pwd->h[1]  = msa_srar_df(DF_HALF, pws->h[1],  pwt->h[1]);
4148     pwd->h[2]  = msa_srar_df(DF_HALF, pws->h[2],  pwt->h[2]);
4149     pwd->h[3]  = msa_srar_df(DF_HALF, pws->h[3],  pwt->h[3]);
4150     pwd->h[4]  = msa_srar_df(DF_HALF, pws->h[4],  pwt->h[4]);
4151     pwd->h[5]  = msa_srar_df(DF_HALF, pws->h[5],  pwt->h[5]);
4152     pwd->h[6]  = msa_srar_df(DF_HALF, pws->h[6],  pwt->h[6]);
4153     pwd->h[7]  = msa_srar_df(DF_HALF, pws->h[7],  pwt->h[7]);
4154 }
4155
4156 void helper_msa_srar_w(CPUMIPSState *env,
4157                        uint32_t wd, uint32_t ws, uint32_t wt)
4158 {
4159     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4160     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4161     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4162
4163     pwd->w[0]  = msa_srar_df(DF_WORD, pws->w[0],  pwt->w[0]);
4164     pwd->w[1]  = msa_srar_df(DF_WORD, pws->w[1],  pwt->w[1]);
4165     pwd->w[2]  = msa_srar_df(DF_WORD, pws->w[2],  pwt->w[2]);
4166     pwd->w[3]  = msa_srar_df(DF_WORD, pws->w[3],  pwt->w[3]);
4167 }
4168
4169 void helper_msa_srar_d(CPUMIPSState *env,
4170                        uint32_t wd, uint32_t ws, uint32_t wt)
4171 {
4172     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4173     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4174     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4175
4176     pwd->d[0]  = msa_srar_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
4177     pwd->d[1]  = msa_srar_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
4178 }
4179
4180
4181 static inline int64_t msa_srl_df(uint32_t df, int64_t arg1, int64_t arg2)
4182 {
4183     uint64_t u_arg1 = UNSIGNED(arg1, df);
4184     int32_t b_arg2 = BIT_POSITION(arg2, df);
4185     return u_arg1 >> b_arg2;
4186 }
4187
4188 void helper_msa_srl_b(CPUMIPSState *env,
4189                       uint32_t wd, uint32_t ws, uint32_t wt)
4190 {
4191     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4192     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4193     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4194
4195     pwd->b[0]  = msa_srl_df(DF_BYTE, pws->b[0],  pwt->b[0]);
4196     pwd->b[1]  = msa_srl_df(DF_BYTE, pws->b[1],  pwt->b[1]);
4197     pwd->b[2]  = msa_srl_df(DF_BYTE, pws->b[2],  pwt->b[2]);
4198     pwd->b[3]  = msa_srl_df(DF_BYTE, pws->b[3],  pwt->b[3]);
4199     pwd->b[4]  = msa_srl_df(DF_BYTE, pws->b[4],  pwt->b[4]);
4200     pwd->b[5]  = msa_srl_df(DF_BYTE, pws->b[5],  pwt->b[5]);
4201     pwd->b[6]  = msa_srl_df(DF_BYTE, pws->b[6],  pwt->b[6]);
4202     pwd->b[7]  = msa_srl_df(DF_BYTE, pws->b[7],  pwt->b[7]);
4203     pwd->b[8]  = msa_srl_df(DF_BYTE, pws->b[8],  pwt->b[8]);
4204     pwd->b[9]  = msa_srl_df(DF_BYTE, pws->b[9],  pwt->b[9]);
4205     pwd->b[10] = msa_srl_df(DF_BYTE, pws->b[10], pwt->b[10]);
4206     pwd->b[11] = msa_srl_df(DF_BYTE, pws->b[11], pwt->b[11]);
4207     pwd->b[12] = msa_srl_df(DF_BYTE, pws->b[12], pwt->b[12]);
4208     pwd->b[13] = msa_srl_df(DF_BYTE, pws->b[13], pwt->b[13]);
4209     pwd->b[14] = msa_srl_df(DF_BYTE, pws->b[14], pwt->b[14]);
4210     pwd->b[15] = msa_srl_df(DF_BYTE, pws->b[15], pwt->b[15]);
4211 }
4212
4213 void helper_msa_srl_h(CPUMIPSState *env,
4214                       uint32_t wd, uint32_t ws, uint32_t wt)
4215 {
4216     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4217     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4218     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4219
4220     pwd->h[0]  = msa_srl_df(DF_HALF, pws->h[0],  pwt->h[0]);
4221     pwd->h[1]  = msa_srl_df(DF_HALF, pws->h[1],  pwt->h[1]);
4222     pwd->h[2]  = msa_srl_df(DF_HALF, pws->h[2],  pwt->h[2]);
4223     pwd->h[3]  = msa_srl_df(DF_HALF, pws->h[3],  pwt->h[3]);
4224     pwd->h[4]  = msa_srl_df(DF_HALF, pws->h[4],  pwt->h[4]);
4225     pwd->h[5]  = msa_srl_df(DF_HALF, pws->h[5],  pwt->h[5]);
4226     pwd->h[6]  = msa_srl_df(DF_HALF, pws->h[6],  pwt->h[6]);
4227     pwd->h[7]  = msa_srl_df(DF_HALF, pws->h[7],  pwt->h[7]);
4228 }
4229
4230 void helper_msa_srl_w(CPUMIPSState *env,
4231                       uint32_t wd, uint32_t ws, uint32_t wt)
4232 {
4233     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4234     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4235     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4236
4237     pwd->w[0]  = msa_srl_df(DF_WORD, pws->w[0],  pwt->w[0]);
4238     pwd->w[1]  = msa_srl_df(DF_WORD, pws->w[1],  pwt->w[1]);
4239     pwd->w[2]  = msa_srl_df(DF_WORD, pws->w[2],  pwt->w[2]);
4240     pwd->w[3]  = msa_srl_df(DF_WORD, pws->w[3],  pwt->w[3]);
4241 }
4242
4243 void helper_msa_srl_d(CPUMIPSState *env,
4244                       uint32_t wd, uint32_t ws, uint32_t wt)
4245 {
4246     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4247     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4248     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4249
4250     pwd->d[0]  = msa_srl_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
4251     pwd->d[1]  = msa_srl_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
4252 }
4253
4254
4255 static inline int64_t msa_srlr_df(uint32_t df, int64_t arg1, int64_t arg2)
4256 {
4257     uint64_t u_arg1 = UNSIGNED(arg1, df);
4258     int32_t b_arg2 = BIT_POSITION(arg2, df);
4259     if (b_arg2 == 0) {
4260         return u_arg1;
4261     } else {
4262         uint64_t r_bit = (u_arg1 >> (b_arg2 - 1)) & 1;
4263         return (u_arg1 >> b_arg2) + r_bit;
4264     }
4265 }
4266
4267 void helper_msa_srlr_b(CPUMIPSState *env,
4268                        uint32_t wd, uint32_t ws, uint32_t wt)
4269 {
4270     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4271     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4272     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4273
4274     pwd->b[0]  = msa_srlr_df(DF_BYTE, pws->b[0],  pwt->b[0]);
4275     pwd->b[1]  = msa_srlr_df(DF_BYTE, pws->b[1],  pwt->b[1]);
4276     pwd->b[2]  = msa_srlr_df(DF_BYTE, pws->b[2],  pwt->b[2]);
4277     pwd->b[3]  = msa_srlr_df(DF_BYTE, pws->b[3],  pwt->b[3]);
4278     pwd->b[4]  = msa_srlr_df(DF_BYTE, pws->b[4],  pwt->b[4]);
4279     pwd->b[5]  = msa_srlr_df(DF_BYTE, pws->b[5],  pwt->b[5]);
4280     pwd->b[6]  = msa_srlr_df(DF_BYTE, pws->b[6],  pwt->b[6]);
4281     pwd->b[7]  = msa_srlr_df(DF_BYTE, pws->b[7],  pwt->b[7]);
4282     pwd->b[8]  = msa_srlr_df(DF_BYTE, pws->b[8],  pwt->b[8]);
4283     pwd->b[9]  = msa_srlr_df(DF_BYTE, pws->b[9],  pwt->b[9]);
4284     pwd->b[10] = msa_srlr_df(DF_BYTE, pws->b[10], pwt->b[10]);
4285     pwd->b[11] = msa_srlr_df(DF_BYTE, pws->b[11], pwt->b[11]);
4286     pwd->b[12] = msa_srlr_df(DF_BYTE, pws->b[12], pwt->b[12]);
4287     pwd->b[13] = msa_srlr_df(DF_BYTE, pws->b[13], pwt->b[13]);
4288     pwd->b[14] = msa_srlr_df(DF_BYTE, pws->b[14], pwt->b[14]);
4289     pwd->b[15] = msa_srlr_df(DF_BYTE, pws->b[15], pwt->b[15]);
4290 }
4291
4292 void helper_msa_srlr_h(CPUMIPSState *env,
4293                        uint32_t wd, uint32_t ws, uint32_t wt)
4294 {
4295     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4296     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4297     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4298
4299     pwd->h[0]  = msa_srlr_df(DF_HALF, pws->h[0],  pwt->h[0]);
4300     pwd->h[1]  = msa_srlr_df(DF_HALF, pws->h[1],  pwt->h[1]);
4301     pwd->h[2]  = msa_srlr_df(DF_HALF, pws->h[2],  pwt->h[2]);
4302     pwd->h[3]  = msa_srlr_df(DF_HALF, pws->h[3],  pwt->h[3]);
4303     pwd->h[4]  = msa_srlr_df(DF_HALF, pws->h[4],  pwt->h[4]);
4304     pwd->h[5]  = msa_srlr_df(DF_HALF, pws->h[5],  pwt->h[5]);
4305     pwd->h[6]  = msa_srlr_df(DF_HALF, pws->h[6],  pwt->h[6]);
4306     pwd->h[7]  = msa_srlr_df(DF_HALF, pws->h[7],  pwt->h[7]);
4307 }
4308
4309 void helper_msa_srlr_w(CPUMIPSState *env,
4310                        uint32_t wd, uint32_t ws, uint32_t wt)
4311 {
4312     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4313     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4314     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4315
4316     pwd->w[0]  = msa_srlr_df(DF_WORD, pws->w[0],  pwt->w[0]);
4317     pwd->w[1]  = msa_srlr_df(DF_WORD, pws->w[1],  pwt->w[1]);
4318     pwd->w[2]  = msa_srlr_df(DF_WORD, pws->w[2],  pwt->w[2]);
4319     pwd->w[3]  = msa_srlr_df(DF_WORD, pws->w[3],  pwt->w[3]);
4320 }
4321
4322 void helper_msa_srlr_d(CPUMIPSState *env,
4323                        uint32_t wd, uint32_t ws, uint32_t wt)
4324 {
4325     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4326     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4327     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4328
4329     pwd->d[0]  = msa_srlr_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
4330     pwd->d[1]  = msa_srlr_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
4331 }
4332
4333
4334 #define MSA_FN_IMM8(FUNC, DEST, OPERATION)                              \
4335 void helper_msa_ ## FUNC(CPUMIPSState *env, uint32_t wd, uint32_t ws,   \
4336         uint32_t i8)                                                    \
4337 {                                                                       \
4338     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
4339     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
4340     uint32_t i;                                                         \
4341     for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {                        \
4342         DEST = OPERATION;                                               \
4343     }                                                                   \
4344 }
4345
4346 MSA_FN_IMM8(andi_b, pwd->b[i], pws->b[i] & i8)
4347 MSA_FN_IMM8(ori_b, pwd->b[i], pws->b[i] | i8)
4348 MSA_FN_IMM8(nori_b, pwd->b[i], ~(pws->b[i] | i8))
4349 MSA_FN_IMM8(xori_b, pwd->b[i], pws->b[i] ^ i8)
4350
4351 #define BIT_MOVE_IF_NOT_ZERO(dest, arg1, arg2, df) \
4352             UNSIGNED(((dest & (~arg2)) | (arg1 & arg2)), df)
4353 MSA_FN_IMM8(bmnzi_b, pwd->b[i],
4354         BIT_MOVE_IF_NOT_ZERO(pwd->b[i], pws->b[i], i8, DF_BYTE))
4355
4356 #define BIT_MOVE_IF_ZERO(dest, arg1, arg2, df) \
4357             UNSIGNED((dest & arg2) | (arg1 & (~arg2)), df)
4358 MSA_FN_IMM8(bmzi_b, pwd->b[i],
4359         BIT_MOVE_IF_ZERO(pwd->b[i], pws->b[i], i8, DF_BYTE))
4360
4361 #define BIT_SELECT(dest, arg1, arg2, df) \
4362             UNSIGNED((arg1 & (~dest)) | (arg2 & dest), df)
4363 MSA_FN_IMM8(bseli_b, pwd->b[i],
4364         BIT_SELECT(pwd->b[i], pws->b[i], i8, DF_BYTE))
4365
4366 #undef BIT_SELECT
4367 #undef BIT_MOVE_IF_ZERO
4368 #undef BIT_MOVE_IF_NOT_ZERO
4369 #undef MSA_FN_IMM8
4370
4371 #define SHF_POS(i, imm) (((i) & 0xfc) + (((imm) >> (2 * ((i) & 0x03))) & 0x03))
4372
4373 void helper_msa_shf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4374                        uint32_t ws, uint32_t imm)
4375 {
4376     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4377     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4378     wr_t wx, *pwx = &wx;
4379     uint32_t i;
4380
4381     switch (df) {
4382     case DF_BYTE:
4383         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
4384             pwx->b[i] = pws->b[SHF_POS(i, imm)];
4385         }
4386         break;
4387     case DF_HALF:
4388         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
4389             pwx->h[i] = pws->h[SHF_POS(i, imm)];
4390         }
4391         break;
4392     case DF_WORD:
4393         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4394             pwx->w[i] = pws->w[SHF_POS(i, imm)];
4395         }
4396         break;
4397     default:
4398         assert(0);
4399     }
4400     msa_move_v(pwd, pwx);
4401 }
4402
4403 static inline int64_t msa_subv_df(uint32_t df, int64_t arg1, int64_t arg2)
4404 {
4405     return arg1 - arg2;
4406 }
4407
4408 #define MSA_BINOP_IMM_DF(helper, func)                                  \
4409 void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df,       \
4410                         uint32_t wd, uint32_t ws, int32_t u5)           \
4411 {                                                                       \
4412     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
4413     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
4414     uint32_t i;                                                         \
4415                                                                         \
4416     switch (df) {                                                       \
4417     case DF_BYTE:                                                       \
4418         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {                    \
4419             pwd->b[i] = msa_ ## func ## _df(df, pws->b[i], u5);         \
4420         }                                                               \
4421         break;                                                          \
4422     case DF_HALF:                                                       \
4423         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {                    \
4424             pwd->h[i] = msa_ ## func ## _df(df, pws->h[i], u5);         \
4425         }                                                               \
4426         break;                                                          \
4427     case DF_WORD:                                                       \
4428         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {                    \
4429             pwd->w[i] = msa_ ## func ## _df(df, pws->w[i], u5);         \
4430         }                                                               \
4431         break;                                                          \
4432     case DF_DOUBLE:                                                     \
4433         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {                  \
4434             pwd->d[i] = msa_ ## func ## _df(df, pws->d[i], u5);         \
4435         }                                                               \
4436         break;                                                          \
4437     default:                                                            \
4438         assert(0);                                                      \
4439     }                                                                   \
4440 }
4441
4442 MSA_BINOP_IMM_DF(addvi, addv)
4443 MSA_BINOP_IMM_DF(subvi, subv)
4444 MSA_BINOP_IMM_DF(ceqi, ceq)
4445 MSA_BINOP_IMM_DF(clei_s, cle_s)
4446 MSA_BINOP_IMM_DF(clei_u, cle_u)
4447 MSA_BINOP_IMM_DF(clti_s, clt_s)
4448 MSA_BINOP_IMM_DF(clti_u, clt_u)
4449 MSA_BINOP_IMM_DF(maxi_s, max_s)
4450 MSA_BINOP_IMM_DF(maxi_u, max_u)
4451 MSA_BINOP_IMM_DF(mini_s, min_s)
4452 MSA_BINOP_IMM_DF(mini_u, min_u)
4453 #undef MSA_BINOP_IMM_DF
4454
4455 void helper_msa_ldi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4456                        int32_t s10)
4457 {
4458     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4459     uint32_t i;
4460
4461     switch (df) {
4462     case DF_BYTE:
4463         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
4464             pwd->b[i] = (int8_t)s10;
4465         }
4466         break;
4467     case DF_HALF:
4468         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
4469             pwd->h[i] = (int16_t)s10;
4470         }
4471         break;
4472     case DF_WORD:
4473         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4474             pwd->w[i] = (int32_t)s10;
4475         }
4476         break;
4477     case DF_DOUBLE:
4478         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4479             pwd->d[i] = (int64_t)s10;
4480         }
4481        break;
4482     default:
4483         assert(0);
4484     }
4485 }
4486
4487 static inline int64_t msa_sat_s_df(uint32_t df, int64_t arg, uint32_t m)
4488 {
4489     return arg < M_MIN_INT(m + 1) ? M_MIN_INT(m + 1) :
4490                                     arg > M_MAX_INT(m + 1) ? M_MAX_INT(m + 1) :
4491                                                              arg;
4492 }
4493
4494 static inline int64_t msa_sat_u_df(uint32_t df, int64_t arg, uint32_t m)
4495 {
4496     uint64_t u_arg = UNSIGNED(arg, df);
4497     return  u_arg < M_MAX_UINT(m + 1) ? u_arg :
4498                                         M_MAX_UINT(m + 1);
4499 }
4500
4501 #define MSA_BINOP_IMMU_DF(helper, func)                                  \
4502 void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, uint32_t wd, \
4503                        uint32_t ws, uint32_t u5)                        \
4504 {                                                                       \
4505     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
4506     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
4507     uint32_t i;                                                         \
4508                                                                         \
4509     switch (df) {                                                       \
4510     case DF_BYTE:                                                       \
4511         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {                    \
4512             pwd->b[i] = msa_ ## func ## _df(df, pws->b[i], u5);         \
4513         }                                                               \
4514         break;                                                          \
4515     case DF_HALF:                                                       \
4516         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {                    \
4517             pwd->h[i] = msa_ ## func ## _df(df, pws->h[i], u5);         \
4518         }                                                               \
4519         break;                                                          \
4520     case DF_WORD:                                                       \
4521         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {                    \
4522             pwd->w[i] = msa_ ## func ## _df(df, pws->w[i], u5);         \
4523         }                                                               \
4524         break;                                                          \
4525     case DF_DOUBLE:                                                     \
4526         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {                  \
4527             pwd->d[i] = msa_ ## func ## _df(df, pws->d[i], u5);         \
4528         }                                                               \
4529         break;                                                          \
4530     default:                                                            \
4531         assert(0);                                                      \
4532     }                                                                   \
4533 }
4534
4535 MSA_BINOP_IMMU_DF(slli, sll)
4536 MSA_BINOP_IMMU_DF(srai, sra)
4537 MSA_BINOP_IMMU_DF(srli, srl)
4538 MSA_BINOP_IMMU_DF(bclri, bclr)
4539 MSA_BINOP_IMMU_DF(bseti, bset)
4540 MSA_BINOP_IMMU_DF(bnegi, bneg)
4541 MSA_BINOP_IMMU_DF(sat_s, sat_s)
4542 MSA_BINOP_IMMU_DF(sat_u, sat_u)
4543 MSA_BINOP_IMMU_DF(srari, srar)
4544 MSA_BINOP_IMMU_DF(srlri, srlr)
4545 #undef MSA_BINOP_IMMU_DF
4546
4547 #define MSA_TEROP_IMMU_DF(helper, func)                                  \
4548 void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df,       \
4549                                   uint32_t wd, uint32_t ws, uint32_t u5) \
4550 {                                                                       \
4551     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
4552     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
4553     uint32_t i;                                                         \
4554                                                                         \
4555     switch (df) {                                                       \
4556     case DF_BYTE:                                                       \
4557         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {                    \
4558             pwd->b[i] = msa_ ## func ## _df(df, pwd->b[i], pws->b[i],   \
4559                                             u5);                        \
4560         }                                                               \
4561         break;                                                          \
4562     case DF_HALF:                                                       \
4563         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {                    \
4564             pwd->h[i] = msa_ ## func ## _df(df, pwd->h[i], pws->h[i],   \
4565                                             u5);                        \
4566         }                                                               \
4567         break;                                                          \
4568     case DF_WORD:                                                       \
4569         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {                    \
4570             pwd->w[i] = msa_ ## func ## _df(df, pwd->w[i], pws->w[i],   \
4571                                             u5);                        \
4572         }                                                               \
4573         break;                                                          \
4574     case DF_DOUBLE:                                                     \
4575         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {                  \
4576             pwd->d[i] = msa_ ## func ## _df(df, pwd->d[i], pws->d[i],   \
4577                                             u5);                        \
4578         }                                                               \
4579         break;                                                          \
4580     default:                                                            \
4581         assert(0);                                                      \
4582     }                                                                   \
4583 }
4584
4585 MSA_TEROP_IMMU_DF(binsli, binsl)
4586 MSA_TEROP_IMMU_DF(binsri, binsr)
4587 #undef MSA_TEROP_IMMU_DF
4588
4589 static inline int64_t msa_subs_s_df(uint32_t df, int64_t arg1, int64_t arg2)
4590 {
4591     int64_t max_int = DF_MAX_INT(df);
4592     int64_t min_int = DF_MIN_INT(df);
4593     if (arg2 > 0) {
4594         return (min_int + arg2 < arg1) ? arg1 - arg2 : min_int;
4595     } else {
4596         return (arg1 < max_int + arg2) ? arg1 - arg2 : max_int;
4597     }
4598 }
4599
4600 static inline int64_t msa_subs_u_df(uint32_t df, int64_t arg1, int64_t arg2)
4601 {
4602     uint64_t u_arg1 = UNSIGNED(arg1, df);
4603     uint64_t u_arg2 = UNSIGNED(arg2, df);
4604     return (u_arg1 > u_arg2) ? u_arg1 - u_arg2 : 0;
4605 }
4606
4607 static inline int64_t msa_subsus_u_df(uint32_t df, int64_t arg1, int64_t arg2)
4608 {
4609     uint64_t u_arg1 = UNSIGNED(arg1, df);
4610     uint64_t max_uint = DF_MAX_UINT(df);
4611     if (arg2 >= 0) {
4612         uint64_t u_arg2 = (uint64_t)arg2;
4613         return (u_arg1 > u_arg2) ?
4614             (int64_t)(u_arg1 - u_arg2) :
4615             0;
4616     } else {
4617         uint64_t u_arg2 = (uint64_t)(-arg2);
4618         return (u_arg1 < max_uint - u_arg2) ?
4619             (int64_t)(u_arg1 + u_arg2) :
4620             (int64_t)max_uint;
4621     }
4622 }
4623
4624 static inline int64_t msa_subsuu_s_df(uint32_t df, int64_t arg1, int64_t arg2)
4625 {
4626     uint64_t u_arg1 = UNSIGNED(arg1, df);
4627     uint64_t u_arg2 = UNSIGNED(arg2, df);
4628     int64_t max_int = DF_MAX_INT(df);
4629     int64_t min_int = DF_MIN_INT(df);
4630     if (u_arg1 > u_arg2) {
4631         return u_arg1 - u_arg2 < (uint64_t)max_int ?
4632             (int64_t)(u_arg1 - u_arg2) :
4633             max_int;
4634     } else {
4635         return u_arg2 - u_arg1 < (uint64_t)(-min_int) ?
4636             (int64_t)(u_arg1 - u_arg2) :
4637             min_int;
4638     }
4639 }
4640
4641 static inline int64_t msa_mulv_df(uint32_t df, int64_t arg1, int64_t arg2)
4642 {
4643     return arg1 * arg2;
4644 }
4645
4646 #define SIGNED_EXTRACT(e, o, a, df)     \
4647     do {                                \
4648         e = SIGNED_EVEN(a, df);         \
4649         o = SIGNED_ODD(a, df);          \
4650     } while (0)
4651
4652 #define UNSIGNED_EXTRACT(e, o, a, df)   \
4653     do {                                \
4654         e = UNSIGNED_EVEN(a, df);       \
4655         o = UNSIGNED_ODD(a, df);        \
4656     } while (0)
4657
4658 static inline int64_t msa_dotp_s_df(uint32_t df, int64_t arg1, int64_t arg2)
4659 {
4660     int64_t even_arg1;
4661     int64_t even_arg2;
4662     int64_t odd_arg1;
4663     int64_t odd_arg2;
4664     SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
4665     SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
4666     return (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
4667 }
4668
4669 static inline int64_t msa_dotp_u_df(uint32_t df, int64_t arg1, int64_t arg2)
4670 {
4671     int64_t even_arg1;
4672     int64_t even_arg2;
4673     int64_t odd_arg1;
4674     int64_t odd_arg2;
4675     UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
4676     UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
4677     return (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
4678 }
4679
4680 #define CONCATENATE_AND_SLIDE(s, k)             \
4681     do {                                        \
4682         for (i = 0; i < s; i++) {               \
4683             v[i]     = pws->b[s * k + i];       \
4684             v[i + s] = pwd->b[s * k + i];       \
4685         }                                       \
4686         for (i = 0; i < s; i++) {               \
4687             pwd->b[s * k + i] = v[i + n];       \
4688         }                                       \
4689     } while (0)
4690
4691 static inline void msa_sld_df(uint32_t df, wr_t *pwd,
4692                               wr_t *pws, target_ulong rt)
4693 {
4694     uint32_t n = rt % DF_ELEMENTS(df);
4695     uint8_t v[64];
4696     uint32_t i, k;
4697
4698     switch (df) {
4699     case DF_BYTE:
4700         CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_BYTE), 0);
4701         break;
4702     case DF_HALF:
4703         for (k = 0; k < 2; k++) {
4704             CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_HALF), k);
4705         }
4706         break;
4707     case DF_WORD:
4708         for (k = 0; k < 4; k++) {
4709             CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_WORD), k);
4710         }
4711         break;
4712     case DF_DOUBLE:
4713         for (k = 0; k < 8; k++) {
4714             CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_DOUBLE), k);
4715         }
4716         break;
4717     default:
4718         assert(0);
4719     }
4720 }
4721
4722 static inline int64_t msa_mul_q_df(uint32_t df, int64_t arg1, int64_t arg2)
4723 {
4724     int64_t q_min = DF_MIN_INT(df);
4725     int64_t q_max = DF_MAX_INT(df);
4726
4727     if (arg1 == q_min && arg2 == q_min) {
4728         return q_max;
4729     }
4730     return (arg1 * arg2) >> (DF_BITS(df) - 1);
4731 }
4732
4733 static inline int64_t msa_mulr_q_df(uint32_t df, int64_t arg1, int64_t arg2)
4734 {
4735     int64_t q_min = DF_MIN_INT(df);
4736     int64_t q_max = DF_MAX_INT(df);
4737     int64_t r_bit = 1 << (DF_BITS(df) - 2);
4738
4739     if (arg1 == q_min && arg2 == q_min) {
4740         return q_max;
4741     }
4742     return (arg1 * arg2 + r_bit) >> (DF_BITS(df) - 1);
4743 }
4744
4745 #define MSA_BINOP_DF(func) \
4746 void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df,         \
4747                                 uint32_t wd, uint32_t ws, uint32_t wt)  \
4748 {                                                                       \
4749     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
4750     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
4751     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);                          \
4752                                                                         \
4753     switch (df) {                                                       \
4754     case DF_BYTE:                                                       \
4755         pwd->b[0]  = msa_ ## func ## _df(df, pws->b[0],  pwt->b[0]);    \
4756         pwd->b[1]  = msa_ ## func ## _df(df, pws->b[1],  pwt->b[1]);    \
4757         pwd->b[2]  = msa_ ## func ## _df(df, pws->b[2],  pwt->b[2]);    \
4758         pwd->b[3]  = msa_ ## func ## _df(df, pws->b[3],  pwt->b[3]);    \
4759         pwd->b[4]  = msa_ ## func ## _df(df, pws->b[4],  pwt->b[4]);    \
4760         pwd->b[5]  = msa_ ## func ## _df(df, pws->b[5],  pwt->b[5]);    \
4761         pwd->b[6]  = msa_ ## func ## _df(df, pws->b[6],  pwt->b[6]);    \
4762         pwd->b[7]  = msa_ ## func ## _df(df, pws->b[7],  pwt->b[7]);    \
4763         pwd->b[8]  = msa_ ## func ## _df(df, pws->b[8],  pwt->b[8]);    \
4764         pwd->b[9]  = msa_ ## func ## _df(df, pws->b[9],  pwt->b[9]);    \
4765         pwd->b[10] = msa_ ## func ## _df(df, pws->b[10], pwt->b[10]);   \
4766         pwd->b[11] = msa_ ## func ## _df(df, pws->b[11], pwt->b[11]);   \
4767         pwd->b[12] = msa_ ## func ## _df(df, pws->b[12], pwt->b[12]);   \
4768         pwd->b[13] = msa_ ## func ## _df(df, pws->b[13], pwt->b[13]);   \
4769         pwd->b[14] = msa_ ## func ## _df(df, pws->b[14], pwt->b[14]);   \
4770         pwd->b[15] = msa_ ## func ## _df(df, pws->b[15], pwt->b[15]);   \
4771         break;                                                          \
4772     case DF_HALF:                                                       \
4773         pwd->h[0] = msa_ ## func ## _df(df, pws->h[0], pwt->h[0]);      \
4774         pwd->h[1] = msa_ ## func ## _df(df, pws->h[1], pwt->h[1]);      \
4775         pwd->h[2] = msa_ ## func ## _df(df, pws->h[2], pwt->h[2]);      \
4776         pwd->h[3] = msa_ ## func ## _df(df, pws->h[3], pwt->h[3]);      \
4777         pwd->h[4] = msa_ ## func ## _df(df, pws->h[4], pwt->h[4]);      \
4778         pwd->h[5] = msa_ ## func ## _df(df, pws->h[5], pwt->h[5]);      \
4779         pwd->h[6] = msa_ ## func ## _df(df, pws->h[6], pwt->h[6]);      \
4780         pwd->h[7] = msa_ ## func ## _df(df, pws->h[7], pwt->h[7]);      \
4781         break;                                                          \
4782     case DF_WORD:                                                       \
4783         pwd->w[0] = msa_ ## func ## _df(df, pws->w[0], pwt->w[0]);      \
4784         pwd->w[1] = msa_ ## func ## _df(df, pws->w[1], pwt->w[1]);      \
4785         pwd->w[2] = msa_ ## func ## _df(df, pws->w[2], pwt->w[2]);      \
4786         pwd->w[3] = msa_ ## func ## _df(df, pws->w[3], pwt->w[3]);      \
4787         break;                                                          \
4788     case DF_DOUBLE:                                                     \
4789         pwd->d[0] = msa_ ## func ## _df(df, pws->d[0], pwt->d[0]);      \
4790         pwd->d[1] = msa_ ## func ## _df(df, pws->d[1], pwt->d[1]);      \
4791         break;                                                          \
4792     default:                                                            \
4793         assert(0);                                                      \
4794     }                                                                   \
4795 }
4796
4797 MSA_BINOP_DF(subv)
4798 MSA_BINOP_DF(subs_s)
4799 MSA_BINOP_DF(subs_u)
4800 MSA_BINOP_DF(subsus_u)
4801 MSA_BINOP_DF(subsuu_s)
4802 MSA_BINOP_DF(mulv)
4803 MSA_BINOP_DF(dotp_s)
4804 MSA_BINOP_DF(dotp_u)
4805
4806 MSA_BINOP_DF(mul_q)
4807 MSA_BINOP_DF(mulr_q)
4808 #undef MSA_BINOP_DF
4809
4810 void helper_msa_sld_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4811                        uint32_t ws, uint32_t rt)
4812 {
4813     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4814     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4815
4816     msa_sld_df(df, pwd, pws, env->active_tc.gpr[rt]);
4817 }
4818
4819 static inline int64_t msa_maddv_df(uint32_t df, int64_t dest, int64_t arg1,
4820                                    int64_t arg2)
4821 {
4822     return dest + arg1 * arg2;
4823 }
4824
4825 static inline int64_t msa_msubv_df(uint32_t df, int64_t dest, int64_t arg1,
4826                                    int64_t arg2)
4827 {
4828     return dest - arg1 * arg2;
4829 }
4830
4831 static inline int64_t msa_dpadd_s_df(uint32_t df, int64_t dest, int64_t arg1,
4832                                      int64_t arg2)
4833 {
4834     int64_t even_arg1;
4835     int64_t even_arg2;
4836     int64_t odd_arg1;
4837     int64_t odd_arg2;
4838     SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
4839     SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
4840     return dest + (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
4841 }
4842
4843 static inline int64_t msa_dpadd_u_df(uint32_t df, int64_t dest, int64_t arg1,
4844                                      int64_t arg2)
4845 {
4846     int64_t even_arg1;
4847     int64_t even_arg2;
4848     int64_t odd_arg1;
4849     int64_t odd_arg2;
4850     UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
4851     UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
4852     return dest + (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
4853 }
4854
4855 static inline int64_t msa_dpsub_s_df(uint32_t df, int64_t dest, int64_t arg1,
4856                                      int64_t arg2)
4857 {
4858     int64_t even_arg1;
4859     int64_t even_arg2;
4860     int64_t odd_arg1;
4861     int64_t odd_arg2;
4862     SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
4863     SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
4864     return dest - ((even_arg1 * even_arg2) + (odd_arg1 * odd_arg2));
4865 }
4866
4867 static inline int64_t msa_dpsub_u_df(uint32_t df, int64_t dest, int64_t arg1,
4868                                      int64_t arg2)
4869 {
4870     int64_t even_arg1;
4871     int64_t even_arg2;
4872     int64_t odd_arg1;
4873     int64_t odd_arg2;
4874     UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
4875     UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
4876     return dest - ((even_arg1 * even_arg2) + (odd_arg1 * odd_arg2));
4877 }
4878
4879 static inline int64_t msa_madd_q_df(uint32_t df, int64_t dest, int64_t arg1,
4880                                     int64_t arg2)
4881 {
4882     int64_t q_prod, q_ret;
4883
4884     int64_t q_max = DF_MAX_INT(df);
4885     int64_t q_min = DF_MIN_INT(df);
4886
4887     q_prod = arg1 * arg2;
4888     q_ret = ((dest << (DF_BITS(df) - 1)) + q_prod) >> (DF_BITS(df) - 1);
4889
4890     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
4891 }
4892
4893 static inline int64_t msa_msub_q_df(uint32_t df, int64_t dest, int64_t arg1,
4894                                     int64_t arg2)
4895 {
4896     int64_t q_prod, q_ret;
4897
4898     int64_t q_max = DF_MAX_INT(df);
4899     int64_t q_min = DF_MIN_INT(df);
4900
4901     q_prod = arg1 * arg2;
4902     q_ret = ((dest << (DF_BITS(df) - 1)) - q_prod) >> (DF_BITS(df) - 1);
4903
4904     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
4905 }
4906
4907 static inline int64_t msa_maddr_q_df(uint32_t df, int64_t dest, int64_t arg1,
4908                                      int64_t arg2)
4909 {
4910     int64_t q_prod, q_ret;
4911
4912     int64_t q_max = DF_MAX_INT(df);
4913     int64_t q_min = DF_MIN_INT(df);
4914     int64_t r_bit = 1 << (DF_BITS(df) - 2);
4915
4916     q_prod = arg1 * arg2;
4917     q_ret = ((dest << (DF_BITS(df) - 1)) + q_prod + r_bit) >> (DF_BITS(df) - 1);
4918
4919     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
4920 }
4921
4922 static inline int64_t msa_msubr_q_df(uint32_t df, int64_t dest, int64_t arg1,
4923                                      int64_t arg2)
4924 {
4925     int64_t q_prod, q_ret;
4926
4927     int64_t q_max = DF_MAX_INT(df);
4928     int64_t q_min = DF_MIN_INT(df);
4929     int64_t r_bit = 1 << (DF_BITS(df) - 2);
4930
4931     q_prod = arg1 * arg2;
4932     q_ret = ((dest << (DF_BITS(df) - 1)) - q_prod + r_bit) >> (DF_BITS(df) - 1);
4933
4934     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
4935 }
4936
4937 #define MSA_TEROP_DF(func) \
4938 void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, uint32_t wd,  \
4939                                 uint32_t ws, uint32_t wt)                     \
4940 {                                                                             \
4941     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                                \
4942     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                                \
4943     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);                                \
4944                                                                               \
4945     switch (df) {                                                             \
4946     case DF_BYTE:                                                             \
4947         pwd->b[0]  = msa_ ## func ## _df(df, pwd->b[0],  pws->b[0],           \
4948                                              pwt->b[0]);                      \
4949         pwd->b[1]  = msa_ ## func ## _df(df, pwd->b[1],  pws->b[1],           \
4950                                              pwt->b[1]);                      \
4951         pwd->b[2]  = msa_ ## func ## _df(df, pwd->b[2],  pws->b[2],           \
4952                                              pwt->b[2]);                      \
4953         pwd->b[3]  = msa_ ## func ## _df(df, pwd->b[3],  pws->b[3],           \
4954                                              pwt->b[3]);                      \
4955         pwd->b[4]  = msa_ ## func ## _df(df, pwd->b[4],  pws->b[4],           \
4956                                              pwt->b[4]);                      \
4957         pwd->b[5]  = msa_ ## func ## _df(df, pwd->b[5],  pws->b[5],           \
4958                                              pwt->b[5]);                      \
4959         pwd->b[6]  = msa_ ## func ## _df(df, pwd->b[6],  pws->b[6],           \
4960                                              pwt->b[6]);                      \
4961         pwd->b[7]  = msa_ ## func ## _df(df, pwd->b[7],  pws->b[7],           \
4962                                              pwt->b[7]);                      \
4963         pwd->b[8]  = msa_ ## func ## _df(df, pwd->b[8],  pws->b[8],           \
4964                                              pwt->b[8]);                      \
4965         pwd->b[9]  = msa_ ## func ## _df(df, pwd->b[9],  pws->b[9],           \
4966                                              pwt->b[9]);                      \
4967         pwd->b[10] = msa_ ## func ## _df(df, pwd->b[10], pws->b[10],          \
4968                                              pwt->b[10]);                     \
4969         pwd->b[11] = msa_ ## func ## _df(df, pwd->b[11], pws->b[11],          \
4970                                              pwt->b[11]);                     \
4971         pwd->b[12] = msa_ ## func ## _df(df, pwd->b[12], pws->b[12],          \
4972                                              pwt->b[12]);                     \
4973         pwd->b[13] = msa_ ## func ## _df(df, pwd->b[13], pws->b[13],          \
4974                                              pwt->b[13]);                     \
4975         pwd->b[14] = msa_ ## func ## _df(df, pwd->b[14], pws->b[14],          \
4976                                              pwt->b[14]);                     \
4977         pwd->b[15] = msa_ ## func ## _df(df, pwd->b[15], pws->b[15],          \
4978                                              pwt->b[15]);                     \
4979         break;                                                                \
4980     case DF_HALF:                                                             \
4981         pwd->h[0] = msa_ ## func ## _df(df, pwd->h[0], pws->h[0], pwt->h[0]); \
4982         pwd->h[1] = msa_ ## func ## _df(df, pwd->h[1], pws->h[1], pwt->h[1]); \
4983         pwd->h[2] = msa_ ## func ## _df(df, pwd->h[2], pws->h[2], pwt->h[2]); \
4984         pwd->h[3] = msa_ ## func ## _df(df, pwd->h[3], pws->h[3], pwt->h[3]); \
4985         pwd->h[4] = msa_ ## func ## _df(df, pwd->h[4], pws->h[4], pwt->h[4]); \
4986         pwd->h[5] = msa_ ## func ## _df(df, pwd->h[5], pws->h[5], pwt->h[5]); \
4987         pwd->h[6] = msa_ ## func ## _df(df, pwd->h[6], pws->h[6], pwt->h[6]); \
4988         pwd->h[7] = msa_ ## func ## _df(df, pwd->h[7], pws->h[7], pwt->h[7]); \
4989         break;                                                                \
4990     case DF_WORD:                                                             \
4991         pwd->w[0] = msa_ ## func ## _df(df, pwd->w[0], pws->w[0], pwt->w[0]); \
4992         pwd->w[1] = msa_ ## func ## _df(df, pwd->w[1], pws->w[1], pwt->w[1]); \
4993         pwd->w[2] = msa_ ## func ## _df(df, pwd->w[2], pws->w[2], pwt->w[2]); \
4994         pwd->w[3] = msa_ ## func ## _df(df, pwd->w[3], pws->w[3], pwt->w[3]); \
4995         break;                                                                \
4996     case DF_DOUBLE:                                                           \
4997         pwd->d[0] = msa_ ## func ## _df(df, pwd->d[0], pws->d[0], pwt->d[0]); \
4998         pwd->d[1] = msa_ ## func ## _df(df, pwd->d[1], pws->d[1], pwt->d[1]); \
4999         break;                                                                \
5000     default:                                                                  \
5001         assert(0);                                                            \
5002     }                                                                         \
5003 }
5004
5005 MSA_TEROP_DF(maddv)
5006 MSA_TEROP_DF(msubv)
5007 MSA_TEROP_DF(dpadd_s)
5008 MSA_TEROP_DF(dpadd_u)
5009 MSA_TEROP_DF(dpsub_s)
5010 MSA_TEROP_DF(dpsub_u)
5011 MSA_TEROP_DF(binsl)
5012 MSA_TEROP_DF(binsr)
5013 MSA_TEROP_DF(madd_q)
5014 MSA_TEROP_DF(msub_q)
5015 MSA_TEROP_DF(maddr_q)
5016 MSA_TEROP_DF(msubr_q)
5017 #undef MSA_TEROP_DF
5018
5019 static inline void msa_splat_df(uint32_t df, wr_t *pwd,
5020                                 wr_t *pws, target_ulong rt)
5021 {
5022     uint32_t n = rt % DF_ELEMENTS(df);
5023     uint32_t i;
5024
5025     switch (df) {
5026     case DF_BYTE:
5027         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
5028             pwd->b[i] = pws->b[n];
5029         }
5030         break;
5031     case DF_HALF:
5032         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
5033             pwd->h[i] = pws->h[n];
5034         }
5035         break;
5036     case DF_WORD:
5037         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5038             pwd->w[i] = pws->w[n];
5039         }
5040         break;
5041     case DF_DOUBLE:
5042         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5043             pwd->d[i] = pws->d[n];
5044         }
5045        break;
5046     default:
5047         assert(0);
5048     }
5049 }
5050
5051 void helper_msa_splat_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5052                          uint32_t ws, uint32_t rt)
5053 {
5054     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5055     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5056
5057     msa_splat_df(df, pwd, pws, env->active_tc.gpr[rt]);
5058 }
5059
5060 #define MSA_DO_B MSA_DO(b)
5061 #define MSA_DO_H MSA_DO(h)
5062 #define MSA_DO_W MSA_DO(w)
5063 #define MSA_DO_D MSA_DO(d)
5064
5065 #define MSA_LOOP_B MSA_LOOP(B)
5066 #define MSA_LOOP_H MSA_LOOP(H)
5067 #define MSA_LOOP_W MSA_LOOP(W)
5068 #define MSA_LOOP_D MSA_LOOP(D)
5069
5070 #define MSA_LOOP_COND_B MSA_LOOP_COND(DF_BYTE)
5071 #define MSA_LOOP_COND_H MSA_LOOP_COND(DF_HALF)
5072 #define MSA_LOOP_COND_W MSA_LOOP_COND(DF_WORD)
5073 #define MSA_LOOP_COND_D MSA_LOOP_COND(DF_DOUBLE)
5074
5075 #define MSA_LOOP(DF) \
5076     do { \
5077         for (i = 0; i < (MSA_LOOP_COND_ ## DF) ; i++) { \
5078             MSA_DO_ ## DF; \
5079         } \
5080     } while (0)
5081
5082 #define MSA_FN_DF(FUNC)                                             \
5083 void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
5084         uint32_t ws, uint32_t wt)                                   \
5085 {                                                                   \
5086     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                      \
5087     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                      \
5088     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);                      \
5089     wr_t wx, *pwx = &wx;                                            \
5090     uint32_t i;                                                     \
5091     switch (df) {                                                   \
5092     case DF_BYTE:                                                   \
5093         MSA_LOOP_B;                                                 \
5094         break;                                                      \
5095     case DF_HALF:                                                   \
5096         MSA_LOOP_H;                                                 \
5097         break;                                                      \
5098     case DF_WORD:                                                   \
5099         MSA_LOOP_W;                                                 \
5100         break;                                                      \
5101     case DF_DOUBLE:                                                 \
5102         MSA_LOOP_D;                                                 \
5103         break;                                                      \
5104     default:                                                        \
5105         assert(0);                                                  \
5106     }                                                               \
5107     msa_move_v(pwd, pwx);                                           \
5108 }
5109
5110 #define MSA_LOOP_COND(DF) \
5111             (DF_ELEMENTS(DF) / 2)
5112
5113 #define Rb(pwr, i) (pwr->b[i])
5114 #define Lb(pwr, i) (pwr->b[i + DF_ELEMENTS(DF_BYTE) / 2])
5115 #define Rh(pwr, i) (pwr->h[i])
5116 #define Lh(pwr, i) (pwr->h[i + DF_ELEMENTS(DF_HALF) / 2])
5117 #define Rw(pwr, i) (pwr->w[i])
5118 #define Lw(pwr, i) (pwr->w[i + DF_ELEMENTS(DF_WORD) / 2])
5119 #define Rd(pwr, i) (pwr->d[i])
5120 #define Ld(pwr, i) (pwr->d[i + DF_ELEMENTS(DF_DOUBLE) / 2])
5121
5122 #undef MSA_LOOP_COND
5123
5124 #define MSA_LOOP_COND(DF) \
5125             (DF_ELEMENTS(DF))
5126
5127 #define MSA_DO(DF)                                                          \
5128     do {                                                                    \
5129         uint32_t n = DF_ELEMENTS(df);                                       \
5130         uint32_t k = (pwd->DF[i] & 0x3f) % (2 * n);                         \
5131         pwx->DF[i] =                                                        \
5132             (pwd->DF[i] & 0xc0) ? 0 : k < n ? pwt->DF[k] : pws->DF[k - n];  \
5133     } while (0)
5134 MSA_FN_DF(vshf_df)
5135 #undef MSA_DO
5136 #undef MSA_LOOP_COND
5137 #undef MSA_FN_DF
5138
5139
5140 void helper_msa_sldi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5141                         uint32_t ws, uint32_t n)
5142 {
5143     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5144     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5145
5146     msa_sld_df(df, pwd, pws, n);
5147 }
5148
5149 void helper_msa_splati_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5150                           uint32_t ws, uint32_t n)
5151 {
5152     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5153     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5154
5155     msa_splat_df(df, pwd, pws, n);
5156 }
5157
5158 void helper_msa_copy_s_b(CPUMIPSState *env, uint32_t rd,
5159                          uint32_t ws, uint32_t n)
5160 {
5161     n %= 16;
5162 #if defined(HOST_WORDS_BIGENDIAN)
5163     if (n < 8) {
5164         n = 8 - n - 1;
5165     } else {
5166         n = 24 - n - 1;
5167     }
5168 #endif
5169     env->active_tc.gpr[rd] = (int8_t)env->active_fpu.fpr[ws].wr.b[n];
5170 }
5171
5172 void helper_msa_copy_s_h(CPUMIPSState *env, uint32_t rd,
5173                          uint32_t ws, uint32_t n)
5174 {
5175     n %= 8;
5176 #if defined(HOST_WORDS_BIGENDIAN)
5177     if (n < 4) {
5178         n = 4 - n - 1;
5179     } else {
5180         n = 12 - n - 1;
5181     }
5182 #endif
5183     env->active_tc.gpr[rd] = (int16_t)env->active_fpu.fpr[ws].wr.h[n];
5184 }
5185
5186 void helper_msa_copy_s_w(CPUMIPSState *env, uint32_t rd,
5187                          uint32_t ws, uint32_t n)
5188 {
5189     n %= 4;
5190 #if defined(HOST_WORDS_BIGENDIAN)
5191     if (n < 2) {
5192         n = 2 - n - 1;
5193     } else {
5194         n = 6 - n - 1;
5195     }
5196 #endif
5197     env->active_tc.gpr[rd] = (int32_t)env->active_fpu.fpr[ws].wr.w[n];
5198 }
5199
5200 void helper_msa_copy_s_d(CPUMIPSState *env, uint32_t rd,
5201                          uint32_t ws, uint32_t n)
5202 {
5203     n %= 2;
5204     env->active_tc.gpr[rd] = (int64_t)env->active_fpu.fpr[ws].wr.d[n];
5205 }
5206
5207 void helper_msa_copy_u_b(CPUMIPSState *env, uint32_t rd,
5208                          uint32_t ws, uint32_t n)
5209 {
5210     n %= 16;
5211 #if defined(HOST_WORDS_BIGENDIAN)
5212     if (n < 8) {
5213         n = 8 - n - 1;
5214     } else {
5215         n = 24 - n - 1;
5216     }
5217 #endif
5218     env->active_tc.gpr[rd] = (uint8_t)env->active_fpu.fpr[ws].wr.b[n];
5219 }
5220
5221 void helper_msa_copy_u_h(CPUMIPSState *env, uint32_t rd,
5222                          uint32_t ws, uint32_t n)
5223 {
5224     n %= 8;
5225 #if defined(HOST_WORDS_BIGENDIAN)
5226     if (n < 4) {
5227         n = 4 - n - 1;
5228     } else {
5229         n = 12 - n - 1;
5230     }
5231 #endif
5232     env->active_tc.gpr[rd] = (uint16_t)env->active_fpu.fpr[ws].wr.h[n];
5233 }
5234
5235 void helper_msa_copy_u_w(CPUMIPSState *env, uint32_t rd,
5236                          uint32_t ws, uint32_t n)
5237 {
5238     n %= 4;
5239 #if defined(HOST_WORDS_BIGENDIAN)
5240     if (n < 2) {
5241         n = 2 - n - 1;
5242     } else {
5243         n = 6 - n - 1;
5244     }
5245 #endif
5246     env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
5247 }
5248
5249 void helper_msa_insert_b(CPUMIPSState *env, uint32_t wd,
5250                           uint32_t rs_num, uint32_t n)
5251 {
5252     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5253     target_ulong rs = env->active_tc.gpr[rs_num];
5254     n %= 16;
5255 #if defined(HOST_WORDS_BIGENDIAN)
5256     if (n < 8) {
5257         n = 8 - n - 1;
5258     } else {
5259         n = 24 - n - 1;
5260     }
5261 #endif
5262     pwd->b[n] = (int8_t)rs;
5263 }
5264
5265 void helper_msa_insert_h(CPUMIPSState *env, uint32_t wd,
5266                           uint32_t rs_num, uint32_t n)
5267 {
5268     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5269     target_ulong rs = env->active_tc.gpr[rs_num];
5270     n %= 8;
5271 #if defined(HOST_WORDS_BIGENDIAN)
5272     if (n < 4) {
5273         n = 4 - n - 1;
5274     } else {
5275         n = 12 - n - 1;
5276     }
5277 #endif
5278     pwd->h[n] = (int16_t)rs;
5279 }
5280
5281 void helper_msa_insert_w(CPUMIPSState *env, uint32_t wd,
5282                           uint32_t rs_num, uint32_t n)
5283 {
5284     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5285     target_ulong rs = env->active_tc.gpr[rs_num];
5286     n %= 4;
5287 #if defined(HOST_WORDS_BIGENDIAN)
5288     if (n < 2) {
5289         n = 2 - n - 1;
5290     } else {
5291         n = 6 - n - 1;
5292     }
5293 #endif
5294     pwd->w[n] = (int32_t)rs;
5295 }
5296
5297 void helper_msa_insert_d(CPUMIPSState *env, uint32_t wd,
5298                           uint32_t rs_num, uint32_t n)
5299 {
5300     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5301     target_ulong rs = env->active_tc.gpr[rs_num];
5302     n %= 2;
5303     pwd->d[n] = (int64_t)rs;
5304 }
5305
5306 void helper_msa_insve_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5307                          uint32_t ws, uint32_t n)
5308 {
5309     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5310     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5311
5312     switch (df) {
5313     case DF_BYTE:
5314         pwd->b[n] = (int8_t)pws->b[0];
5315         break;
5316     case DF_HALF:
5317         pwd->h[n] = (int16_t)pws->h[0];
5318         break;
5319     case DF_WORD:
5320         pwd->w[n] = (int32_t)pws->w[0];
5321         break;
5322     case DF_DOUBLE:
5323         pwd->d[n] = (int64_t)pws->d[0];
5324         break;
5325     default:
5326         assert(0);
5327     }
5328 }
5329
5330 void helper_msa_ctcmsa(CPUMIPSState *env, target_ulong elm, uint32_t cd)
5331 {
5332     switch (cd) {
5333     case 0:
5334         break;
5335     case 1:
5336         env->active_tc.msacsr = (int32_t)elm & MSACSR_MASK;
5337         restore_msa_fp_status(env);
5338         /* check exception */
5339         if ((GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)
5340             & GET_FP_CAUSE(env->active_tc.msacsr)) {
5341             do_raise_exception(env, EXCP_MSAFPE, GETPC());
5342         }
5343         break;
5344     }
5345 }
5346
5347 target_ulong helper_msa_cfcmsa(CPUMIPSState *env, uint32_t cs)
5348 {
5349     switch (cs) {
5350     case 0:
5351         return env->msair;
5352     case 1:
5353         return env->active_tc.msacsr & MSACSR_MASK;
5354     }
5355     return 0;
5356 }
5357
5358 void helper_msa_fill_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5359                         uint32_t rs)
5360 {
5361     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5362     uint32_t i;
5363
5364     switch (df) {
5365     case DF_BYTE:
5366         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
5367             pwd->b[i] = (int8_t)env->active_tc.gpr[rs];
5368         }
5369         break;
5370     case DF_HALF:
5371         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
5372             pwd->h[i] = (int16_t)env->active_tc.gpr[rs];
5373         }
5374         break;
5375     case DF_WORD:
5376         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5377             pwd->w[i] = (int32_t)env->active_tc.gpr[rs];
5378         }
5379         break;
5380     case DF_DOUBLE:
5381         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5382             pwd->d[i] = (int64_t)env->active_tc.gpr[rs];
5383         }
5384        break;
5385     default:
5386         assert(0);
5387     }
5388 }
5389
5390
5391 #define FLOAT_ONE32 make_float32(0x3f8 << 20)
5392 #define FLOAT_ONE64 make_float64(0x3ffULL << 52)
5393
5394 #define FLOAT_SNAN16(s) (float16_default_nan(s) ^ 0x0220)
5395         /* 0x7c20 */
5396 #define FLOAT_SNAN32(s) (float32_default_nan(s) ^ 0x00400020)
5397         /* 0x7f800020 */
5398 #define FLOAT_SNAN64(s) (float64_default_nan(s) ^ 0x0008000000000020ULL)
5399         /* 0x7ff0000000000020 */
5400
5401 static inline void clear_msacsr_cause(CPUMIPSState *env)
5402 {
5403     SET_FP_CAUSE(env->active_tc.msacsr, 0);
5404 }
5405
5406 static inline void check_msacsr_cause(CPUMIPSState *env, uintptr_t retaddr)
5407 {
5408     if ((GET_FP_CAUSE(env->active_tc.msacsr) &
5409             (GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)) == 0) {
5410         UPDATE_FP_FLAGS(env->active_tc.msacsr,
5411                 GET_FP_CAUSE(env->active_tc.msacsr));
5412     } else {
5413         do_raise_exception(env, EXCP_MSAFPE, retaddr);
5414     }
5415 }
5416
5417 /* Flush-to-zero use cases for update_msacsr() */
5418 #define CLEAR_FS_UNDERFLOW 1
5419 #define CLEAR_IS_INEXACT   2
5420 #define RECIPROCAL_INEXACT 4
5421
5422 static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
5423 {
5424     int ieee_ex;
5425
5426     int c;
5427     int cause;
5428     int enable;
5429
5430     ieee_ex = get_float_exception_flags(&env->active_tc.msa_fp_status);
5431
5432     /* QEMU softfloat does not signal all underflow cases */
5433     if (denormal) {
5434         ieee_ex |= float_flag_underflow;
5435     }
5436
5437     c = ieee_ex_to_mips(ieee_ex);
5438     enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
5439
5440     /* Set Inexact (I) when flushing inputs to zero */
5441     if ((ieee_ex & float_flag_input_denormal) &&
5442             (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
5443         if (action & CLEAR_IS_INEXACT) {
5444             c &= ~FP_INEXACT;
5445         } else {
5446             c |=  FP_INEXACT;
5447         }
5448     }
5449
5450     /* Set Inexact (I) and Underflow (U) when flushing outputs to zero */
5451     if ((ieee_ex & float_flag_output_denormal) &&
5452             (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
5453         c |= FP_INEXACT;
5454         if (action & CLEAR_FS_UNDERFLOW) {
5455             c &= ~FP_UNDERFLOW;
5456         } else {
5457             c |=  FP_UNDERFLOW;
5458         }
5459     }
5460
5461     /* Set Inexact (I) when Overflow (O) is not enabled */
5462     if ((c & FP_OVERFLOW) != 0 && (enable & FP_OVERFLOW) == 0) {
5463         c |= FP_INEXACT;
5464     }
5465
5466     /* Clear Exact Underflow when Underflow (U) is not enabled */
5467     if ((c & FP_UNDERFLOW) != 0 && (enable & FP_UNDERFLOW) == 0 &&
5468             (c & FP_INEXACT) == 0) {
5469         c &= ~FP_UNDERFLOW;
5470     }
5471
5472     /*
5473      * Reciprocal operations set only Inexact when valid and not
5474      * divide by zero
5475      */
5476     if ((action & RECIPROCAL_INEXACT) &&
5477             (c & (FP_INVALID | FP_DIV0)) == 0) {
5478         c = FP_INEXACT;
5479     }
5480
5481     cause = c & enable;    /* all current enabled exceptions */
5482
5483     if (cause == 0) {
5484         /*
5485          * No enabled exception, update the MSACSR Cause
5486          * with all current exceptions
5487          */
5488         SET_FP_CAUSE(env->active_tc.msacsr,
5489                 (GET_FP_CAUSE(env->active_tc.msacsr) | c));
5490     } else {
5491         /* Current exceptions are enabled */
5492         if ((env->active_tc.msacsr & MSACSR_NX_MASK) == 0) {
5493             /*
5494              * Exception(s) will trap, update MSACSR Cause
5495              * with all enabled exceptions
5496              */
5497             SET_FP_CAUSE(env->active_tc.msacsr,
5498                     (GET_FP_CAUSE(env->active_tc.msacsr) | c));
5499         }
5500     }
5501
5502     return c;
5503 }
5504
5505 static inline int get_enabled_exceptions(const CPUMIPSState *env, int c)
5506 {
5507     int enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
5508     return c & enable;
5509 }
5510
5511 static inline float16 float16_from_float32(int32_t a, flag ieee,
5512                                            float_status *status)
5513 {
5514       float16 f_val;
5515
5516       f_val = float32_to_float16((float32)a, ieee, status);
5517
5518       return a < 0 ? (f_val | (1 << 15)) : f_val;
5519 }
5520
5521 static inline float32 float32_from_float64(int64_t a, float_status *status)
5522 {
5523       float32 f_val;
5524
5525       f_val = float64_to_float32((float64)a, status);
5526
5527       return a < 0 ? (f_val | (1 << 31)) : f_val;
5528 }
5529
5530 static inline float32 float32_from_float16(int16_t a, flag ieee,
5531                                            float_status *status)
5532 {
5533       float32 f_val;
5534
5535       f_val = float16_to_float32((float16)a, ieee, status);
5536
5537       return a < 0 ? (f_val | (1 << 31)) : f_val;
5538 }
5539
5540 static inline float64 float64_from_float32(int32_t a, float_status *status)
5541 {
5542       float64 f_val;
5543
5544       f_val = float32_to_float64((float64)a, status);
5545
5546       return a < 0 ? (f_val | (1ULL << 63)) : f_val;
5547 }
5548
5549 static inline float32 float32_from_q16(int16_t a, float_status *status)
5550 {
5551     float32 f_val;
5552
5553     /* conversion as integer and scaling */
5554     f_val = int32_to_float32(a, status);
5555     f_val = float32_scalbn(f_val, -15, status);
5556
5557     return f_val;
5558 }
5559
5560 static inline float64 float64_from_q32(int32_t a, float_status *status)
5561 {
5562     float64 f_val;
5563
5564     /* conversion as integer and scaling */
5565     f_val = int32_to_float64(a, status);
5566     f_val = float64_scalbn(f_val, -31, status);
5567
5568     return f_val;
5569 }
5570
5571 static inline int16_t float32_to_q16(float32 a, float_status *status)
5572 {
5573     int32_t q_val;
5574     int32_t q_min = 0xffff8000;
5575     int32_t q_max = 0x00007fff;
5576
5577     int ieee_ex;
5578
5579     if (float32_is_any_nan(a)) {
5580         float_raise(float_flag_invalid, status);
5581         return 0;
5582     }
5583
5584     /* scaling */
5585     a = float32_scalbn(a, 15, status);
5586
5587     ieee_ex = get_float_exception_flags(status);
5588     set_float_exception_flags(ieee_ex & (~float_flag_underflow)
5589                              , status);
5590
5591     if (ieee_ex & float_flag_overflow) {
5592         float_raise(float_flag_inexact, status);
5593         return (int32_t)a < 0 ? q_min : q_max;
5594     }
5595
5596     /* conversion to int */
5597     q_val = float32_to_int32(a, status);
5598
5599     ieee_ex = get_float_exception_flags(status);
5600     set_float_exception_flags(ieee_ex & (~float_flag_underflow)
5601                              , status);
5602
5603     if (ieee_ex & float_flag_invalid) {
5604         set_float_exception_flags(ieee_ex & (~float_flag_invalid)
5605                                , status);
5606         float_raise(float_flag_overflow | float_flag_inexact, status);
5607         return (int32_t)a < 0 ? q_min : q_max;
5608     }
5609
5610     if (q_val < q_min) {
5611         float_raise(float_flag_overflow | float_flag_inexact, status);
5612         return (int16_t)q_min;
5613     }
5614
5615     if (q_max < q_val) {
5616         float_raise(float_flag_overflow | float_flag_inexact, status);
5617         return (int16_t)q_max;
5618     }
5619
5620     return (int16_t)q_val;
5621 }
5622
5623 static inline int32_t float64_to_q32(float64 a, float_status *status)
5624 {
5625     int64_t q_val;
5626     int64_t q_min = 0xffffffff80000000LL;
5627     int64_t q_max = 0x000000007fffffffLL;
5628
5629     int ieee_ex;
5630
5631     if (float64_is_any_nan(a)) {
5632         float_raise(float_flag_invalid, status);
5633         return 0;
5634     }
5635
5636     /* scaling */
5637     a = float64_scalbn(a, 31, status);
5638
5639     ieee_ex = get_float_exception_flags(status);
5640     set_float_exception_flags(ieee_ex & (~float_flag_underflow)
5641            , status);
5642
5643     if (ieee_ex & float_flag_overflow) {
5644         float_raise(float_flag_inexact, status);
5645         return (int64_t)a < 0 ? q_min : q_max;
5646     }
5647
5648     /* conversion to integer */
5649     q_val = float64_to_int64(a, status);
5650
5651     ieee_ex = get_float_exception_flags(status);
5652     set_float_exception_flags(ieee_ex & (~float_flag_underflow)
5653            , status);
5654
5655     if (ieee_ex & float_flag_invalid) {
5656         set_float_exception_flags(ieee_ex & (~float_flag_invalid)
5657                , status);
5658         float_raise(float_flag_overflow | float_flag_inexact, status);
5659         return (int64_t)a < 0 ? q_min : q_max;
5660     }
5661
5662     if (q_val < q_min) {
5663         float_raise(float_flag_overflow | float_flag_inexact, status);
5664         return (int32_t)q_min;
5665     }
5666
5667     if (q_max < q_val) {
5668         float_raise(float_flag_overflow | float_flag_inexact, status);
5669         return (int32_t)q_max;
5670     }
5671
5672     return (int32_t)q_val;
5673 }
5674
5675 #define MSA_FLOAT_COND(DEST, OP, ARG1, ARG2, BITS, QUIET)                   \
5676     do {                                                                    \
5677         float_status *status = &env->active_tc.msa_fp_status;               \
5678         int c;                                                              \
5679         int64_t cond;                                                       \
5680         set_float_exception_flags(0, status);                               \
5681         if (!QUIET) {                                                       \
5682             cond = float ## BITS ## _ ## OP(ARG1, ARG2, status);            \
5683         } else {                                                            \
5684             cond = float ## BITS ## _ ## OP ## _quiet(ARG1, ARG2, status);  \
5685         }                                                                   \
5686         DEST = cond ? M_MAX_UINT(BITS) : 0;                                 \
5687         c = update_msacsr(env, CLEAR_IS_INEXACT, 0);                        \
5688                                                                             \
5689         if (get_enabled_exceptions(env, c)) {                               \
5690             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
5691         }                                                                   \
5692     } while (0)
5693
5694 #define MSA_FLOAT_AF(DEST, ARG1, ARG2, BITS, QUIET)                 \
5695     do {                                                            \
5696         MSA_FLOAT_COND(DEST, eq, ARG1, ARG2, BITS, QUIET);          \
5697         if ((DEST & M_MAX_UINT(BITS)) == M_MAX_UINT(BITS)) {        \
5698             DEST = 0;                                               \
5699         }                                                           \
5700     } while (0)
5701
5702 #define MSA_FLOAT_UEQ(DEST, ARG1, ARG2, BITS, QUIET)                \
5703     do {                                                            \
5704         MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET);   \
5705         if (DEST == 0) {                                            \
5706             MSA_FLOAT_COND(DEST, eq, ARG1, ARG2, BITS, QUIET);      \
5707         }                                                           \
5708     } while (0)
5709
5710 #define MSA_FLOAT_NE(DEST, ARG1, ARG2, BITS, QUIET)                 \
5711     do {                                                            \
5712         MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET);          \
5713         if (DEST == 0) {                                            \
5714             MSA_FLOAT_COND(DEST, lt, ARG2, ARG1, BITS, QUIET);      \
5715         }                                                           \
5716     } while (0)
5717
5718 #define MSA_FLOAT_UNE(DEST, ARG1, ARG2, BITS, QUIET)                \
5719     do {                                                            \
5720         MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET);   \
5721         if (DEST == 0) {                                            \
5722             MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET);      \
5723             if (DEST == 0) {                                        \
5724                 MSA_FLOAT_COND(DEST, lt, ARG2, ARG1, BITS, QUIET);  \
5725             }                                                       \
5726         }                                                           \
5727     } while (0)
5728
5729 #define MSA_FLOAT_ULE(DEST, ARG1, ARG2, BITS, QUIET)                \
5730     do {                                                            \
5731         MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET);   \
5732         if (DEST == 0) {                                            \
5733             MSA_FLOAT_COND(DEST, le, ARG1, ARG2, BITS, QUIET);      \
5734         }                                                           \
5735     } while (0)
5736
5737 #define MSA_FLOAT_ULT(DEST, ARG1, ARG2, BITS, QUIET)                \
5738     do {                                                            \
5739         MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET);   \
5740         if (DEST == 0) {                                            \
5741             MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET);      \
5742         }                                                           \
5743     } while (0)
5744
5745 #define MSA_FLOAT_OR(DEST, ARG1, ARG2, BITS, QUIET)                 \
5746     do {                                                            \
5747         MSA_FLOAT_COND(DEST, le, ARG1, ARG2, BITS, QUIET);          \
5748         if (DEST == 0) {                                            \
5749             MSA_FLOAT_COND(DEST, le, ARG2, ARG1, BITS, QUIET);      \
5750         }                                                           \
5751     } while (0)
5752
5753 static inline void compare_af(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5754                               wr_t *pwt, uint32_t df, int quiet,
5755                               uintptr_t retaddr)
5756 {
5757     wr_t wx, *pwx = &wx;
5758     uint32_t i;
5759
5760     clear_msacsr_cause(env);
5761
5762     switch (df) {
5763     case DF_WORD:
5764         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5765             MSA_FLOAT_AF(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
5766         }
5767         break;
5768     case DF_DOUBLE:
5769         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5770             MSA_FLOAT_AF(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
5771         }
5772         break;
5773     default:
5774         assert(0);
5775     }
5776
5777     check_msacsr_cause(env, retaddr);
5778
5779     msa_move_v(pwd, pwx);
5780 }
5781
5782 static inline void compare_un(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5783                               wr_t *pwt, uint32_t df, int quiet,
5784                               uintptr_t retaddr)
5785 {
5786     wr_t wx, *pwx = &wx;
5787     uint32_t i;
5788
5789     clear_msacsr_cause(env);
5790
5791     switch (df) {
5792     case DF_WORD:
5793         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5794             MSA_FLOAT_COND(pwx->w[i], unordered, pws->w[i], pwt->w[i], 32,
5795                     quiet);
5796         }
5797         break;
5798     case DF_DOUBLE:
5799         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5800             MSA_FLOAT_COND(pwx->d[i], unordered, pws->d[i], pwt->d[i], 64,
5801                     quiet);
5802         }
5803         break;
5804     default:
5805         assert(0);
5806     }
5807
5808     check_msacsr_cause(env, retaddr);
5809
5810     msa_move_v(pwd, pwx);
5811 }
5812
5813 static inline void compare_eq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5814                               wr_t *pwt, uint32_t df, int quiet,
5815                               uintptr_t retaddr)
5816 {
5817     wr_t wx, *pwx = &wx;
5818     uint32_t i;
5819
5820     clear_msacsr_cause(env);
5821
5822     switch (df) {
5823     case DF_WORD:
5824         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5825             MSA_FLOAT_COND(pwx->w[i], eq, pws->w[i], pwt->w[i], 32, quiet);
5826         }
5827         break;
5828     case DF_DOUBLE:
5829         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5830             MSA_FLOAT_COND(pwx->d[i], eq, pws->d[i], pwt->d[i], 64, quiet);
5831         }
5832         break;
5833     default:
5834         assert(0);
5835     }
5836
5837     check_msacsr_cause(env, retaddr);
5838
5839     msa_move_v(pwd, pwx);
5840 }
5841
5842 static inline void compare_ueq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5843                                wr_t *pwt, uint32_t df, int quiet,
5844                                uintptr_t retaddr)
5845 {
5846     wr_t wx, *pwx = &wx;
5847     uint32_t i;
5848
5849     clear_msacsr_cause(env);
5850
5851     switch (df) {
5852     case DF_WORD:
5853         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5854             MSA_FLOAT_UEQ(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
5855         }
5856         break;
5857     case DF_DOUBLE:
5858         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5859             MSA_FLOAT_UEQ(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
5860         }
5861         break;
5862     default:
5863         assert(0);
5864     }
5865
5866     check_msacsr_cause(env, retaddr);
5867
5868     msa_move_v(pwd, pwx);
5869 }
5870
5871 static inline void compare_lt(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5872                               wr_t *pwt, uint32_t df, int quiet,
5873                               uintptr_t retaddr)
5874 {
5875     wr_t wx, *pwx = &wx;
5876     uint32_t i;
5877
5878     clear_msacsr_cause(env);
5879
5880     switch (df) {
5881     case DF_WORD:
5882         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5883             MSA_FLOAT_COND(pwx->w[i], lt, pws->w[i], pwt->w[i], 32, quiet);
5884         }
5885         break;
5886     case DF_DOUBLE:
5887         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5888             MSA_FLOAT_COND(pwx->d[i], lt, pws->d[i], pwt->d[i], 64, quiet);
5889         }
5890         break;
5891     default:
5892         assert(0);
5893     }
5894
5895     check_msacsr_cause(env, retaddr);
5896
5897     msa_move_v(pwd, pwx);
5898 }
5899
5900 static inline void compare_ult(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5901                                wr_t *pwt, uint32_t df, int quiet,
5902                                uintptr_t retaddr)
5903 {
5904     wr_t wx, *pwx = &wx;
5905     uint32_t i;
5906
5907     clear_msacsr_cause(env);
5908
5909     switch (df) {
5910     case DF_WORD:
5911         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5912             MSA_FLOAT_ULT(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
5913         }
5914         break;
5915     case DF_DOUBLE:
5916         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5917             MSA_FLOAT_ULT(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
5918         }
5919         break;
5920     default:
5921         assert(0);
5922     }
5923
5924     check_msacsr_cause(env, retaddr);
5925
5926     msa_move_v(pwd, pwx);
5927 }
5928
5929 static inline void compare_le(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5930                               wr_t *pwt, uint32_t df, int quiet,
5931                               uintptr_t retaddr)
5932 {
5933     wr_t wx, *pwx = &wx;
5934     uint32_t i;
5935
5936     clear_msacsr_cause(env);
5937
5938     switch (df) {
5939     case DF_WORD:
5940         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5941             MSA_FLOAT_COND(pwx->w[i], le, pws->w[i], pwt->w[i], 32, quiet);
5942         }
5943         break;
5944     case DF_DOUBLE:
5945         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5946             MSA_FLOAT_COND(pwx->d[i], le, pws->d[i], pwt->d[i], 64, quiet);
5947         }
5948         break;
5949     default:
5950         assert(0);
5951     }
5952
5953     check_msacsr_cause(env, retaddr);
5954
5955     msa_move_v(pwd, pwx);
5956 }
5957
5958 static inline void compare_ule(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5959                                wr_t *pwt, uint32_t df, int quiet,
5960                                uintptr_t retaddr)
5961 {
5962     wr_t wx, *pwx = &wx;
5963     uint32_t i;
5964
5965     clear_msacsr_cause(env);
5966
5967     switch (df) {
5968     case DF_WORD:
5969         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5970             MSA_FLOAT_ULE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
5971         }
5972         break;
5973     case DF_DOUBLE:
5974         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5975             MSA_FLOAT_ULE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
5976         }
5977         break;
5978     default:
5979         assert(0);
5980     }
5981
5982     check_msacsr_cause(env, retaddr);
5983
5984     msa_move_v(pwd, pwx);
5985 }
5986
5987 static inline void compare_or(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
5988                               wr_t *pwt, uint32_t df, int quiet,
5989                               uintptr_t retaddr)
5990 {
5991     wr_t wx, *pwx = &wx;
5992     uint32_t i;
5993
5994     clear_msacsr_cause(env);
5995
5996     switch (df) {
5997     case DF_WORD:
5998         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5999             MSA_FLOAT_OR(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
6000         }
6001         break;
6002     case DF_DOUBLE:
6003         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6004             MSA_FLOAT_OR(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
6005         }
6006         break;
6007     default:
6008         assert(0);
6009     }
6010
6011     check_msacsr_cause(env, retaddr);
6012
6013     msa_move_v(pwd, pwx);
6014 }
6015
6016 static inline void compare_une(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6017                                wr_t *pwt, uint32_t df, int quiet,
6018                                uintptr_t retaddr)
6019 {
6020     wr_t wx, *pwx = &wx;
6021     uint32_t i;
6022
6023     clear_msacsr_cause(env);
6024
6025     switch (df) {
6026     case DF_WORD:
6027         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6028             MSA_FLOAT_UNE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
6029         }
6030         break;
6031     case DF_DOUBLE:
6032         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6033             MSA_FLOAT_UNE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
6034         }
6035         break;
6036     default:
6037         assert(0);
6038     }
6039
6040     check_msacsr_cause(env, retaddr);
6041
6042     msa_move_v(pwd, pwx);
6043 }
6044
6045 static inline void compare_ne(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6046                               wr_t *pwt, uint32_t df, int quiet,
6047                               uintptr_t retaddr)
6048 {
6049     wr_t wx, *pwx = &wx;
6050     uint32_t i;
6051
6052     clear_msacsr_cause(env);
6053
6054     switch (df) {
6055     case DF_WORD:
6056         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6057             MSA_FLOAT_NE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
6058         }
6059         break;
6060     case DF_DOUBLE:
6061         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6062             MSA_FLOAT_NE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
6063         }
6064         break;
6065     default:
6066         assert(0);
6067     }
6068
6069     check_msacsr_cause(env, retaddr);
6070
6071     msa_move_v(pwd, pwx);
6072 }
6073
6074 void helper_msa_fcaf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6075                         uint32_t ws, uint32_t wt)
6076 {
6077     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6078     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6079     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6080     compare_af(env, pwd, pws, pwt, df, 1, GETPC());
6081 }
6082
6083 void helper_msa_fcun_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6084                         uint32_t ws, uint32_t wt)
6085 {
6086     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6087     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6088     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6089     compare_un(env, pwd, pws, pwt, df, 1, GETPC());
6090 }
6091
6092 void helper_msa_fceq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6093                         uint32_t ws, uint32_t wt)
6094 {
6095     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6096     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6097     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6098     compare_eq(env, pwd, pws, pwt, df, 1, GETPC());
6099 }
6100
6101 void helper_msa_fcueq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6102                          uint32_t ws, uint32_t wt)
6103 {
6104     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6105     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6106     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6107     compare_ueq(env, pwd, pws, pwt, df, 1, GETPC());
6108 }
6109
6110 void helper_msa_fclt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6111                         uint32_t ws, uint32_t wt)
6112 {
6113     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6114     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6115     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6116     compare_lt(env, pwd, pws, pwt, df, 1, GETPC());
6117 }
6118
6119 void helper_msa_fcult_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6120                          uint32_t ws, uint32_t wt)
6121 {
6122     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6123     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6124     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6125     compare_ult(env, pwd, pws, pwt, df, 1, GETPC());
6126 }
6127
6128 void helper_msa_fcle_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6129                         uint32_t ws, uint32_t wt)
6130 {
6131     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6132     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6133     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6134     compare_le(env, pwd, pws, pwt, df, 1, GETPC());
6135 }
6136
6137 void helper_msa_fcule_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6138                          uint32_t ws, uint32_t wt)
6139 {
6140     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6141     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6142     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6143     compare_ule(env, pwd, pws, pwt, df, 1, GETPC());
6144 }
6145
6146 void helper_msa_fsaf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6147                         uint32_t ws, uint32_t wt)
6148 {
6149     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6150     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6151     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6152     compare_af(env, pwd, pws, pwt, df, 0, GETPC());
6153 }
6154
6155 void helper_msa_fsun_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6156                         uint32_t ws, uint32_t wt)
6157 {
6158     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6159     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6160     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6161     compare_un(env, pwd, pws, pwt, df, 0, GETPC());
6162 }
6163
6164 void helper_msa_fseq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6165                         uint32_t ws, uint32_t wt)
6166 {
6167     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6168     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6169     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6170     compare_eq(env, pwd, pws, pwt, df, 0, GETPC());
6171 }
6172
6173 void helper_msa_fsueq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6174                          uint32_t ws, uint32_t wt)
6175 {
6176     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6177     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6178     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6179     compare_ueq(env, pwd, pws, pwt, df, 0, GETPC());
6180 }
6181
6182 void helper_msa_fslt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6183                         uint32_t ws, uint32_t wt)
6184 {
6185     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6186     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6187     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6188     compare_lt(env, pwd, pws, pwt, df, 0, GETPC());
6189 }
6190
6191 void helper_msa_fsult_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6192                          uint32_t ws, uint32_t wt)
6193 {
6194     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6195     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6196     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6197     compare_ult(env, pwd, pws, pwt, df, 0, GETPC());
6198 }
6199
6200 void helper_msa_fsle_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6201                         uint32_t ws, uint32_t wt)
6202 {
6203     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6204     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6205     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6206     compare_le(env, pwd, pws, pwt, df, 0, GETPC());
6207 }
6208
6209 void helper_msa_fsule_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6210                          uint32_t ws, uint32_t wt)
6211 {
6212     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6213     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6214     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6215     compare_ule(env, pwd, pws, pwt, df, 0, GETPC());
6216 }
6217
6218 void helper_msa_fcor_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6219                         uint32_t ws, uint32_t wt)
6220 {
6221     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6222     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6223     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6224     compare_or(env, pwd, pws, pwt, df, 1, GETPC());
6225 }
6226
6227 void helper_msa_fcune_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6228                          uint32_t ws, uint32_t wt)
6229 {
6230     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6231     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6232     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6233     compare_une(env, pwd, pws, pwt, df, 1, GETPC());
6234 }
6235
6236 void helper_msa_fcne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6237                         uint32_t ws, uint32_t wt)
6238 {
6239     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6240     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6241     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6242     compare_ne(env, pwd, pws, pwt, df, 1, GETPC());
6243 }
6244
6245 void helper_msa_fsor_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6246                         uint32_t ws, uint32_t wt)
6247 {
6248     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6249     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6250     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6251     compare_or(env, pwd, pws, pwt, df, 0, GETPC());
6252 }
6253
6254 void helper_msa_fsune_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6255                          uint32_t ws, uint32_t wt)
6256 {
6257     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6258     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6259     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6260     compare_une(env, pwd, pws, pwt, df, 0, GETPC());
6261 }
6262
6263 void helper_msa_fsne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6264                         uint32_t ws, uint32_t wt)
6265 {
6266     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6267     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6268     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6269     compare_ne(env, pwd, pws, pwt, df, 0, GETPC());
6270 }
6271
6272 #define float16_is_zero(ARG) 0
6273 #define float16_is_zero_or_denormal(ARG) 0
6274
6275 #define IS_DENORMAL(ARG, BITS)                      \
6276     (!float ## BITS ## _is_zero(ARG)                \
6277     && float ## BITS ## _is_zero_or_denormal(ARG))
6278
6279 #define MSA_FLOAT_BINOP(DEST, OP, ARG1, ARG2, BITS)                         \
6280     do {                                                                    \
6281         float_status *status = &env->active_tc.msa_fp_status;               \
6282         int c;                                                              \
6283                                                                             \
6284         set_float_exception_flags(0, status);                               \
6285         DEST = float ## BITS ## _ ## OP(ARG1, ARG2, status);                \
6286         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
6287                                                                             \
6288         if (get_enabled_exceptions(env, c)) {                               \
6289             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
6290         }                                                                   \
6291     } while (0)
6292
6293 void helper_msa_fadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6294         uint32_t ws, uint32_t wt)
6295 {
6296     wr_t wx, *pwx = &wx;
6297     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6298     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6299     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6300     uint32_t i;
6301
6302     clear_msacsr_cause(env);
6303
6304     switch (df) {
6305     case DF_WORD:
6306         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6307             MSA_FLOAT_BINOP(pwx->w[i], add, pws->w[i], pwt->w[i], 32);
6308         }
6309         break;
6310     case DF_DOUBLE:
6311         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6312             MSA_FLOAT_BINOP(pwx->d[i], add, pws->d[i], pwt->d[i], 64);
6313         }
6314         break;
6315     default:
6316         assert(0);
6317     }
6318
6319     check_msacsr_cause(env, GETPC());
6320     msa_move_v(pwd, pwx);
6321 }
6322
6323 void helper_msa_fsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6324         uint32_t ws, uint32_t wt)
6325 {
6326     wr_t wx, *pwx = &wx;
6327     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6328     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6329     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6330     uint32_t i;
6331
6332     clear_msacsr_cause(env);
6333
6334     switch (df) {
6335     case DF_WORD:
6336         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6337             MSA_FLOAT_BINOP(pwx->w[i], sub, pws->w[i], pwt->w[i], 32);
6338         }
6339         break;
6340     case DF_DOUBLE:
6341         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6342             MSA_FLOAT_BINOP(pwx->d[i], sub, pws->d[i], pwt->d[i], 64);
6343         }
6344         break;
6345     default:
6346         assert(0);
6347     }
6348
6349     check_msacsr_cause(env, GETPC());
6350     msa_move_v(pwd, pwx);
6351 }
6352
6353 void helper_msa_fmul_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6354         uint32_t ws, uint32_t wt)
6355 {
6356     wr_t wx, *pwx = &wx;
6357     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6358     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6359     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6360     uint32_t i;
6361
6362     clear_msacsr_cause(env);
6363
6364     switch (df) {
6365     case DF_WORD:
6366         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6367             MSA_FLOAT_BINOP(pwx->w[i], mul, pws->w[i], pwt->w[i], 32);
6368         }
6369         break;
6370     case DF_DOUBLE:
6371         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6372             MSA_FLOAT_BINOP(pwx->d[i], mul, pws->d[i], pwt->d[i], 64);
6373         }
6374         break;
6375     default:
6376         assert(0);
6377     }
6378
6379     check_msacsr_cause(env, GETPC());
6380
6381     msa_move_v(pwd, pwx);
6382 }
6383
6384 void helper_msa_fdiv_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6385         uint32_t ws, uint32_t wt)
6386 {
6387     wr_t wx, *pwx = &wx;
6388     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6389     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6390     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6391     uint32_t i;
6392
6393     clear_msacsr_cause(env);
6394
6395     switch (df) {
6396     case DF_WORD:
6397         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6398             MSA_FLOAT_BINOP(pwx->w[i], div, pws->w[i], pwt->w[i], 32);
6399         }
6400         break;
6401     case DF_DOUBLE:
6402         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6403             MSA_FLOAT_BINOP(pwx->d[i], div, pws->d[i], pwt->d[i], 64);
6404         }
6405         break;
6406     default:
6407         assert(0);
6408     }
6409
6410     check_msacsr_cause(env, GETPC());
6411
6412     msa_move_v(pwd, pwx);
6413 }
6414
6415 #define MSA_FLOAT_MULADD(DEST, ARG1, ARG2, ARG3, NEGATE, BITS)              \
6416     do {                                                                    \
6417         float_status *status = &env->active_tc.msa_fp_status;               \
6418         int c;                                                              \
6419                                                                             \
6420         set_float_exception_flags(0, status);                               \
6421         DEST = float ## BITS ## _muladd(ARG2, ARG3, ARG1, NEGATE, status);  \
6422         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
6423                                                                             \
6424         if (get_enabled_exceptions(env, c)) {                               \
6425             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
6426         }                                                                   \
6427     } while (0)
6428
6429 void helper_msa_fmadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6430         uint32_t ws, uint32_t wt)
6431 {
6432     wr_t wx, *pwx = &wx;
6433     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6434     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6435     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6436     uint32_t i;
6437
6438     clear_msacsr_cause(env);
6439
6440     switch (df) {
6441     case DF_WORD:
6442         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6443             MSA_FLOAT_MULADD(pwx->w[i], pwd->w[i],
6444                            pws->w[i], pwt->w[i], 0, 32);
6445         }
6446         break;
6447     case DF_DOUBLE:
6448         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6449             MSA_FLOAT_MULADD(pwx->d[i], pwd->d[i],
6450                            pws->d[i], pwt->d[i], 0, 64);
6451         }
6452         break;
6453     default:
6454         assert(0);
6455     }
6456
6457     check_msacsr_cause(env, GETPC());
6458
6459     msa_move_v(pwd, pwx);
6460 }
6461
6462 void helper_msa_fmsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6463         uint32_t ws, uint32_t wt)
6464 {
6465     wr_t wx, *pwx = &wx;
6466     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6467     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6468     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6469     uint32_t i;
6470
6471     clear_msacsr_cause(env);
6472
6473     switch (df) {
6474     case DF_WORD:
6475         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6476             MSA_FLOAT_MULADD(pwx->w[i], pwd->w[i],
6477                            pws->w[i], pwt->w[i],
6478                            float_muladd_negate_product, 32);
6479       }
6480       break;
6481     case DF_DOUBLE:
6482         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6483             MSA_FLOAT_MULADD(pwx->d[i], pwd->d[i],
6484                            pws->d[i], pwt->d[i],
6485                            float_muladd_negate_product, 64);
6486         }
6487         break;
6488     default:
6489         assert(0);
6490     }
6491
6492     check_msacsr_cause(env, GETPC());
6493
6494     msa_move_v(pwd, pwx);
6495 }
6496
6497 void helper_msa_fexp2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6498         uint32_t ws, uint32_t wt)
6499 {
6500     wr_t wx, *pwx = &wx;
6501     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6502     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6503     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6504     uint32_t i;
6505
6506     clear_msacsr_cause(env);
6507
6508     switch (df) {
6509     case DF_WORD:
6510         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6511             MSA_FLOAT_BINOP(pwx->w[i], scalbn, pws->w[i],
6512                             pwt->w[i] >  0x200 ?  0x200 :
6513                             pwt->w[i] < -0x200 ? -0x200 : pwt->w[i],
6514                             32);
6515         }
6516         break;
6517     case DF_DOUBLE:
6518         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6519             MSA_FLOAT_BINOP(pwx->d[i], scalbn, pws->d[i],
6520                             pwt->d[i] >  0x1000 ?  0x1000 :
6521                             pwt->d[i] < -0x1000 ? -0x1000 : pwt->d[i],
6522                             64);
6523         }
6524         break;
6525     default:
6526         assert(0);
6527     }
6528
6529     check_msacsr_cause(env, GETPC());
6530
6531     msa_move_v(pwd, pwx);
6532 }
6533
6534 #define MSA_FLOAT_UNOP(DEST, OP, ARG, BITS)                                 \
6535     do {                                                                    \
6536         float_status *status = &env->active_tc.msa_fp_status;               \
6537         int c;                                                              \
6538                                                                             \
6539         set_float_exception_flags(0, status);                               \
6540         DEST = float ## BITS ## _ ## OP(ARG, status);                       \
6541         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
6542                                                                             \
6543         if (get_enabled_exceptions(env, c)) {                               \
6544             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
6545         }                                                                   \
6546     } while (0)
6547
6548 void helper_msa_fexdo_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6549                          uint32_t ws, uint32_t wt)
6550 {
6551     wr_t wx, *pwx = &wx;
6552     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6553     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6554     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6555     uint32_t i;
6556
6557     clear_msacsr_cause(env);
6558
6559     switch (df) {
6560     case DF_WORD:
6561         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6562             /*
6563              * Half precision floats come in two formats: standard
6564              * IEEE and "ARM" format.  The latter gains extra exponent
6565              * range by omitting the NaN/Inf encodings.
6566              */
6567             flag ieee = 1;
6568
6569             MSA_FLOAT_BINOP(Lh(pwx, i), from_float32, pws->w[i], ieee, 16);
6570             MSA_FLOAT_BINOP(Rh(pwx, i), from_float32, pwt->w[i], ieee, 16);
6571         }
6572         break;
6573     case DF_DOUBLE:
6574         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6575             MSA_FLOAT_UNOP(Lw(pwx, i), from_float64, pws->d[i], 32);
6576             MSA_FLOAT_UNOP(Rw(pwx, i), from_float64, pwt->d[i], 32);
6577         }
6578         break;
6579     default:
6580         assert(0);
6581     }
6582
6583     check_msacsr_cause(env, GETPC());
6584     msa_move_v(pwd, pwx);
6585 }
6586
6587 #define MSA_FLOAT_UNOP_XD(DEST, OP, ARG, BITS, XBITS)                       \
6588     do {                                                                    \
6589         float_status *status = &env->active_tc.msa_fp_status;               \
6590         int c;                                                              \
6591                                                                             \
6592         set_float_exception_flags(0, status);                               \
6593         DEST = float ## BITS ## _ ## OP(ARG, status);                       \
6594         c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0);                      \
6595                                                                             \
6596         if (get_enabled_exceptions(env, c)) {                               \
6597             DEST = ((FLOAT_SNAN ## XBITS(status) >> 6) << 6) | c;           \
6598         }                                                                   \
6599     } while (0)
6600
6601 void helper_msa_ftq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6602                        uint32_t ws, uint32_t wt)
6603 {
6604     wr_t wx, *pwx = &wx;
6605     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6606     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6607     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6608     uint32_t i;
6609
6610     clear_msacsr_cause(env);
6611
6612     switch (df) {
6613     case DF_WORD:
6614         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6615             MSA_FLOAT_UNOP_XD(Lh(pwx, i), to_q16, pws->w[i], 32, 16);
6616             MSA_FLOAT_UNOP_XD(Rh(pwx, i), to_q16, pwt->w[i], 32, 16);
6617         }
6618         break;
6619     case DF_DOUBLE:
6620         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6621             MSA_FLOAT_UNOP_XD(Lw(pwx, i), to_q32, pws->d[i], 64, 32);
6622             MSA_FLOAT_UNOP_XD(Rw(pwx, i), to_q32, pwt->d[i], 64, 32);
6623         }
6624         break;
6625     default:
6626         assert(0);
6627     }
6628
6629     check_msacsr_cause(env, GETPC());
6630
6631     msa_move_v(pwd, pwx);
6632 }
6633
6634 #define NUMBER_QNAN_PAIR(ARG1, ARG2, BITS, STATUS)      \
6635     !float ## BITS ## _is_any_nan(ARG1)                 \
6636     && float ## BITS ## _is_quiet_nan(ARG2, STATUS)
6637
6638 #define MSA_FLOAT_MAXOP(DEST, OP, ARG1, ARG2, BITS)                         \
6639     do {                                                                    \
6640         float_status *status = &env->active_tc.msa_fp_status;               \
6641         int c;                                                              \
6642                                                                             \
6643         set_float_exception_flags(0, status);                               \
6644         DEST = float ## BITS ## _ ## OP(ARG1, ARG2, status);                \
6645         c = update_msacsr(env, 0, 0);                                       \
6646                                                                             \
6647         if (get_enabled_exceptions(env, c)) {                               \
6648             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
6649         }                                                                   \
6650     } while (0)
6651
6652 #define FMAXMIN_A(F, G, X, _S, _T, BITS, STATUS)                    \
6653     do {                                                            \
6654         uint## BITS ##_t S = _S, T = _T;                            \
6655         uint## BITS ##_t as, at, xs, xt, xd;                        \
6656         if (NUMBER_QNAN_PAIR(S, T, BITS, STATUS)) {                 \
6657             T = S;                                                  \
6658         }                                                           \
6659         else if (NUMBER_QNAN_PAIR(T, S, BITS, STATUS)) {            \
6660             S = T;                                                  \
6661         }                                                           \
6662         as = float## BITS ##_abs(S);                                \
6663         at = float## BITS ##_abs(T);                                \
6664         MSA_FLOAT_MAXOP(xs, F,  S,  T, BITS);                       \
6665         MSA_FLOAT_MAXOP(xt, G,  S,  T, BITS);                       \
6666         MSA_FLOAT_MAXOP(xd, F, as, at, BITS);                       \
6667         X = (as == at || xd == float## BITS ##_abs(xs)) ? xs : xt;  \
6668     } while (0)
6669
6670 void helper_msa_fmin_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6671         uint32_t ws, uint32_t wt)
6672 {
6673     float_status *status = &env->active_tc.msa_fp_status;
6674     wr_t wx, *pwx = &wx;
6675     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6676     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6677     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6678
6679     clear_msacsr_cause(env);
6680
6681     if (df == DF_WORD) {
6682
6683         if (NUMBER_QNAN_PAIR(pws->w[0], pwt->w[0], 32, status)) {
6684             MSA_FLOAT_MAXOP(pwx->w[0], min, pws->w[0], pws->w[0], 32);
6685         } else if (NUMBER_QNAN_PAIR(pwt->w[0], pws->w[0], 32, status)) {
6686             MSA_FLOAT_MAXOP(pwx->w[0], min, pwt->w[0], pwt->w[0], 32);
6687         } else {
6688             MSA_FLOAT_MAXOP(pwx->w[0], min, pws->w[0], pwt->w[0], 32);
6689         }
6690
6691         if (NUMBER_QNAN_PAIR(pws->w[1], pwt->w[1], 32, status)) {
6692             MSA_FLOAT_MAXOP(pwx->w[1], min, pws->w[1], pws->w[1], 32);
6693         } else if (NUMBER_QNAN_PAIR(pwt->w[1], pws->w[1], 32, status)) {
6694             MSA_FLOAT_MAXOP(pwx->w[1], min, pwt->w[1], pwt->w[1], 32);
6695         } else {
6696             MSA_FLOAT_MAXOP(pwx->w[1], min, pws->w[1], pwt->w[1], 32);
6697         }
6698
6699         if (NUMBER_QNAN_PAIR(pws->w[2], pwt->w[2], 32, status)) {
6700             MSA_FLOAT_MAXOP(pwx->w[2], min, pws->w[2], pws->w[2], 32);
6701         } else if (NUMBER_QNAN_PAIR(pwt->w[2], pws->w[2], 32, status)) {
6702             MSA_FLOAT_MAXOP(pwx->w[2], min, pwt->w[2], pwt->w[2], 32);
6703         } else {
6704             MSA_FLOAT_MAXOP(pwx->w[2], min, pws->w[2], pwt->w[2], 32);
6705         }
6706
6707         if (NUMBER_QNAN_PAIR(pws->w[3], pwt->w[3], 32, status)) {
6708             MSA_FLOAT_MAXOP(pwx->w[3], min, pws->w[3], pws->w[3], 32);
6709         } else if (NUMBER_QNAN_PAIR(pwt->w[3], pws->w[3], 32, status)) {
6710             MSA_FLOAT_MAXOP(pwx->w[3], min, pwt->w[3], pwt->w[3], 32);
6711         } else {
6712             MSA_FLOAT_MAXOP(pwx->w[3], min, pws->w[3], pwt->w[3], 32);
6713         }
6714
6715     } else if (df == DF_DOUBLE) {
6716
6717         if (NUMBER_QNAN_PAIR(pws->d[0], pwt->d[0], 64, status)) {
6718             MSA_FLOAT_MAXOP(pwx->d[0], min, pws->d[0], pws->d[0], 64);
6719         } else if (NUMBER_QNAN_PAIR(pwt->d[0], pws->d[0], 64, status)) {
6720             MSA_FLOAT_MAXOP(pwx->d[0], min, pwt->d[0], pwt->d[0], 64);
6721         } else {
6722             MSA_FLOAT_MAXOP(pwx->d[0], min, pws->d[0], pwt->d[0], 64);
6723         }
6724
6725         if (NUMBER_QNAN_PAIR(pws->d[1], pwt->d[1], 64, status)) {
6726             MSA_FLOAT_MAXOP(pwx->d[1], min, pws->d[1], pws->d[1], 64);
6727         } else if (NUMBER_QNAN_PAIR(pwt->d[1], pws->d[1], 64, status)) {
6728             MSA_FLOAT_MAXOP(pwx->d[1], min, pwt->d[1], pwt->d[1], 64);
6729         } else {
6730             MSA_FLOAT_MAXOP(pwx->d[1], min, pws->d[1], pwt->d[1], 64);
6731         }
6732
6733     } else {
6734
6735         assert(0);
6736
6737     }
6738
6739     check_msacsr_cause(env, GETPC());
6740
6741     msa_move_v(pwd, pwx);
6742 }
6743
6744 void helper_msa_fmin_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6745         uint32_t ws, uint32_t wt)
6746 {
6747     float_status *status = &env->active_tc.msa_fp_status;
6748     wr_t wx, *pwx = &wx;
6749     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6750     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6751     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6752
6753     clear_msacsr_cause(env);
6754
6755     if (df == DF_WORD) {
6756         FMAXMIN_A(min, max, pwx->w[0], pws->w[0], pwt->w[0], 32, status);
6757         FMAXMIN_A(min, max, pwx->w[1], pws->w[1], pwt->w[1], 32, status);
6758         FMAXMIN_A(min, max, pwx->w[2], pws->w[2], pwt->w[2], 32, status);
6759         FMAXMIN_A(min, max, pwx->w[3], pws->w[3], pwt->w[3], 32, status);
6760     } else if (df == DF_DOUBLE) {
6761         FMAXMIN_A(min, max, pwx->d[0], pws->d[0], pwt->d[0], 64, status);
6762         FMAXMIN_A(min, max, pwx->d[1], pws->d[1], pwt->d[1], 64, status);
6763     } else {
6764         assert(0);
6765     }
6766
6767     check_msacsr_cause(env, GETPC());
6768
6769     msa_move_v(pwd, pwx);
6770 }
6771
6772 void helper_msa_fmax_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6773         uint32_t ws, uint32_t wt)
6774 {
6775      float_status *status = &env->active_tc.msa_fp_status;
6776     wr_t wx, *pwx = &wx;
6777     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6778     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6779     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6780
6781     clear_msacsr_cause(env);
6782
6783     if (df == DF_WORD) {
6784
6785         if (NUMBER_QNAN_PAIR(pws->w[0], pwt->w[0], 32, status)) {
6786             MSA_FLOAT_MAXOP(pwx->w[0], max, pws->w[0], pws->w[0], 32);
6787         } else if (NUMBER_QNAN_PAIR(pwt->w[0], pws->w[0], 32, status)) {
6788             MSA_FLOAT_MAXOP(pwx->w[0], max, pwt->w[0], pwt->w[0], 32);
6789         } else {
6790             MSA_FLOAT_MAXOP(pwx->w[0], max, pws->w[0], pwt->w[0], 32);
6791         }
6792
6793         if (NUMBER_QNAN_PAIR(pws->w[1], pwt->w[1], 32, status)) {
6794             MSA_FLOAT_MAXOP(pwx->w[1], max, pws->w[1], pws->w[1], 32);
6795         } else if (NUMBER_QNAN_PAIR(pwt->w[1], pws->w[1], 32, status)) {
6796             MSA_FLOAT_MAXOP(pwx->w[1], max, pwt->w[1], pwt->w[1], 32);
6797         } else {
6798             MSA_FLOAT_MAXOP(pwx->w[1], max, pws->w[1], pwt->w[1], 32);
6799         }
6800
6801         if (NUMBER_QNAN_PAIR(pws->w[2], pwt->w[2], 32, status)) {
6802             MSA_FLOAT_MAXOP(pwx->w[2], max, pws->w[2], pws->w[2], 32);
6803         } else if (NUMBER_QNAN_PAIR(pwt->w[2], pws->w[2], 32, status)) {
6804             MSA_FLOAT_MAXOP(pwx->w[2], max, pwt->w[2], pwt->w[2], 32);
6805         } else {
6806             MSA_FLOAT_MAXOP(pwx->w[2], max, pws->w[2], pwt->w[2], 32);
6807         }
6808
6809         if (NUMBER_QNAN_PAIR(pws->w[3], pwt->w[3], 32, status)) {
6810             MSA_FLOAT_MAXOP(pwx->w[3], max, pws->w[3], pws->w[3], 32);
6811         } else if (NUMBER_QNAN_PAIR(pwt->w[3], pws->w[3], 32, status)) {
6812             MSA_FLOAT_MAXOP(pwx->w[3], max, pwt->w[3], pwt->w[3], 32);
6813         } else {
6814             MSA_FLOAT_MAXOP(pwx->w[3], max, pws->w[3], pwt->w[3], 32);
6815         }
6816
6817     } else if (df == DF_DOUBLE) {
6818
6819         if (NUMBER_QNAN_PAIR(pws->d[0], pwt->d[0], 64, status)) {
6820             MSA_FLOAT_MAXOP(pwx->d[0], max, pws->d[0], pws->d[0], 64);
6821         } else if (NUMBER_QNAN_PAIR(pwt->d[0], pws->d[0], 64, status)) {
6822             MSA_FLOAT_MAXOP(pwx->d[0], max, pwt->d[0], pwt->d[0], 64);
6823         } else {
6824             MSA_FLOAT_MAXOP(pwx->d[0], max, pws->d[0], pwt->d[0], 64);
6825         }
6826
6827         if (NUMBER_QNAN_PAIR(pws->d[1], pwt->d[1], 64, status)) {
6828             MSA_FLOAT_MAXOP(pwx->d[1], max, pws->d[1], pws->d[1], 64);
6829         } else if (NUMBER_QNAN_PAIR(pwt->d[1], pws->d[1], 64, status)) {
6830             MSA_FLOAT_MAXOP(pwx->d[1], max, pwt->d[1], pwt->d[1], 64);
6831         } else {
6832             MSA_FLOAT_MAXOP(pwx->d[1], max, pws->d[1], pwt->d[1], 64);
6833         }
6834
6835     } else {
6836
6837         assert(0);
6838
6839     }
6840
6841     check_msacsr_cause(env, GETPC());
6842
6843     msa_move_v(pwd, pwx);
6844 }
6845
6846 void helper_msa_fmax_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6847         uint32_t ws, uint32_t wt)
6848 {
6849     float_status *status = &env->active_tc.msa_fp_status;
6850     wr_t wx, *pwx = &wx;
6851     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6852     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6853     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6854
6855     clear_msacsr_cause(env);
6856
6857     if (df == DF_WORD) {
6858         FMAXMIN_A(max, min, pwx->w[0], pws->w[0], pwt->w[0], 32, status);
6859         FMAXMIN_A(max, min, pwx->w[1], pws->w[1], pwt->w[1], 32, status);
6860         FMAXMIN_A(max, min, pwx->w[2], pws->w[2], pwt->w[2], 32, status);
6861         FMAXMIN_A(max, min, pwx->w[3], pws->w[3], pwt->w[3], 32, status);
6862     } else if (df == DF_DOUBLE) {
6863         FMAXMIN_A(max, min, pwx->d[0], pws->d[0], pwt->d[0], 64, status);
6864         FMAXMIN_A(max, min, pwx->d[1], pws->d[1], pwt->d[1], 64, status);
6865     } else {
6866         assert(0);
6867     }
6868
6869     check_msacsr_cause(env, GETPC());
6870
6871     msa_move_v(pwd, pwx);
6872 }
6873
6874 void helper_msa_fclass_df(CPUMIPSState *env, uint32_t df,
6875         uint32_t wd, uint32_t ws)
6876 {
6877     float_status *status = &env->active_tc.msa_fp_status;
6878
6879     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6880     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6881     if (df == DF_WORD) {
6882         pwd->w[0] = float_class_s(pws->w[0], status);
6883         pwd->w[1] = float_class_s(pws->w[1], status);
6884         pwd->w[2] = float_class_s(pws->w[2], status);
6885         pwd->w[3] = float_class_s(pws->w[3], status);
6886     } else if (df == DF_DOUBLE) {
6887         pwd->d[0] = float_class_d(pws->d[0], status);
6888         pwd->d[1] = float_class_d(pws->d[1], status);
6889     } else {
6890         assert(0);
6891     }
6892 }
6893
6894 #define MSA_FLOAT_UNOP0(DEST, OP, ARG, BITS)                                \
6895     do {                                                                    \
6896         float_status *status = &env->active_tc.msa_fp_status;               \
6897         int c;                                                              \
6898                                                                             \
6899         set_float_exception_flags(0, status);                               \
6900         DEST = float ## BITS ## _ ## OP(ARG, status);                       \
6901         c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0);                      \
6902                                                                             \
6903         if (get_enabled_exceptions(env, c)) {                               \
6904             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
6905         } else if (float ## BITS ## _is_any_nan(ARG)) {                     \
6906             DEST = 0;                                                       \
6907         }                                                                   \
6908     } while (0)
6909
6910 void helper_msa_ftrunc_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6911                             uint32_t ws)
6912 {
6913     wr_t wx, *pwx = &wx;
6914     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6915     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6916     uint32_t i;
6917
6918     clear_msacsr_cause(env);
6919
6920     switch (df) {
6921     case DF_WORD:
6922         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6923             MSA_FLOAT_UNOP0(pwx->w[i], to_int32_round_to_zero, pws->w[i], 32);
6924         }
6925         break;
6926     case DF_DOUBLE:
6927         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6928             MSA_FLOAT_UNOP0(pwx->d[i], to_int64_round_to_zero, pws->d[i], 64);
6929         }
6930         break;
6931     default:
6932         assert(0);
6933     }
6934
6935     check_msacsr_cause(env, GETPC());
6936
6937     msa_move_v(pwd, pwx);
6938 }
6939
6940 void helper_msa_ftrunc_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6941                             uint32_t ws)
6942 {
6943     wr_t wx, *pwx = &wx;
6944     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6945     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6946     uint32_t i;
6947
6948     clear_msacsr_cause(env);
6949
6950     switch (df) {
6951     case DF_WORD:
6952         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6953             MSA_FLOAT_UNOP0(pwx->w[i], to_uint32_round_to_zero, pws->w[i], 32);
6954         }
6955         break;
6956     case DF_DOUBLE:
6957         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6958             MSA_FLOAT_UNOP0(pwx->d[i], to_uint64_round_to_zero, pws->d[i], 64);
6959         }
6960         break;
6961     default:
6962         assert(0);
6963     }
6964
6965     check_msacsr_cause(env, GETPC());
6966
6967     msa_move_v(pwd, pwx);
6968 }
6969
6970 void helper_msa_fsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6971                          uint32_t ws)
6972 {
6973     wr_t wx, *pwx = &wx;
6974     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6975     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6976     uint32_t i;
6977
6978     clear_msacsr_cause(env);
6979
6980     switch (df) {
6981     case DF_WORD:
6982         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6983             MSA_FLOAT_UNOP(pwx->w[i], sqrt, pws->w[i], 32);
6984         }
6985         break;
6986     case DF_DOUBLE:
6987         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6988             MSA_FLOAT_UNOP(pwx->d[i], sqrt, pws->d[i], 64);
6989         }
6990         break;
6991     default:
6992         assert(0);
6993     }
6994
6995     check_msacsr_cause(env, GETPC());
6996
6997     msa_move_v(pwd, pwx);
6998 }
6999
7000 #define MSA_FLOAT_RECIPROCAL(DEST, ARG, BITS)                               \
7001     do {                                                                    \
7002         float_status *status = &env->active_tc.msa_fp_status;               \
7003         int c;                                                              \
7004                                                                             \
7005         set_float_exception_flags(0, status);                               \
7006         DEST = float ## BITS ## _ ## div(FLOAT_ONE ## BITS, ARG, status);   \
7007         c = update_msacsr(env, float ## BITS ## _is_infinity(ARG) ||        \
7008                           float ## BITS ## _is_quiet_nan(DEST, status) ?    \
7009                           0 : RECIPROCAL_INEXACT,                           \
7010                           IS_DENORMAL(DEST, BITS));                         \
7011                                                                             \
7012         if (get_enabled_exceptions(env, c)) {                               \
7013             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
7014         }                                                                   \
7015     } while (0)
7016
7017 void helper_msa_frsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7018                           uint32_t ws)
7019 {
7020     wr_t wx, *pwx = &wx;
7021     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7022     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7023     uint32_t i;
7024
7025     clear_msacsr_cause(env);
7026
7027     switch (df) {
7028     case DF_WORD:
7029         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7030             MSA_FLOAT_RECIPROCAL(pwx->w[i], float32_sqrt(pws->w[i],
7031                     &env->active_tc.msa_fp_status), 32);
7032         }
7033         break;
7034     case DF_DOUBLE:
7035         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7036             MSA_FLOAT_RECIPROCAL(pwx->d[i], float64_sqrt(pws->d[i],
7037                     &env->active_tc.msa_fp_status), 64);
7038         }
7039         break;
7040     default:
7041         assert(0);
7042     }
7043
7044     check_msacsr_cause(env, GETPC());
7045
7046     msa_move_v(pwd, pwx);
7047 }
7048
7049 void helper_msa_frcp_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7050                         uint32_t ws)
7051 {
7052     wr_t wx, *pwx = &wx;
7053     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7054     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7055     uint32_t i;
7056
7057     clear_msacsr_cause(env);
7058
7059     switch (df) {
7060     case DF_WORD:
7061         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7062             MSA_FLOAT_RECIPROCAL(pwx->w[i], pws->w[i], 32);
7063         }
7064         break;
7065     case DF_DOUBLE:
7066         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7067             MSA_FLOAT_RECIPROCAL(pwx->d[i], pws->d[i], 64);
7068         }
7069         break;
7070     default:
7071         assert(0);
7072     }
7073
7074     check_msacsr_cause(env, GETPC());
7075
7076     msa_move_v(pwd, pwx);
7077 }
7078
7079 void helper_msa_frint_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7080                          uint32_t ws)
7081 {
7082     wr_t wx, *pwx = &wx;
7083     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7084     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7085     uint32_t i;
7086
7087     clear_msacsr_cause(env);
7088
7089     switch (df) {
7090     case DF_WORD:
7091         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7092             MSA_FLOAT_UNOP(pwx->w[i], round_to_int, pws->w[i], 32);
7093         }
7094         break;
7095     case DF_DOUBLE:
7096         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7097             MSA_FLOAT_UNOP(pwx->d[i], round_to_int, pws->d[i], 64);
7098         }
7099         break;
7100     default:
7101         assert(0);
7102     }
7103
7104     check_msacsr_cause(env, GETPC());
7105
7106     msa_move_v(pwd, pwx);
7107 }
7108
7109 #define MSA_FLOAT_LOGB(DEST, ARG, BITS)                                     \
7110     do {                                                                    \
7111         float_status *status = &env->active_tc.msa_fp_status;               \
7112         int c;                                                              \
7113                                                                             \
7114         set_float_exception_flags(0, status);                               \
7115         set_float_rounding_mode(float_round_down, status);                  \
7116         DEST = float ## BITS ## _ ## log2(ARG, status);                     \
7117         DEST = float ## BITS ## _ ## round_to_int(DEST, status);            \
7118         set_float_rounding_mode(ieee_rm[(env->active_tc.msacsr &            \
7119                                          MSACSR_RM_MASK) >> MSACSR_RM],     \
7120                                 status);                                    \
7121                                                                             \
7122         set_float_exception_flags(get_float_exception_flags(status) &       \
7123                                   (~float_flag_inexact),                    \
7124                                   status);                                  \
7125                                                                             \
7126         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
7127                                                                             \
7128         if (get_enabled_exceptions(env, c)) {                               \
7129             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
7130         }                                                                   \
7131     } while (0)
7132
7133 void helper_msa_flog2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7134                          uint32_t ws)
7135 {
7136     wr_t wx, *pwx = &wx;
7137     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7138     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7139     uint32_t i;
7140
7141     clear_msacsr_cause(env);
7142
7143     switch (df) {
7144     case DF_WORD:
7145         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7146             MSA_FLOAT_LOGB(pwx->w[i], pws->w[i], 32);
7147         }
7148         break;
7149     case DF_DOUBLE:
7150         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7151             MSA_FLOAT_LOGB(pwx->d[i], pws->d[i], 64);
7152         }
7153         break;
7154     default:
7155         assert(0);
7156     }
7157
7158     check_msacsr_cause(env, GETPC());
7159
7160     msa_move_v(pwd, pwx);
7161 }
7162
7163 void helper_msa_fexupl_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7164                           uint32_t ws)
7165 {
7166     wr_t wx, *pwx = &wx;
7167     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7168     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7169     uint32_t i;
7170
7171     clear_msacsr_cause(env);
7172
7173     switch (df) {
7174     case DF_WORD:
7175         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7176             /*
7177              * Half precision floats come in two formats: standard
7178              * IEEE and "ARM" format.  The latter gains extra exponent
7179              * range by omitting the NaN/Inf encodings.
7180              */
7181             flag ieee = 1;
7182
7183             MSA_FLOAT_BINOP(pwx->w[i], from_float16, Lh(pws, i), ieee, 32);
7184         }
7185         break;
7186     case DF_DOUBLE:
7187         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7188             MSA_FLOAT_UNOP(pwx->d[i], from_float32, Lw(pws, i), 64);
7189         }
7190         break;
7191     default:
7192         assert(0);
7193     }
7194
7195     check_msacsr_cause(env, GETPC());
7196     msa_move_v(pwd, pwx);
7197 }
7198
7199 void helper_msa_fexupr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7200                           uint32_t ws)
7201 {
7202     wr_t wx, *pwx = &wx;
7203     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7204     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7205     uint32_t i;
7206
7207     clear_msacsr_cause(env);
7208
7209     switch (df) {
7210     case DF_WORD:
7211         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7212             /*
7213              * Half precision floats come in two formats: standard
7214              * IEEE and "ARM" format.  The latter gains extra exponent
7215              * range by omitting the NaN/Inf encodings.
7216              */
7217             flag ieee = 1;
7218
7219             MSA_FLOAT_BINOP(pwx->w[i], from_float16, Rh(pws, i), ieee, 32);
7220         }
7221         break;
7222     case DF_DOUBLE:
7223         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7224             MSA_FLOAT_UNOP(pwx->d[i], from_float32, Rw(pws, i), 64);
7225         }
7226         break;
7227     default:
7228         assert(0);
7229     }
7230
7231     check_msacsr_cause(env, GETPC());
7232     msa_move_v(pwd, pwx);
7233 }
7234
7235 void helper_msa_ffql_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7236                         uint32_t ws)
7237 {
7238     wr_t wx, *pwx = &wx;
7239     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7240     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7241     uint32_t i;
7242
7243     switch (df) {
7244     case DF_WORD:
7245         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7246             MSA_FLOAT_UNOP(pwx->w[i], from_q16, Lh(pws, i), 32);
7247         }
7248         break;
7249     case DF_DOUBLE:
7250         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7251             MSA_FLOAT_UNOP(pwx->d[i], from_q32, Lw(pws, i), 64);
7252         }
7253         break;
7254     default:
7255         assert(0);
7256     }
7257
7258     msa_move_v(pwd, pwx);
7259 }
7260
7261 void helper_msa_ffqr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7262                         uint32_t ws)
7263 {
7264     wr_t wx, *pwx = &wx;
7265     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7266     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7267     uint32_t i;
7268
7269     switch (df) {
7270     case DF_WORD:
7271         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7272             MSA_FLOAT_UNOP(pwx->w[i], from_q16, Rh(pws, i), 32);
7273         }
7274         break;
7275     case DF_DOUBLE:
7276         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7277             MSA_FLOAT_UNOP(pwx->d[i], from_q32, Rw(pws, i), 64);
7278         }
7279         break;
7280     default:
7281         assert(0);
7282     }
7283
7284     msa_move_v(pwd, pwx);
7285 }
7286
7287 void helper_msa_ftint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7288                            uint32_t ws)
7289 {
7290     wr_t wx, *pwx = &wx;
7291     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7292     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7293     uint32_t i;
7294
7295     clear_msacsr_cause(env);
7296
7297     switch (df) {
7298     case DF_WORD:
7299         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7300             MSA_FLOAT_UNOP0(pwx->w[i], to_int32, pws->w[i], 32);
7301         }
7302         break;
7303     case DF_DOUBLE:
7304         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7305             MSA_FLOAT_UNOP0(pwx->d[i], to_int64, pws->d[i], 64);
7306         }
7307         break;
7308     default:
7309         assert(0);
7310     }
7311
7312     check_msacsr_cause(env, GETPC());
7313
7314     msa_move_v(pwd, pwx);
7315 }
7316
7317 void helper_msa_ftint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7318                            uint32_t ws)
7319 {
7320     wr_t wx, *pwx = &wx;
7321     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7322     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7323     uint32_t i;
7324
7325     clear_msacsr_cause(env);
7326
7327     switch (df) {
7328     case DF_WORD:
7329         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7330             MSA_FLOAT_UNOP0(pwx->w[i], to_uint32, pws->w[i], 32);
7331         }
7332         break;
7333     case DF_DOUBLE:
7334         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7335             MSA_FLOAT_UNOP0(pwx->d[i], to_uint64, pws->d[i], 64);
7336         }
7337         break;
7338     default:
7339         assert(0);
7340     }
7341
7342     check_msacsr_cause(env, GETPC());
7343
7344     msa_move_v(pwd, pwx);
7345 }
7346
7347 #define float32_from_int32 int32_to_float32
7348 #define float32_from_uint32 uint32_to_float32
7349
7350 #define float64_from_int64 int64_to_float64
7351 #define float64_from_uint64 uint64_to_float64
7352
7353 void helper_msa_ffint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7354                            uint32_t ws)
7355 {
7356     wr_t wx, *pwx = &wx;
7357     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7358     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7359     uint32_t i;
7360
7361     clear_msacsr_cause(env);
7362
7363     switch (df) {
7364     case DF_WORD:
7365         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7366             MSA_FLOAT_UNOP(pwx->w[i], from_int32, pws->w[i], 32);
7367         }
7368         break;
7369     case DF_DOUBLE:
7370         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7371             MSA_FLOAT_UNOP(pwx->d[i], from_int64, pws->d[i], 64);
7372         }
7373         break;
7374     default:
7375         assert(0);
7376     }
7377
7378     check_msacsr_cause(env, GETPC());
7379
7380     msa_move_v(pwd, pwx);
7381 }
7382
7383 void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7384                            uint32_t ws)
7385 {
7386     wr_t wx, *pwx = &wx;
7387     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7388     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7389     uint32_t i;
7390
7391     clear_msacsr_cause(env);
7392
7393     switch (df) {
7394     case DF_WORD:
7395         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7396             MSA_FLOAT_UNOP(pwx->w[i], from_uint32, pws->w[i], 32);
7397         }
7398         break;
7399     case DF_DOUBLE:
7400         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7401             MSA_FLOAT_UNOP(pwx->d[i], from_uint64, pws->d[i], 64);
7402         }
7403         break;
7404     default:
7405         assert(0);
7406     }
7407
7408     check_msacsr_cause(env, GETPC());
7409
7410     msa_move_v(pwd, pwx);
7411 }
This page took 0.453465 seconds and 4 git commands to generate.