xref: /openbmc/qemu/target/mips/tcg/msa_helper.c (revision ea06a006)
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.1 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 "tcg/tcg.h"
24 #include "exec/exec-all.h"
25 #include "exec/helper-proto.h"
26 #include "exec/memop.h"
27 #include "fpu/softfloat.h"
28 #include "fpu_helper.h"
29 
30 /* Data format min and max values */
31 #define DF_BITS(df) (1 << ((df) + 3))
32 
33 #define DF_MAX_INT(df)  (int64_t)((1LL << (DF_BITS(df) - 1)) - 1)
34 #define M_MAX_INT(m)    (int64_t)((1LL << ((m)         - 1)) - 1)
35 
36 #define DF_MIN_INT(df)  (int64_t)(-(1LL << (DF_BITS(df) - 1)))
37 #define M_MIN_INT(m)    (int64_t)(-(1LL << ((m)         - 1)))
38 
39 #define DF_MAX_UINT(df) (uint64_t)(-1ULL >> (64 - DF_BITS(df)))
40 #define M_MAX_UINT(m)   (uint64_t)(-1ULL >> (64 - (m)))
41 
42 #define UNSIGNED(x, df) ((x) & DF_MAX_UINT(df))
43 #define SIGNED(x, df)                                                   \
44     ((((int64_t)x) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df)))
45 
46 /* Element-by-element access macros */
47 #define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df))
48 
49 
50 
51 /*
52  * Bit Count
53  * ---------
54  *
55  * +---------------+----------------------------------------------------------+
56  * | NLOC.B        | Vector Leading Ones Count (byte)                         |
57  * | NLOC.H        | Vector Leading Ones Count (halfword)                     |
58  * | NLOC.W        | Vector Leading Ones Count (word)                         |
59  * | NLOC.D        | Vector Leading Ones Count (doubleword)                   |
60  * | NLZC.B        | Vector Leading Zeros Count (byte)                        |
61  * | NLZC.H        | Vector Leading Zeros Count (halfword)                    |
62  * | NLZC.W        | Vector Leading Zeros Count (word)                        |
63  * | NLZC.D        | Vector Leading Zeros Count (doubleword)                  |
64  * | PCNT.B        | Vector Population Count (byte)                           |
65  * | PCNT.H        | Vector Population Count (halfword)                       |
66  * | PCNT.W        | Vector Population Count (word)                           |
67  * | PCNT.D        | Vector Population Count (doubleword)                     |
68  * +---------------+----------------------------------------------------------+
69  */
70 
71 static inline int64_t msa_nlzc_df(uint32_t df, int64_t arg)
72 {
73     uint64_t x, y;
74     int n, c;
75 
76     x = UNSIGNED(arg, df);
77     n = DF_BITS(df);
78     c = DF_BITS(df) / 2;
79 
80     do {
81         y = x >> c;
82         if (y != 0) {
83             n = n - c;
84             x = y;
85         }
86         c = c >> 1;
87     } while (c != 0);
88 
89     return n - x;
90 }
91 
92 static inline int64_t msa_nloc_df(uint32_t df, int64_t arg)
93 {
94     return msa_nlzc_df(df, UNSIGNED((~arg), df));
95 }
96 
97 void helper_msa_nloc_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
98 {
99     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
100     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
101 
102     pwd->b[0]  = msa_nloc_df(DF_BYTE, pws->b[0]);
103     pwd->b[1]  = msa_nloc_df(DF_BYTE, pws->b[1]);
104     pwd->b[2]  = msa_nloc_df(DF_BYTE, pws->b[2]);
105     pwd->b[3]  = msa_nloc_df(DF_BYTE, pws->b[3]);
106     pwd->b[4]  = msa_nloc_df(DF_BYTE, pws->b[4]);
107     pwd->b[5]  = msa_nloc_df(DF_BYTE, pws->b[5]);
108     pwd->b[6]  = msa_nloc_df(DF_BYTE, pws->b[6]);
109     pwd->b[7]  = msa_nloc_df(DF_BYTE, pws->b[7]);
110     pwd->b[8]  = msa_nloc_df(DF_BYTE, pws->b[8]);
111     pwd->b[9]  = msa_nloc_df(DF_BYTE, pws->b[9]);
112     pwd->b[10] = msa_nloc_df(DF_BYTE, pws->b[10]);
113     pwd->b[11] = msa_nloc_df(DF_BYTE, pws->b[11]);
114     pwd->b[12] = msa_nloc_df(DF_BYTE, pws->b[12]);
115     pwd->b[13] = msa_nloc_df(DF_BYTE, pws->b[13]);
116     pwd->b[14] = msa_nloc_df(DF_BYTE, pws->b[14]);
117     pwd->b[15] = msa_nloc_df(DF_BYTE, pws->b[15]);
118 }
119 
120 void helper_msa_nloc_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
121 {
122     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
123     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
124 
125     pwd->h[0]  = msa_nloc_df(DF_HALF, pws->h[0]);
126     pwd->h[1]  = msa_nloc_df(DF_HALF, pws->h[1]);
127     pwd->h[2]  = msa_nloc_df(DF_HALF, pws->h[2]);
128     pwd->h[3]  = msa_nloc_df(DF_HALF, pws->h[3]);
129     pwd->h[4]  = msa_nloc_df(DF_HALF, pws->h[4]);
130     pwd->h[5]  = msa_nloc_df(DF_HALF, pws->h[5]);
131     pwd->h[6]  = msa_nloc_df(DF_HALF, pws->h[6]);
132     pwd->h[7]  = msa_nloc_df(DF_HALF, pws->h[7]);
133 }
134 
135 void helper_msa_nloc_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
136 {
137     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
138     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
139 
140     pwd->w[0]  = msa_nloc_df(DF_WORD, pws->w[0]);
141     pwd->w[1]  = msa_nloc_df(DF_WORD, pws->w[1]);
142     pwd->w[2]  = msa_nloc_df(DF_WORD, pws->w[2]);
143     pwd->w[3]  = msa_nloc_df(DF_WORD, pws->w[3]);
144 }
145 
146 void helper_msa_nloc_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
147 {
148     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
149     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
150 
151     pwd->d[0]  = msa_nloc_df(DF_DOUBLE, pws->d[0]);
152     pwd->d[1]  = msa_nloc_df(DF_DOUBLE, pws->d[1]);
153 }
154 
155 void helper_msa_nlzc_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
156 {
157     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
158     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
159 
160     pwd->b[0]  = msa_nlzc_df(DF_BYTE, pws->b[0]);
161     pwd->b[1]  = msa_nlzc_df(DF_BYTE, pws->b[1]);
162     pwd->b[2]  = msa_nlzc_df(DF_BYTE, pws->b[2]);
163     pwd->b[3]  = msa_nlzc_df(DF_BYTE, pws->b[3]);
164     pwd->b[4]  = msa_nlzc_df(DF_BYTE, pws->b[4]);
165     pwd->b[5]  = msa_nlzc_df(DF_BYTE, pws->b[5]);
166     pwd->b[6]  = msa_nlzc_df(DF_BYTE, pws->b[6]);
167     pwd->b[7]  = msa_nlzc_df(DF_BYTE, pws->b[7]);
168     pwd->b[8]  = msa_nlzc_df(DF_BYTE, pws->b[8]);
169     pwd->b[9]  = msa_nlzc_df(DF_BYTE, pws->b[9]);
170     pwd->b[10] = msa_nlzc_df(DF_BYTE, pws->b[10]);
171     pwd->b[11] = msa_nlzc_df(DF_BYTE, pws->b[11]);
172     pwd->b[12] = msa_nlzc_df(DF_BYTE, pws->b[12]);
173     pwd->b[13] = msa_nlzc_df(DF_BYTE, pws->b[13]);
174     pwd->b[14] = msa_nlzc_df(DF_BYTE, pws->b[14]);
175     pwd->b[15] = msa_nlzc_df(DF_BYTE, pws->b[15]);
176 }
177 
178 void helper_msa_nlzc_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
179 {
180     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
181     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
182 
183     pwd->h[0]  = msa_nlzc_df(DF_HALF, pws->h[0]);
184     pwd->h[1]  = msa_nlzc_df(DF_HALF, pws->h[1]);
185     pwd->h[2]  = msa_nlzc_df(DF_HALF, pws->h[2]);
186     pwd->h[3]  = msa_nlzc_df(DF_HALF, pws->h[3]);
187     pwd->h[4]  = msa_nlzc_df(DF_HALF, pws->h[4]);
188     pwd->h[5]  = msa_nlzc_df(DF_HALF, pws->h[5]);
189     pwd->h[6]  = msa_nlzc_df(DF_HALF, pws->h[6]);
190     pwd->h[7]  = msa_nlzc_df(DF_HALF, pws->h[7]);
191 }
192 
193 void helper_msa_nlzc_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
194 {
195     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
196     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
197 
198     pwd->w[0]  = msa_nlzc_df(DF_WORD, pws->w[0]);
199     pwd->w[1]  = msa_nlzc_df(DF_WORD, pws->w[1]);
200     pwd->w[2]  = msa_nlzc_df(DF_WORD, pws->w[2]);
201     pwd->w[3]  = msa_nlzc_df(DF_WORD, pws->w[3]);
202 }
203 
204 void helper_msa_nlzc_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
205 {
206     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
207     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
208 
209     pwd->d[0]  = msa_nlzc_df(DF_DOUBLE, pws->d[0]);
210     pwd->d[1]  = msa_nlzc_df(DF_DOUBLE, pws->d[1]);
211 }
212 
213 static inline int64_t msa_pcnt_df(uint32_t df, int64_t arg)
214 {
215     uint64_t x;
216 
217     x = UNSIGNED(arg, df);
218 
219     x = (x & 0x5555555555555555ULL) + ((x >>  1) & 0x5555555555555555ULL);
220     x = (x & 0x3333333333333333ULL) + ((x >>  2) & 0x3333333333333333ULL);
221     x = (x & 0x0F0F0F0F0F0F0F0FULL) + ((x >>  4) & 0x0F0F0F0F0F0F0F0FULL);
222     x = (x & 0x00FF00FF00FF00FFULL) + ((x >>  8) & 0x00FF00FF00FF00FFULL);
223     x = (x & 0x0000FFFF0000FFFFULL) + ((x >> 16) & 0x0000FFFF0000FFFFULL);
224     x = (x & 0x00000000FFFFFFFFULL) + ((x >> 32));
225 
226     return x;
227 }
228 
229 void helper_msa_pcnt_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
230 {
231     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
232     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
233 
234     pwd->b[0]  = msa_pcnt_df(DF_BYTE, pws->b[0]);
235     pwd->b[1]  = msa_pcnt_df(DF_BYTE, pws->b[1]);
236     pwd->b[2]  = msa_pcnt_df(DF_BYTE, pws->b[2]);
237     pwd->b[3]  = msa_pcnt_df(DF_BYTE, pws->b[3]);
238     pwd->b[4]  = msa_pcnt_df(DF_BYTE, pws->b[4]);
239     pwd->b[5]  = msa_pcnt_df(DF_BYTE, pws->b[5]);
240     pwd->b[6]  = msa_pcnt_df(DF_BYTE, pws->b[6]);
241     pwd->b[7]  = msa_pcnt_df(DF_BYTE, pws->b[7]);
242     pwd->b[8]  = msa_pcnt_df(DF_BYTE, pws->b[8]);
243     pwd->b[9]  = msa_pcnt_df(DF_BYTE, pws->b[9]);
244     pwd->b[10] = msa_pcnt_df(DF_BYTE, pws->b[10]);
245     pwd->b[11] = msa_pcnt_df(DF_BYTE, pws->b[11]);
246     pwd->b[12] = msa_pcnt_df(DF_BYTE, pws->b[12]);
247     pwd->b[13] = msa_pcnt_df(DF_BYTE, pws->b[13]);
248     pwd->b[14] = msa_pcnt_df(DF_BYTE, pws->b[14]);
249     pwd->b[15] = msa_pcnt_df(DF_BYTE, pws->b[15]);
250 }
251 
252 void helper_msa_pcnt_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
253 {
254     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
255     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
256 
257     pwd->h[0]  = msa_pcnt_df(DF_HALF, pws->h[0]);
258     pwd->h[1]  = msa_pcnt_df(DF_HALF, pws->h[1]);
259     pwd->h[2]  = msa_pcnt_df(DF_HALF, pws->h[2]);
260     pwd->h[3]  = msa_pcnt_df(DF_HALF, pws->h[3]);
261     pwd->h[4]  = msa_pcnt_df(DF_HALF, pws->h[4]);
262     pwd->h[5]  = msa_pcnt_df(DF_HALF, pws->h[5]);
263     pwd->h[6]  = msa_pcnt_df(DF_HALF, pws->h[6]);
264     pwd->h[7]  = msa_pcnt_df(DF_HALF, pws->h[7]);
265 }
266 
267 void helper_msa_pcnt_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
268 {
269     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
270     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
271 
272     pwd->w[0]  = msa_pcnt_df(DF_WORD, pws->w[0]);
273     pwd->w[1]  = msa_pcnt_df(DF_WORD, pws->w[1]);
274     pwd->w[2]  = msa_pcnt_df(DF_WORD, pws->w[2]);
275     pwd->w[3]  = msa_pcnt_df(DF_WORD, pws->w[3]);
276 }
277 
278 void helper_msa_pcnt_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
279 {
280     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
281     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
282 
283     pwd->d[0]  = msa_pcnt_df(DF_DOUBLE, pws->d[0]);
284     pwd->d[1]  = msa_pcnt_df(DF_DOUBLE, pws->d[1]);
285 }
286 
287 
288 /*
289  * Bit Move
290  * --------
291  *
292  * +---------------+----------------------------------------------------------+
293  * | BINSL.B       | Vector Bit Insert Left (byte)                            |
294  * | BINSL.H       | Vector Bit Insert Left (halfword)                        |
295  * | BINSL.W       | Vector Bit Insert Left (word)                            |
296  * | BINSL.D       | Vector Bit Insert Left (doubleword)                      |
297  * | BINSR.B       | Vector Bit Insert Right (byte)                           |
298  * | BINSR.H       | Vector Bit Insert Right (halfword)                       |
299  * | BINSR.W       | Vector Bit Insert Right (word)                           |
300  * | BINSR.D       | Vector Bit Insert Right (doubleword)                     |
301  * | BMNZ.V        | Vector Bit Move If Not Zero                              |
302  * | BMZ.V         | Vector Bit Move If Zero                                  |
303  * | BSEL.V        | Vector Bit Select                                        |
304  * +---------------+----------------------------------------------------------+
305  */
306 
307 /* Data format bit position and unsigned values */
308 #define BIT_POSITION(x, df) ((uint64_t)(x) % DF_BITS(df))
309 
310 static inline int64_t msa_binsl_df(uint32_t df,
311                                    int64_t dest, int64_t arg1, int64_t arg2)
312 {
313     uint64_t u_arg1 = UNSIGNED(arg1, df);
314     uint64_t u_dest = UNSIGNED(dest, df);
315     int32_t sh_d = BIT_POSITION(arg2, df) + 1;
316     int32_t sh_a = DF_BITS(df) - sh_d;
317     if (sh_d == DF_BITS(df)) {
318         return u_arg1;
319     } else {
320         return UNSIGNED(UNSIGNED(u_dest << sh_d, df) >> sh_d, df) |
321                UNSIGNED(UNSIGNED(u_arg1 >> sh_a, df) << sh_a, df);
322     }
323 }
324 
325 void helper_msa_binsl_b(CPUMIPSState *env,
326                         uint32_t wd, uint32_t ws, uint32_t wt)
327 {
328     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
329     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
330     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
331 
332     pwd->b[0]  = msa_binsl_df(DF_BYTE, pwd->b[0],  pws->b[0],  pwt->b[0]);
333     pwd->b[1]  = msa_binsl_df(DF_BYTE, pwd->b[1],  pws->b[1],  pwt->b[1]);
334     pwd->b[2]  = msa_binsl_df(DF_BYTE, pwd->b[2],  pws->b[2],  pwt->b[2]);
335     pwd->b[3]  = msa_binsl_df(DF_BYTE, pwd->b[3],  pws->b[3],  pwt->b[3]);
336     pwd->b[4]  = msa_binsl_df(DF_BYTE, pwd->b[4],  pws->b[4],  pwt->b[4]);
337     pwd->b[5]  = msa_binsl_df(DF_BYTE, pwd->b[5],  pws->b[5],  pwt->b[5]);
338     pwd->b[6]  = msa_binsl_df(DF_BYTE, pwd->b[6],  pws->b[6],  pwt->b[6]);
339     pwd->b[7]  = msa_binsl_df(DF_BYTE, pwd->b[7],  pws->b[7],  pwt->b[7]);
340     pwd->b[8]  = msa_binsl_df(DF_BYTE, pwd->b[8],  pws->b[8],  pwt->b[8]);
341     pwd->b[9]  = msa_binsl_df(DF_BYTE, pwd->b[9],  pws->b[9],  pwt->b[9]);
342     pwd->b[10] = msa_binsl_df(DF_BYTE, pwd->b[10], pws->b[10], pwt->b[10]);
343     pwd->b[11] = msa_binsl_df(DF_BYTE, pwd->b[11], pws->b[11], pwt->b[11]);
344     pwd->b[12] = msa_binsl_df(DF_BYTE, pwd->b[12], pws->b[12], pwt->b[12]);
345     pwd->b[13] = msa_binsl_df(DF_BYTE, pwd->b[13], pws->b[13], pwt->b[13]);
346     pwd->b[14] = msa_binsl_df(DF_BYTE, pwd->b[14], pws->b[14], pwt->b[14]);
347     pwd->b[15] = msa_binsl_df(DF_BYTE, pwd->b[15], pws->b[15], pwt->b[15]);
348 }
349 
350 void helper_msa_binsl_h(CPUMIPSState *env,
351                         uint32_t wd, uint32_t ws, uint32_t wt)
352 {
353     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
354     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
355     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
356 
357     pwd->h[0]  = msa_binsl_df(DF_HALF, pwd->h[0],  pws->h[0],  pwt->h[0]);
358     pwd->h[1]  = msa_binsl_df(DF_HALF, pwd->h[1],  pws->h[1],  pwt->h[1]);
359     pwd->h[2]  = msa_binsl_df(DF_HALF, pwd->h[2],  pws->h[2],  pwt->h[2]);
360     pwd->h[3]  = msa_binsl_df(DF_HALF, pwd->h[3],  pws->h[3],  pwt->h[3]);
361     pwd->h[4]  = msa_binsl_df(DF_HALF, pwd->h[4],  pws->h[4],  pwt->h[4]);
362     pwd->h[5]  = msa_binsl_df(DF_HALF, pwd->h[5],  pws->h[5],  pwt->h[5]);
363     pwd->h[6]  = msa_binsl_df(DF_HALF, pwd->h[6],  pws->h[6],  pwt->h[6]);
364     pwd->h[7]  = msa_binsl_df(DF_HALF, pwd->h[7],  pws->h[7],  pwt->h[7]);
365 }
366 
367 void helper_msa_binsl_w(CPUMIPSState *env,
368                         uint32_t wd, uint32_t ws, uint32_t wt)
369 {
370     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
371     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
372     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
373 
374     pwd->w[0]  = msa_binsl_df(DF_WORD, pwd->w[0],  pws->w[0],  pwt->w[0]);
375     pwd->w[1]  = msa_binsl_df(DF_WORD, pwd->w[1],  pws->w[1],  pwt->w[1]);
376     pwd->w[2]  = msa_binsl_df(DF_WORD, pwd->w[2],  pws->w[2],  pwt->w[2]);
377     pwd->w[3]  = msa_binsl_df(DF_WORD, pwd->w[3],  pws->w[3],  pwt->w[3]);
378 }
379 
380 void helper_msa_binsl_d(CPUMIPSState *env,
381                         uint32_t wd, uint32_t ws, uint32_t wt)
382 {
383     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
384     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
385     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
386 
387     pwd->d[0]  = msa_binsl_df(DF_DOUBLE, pwd->d[0],  pws->d[0],  pwt->d[0]);
388     pwd->d[1]  = msa_binsl_df(DF_DOUBLE, pwd->d[1],  pws->d[1],  pwt->d[1]);
389 }
390 
391 static inline int64_t msa_binsr_df(uint32_t df,
392                                    int64_t dest, int64_t arg1, int64_t arg2)
393 {
394     uint64_t u_arg1 = UNSIGNED(arg1, df);
395     uint64_t u_dest = UNSIGNED(dest, df);
396     int32_t sh_d = BIT_POSITION(arg2, df) + 1;
397     int32_t sh_a = DF_BITS(df) - sh_d;
398     if (sh_d == DF_BITS(df)) {
399         return u_arg1;
400     } else {
401         return UNSIGNED(UNSIGNED(u_dest >> sh_d, df) << sh_d, df) |
402                UNSIGNED(UNSIGNED(u_arg1 << sh_a, df) >> sh_a, df);
403     }
404 }
405 
406 void helper_msa_binsr_b(CPUMIPSState *env,
407                         uint32_t wd, uint32_t ws, uint32_t wt)
408 {
409     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
410     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
411     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
412 
413     pwd->b[0]  = msa_binsr_df(DF_BYTE, pwd->b[0],  pws->b[0],  pwt->b[0]);
414     pwd->b[1]  = msa_binsr_df(DF_BYTE, pwd->b[1],  pws->b[1],  pwt->b[1]);
415     pwd->b[2]  = msa_binsr_df(DF_BYTE, pwd->b[2],  pws->b[2],  pwt->b[2]);
416     pwd->b[3]  = msa_binsr_df(DF_BYTE, pwd->b[3],  pws->b[3],  pwt->b[3]);
417     pwd->b[4]  = msa_binsr_df(DF_BYTE, pwd->b[4],  pws->b[4],  pwt->b[4]);
418     pwd->b[5]  = msa_binsr_df(DF_BYTE, pwd->b[5],  pws->b[5],  pwt->b[5]);
419     pwd->b[6]  = msa_binsr_df(DF_BYTE, pwd->b[6],  pws->b[6],  pwt->b[6]);
420     pwd->b[7]  = msa_binsr_df(DF_BYTE, pwd->b[7],  pws->b[7],  pwt->b[7]);
421     pwd->b[8]  = msa_binsr_df(DF_BYTE, pwd->b[8],  pws->b[8],  pwt->b[8]);
422     pwd->b[9]  = msa_binsr_df(DF_BYTE, pwd->b[9],  pws->b[9],  pwt->b[9]);
423     pwd->b[10] = msa_binsr_df(DF_BYTE, pwd->b[10], pws->b[10], pwt->b[10]);
424     pwd->b[11] = msa_binsr_df(DF_BYTE, pwd->b[11], pws->b[11], pwt->b[11]);
425     pwd->b[12] = msa_binsr_df(DF_BYTE, pwd->b[12], pws->b[12], pwt->b[12]);
426     pwd->b[13] = msa_binsr_df(DF_BYTE, pwd->b[13], pws->b[13], pwt->b[13]);
427     pwd->b[14] = msa_binsr_df(DF_BYTE, pwd->b[14], pws->b[14], pwt->b[14]);
428     pwd->b[15] = msa_binsr_df(DF_BYTE, pwd->b[15], pws->b[15], pwt->b[15]);
429 }
430 
431 void helper_msa_binsr_h(CPUMIPSState *env,
432                         uint32_t wd, uint32_t ws, uint32_t wt)
433 {
434     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
435     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
436     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
437 
438     pwd->h[0]  = msa_binsr_df(DF_HALF, pwd->h[0],  pws->h[0],  pwt->h[0]);
439     pwd->h[1]  = msa_binsr_df(DF_HALF, pwd->h[1],  pws->h[1],  pwt->h[1]);
440     pwd->h[2]  = msa_binsr_df(DF_HALF, pwd->h[2],  pws->h[2],  pwt->h[2]);
441     pwd->h[3]  = msa_binsr_df(DF_HALF, pwd->h[3],  pws->h[3],  pwt->h[3]);
442     pwd->h[4]  = msa_binsr_df(DF_HALF, pwd->h[4],  pws->h[4],  pwt->h[4]);
443     pwd->h[5]  = msa_binsr_df(DF_HALF, pwd->h[5],  pws->h[5],  pwt->h[5]);
444     pwd->h[6]  = msa_binsr_df(DF_HALF, pwd->h[6],  pws->h[6],  pwt->h[6]);
445     pwd->h[7]  = msa_binsr_df(DF_HALF, pwd->h[7],  pws->h[7],  pwt->h[7]);
446 }
447 
448 void helper_msa_binsr_w(CPUMIPSState *env,
449                         uint32_t wd, uint32_t ws, uint32_t wt)
450 {
451     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
452     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
453     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
454 
455     pwd->w[0]  = msa_binsr_df(DF_WORD, pwd->w[0],  pws->w[0],  pwt->w[0]);
456     pwd->w[1]  = msa_binsr_df(DF_WORD, pwd->w[1],  pws->w[1],  pwt->w[1]);
457     pwd->w[2]  = msa_binsr_df(DF_WORD, pwd->w[2],  pws->w[2],  pwt->w[2]);
458     pwd->w[3]  = msa_binsr_df(DF_WORD, pwd->w[3],  pws->w[3],  pwt->w[3]);
459 }
460 
461 void helper_msa_binsr_d(CPUMIPSState *env,
462                         uint32_t wd, uint32_t ws, uint32_t wt)
463 {
464     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
465     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
466     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
467 
468     pwd->d[0]  = msa_binsr_df(DF_DOUBLE, pwd->d[0],  pws->d[0],  pwt->d[0]);
469     pwd->d[1]  = msa_binsr_df(DF_DOUBLE, pwd->d[1],  pws->d[1],  pwt->d[1]);
470 }
471 
472 void helper_msa_bmnz_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
473 {
474     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
475     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
476     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
477 
478     pwd->d[0] = UNSIGNED(                                                     \
479         ((pwd->d[0] & (~pwt->d[0])) | (pws->d[0] & pwt->d[0])), DF_DOUBLE);
480     pwd->d[1] = UNSIGNED(                                                     \
481         ((pwd->d[1] & (~pwt->d[1])) | (pws->d[1] & pwt->d[1])), DF_DOUBLE);
482 }
483 
484 void helper_msa_bmz_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
485 {
486     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
487     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
488     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
489 
490     pwd->d[0] = UNSIGNED(                                                     \
491         ((pwd->d[0] & pwt->d[0]) | (pws->d[0] & (~pwt->d[0]))), DF_DOUBLE);
492     pwd->d[1] = UNSIGNED(                                                     \
493         ((pwd->d[1] & pwt->d[1]) | (pws->d[1] & (~pwt->d[1]))), DF_DOUBLE);
494 }
495 
496 void helper_msa_bsel_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
497 {
498     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
499     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
500     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
501 
502     pwd->d[0] = UNSIGNED(                                                     \
503         (pws->d[0] & (~pwd->d[0])) | (pwt->d[0] & pwd->d[0]), DF_DOUBLE);
504     pwd->d[1] = UNSIGNED(                                                     \
505         (pws->d[1] & (~pwd->d[1])) | (pwt->d[1] & pwd->d[1]), DF_DOUBLE);
506 }
507 
508 
509 /*
510  * Bit Set
511  * -------
512  *
513  * +---------------+----------------------------------------------------------+
514  * | BCLR.B        | Vector Bit Clear (byte)                                  |
515  * | BCLR.H        | Vector Bit Clear (halfword)                              |
516  * | BCLR.W        | Vector Bit Clear (word)                                  |
517  * | BCLR.D        | Vector Bit Clear (doubleword)                            |
518  * | BNEG.B        | Vector Bit Negate (byte)                                 |
519  * | BNEG.H        | Vector Bit Negate (halfword)                             |
520  * | BNEG.W        | Vector Bit Negate (word)                                 |
521  * | BNEG.D        | Vector Bit Negate (doubleword)                           |
522  * | BSET.B        | Vector Bit Set (byte)                                    |
523  * | BSET.H        | Vector Bit Set (halfword)                                |
524  * | BSET.W        | Vector Bit Set (word)                                    |
525  * | BSET.D        | Vector Bit Set (doubleword)                              |
526  * +---------------+----------------------------------------------------------+
527  */
528 
529 static inline int64_t msa_bclr_df(uint32_t df, int64_t arg1, int64_t arg2)
530 {
531     int32_t b_arg2 = BIT_POSITION(arg2, df);
532     return UNSIGNED(arg1 & (~(1LL << b_arg2)), df);
533 }
534 
535 void helper_msa_bclr_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
536 {
537     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
538     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
539     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
540 
541     pwd->b[0]  = msa_bclr_df(DF_BYTE, pws->b[0],  pwt->b[0]);
542     pwd->b[1]  = msa_bclr_df(DF_BYTE, pws->b[1],  pwt->b[1]);
543     pwd->b[2]  = msa_bclr_df(DF_BYTE, pws->b[2],  pwt->b[2]);
544     pwd->b[3]  = msa_bclr_df(DF_BYTE, pws->b[3],  pwt->b[3]);
545     pwd->b[4]  = msa_bclr_df(DF_BYTE, pws->b[4],  pwt->b[4]);
546     pwd->b[5]  = msa_bclr_df(DF_BYTE, pws->b[5],  pwt->b[5]);
547     pwd->b[6]  = msa_bclr_df(DF_BYTE, pws->b[6],  pwt->b[6]);
548     pwd->b[7]  = msa_bclr_df(DF_BYTE, pws->b[7],  pwt->b[7]);
549     pwd->b[8]  = msa_bclr_df(DF_BYTE, pws->b[8],  pwt->b[8]);
550     pwd->b[9]  = msa_bclr_df(DF_BYTE, pws->b[9],  pwt->b[9]);
551     pwd->b[10] = msa_bclr_df(DF_BYTE, pws->b[10], pwt->b[10]);
552     pwd->b[11] = msa_bclr_df(DF_BYTE, pws->b[11], pwt->b[11]);
553     pwd->b[12] = msa_bclr_df(DF_BYTE, pws->b[12], pwt->b[12]);
554     pwd->b[13] = msa_bclr_df(DF_BYTE, pws->b[13], pwt->b[13]);
555     pwd->b[14] = msa_bclr_df(DF_BYTE, pws->b[14], pwt->b[14]);
556     pwd->b[15] = msa_bclr_df(DF_BYTE, pws->b[15], pwt->b[15]);
557 }
558 
559 void helper_msa_bclr_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
560 {
561     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
562     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
563     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
564 
565     pwd->h[0]  = msa_bclr_df(DF_HALF, pws->h[0],  pwt->h[0]);
566     pwd->h[1]  = msa_bclr_df(DF_HALF, pws->h[1],  pwt->h[1]);
567     pwd->h[2]  = msa_bclr_df(DF_HALF, pws->h[2],  pwt->h[2]);
568     pwd->h[3]  = msa_bclr_df(DF_HALF, pws->h[3],  pwt->h[3]);
569     pwd->h[4]  = msa_bclr_df(DF_HALF, pws->h[4],  pwt->h[4]);
570     pwd->h[5]  = msa_bclr_df(DF_HALF, pws->h[5],  pwt->h[5]);
571     pwd->h[6]  = msa_bclr_df(DF_HALF, pws->h[6],  pwt->h[6]);
572     pwd->h[7]  = msa_bclr_df(DF_HALF, pws->h[7],  pwt->h[7]);
573 }
574 
575 void helper_msa_bclr_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
576 {
577     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
578     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
579     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
580 
581     pwd->w[0]  = msa_bclr_df(DF_WORD, pws->w[0],  pwt->w[0]);
582     pwd->w[1]  = msa_bclr_df(DF_WORD, pws->w[1],  pwt->w[1]);
583     pwd->w[2]  = msa_bclr_df(DF_WORD, pws->w[2],  pwt->w[2]);
584     pwd->w[3]  = msa_bclr_df(DF_WORD, pws->w[3],  pwt->w[3]);
585 }
586 
587 void helper_msa_bclr_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
588 {
589     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
590     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
591     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
592 
593     pwd->d[0]  = msa_bclr_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
594     pwd->d[1]  = msa_bclr_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
595 }
596 
597 static inline int64_t msa_bneg_df(uint32_t df, int64_t arg1, int64_t arg2)
598 {
599     int32_t b_arg2 = BIT_POSITION(arg2, df);
600     return UNSIGNED(arg1 ^ (1LL << b_arg2), df);
601 }
602 
603 void helper_msa_bneg_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
604 {
605     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
606     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
607     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
608 
609     pwd->b[0]  = msa_bneg_df(DF_BYTE, pws->b[0],  pwt->b[0]);
610     pwd->b[1]  = msa_bneg_df(DF_BYTE, pws->b[1],  pwt->b[1]);
611     pwd->b[2]  = msa_bneg_df(DF_BYTE, pws->b[2],  pwt->b[2]);
612     pwd->b[3]  = msa_bneg_df(DF_BYTE, pws->b[3],  pwt->b[3]);
613     pwd->b[4]  = msa_bneg_df(DF_BYTE, pws->b[4],  pwt->b[4]);
614     pwd->b[5]  = msa_bneg_df(DF_BYTE, pws->b[5],  pwt->b[5]);
615     pwd->b[6]  = msa_bneg_df(DF_BYTE, pws->b[6],  pwt->b[6]);
616     pwd->b[7]  = msa_bneg_df(DF_BYTE, pws->b[7],  pwt->b[7]);
617     pwd->b[8]  = msa_bneg_df(DF_BYTE, pws->b[8],  pwt->b[8]);
618     pwd->b[9]  = msa_bneg_df(DF_BYTE, pws->b[9],  pwt->b[9]);
619     pwd->b[10] = msa_bneg_df(DF_BYTE, pws->b[10], pwt->b[10]);
620     pwd->b[11] = msa_bneg_df(DF_BYTE, pws->b[11], pwt->b[11]);
621     pwd->b[12] = msa_bneg_df(DF_BYTE, pws->b[12], pwt->b[12]);
622     pwd->b[13] = msa_bneg_df(DF_BYTE, pws->b[13], pwt->b[13]);
623     pwd->b[14] = msa_bneg_df(DF_BYTE, pws->b[14], pwt->b[14]);
624     pwd->b[15] = msa_bneg_df(DF_BYTE, pws->b[15], pwt->b[15]);
625 }
626 
627 void helper_msa_bneg_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
628 {
629     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
630     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
631     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
632 
633     pwd->h[0]  = msa_bneg_df(DF_HALF, pws->h[0],  pwt->h[0]);
634     pwd->h[1]  = msa_bneg_df(DF_HALF, pws->h[1],  pwt->h[1]);
635     pwd->h[2]  = msa_bneg_df(DF_HALF, pws->h[2],  pwt->h[2]);
636     pwd->h[3]  = msa_bneg_df(DF_HALF, pws->h[3],  pwt->h[3]);
637     pwd->h[4]  = msa_bneg_df(DF_HALF, pws->h[4],  pwt->h[4]);
638     pwd->h[5]  = msa_bneg_df(DF_HALF, pws->h[5],  pwt->h[5]);
639     pwd->h[6]  = msa_bneg_df(DF_HALF, pws->h[6],  pwt->h[6]);
640     pwd->h[7]  = msa_bneg_df(DF_HALF, pws->h[7],  pwt->h[7]);
641 }
642 
643 void helper_msa_bneg_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
644 {
645     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
646     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
647     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
648 
649     pwd->w[0]  = msa_bneg_df(DF_WORD, pws->w[0],  pwt->w[0]);
650     pwd->w[1]  = msa_bneg_df(DF_WORD, pws->w[1],  pwt->w[1]);
651     pwd->w[2]  = msa_bneg_df(DF_WORD, pws->w[2],  pwt->w[2]);
652     pwd->w[3]  = msa_bneg_df(DF_WORD, pws->w[3],  pwt->w[3]);
653 }
654 
655 void helper_msa_bneg_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
656 {
657     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
658     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
659     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
660 
661     pwd->d[0]  = msa_bneg_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
662     pwd->d[1]  = msa_bneg_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
663 }
664 
665 static inline int64_t msa_bset_df(uint32_t df, int64_t arg1,
666         int64_t arg2)
667 {
668     int32_t b_arg2 = BIT_POSITION(arg2, df);
669     return UNSIGNED(arg1 | (1LL << b_arg2), df);
670 }
671 
672 void helper_msa_bset_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
673 {
674     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
675     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
676     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
677 
678     pwd->b[0]  = msa_bset_df(DF_BYTE, pws->b[0],  pwt->b[0]);
679     pwd->b[1]  = msa_bset_df(DF_BYTE, pws->b[1],  pwt->b[1]);
680     pwd->b[2]  = msa_bset_df(DF_BYTE, pws->b[2],  pwt->b[2]);
681     pwd->b[3]  = msa_bset_df(DF_BYTE, pws->b[3],  pwt->b[3]);
682     pwd->b[4]  = msa_bset_df(DF_BYTE, pws->b[4],  pwt->b[4]);
683     pwd->b[5]  = msa_bset_df(DF_BYTE, pws->b[5],  pwt->b[5]);
684     pwd->b[6]  = msa_bset_df(DF_BYTE, pws->b[6],  pwt->b[6]);
685     pwd->b[7]  = msa_bset_df(DF_BYTE, pws->b[7],  pwt->b[7]);
686     pwd->b[8]  = msa_bset_df(DF_BYTE, pws->b[8],  pwt->b[8]);
687     pwd->b[9]  = msa_bset_df(DF_BYTE, pws->b[9],  pwt->b[9]);
688     pwd->b[10] = msa_bset_df(DF_BYTE, pws->b[10], pwt->b[10]);
689     pwd->b[11] = msa_bset_df(DF_BYTE, pws->b[11], pwt->b[11]);
690     pwd->b[12] = msa_bset_df(DF_BYTE, pws->b[12], pwt->b[12]);
691     pwd->b[13] = msa_bset_df(DF_BYTE, pws->b[13], pwt->b[13]);
692     pwd->b[14] = msa_bset_df(DF_BYTE, pws->b[14], pwt->b[14]);
693     pwd->b[15] = msa_bset_df(DF_BYTE, pws->b[15], pwt->b[15]);
694 }
695 
696 void helper_msa_bset_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
697 {
698     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
699     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
700     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
701 
702     pwd->h[0]  = msa_bset_df(DF_HALF, pws->h[0],  pwt->h[0]);
703     pwd->h[1]  = msa_bset_df(DF_HALF, pws->h[1],  pwt->h[1]);
704     pwd->h[2]  = msa_bset_df(DF_HALF, pws->h[2],  pwt->h[2]);
705     pwd->h[3]  = msa_bset_df(DF_HALF, pws->h[3],  pwt->h[3]);
706     pwd->h[4]  = msa_bset_df(DF_HALF, pws->h[4],  pwt->h[4]);
707     pwd->h[5]  = msa_bset_df(DF_HALF, pws->h[5],  pwt->h[5]);
708     pwd->h[6]  = msa_bset_df(DF_HALF, pws->h[6],  pwt->h[6]);
709     pwd->h[7]  = msa_bset_df(DF_HALF, pws->h[7],  pwt->h[7]);
710 }
711 
712 void helper_msa_bset_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
713 {
714     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
715     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
716     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
717 
718     pwd->w[0]  = msa_bset_df(DF_WORD, pws->w[0],  pwt->w[0]);
719     pwd->w[1]  = msa_bset_df(DF_WORD, pws->w[1],  pwt->w[1]);
720     pwd->w[2]  = msa_bset_df(DF_WORD, pws->w[2],  pwt->w[2]);
721     pwd->w[3]  = msa_bset_df(DF_WORD, pws->w[3],  pwt->w[3]);
722 }
723 
724 void helper_msa_bset_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
725 {
726     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
727     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
728     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
729 
730     pwd->d[0]  = msa_bset_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
731     pwd->d[1]  = msa_bset_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
732 }
733 
734 
735 /*
736  * Fixed Multiply
737  * --------------
738  *
739  * +---------------+----------------------------------------------------------+
740  * | MADD_Q.H      | Vector Fixed-Point Multiply and Add (halfword)           |
741  * | MADD_Q.W      | Vector Fixed-Point Multiply and Add (word)               |
742  * | MADDR_Q.H     | Vector Fixed-Point Multiply and Add Rounded (halfword)   |
743  * | MADDR_Q.W     | Vector Fixed-Point Multiply and Add Rounded (word)       |
744  * | MSUB_Q.H      | Vector Fixed-Point Multiply and Subtr. (halfword)        |
745  * | MSUB_Q.W      | Vector Fixed-Point Multiply and Subtr. (word)            |
746  * | MSUBR_Q.H     | Vector Fixed-Point Multiply and Subtr. Rounded (halfword)|
747  * | MSUBR_Q.W     | Vector Fixed-Point Multiply and Subtr. Rounded (word)    |
748  * | MUL_Q.H       | Vector Fixed-Point Multiply (halfword)                   |
749  * | MUL_Q.W       | Vector Fixed-Point Multiply (word)                       |
750  * | MULR_Q.H      | Vector Fixed-Point Multiply Rounded (halfword)           |
751  * | MULR_Q.W      | Vector Fixed-Point Multiply Rounded (word)               |
752  * +---------------+----------------------------------------------------------+
753  */
754 
755 /* TODO: insert Fixed Multiply group helpers here */
756 
757 
758 /*
759  * Float Max Min
760  * -------------
761  *
762  * +---------------+----------------------------------------------------------+
763  * | FMAX_A.W      | Vector Floating-Point Maximum (Absolute) (word)          |
764  * | FMAX_A.D      | Vector Floating-Point Maximum (Absolute) (doubleword)    |
765  * | FMAX.W        | Vector Floating-Point Maximum (word)                     |
766  * | FMAX.D        | Vector Floating-Point Maximum (doubleword)               |
767  * | FMIN_A.W      | Vector Floating-Point Minimum (Absolute) (word)          |
768  * | FMIN_A.D      | Vector Floating-Point Minimum (Absolute) (doubleword)    |
769  * | FMIN.W        | Vector Floating-Point Minimum (word)                     |
770  * | FMIN.D        | Vector Floating-Point Minimum (doubleword)               |
771  * +---------------+----------------------------------------------------------+
772  */
773 
774 /* TODO: insert Float Max Min group helpers here */
775 
776 
777 /*
778  * Int Add
779  * -------
780  *
781  * +---------------+----------------------------------------------------------+
782  * | ADD_A.B       | Vector Add Absolute Values (byte)                        |
783  * | ADD_A.H       | Vector Add Absolute Values (halfword)                    |
784  * | ADD_A.W       | Vector Add Absolute Values (word)                        |
785  * | ADD_A.D       | Vector Add Absolute Values (doubleword)                  |
786  * | ADDS_A.B      | Vector Signed Saturated Add (of Absolute) (byte)         |
787  * | ADDS_A.H      | Vector Signed Saturated Add (of Absolute) (halfword)     |
788  * | ADDS_A.W      | Vector Signed Saturated Add (of Absolute) (word)         |
789  * | ADDS_A.D      | Vector Signed Saturated Add (of Absolute) (doubleword)   |
790  * | ADDS_S.B      | Vector Signed Saturated Add (of Signed) (byte)           |
791  * | ADDS_S.H      | Vector Signed Saturated Add (of Signed) (halfword)       |
792  * | ADDS_S.W      | Vector Signed Saturated Add (of Signed) (word)           |
793  * | ADDS_S.D      | Vector Signed Saturated Add (of Signed) (doubleword)     |
794  * | ADDS_U.B      | Vector Unsigned Saturated Add (of Unsigned) (byte)       |
795  * | ADDS_U.H      | Vector Unsigned Saturated Add (of Unsigned) (halfword)   |
796  * | ADDS_U.W      | Vector Unsigned Saturated Add (of Unsigned) (word)       |
797  * | ADDS_U.D      | Vector Unsigned Saturated Add (of Unsigned) (doubleword) |
798  * | ADDV.B        | Vector Add (byte)                                        |
799  * | ADDV.H        | Vector Add (halfword)                                    |
800  * | ADDV.W        | Vector Add (word)                                        |
801  * | ADDV.D        | Vector Add (doubleword)                                  |
802  * | HADD_S.H      | Vector Signed Horizontal Add (halfword)                  |
803  * | HADD_S.W      | Vector Signed Horizontal Add (word)                      |
804  * | HADD_S.D      | Vector Signed Horizontal Add (doubleword)                |
805  * | HADD_U.H      | Vector Unigned Horizontal Add (halfword)                 |
806  * | HADD_U.W      | Vector Unigned Horizontal Add (word)                     |
807  * | HADD_U.D      | Vector Unigned Horizontal Add (doubleword)               |
808  * +---------------+----------------------------------------------------------+
809  */
810 
811 
812 static inline int64_t msa_add_a_df(uint32_t df, int64_t arg1, int64_t arg2)
813 {
814     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
815     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
816     return abs_arg1 + abs_arg2;
817 }
818 
819 void helper_msa_add_a_b(CPUMIPSState *env,
820                         uint32_t wd, uint32_t ws, uint32_t wt)
821 {
822     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
823     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
824     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
825 
826     pwd->b[0]  = msa_add_a_df(DF_BYTE, pws->b[0],  pwt->b[0]);
827     pwd->b[1]  = msa_add_a_df(DF_BYTE, pws->b[1],  pwt->b[1]);
828     pwd->b[2]  = msa_add_a_df(DF_BYTE, pws->b[2],  pwt->b[2]);
829     pwd->b[3]  = msa_add_a_df(DF_BYTE, pws->b[3],  pwt->b[3]);
830     pwd->b[4]  = msa_add_a_df(DF_BYTE, pws->b[4],  pwt->b[4]);
831     pwd->b[5]  = msa_add_a_df(DF_BYTE, pws->b[5],  pwt->b[5]);
832     pwd->b[6]  = msa_add_a_df(DF_BYTE, pws->b[6],  pwt->b[6]);
833     pwd->b[7]  = msa_add_a_df(DF_BYTE, pws->b[7],  pwt->b[7]);
834     pwd->b[8]  = msa_add_a_df(DF_BYTE, pws->b[8],  pwt->b[8]);
835     pwd->b[9]  = msa_add_a_df(DF_BYTE, pws->b[9],  pwt->b[9]);
836     pwd->b[10] = msa_add_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
837     pwd->b[11] = msa_add_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
838     pwd->b[12] = msa_add_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
839     pwd->b[13] = msa_add_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
840     pwd->b[14] = msa_add_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
841     pwd->b[15] = msa_add_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
842 }
843 
844 void helper_msa_add_a_h(CPUMIPSState *env,
845                         uint32_t wd, uint32_t ws, uint32_t wt)
846 {
847     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
848     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
849     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
850 
851     pwd->h[0]  = msa_add_a_df(DF_HALF, pws->h[0],  pwt->h[0]);
852     pwd->h[1]  = msa_add_a_df(DF_HALF, pws->h[1],  pwt->h[1]);
853     pwd->h[2]  = msa_add_a_df(DF_HALF, pws->h[2],  pwt->h[2]);
854     pwd->h[3]  = msa_add_a_df(DF_HALF, pws->h[3],  pwt->h[3]);
855     pwd->h[4]  = msa_add_a_df(DF_HALF, pws->h[4],  pwt->h[4]);
856     pwd->h[5]  = msa_add_a_df(DF_HALF, pws->h[5],  pwt->h[5]);
857     pwd->h[6]  = msa_add_a_df(DF_HALF, pws->h[6],  pwt->h[6]);
858     pwd->h[7]  = msa_add_a_df(DF_HALF, pws->h[7],  pwt->h[7]);
859 }
860 
861 void helper_msa_add_a_w(CPUMIPSState *env,
862                         uint32_t wd, uint32_t ws, uint32_t wt)
863 {
864     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
865     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
866     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
867 
868     pwd->w[0]  = msa_add_a_df(DF_WORD, pws->w[0],  pwt->w[0]);
869     pwd->w[1]  = msa_add_a_df(DF_WORD, pws->w[1],  pwt->w[1]);
870     pwd->w[2]  = msa_add_a_df(DF_WORD, pws->w[2],  pwt->w[2]);
871     pwd->w[3]  = msa_add_a_df(DF_WORD, pws->w[3],  pwt->w[3]);
872 }
873 
874 void helper_msa_add_a_d(CPUMIPSState *env,
875                         uint32_t wd, uint32_t ws, uint32_t wt)
876 {
877     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
878     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
879     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
880 
881     pwd->d[0]  = msa_add_a_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
882     pwd->d[1]  = msa_add_a_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
883 }
884 
885 
886 static inline int64_t msa_adds_a_df(uint32_t df, int64_t arg1, int64_t arg2)
887 {
888     uint64_t max_int = (uint64_t)DF_MAX_INT(df);
889     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
890     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
891     if (abs_arg1 > max_int || abs_arg2 > max_int) {
892         return (int64_t)max_int;
893     } else {
894         return (abs_arg1 < max_int - abs_arg2) ? abs_arg1 + abs_arg2 : max_int;
895     }
896 }
897 
898 void helper_msa_adds_a_b(CPUMIPSState *env,
899                          uint32_t wd, uint32_t ws, uint32_t wt)
900 {
901     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
902     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
903     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
904 
905     pwd->b[0]  = msa_adds_a_df(DF_BYTE, pws->b[0],  pwt->b[0]);
906     pwd->b[1]  = msa_adds_a_df(DF_BYTE, pws->b[1],  pwt->b[1]);
907     pwd->b[2]  = msa_adds_a_df(DF_BYTE, pws->b[2],  pwt->b[2]);
908     pwd->b[3]  = msa_adds_a_df(DF_BYTE, pws->b[3],  pwt->b[3]);
909     pwd->b[4]  = msa_adds_a_df(DF_BYTE, pws->b[4],  pwt->b[4]);
910     pwd->b[5]  = msa_adds_a_df(DF_BYTE, pws->b[5],  pwt->b[5]);
911     pwd->b[6]  = msa_adds_a_df(DF_BYTE, pws->b[6],  pwt->b[6]);
912     pwd->b[7]  = msa_adds_a_df(DF_BYTE, pws->b[7],  pwt->b[7]);
913     pwd->b[8]  = msa_adds_a_df(DF_BYTE, pws->b[8],  pwt->b[8]);
914     pwd->b[9]  = msa_adds_a_df(DF_BYTE, pws->b[9],  pwt->b[9]);
915     pwd->b[10] = msa_adds_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
916     pwd->b[11] = msa_adds_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
917     pwd->b[12] = msa_adds_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
918     pwd->b[13] = msa_adds_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
919     pwd->b[14] = msa_adds_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
920     pwd->b[15] = msa_adds_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
921 }
922 
923 void helper_msa_adds_a_h(CPUMIPSState *env,
924                          uint32_t wd, uint32_t ws, uint32_t wt)
925 {
926     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
927     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
928     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
929 
930     pwd->h[0]  = msa_adds_a_df(DF_HALF, pws->h[0],  pwt->h[0]);
931     pwd->h[1]  = msa_adds_a_df(DF_HALF, pws->h[1],  pwt->h[1]);
932     pwd->h[2]  = msa_adds_a_df(DF_HALF, pws->h[2],  pwt->h[2]);
933     pwd->h[3]  = msa_adds_a_df(DF_HALF, pws->h[3],  pwt->h[3]);
934     pwd->h[4]  = msa_adds_a_df(DF_HALF, pws->h[4],  pwt->h[4]);
935     pwd->h[5]  = msa_adds_a_df(DF_HALF, pws->h[5],  pwt->h[5]);
936     pwd->h[6]  = msa_adds_a_df(DF_HALF, pws->h[6],  pwt->h[6]);
937     pwd->h[7]  = msa_adds_a_df(DF_HALF, pws->h[7],  pwt->h[7]);
938 }
939 
940 void helper_msa_adds_a_w(CPUMIPSState *env,
941                          uint32_t wd, uint32_t ws, uint32_t wt)
942 {
943     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
944     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
945     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
946 
947     pwd->w[0]  = msa_adds_a_df(DF_WORD, pws->w[0],  pwt->w[0]);
948     pwd->w[1]  = msa_adds_a_df(DF_WORD, pws->w[1],  pwt->w[1]);
949     pwd->w[2]  = msa_adds_a_df(DF_WORD, pws->w[2],  pwt->w[2]);
950     pwd->w[3]  = msa_adds_a_df(DF_WORD, pws->w[3],  pwt->w[3]);
951 }
952 
953 void helper_msa_adds_a_d(CPUMIPSState *env,
954                          uint32_t wd, uint32_t ws, uint32_t wt)
955 {
956     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
957     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
958     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
959 
960     pwd->d[0]  = msa_adds_a_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
961     pwd->d[1]  = msa_adds_a_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
962 }
963 
964 
965 static inline int64_t msa_adds_s_df(uint32_t df, int64_t arg1, int64_t arg2)
966 {
967     int64_t max_int = DF_MAX_INT(df);
968     int64_t min_int = DF_MIN_INT(df);
969     if (arg1 < 0) {
970         return (min_int - arg1 < arg2) ? arg1 + arg2 : min_int;
971     } else {
972         return (arg2 < max_int - arg1) ? arg1 + arg2 : max_int;
973     }
974 }
975 
976 void helper_msa_adds_s_b(CPUMIPSState *env,
977                          uint32_t wd, uint32_t ws, uint32_t wt)
978 {
979     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
980     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
981     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
982 
983     pwd->b[0]  = msa_adds_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
984     pwd->b[1]  = msa_adds_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
985     pwd->b[2]  = msa_adds_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
986     pwd->b[3]  = msa_adds_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
987     pwd->b[4]  = msa_adds_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
988     pwd->b[5]  = msa_adds_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
989     pwd->b[6]  = msa_adds_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
990     pwd->b[7]  = msa_adds_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
991     pwd->b[8]  = msa_adds_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
992     pwd->b[9]  = msa_adds_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
993     pwd->b[10] = msa_adds_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
994     pwd->b[11] = msa_adds_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
995     pwd->b[12] = msa_adds_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
996     pwd->b[13] = msa_adds_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
997     pwd->b[14] = msa_adds_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
998     pwd->b[15] = msa_adds_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
999 }
1000 
1001 void helper_msa_adds_s_h(CPUMIPSState *env,
1002                          uint32_t wd, uint32_t ws, uint32_t wt)
1003 {
1004     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1005     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1006     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1007 
1008     pwd->h[0]  = msa_adds_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1009     pwd->h[1]  = msa_adds_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1010     pwd->h[2]  = msa_adds_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1011     pwd->h[3]  = msa_adds_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1012     pwd->h[4]  = msa_adds_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1013     pwd->h[5]  = msa_adds_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1014     pwd->h[6]  = msa_adds_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1015     pwd->h[7]  = msa_adds_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1016 }
1017 
1018 void helper_msa_adds_s_w(CPUMIPSState *env,
1019                          uint32_t wd, uint32_t ws, uint32_t wt)
1020 {
1021     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1022     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1023     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1024 
1025     pwd->w[0]  = msa_adds_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1026     pwd->w[1]  = msa_adds_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1027     pwd->w[2]  = msa_adds_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1028     pwd->w[3]  = msa_adds_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1029 }
1030 
1031 void helper_msa_adds_s_d(CPUMIPSState *env,
1032                          uint32_t wd, uint32_t ws, uint32_t wt)
1033 {
1034     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1035     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1036     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1037 
1038     pwd->d[0]  = msa_adds_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1039     pwd->d[1]  = msa_adds_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1040 }
1041 
1042 
1043 static inline uint64_t msa_adds_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1044 {
1045     uint64_t max_uint = DF_MAX_UINT(df);
1046     uint64_t u_arg1 = UNSIGNED(arg1, df);
1047     uint64_t u_arg2 = UNSIGNED(arg2, df);
1048     return (u_arg1 < max_uint - u_arg2) ? u_arg1 + u_arg2 : max_uint;
1049 }
1050 
1051 void helper_msa_adds_u_b(CPUMIPSState *env,
1052                          uint32_t wd, uint32_t ws, uint32_t wt)
1053 {
1054     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1055     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1056     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1057 
1058     pwd->b[0]  = msa_adds_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1059     pwd->b[1]  = msa_adds_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1060     pwd->b[2]  = msa_adds_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1061     pwd->b[3]  = msa_adds_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1062     pwd->b[4]  = msa_adds_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1063     pwd->b[5]  = msa_adds_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1064     pwd->b[6]  = msa_adds_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1065     pwd->b[7]  = msa_adds_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1066     pwd->b[8]  = msa_adds_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1067     pwd->b[9]  = msa_adds_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1068     pwd->b[10] = msa_adds_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1069     pwd->b[11] = msa_adds_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1070     pwd->b[12] = msa_adds_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1071     pwd->b[13] = msa_adds_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1072     pwd->b[14] = msa_adds_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1073     pwd->b[15] = msa_adds_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1074 }
1075 
1076 void helper_msa_adds_u_h(CPUMIPSState *env,
1077                          uint32_t wd, uint32_t ws, uint32_t wt)
1078 {
1079     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1080     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1081     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1082 
1083     pwd->h[0]  = msa_adds_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1084     pwd->h[1]  = msa_adds_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1085     pwd->h[2]  = msa_adds_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1086     pwd->h[3]  = msa_adds_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1087     pwd->h[4]  = msa_adds_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1088     pwd->h[5]  = msa_adds_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1089     pwd->h[6]  = msa_adds_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1090     pwd->h[7]  = msa_adds_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1091 }
1092 
1093 void helper_msa_adds_u_w(CPUMIPSState *env,
1094                          uint32_t wd, uint32_t ws, uint32_t wt)
1095 {
1096     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1097     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1098     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1099 
1100     pwd->w[0]  = msa_adds_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1101     pwd->w[1]  = msa_adds_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1102     pwd->w[2]  = msa_adds_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1103     pwd->w[3]  = msa_adds_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1104 }
1105 
1106 void helper_msa_adds_u_d(CPUMIPSState *env,
1107                          uint32_t wd, uint32_t ws, uint32_t wt)
1108 {
1109     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1110     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1111     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1112 
1113     pwd->d[0]  = msa_adds_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1114     pwd->d[1]  = msa_adds_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1115 }
1116 
1117 
1118 static inline int64_t msa_addv_df(uint32_t df, int64_t arg1, int64_t arg2)
1119 {
1120     return arg1 + arg2;
1121 }
1122 
1123 void helper_msa_addv_b(CPUMIPSState *env,
1124                        uint32_t wd, uint32_t ws, uint32_t wt)
1125 {
1126     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1127     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1128     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1129 
1130     pwd->b[0]  = msa_addv_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1131     pwd->b[1]  = msa_addv_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1132     pwd->b[2]  = msa_addv_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1133     pwd->b[3]  = msa_addv_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1134     pwd->b[4]  = msa_addv_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1135     pwd->b[5]  = msa_addv_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1136     pwd->b[6]  = msa_addv_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1137     pwd->b[7]  = msa_addv_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1138     pwd->b[8]  = msa_addv_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1139     pwd->b[9]  = msa_addv_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1140     pwd->b[10] = msa_addv_df(DF_BYTE, pws->b[10], pwt->b[10]);
1141     pwd->b[11] = msa_addv_df(DF_BYTE, pws->b[11], pwt->b[11]);
1142     pwd->b[12] = msa_addv_df(DF_BYTE, pws->b[12], pwt->b[12]);
1143     pwd->b[13] = msa_addv_df(DF_BYTE, pws->b[13], pwt->b[13]);
1144     pwd->b[14] = msa_addv_df(DF_BYTE, pws->b[14], pwt->b[14]);
1145     pwd->b[15] = msa_addv_df(DF_BYTE, pws->b[15], pwt->b[15]);
1146 }
1147 
1148 void helper_msa_addv_h(CPUMIPSState *env,
1149                        uint32_t wd, uint32_t ws, uint32_t wt)
1150 {
1151     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1152     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1153     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1154 
1155     pwd->h[0]  = msa_addv_df(DF_HALF, pws->h[0],  pwt->h[0]);
1156     pwd->h[1]  = msa_addv_df(DF_HALF, pws->h[1],  pwt->h[1]);
1157     pwd->h[2]  = msa_addv_df(DF_HALF, pws->h[2],  pwt->h[2]);
1158     pwd->h[3]  = msa_addv_df(DF_HALF, pws->h[3],  pwt->h[3]);
1159     pwd->h[4]  = msa_addv_df(DF_HALF, pws->h[4],  pwt->h[4]);
1160     pwd->h[5]  = msa_addv_df(DF_HALF, pws->h[5],  pwt->h[5]);
1161     pwd->h[6]  = msa_addv_df(DF_HALF, pws->h[6],  pwt->h[6]);
1162     pwd->h[7]  = msa_addv_df(DF_HALF, pws->h[7],  pwt->h[7]);
1163 }
1164 
1165 void helper_msa_addv_w(CPUMIPSState *env,
1166                        uint32_t wd, uint32_t ws, uint32_t wt)
1167 {
1168     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1169     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1170     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1171 
1172     pwd->w[0]  = msa_addv_df(DF_WORD, pws->w[0],  pwt->w[0]);
1173     pwd->w[1]  = msa_addv_df(DF_WORD, pws->w[1],  pwt->w[1]);
1174     pwd->w[2]  = msa_addv_df(DF_WORD, pws->w[2],  pwt->w[2]);
1175     pwd->w[3]  = msa_addv_df(DF_WORD, pws->w[3],  pwt->w[3]);
1176 }
1177 
1178 void helper_msa_addv_d(CPUMIPSState *env,
1179                        uint32_t wd, uint32_t ws, uint32_t wt)
1180 {
1181     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1182     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1183     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1184 
1185     pwd->d[0]  = msa_addv_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1186     pwd->d[1]  = msa_addv_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1187 }
1188 
1189 
1190 #define SIGNED_EVEN(a, df) \
1191         ((((int64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2))
1192 
1193 #define UNSIGNED_EVEN(a, df) \
1194         ((((uint64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2))
1195 
1196 #define SIGNED_ODD(a, df) \
1197         ((((int64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
1198 
1199 #define UNSIGNED_ODD(a, df) \
1200         ((((uint64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
1201 
1202 
1203 static inline int64_t msa_hadd_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1204 {
1205     return SIGNED_ODD(arg1, df) + SIGNED_EVEN(arg2, df);
1206 }
1207 
1208 void helper_msa_hadd_s_h(CPUMIPSState *env,
1209                          uint32_t wd, uint32_t ws, uint32_t wt)
1210 {
1211     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1212     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1213     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1214 
1215     pwd->h[0]  = msa_hadd_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1216     pwd->h[1]  = msa_hadd_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1217     pwd->h[2]  = msa_hadd_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1218     pwd->h[3]  = msa_hadd_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1219     pwd->h[4]  = msa_hadd_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1220     pwd->h[5]  = msa_hadd_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1221     pwd->h[6]  = msa_hadd_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1222     pwd->h[7]  = msa_hadd_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1223 }
1224 
1225 void helper_msa_hadd_s_w(CPUMIPSState *env,
1226                          uint32_t wd, uint32_t ws, uint32_t wt)
1227 {
1228     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1229     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1230     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1231 
1232     pwd->w[0]  = msa_hadd_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1233     pwd->w[1]  = msa_hadd_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1234     pwd->w[2]  = msa_hadd_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1235     pwd->w[3]  = msa_hadd_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1236 }
1237 
1238 void helper_msa_hadd_s_d(CPUMIPSState *env,
1239                          uint32_t wd, uint32_t ws, uint32_t wt)
1240 {
1241     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1242     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1243     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1244 
1245     pwd->d[0]  = msa_hadd_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1246     pwd->d[1]  = msa_hadd_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1247 }
1248 
1249 
1250 static inline int64_t msa_hadd_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1251 {
1252     return UNSIGNED_ODD(arg1, df) + UNSIGNED_EVEN(arg2, df);
1253 }
1254 
1255 void helper_msa_hadd_u_h(CPUMIPSState *env,
1256                          uint32_t wd, uint32_t ws, uint32_t wt)
1257 {
1258     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1259     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1260     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1261 
1262     pwd->h[0]  = msa_hadd_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1263     pwd->h[1]  = msa_hadd_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1264     pwd->h[2]  = msa_hadd_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1265     pwd->h[3]  = msa_hadd_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1266     pwd->h[4]  = msa_hadd_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1267     pwd->h[5]  = msa_hadd_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1268     pwd->h[6]  = msa_hadd_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1269     pwd->h[7]  = msa_hadd_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1270 }
1271 
1272 void helper_msa_hadd_u_w(CPUMIPSState *env,
1273                          uint32_t wd, uint32_t ws, uint32_t wt)
1274 {
1275     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1276     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1277     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1278 
1279     pwd->w[0]  = msa_hadd_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1280     pwd->w[1]  = msa_hadd_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1281     pwd->w[2]  = msa_hadd_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1282     pwd->w[3]  = msa_hadd_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1283 }
1284 
1285 void helper_msa_hadd_u_d(CPUMIPSState *env,
1286                          uint32_t wd, uint32_t ws, uint32_t wt)
1287 {
1288     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1289     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1290     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1291 
1292     pwd->d[0]  = msa_hadd_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1293     pwd->d[1]  = msa_hadd_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1294 }
1295 
1296 
1297 /*
1298  * Int Average
1299  * -----------
1300  *
1301  * +---------------+----------------------------------------------------------+
1302  * | AVE_S.B       | Vector Signed Average (byte)                             |
1303  * | AVE_S.H       | Vector Signed Average (halfword)                         |
1304  * | AVE_S.W       | Vector Signed Average (word)                             |
1305  * | AVE_S.D       | Vector Signed Average (doubleword)                       |
1306  * | AVE_U.B       | Vector Unsigned Average (byte)                           |
1307  * | AVE_U.H       | Vector Unsigned Average (halfword)                       |
1308  * | AVE_U.W       | Vector Unsigned Average (word)                           |
1309  * | AVE_U.D       | Vector Unsigned Average (doubleword)                     |
1310  * | AVER_S.B      | Vector Signed Average Rounded (byte)                     |
1311  * | AVER_S.H      | Vector Signed Average Rounded (halfword)                 |
1312  * | AVER_S.W      | Vector Signed Average Rounded (word)                     |
1313  * | AVER_S.D      | Vector Signed Average Rounded (doubleword)               |
1314  * | AVER_U.B      | Vector Unsigned Average Rounded (byte)                   |
1315  * | AVER_U.H      | Vector Unsigned Average Rounded (halfword)               |
1316  * | AVER_U.W      | Vector Unsigned Average Rounded (word)                   |
1317  * | AVER_U.D      | Vector Unsigned Average Rounded (doubleword)             |
1318  * +---------------+----------------------------------------------------------+
1319  */
1320 
1321 static inline int64_t msa_ave_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1322 {
1323     /* signed shift */
1324     return (arg1 >> 1) + (arg2 >> 1) + (arg1 & arg2 & 1);
1325 }
1326 
1327 void helper_msa_ave_s_b(CPUMIPSState *env,
1328                         uint32_t wd, uint32_t ws, uint32_t wt)
1329 {
1330     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1331     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1332     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1333 
1334     pwd->b[0]  = msa_ave_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1335     pwd->b[1]  = msa_ave_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1336     pwd->b[2]  = msa_ave_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1337     pwd->b[3]  = msa_ave_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1338     pwd->b[4]  = msa_ave_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1339     pwd->b[5]  = msa_ave_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1340     pwd->b[6]  = msa_ave_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1341     pwd->b[7]  = msa_ave_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1342     pwd->b[8]  = msa_ave_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1343     pwd->b[9]  = msa_ave_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1344     pwd->b[10] = msa_ave_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
1345     pwd->b[11] = msa_ave_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
1346     pwd->b[12] = msa_ave_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
1347     pwd->b[13] = msa_ave_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
1348     pwd->b[14] = msa_ave_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
1349     pwd->b[15] = msa_ave_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
1350 }
1351 
1352 void helper_msa_ave_s_h(CPUMIPSState *env,
1353                         uint32_t wd, uint32_t ws, uint32_t wt)
1354 {
1355     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1356     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1357     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1358 
1359     pwd->h[0]  = msa_ave_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1360     pwd->h[1]  = msa_ave_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1361     pwd->h[2]  = msa_ave_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1362     pwd->h[3]  = msa_ave_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1363     pwd->h[4]  = msa_ave_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1364     pwd->h[5]  = msa_ave_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1365     pwd->h[6]  = msa_ave_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1366     pwd->h[7]  = msa_ave_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1367 }
1368 
1369 void helper_msa_ave_s_w(CPUMIPSState *env,
1370                         uint32_t wd, uint32_t ws, uint32_t wt)
1371 {
1372     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1373     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1374     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1375 
1376     pwd->w[0]  = msa_ave_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1377     pwd->w[1]  = msa_ave_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1378     pwd->w[2]  = msa_ave_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1379     pwd->w[3]  = msa_ave_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1380 }
1381 
1382 void helper_msa_ave_s_d(CPUMIPSState *env,
1383                         uint32_t wd, uint32_t ws, uint32_t wt)
1384 {
1385     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1386     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1387     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1388 
1389     pwd->d[0]  = msa_ave_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1390     pwd->d[1]  = msa_ave_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1391 }
1392 
1393 static inline uint64_t msa_ave_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1394 {
1395     uint64_t u_arg1 = UNSIGNED(arg1, df);
1396     uint64_t u_arg2 = UNSIGNED(arg2, df);
1397     /* unsigned shift */
1398     return (u_arg1 >> 1) + (u_arg2 >> 1) + (u_arg1 & u_arg2 & 1);
1399 }
1400 
1401 void helper_msa_ave_u_b(CPUMIPSState *env,
1402                         uint32_t wd, uint32_t ws, uint32_t wt)
1403 {
1404     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1405     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1406     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1407 
1408     pwd->b[0]  = msa_ave_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1409     pwd->b[1]  = msa_ave_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1410     pwd->b[2]  = msa_ave_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1411     pwd->b[3]  = msa_ave_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1412     pwd->b[4]  = msa_ave_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1413     pwd->b[5]  = msa_ave_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1414     pwd->b[6]  = msa_ave_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1415     pwd->b[7]  = msa_ave_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1416     pwd->b[8]  = msa_ave_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1417     pwd->b[9]  = msa_ave_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1418     pwd->b[10] = msa_ave_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1419     pwd->b[11] = msa_ave_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1420     pwd->b[12] = msa_ave_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1421     pwd->b[13] = msa_ave_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1422     pwd->b[14] = msa_ave_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1423     pwd->b[15] = msa_ave_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1424 }
1425 
1426 void helper_msa_ave_u_h(CPUMIPSState *env,
1427                         uint32_t wd, uint32_t ws, uint32_t wt)
1428 {
1429     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1430     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1431     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1432 
1433     pwd->h[0]  = msa_ave_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1434     pwd->h[1]  = msa_ave_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1435     pwd->h[2]  = msa_ave_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1436     pwd->h[3]  = msa_ave_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1437     pwd->h[4]  = msa_ave_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1438     pwd->h[5]  = msa_ave_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1439     pwd->h[6]  = msa_ave_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1440     pwd->h[7]  = msa_ave_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1441 }
1442 
1443 void helper_msa_ave_u_w(CPUMIPSState *env,
1444                         uint32_t wd, uint32_t ws, uint32_t wt)
1445 {
1446     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1447     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1448     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1449 
1450     pwd->w[0]  = msa_ave_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1451     pwd->w[1]  = msa_ave_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1452     pwd->w[2]  = msa_ave_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1453     pwd->w[3]  = msa_ave_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1454 }
1455 
1456 void helper_msa_ave_u_d(CPUMIPSState *env,
1457                         uint32_t wd, uint32_t ws, uint32_t wt)
1458 {
1459     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1460     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1461     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1462 
1463     pwd->d[0]  = msa_ave_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1464     pwd->d[1]  = msa_ave_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1465 }
1466 
1467 static inline int64_t msa_aver_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1468 {
1469     /* signed shift */
1470     return (arg1 >> 1) + (arg2 >> 1) + ((arg1 | arg2) & 1);
1471 }
1472 
1473 void helper_msa_aver_s_b(CPUMIPSState *env,
1474                          uint32_t wd, uint32_t ws, uint32_t wt)
1475 {
1476     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1477     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1478     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1479 
1480     pwd->b[0]  = msa_aver_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1481     pwd->b[1]  = msa_aver_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1482     pwd->b[2]  = msa_aver_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1483     pwd->b[3]  = msa_aver_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1484     pwd->b[4]  = msa_aver_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1485     pwd->b[5]  = msa_aver_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1486     pwd->b[6]  = msa_aver_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1487     pwd->b[7]  = msa_aver_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1488     pwd->b[8]  = msa_aver_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1489     pwd->b[9]  = msa_aver_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1490     pwd->b[10] = msa_aver_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
1491     pwd->b[11] = msa_aver_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
1492     pwd->b[12] = msa_aver_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
1493     pwd->b[13] = msa_aver_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
1494     pwd->b[14] = msa_aver_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
1495     pwd->b[15] = msa_aver_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
1496 }
1497 
1498 void helper_msa_aver_s_h(CPUMIPSState *env,
1499                          uint32_t wd, uint32_t ws, uint32_t wt)
1500 {
1501     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1502     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1503     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1504 
1505     pwd->h[0]  = msa_aver_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1506     pwd->h[1]  = msa_aver_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1507     pwd->h[2]  = msa_aver_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1508     pwd->h[3]  = msa_aver_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1509     pwd->h[4]  = msa_aver_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1510     pwd->h[5]  = msa_aver_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1511     pwd->h[6]  = msa_aver_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1512     pwd->h[7]  = msa_aver_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1513 }
1514 
1515 void helper_msa_aver_s_w(CPUMIPSState *env,
1516                          uint32_t wd, uint32_t ws, uint32_t wt)
1517 {
1518     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1519     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1520     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1521 
1522     pwd->w[0]  = msa_aver_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1523     pwd->w[1]  = msa_aver_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1524     pwd->w[2]  = msa_aver_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1525     pwd->w[3]  = msa_aver_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1526 }
1527 
1528 void helper_msa_aver_s_d(CPUMIPSState *env,
1529                          uint32_t wd, uint32_t ws, uint32_t wt)
1530 {
1531     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1532     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1533     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1534 
1535     pwd->d[0]  = msa_aver_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1536     pwd->d[1]  = msa_aver_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1537 }
1538 
1539 static inline uint64_t msa_aver_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1540 {
1541     uint64_t u_arg1 = UNSIGNED(arg1, df);
1542     uint64_t u_arg2 = UNSIGNED(arg2, df);
1543     /* unsigned shift */
1544     return (u_arg1 >> 1) + (u_arg2 >> 1) + ((u_arg1 | u_arg2) & 1);
1545 }
1546 
1547 void helper_msa_aver_u_b(CPUMIPSState *env,
1548                          uint32_t wd, uint32_t ws, uint32_t wt)
1549 {
1550     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1551     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1552     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1553 
1554     pwd->b[0]  = msa_aver_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1555     pwd->b[1]  = msa_aver_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1556     pwd->b[2]  = msa_aver_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1557     pwd->b[3]  = msa_aver_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1558     pwd->b[4]  = msa_aver_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1559     pwd->b[5]  = msa_aver_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1560     pwd->b[6]  = msa_aver_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1561     pwd->b[7]  = msa_aver_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1562     pwd->b[8]  = msa_aver_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1563     pwd->b[9]  = msa_aver_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1564     pwd->b[10] = msa_aver_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1565     pwd->b[11] = msa_aver_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1566     pwd->b[12] = msa_aver_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1567     pwd->b[13] = msa_aver_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1568     pwd->b[14] = msa_aver_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1569     pwd->b[15] = msa_aver_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1570 }
1571 
1572 void helper_msa_aver_u_h(CPUMIPSState *env,
1573                          uint32_t wd, uint32_t ws, uint32_t wt)
1574 {
1575     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1576     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1577     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1578 
1579     pwd->h[0]  = msa_aver_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1580     pwd->h[1]  = msa_aver_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1581     pwd->h[2]  = msa_aver_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1582     pwd->h[3]  = msa_aver_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1583     pwd->h[4]  = msa_aver_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1584     pwd->h[5]  = msa_aver_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1585     pwd->h[6]  = msa_aver_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1586     pwd->h[7]  = msa_aver_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1587 }
1588 
1589 void helper_msa_aver_u_w(CPUMIPSState *env,
1590                          uint32_t wd, uint32_t ws, uint32_t wt)
1591 {
1592     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1593     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1594     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1595 
1596     pwd->w[0]  = msa_aver_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1597     pwd->w[1]  = msa_aver_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1598     pwd->w[2]  = msa_aver_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1599     pwd->w[3]  = msa_aver_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1600 }
1601 
1602 void helper_msa_aver_u_d(CPUMIPSState *env,
1603                          uint32_t wd, uint32_t ws, uint32_t wt)
1604 {
1605     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1606     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1607     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1608 
1609     pwd->d[0]  = msa_aver_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1610     pwd->d[1]  = msa_aver_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1611 }
1612 
1613 
1614 /*
1615  * Int Compare
1616  * -----------
1617  *
1618  * +---------------+----------------------------------------------------------+
1619  * | CEQ.B         | Vector Compare Equal (byte)                              |
1620  * | CEQ.H         | Vector Compare Equal (halfword)                          |
1621  * | CEQ.W         | Vector Compare Equal (word)                              |
1622  * | CEQ.D         | Vector Compare Equal (doubleword)                        |
1623  * | CLE_S.B       | Vector Compare Signed Less Than or Equal (byte)          |
1624  * | CLE_S.H       | Vector Compare Signed Less Than or Equal (halfword)      |
1625  * | CLE_S.W       | Vector Compare Signed Less Than or Equal (word)          |
1626  * | CLE_S.D       | Vector Compare Signed Less Than or Equal (doubleword)    |
1627  * | CLE_U.B       | Vector Compare Unsigned Less Than or Equal (byte)        |
1628  * | CLE_U.H       | Vector Compare Unsigned Less Than or Equal (halfword)    |
1629  * | CLE_U.W       | Vector Compare Unsigned Less Than or Equal (word)        |
1630  * | CLE_U.D       | Vector Compare Unsigned Less Than or Equal (doubleword)  |
1631  * | CLT_S.B       | Vector Compare Signed Less Than (byte)                   |
1632  * | CLT_S.H       | Vector Compare Signed Less Than (halfword)               |
1633  * | CLT_S.W       | Vector Compare Signed Less Than (word)                   |
1634  * | CLT_S.D       | Vector Compare Signed Less Than (doubleword)             |
1635  * | CLT_U.B       | Vector Compare Unsigned Less Than (byte)                 |
1636  * | CLT_U.H       | Vector Compare Unsigned Less Than (halfword)             |
1637  * | CLT_U.W       | Vector Compare Unsigned Less Than (word)                 |
1638  * | CLT_U.D       | Vector Compare Unsigned Less Than (doubleword)           |
1639  * +---------------+----------------------------------------------------------+
1640  */
1641 
1642 static inline int64_t msa_ceq_df(uint32_t df, int64_t arg1, int64_t arg2)
1643 {
1644     return arg1 == arg2 ? -1 : 0;
1645 }
1646 
1647 static inline int8_t msa_ceq_b(int8_t arg1, int8_t arg2)
1648 {
1649     return arg1 == arg2 ? -1 : 0;
1650 }
1651 
1652 void helper_msa_ceq_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1653 {
1654     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1655     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1656     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1657 
1658     pwd->b[0]  = msa_ceq_b(pws->b[0],  pwt->b[0]);
1659     pwd->b[1]  = msa_ceq_b(pws->b[1],  pwt->b[1]);
1660     pwd->b[2]  = msa_ceq_b(pws->b[2],  pwt->b[2]);
1661     pwd->b[3]  = msa_ceq_b(pws->b[3],  pwt->b[3]);
1662     pwd->b[4]  = msa_ceq_b(pws->b[4],  pwt->b[4]);
1663     pwd->b[5]  = msa_ceq_b(pws->b[5],  pwt->b[5]);
1664     pwd->b[6]  = msa_ceq_b(pws->b[6],  pwt->b[6]);
1665     pwd->b[7]  = msa_ceq_b(pws->b[7],  pwt->b[7]);
1666     pwd->b[8]  = msa_ceq_b(pws->b[8],  pwt->b[8]);
1667     pwd->b[9]  = msa_ceq_b(pws->b[9],  pwt->b[9]);
1668     pwd->b[10] = msa_ceq_b(pws->b[10], pwt->b[10]);
1669     pwd->b[11] = msa_ceq_b(pws->b[11], pwt->b[11]);
1670     pwd->b[12] = msa_ceq_b(pws->b[12], pwt->b[12]);
1671     pwd->b[13] = msa_ceq_b(pws->b[13], pwt->b[13]);
1672     pwd->b[14] = msa_ceq_b(pws->b[14], pwt->b[14]);
1673     pwd->b[15] = msa_ceq_b(pws->b[15], pwt->b[15]);
1674 }
1675 
1676 static inline int16_t msa_ceq_h(int16_t arg1, int16_t arg2)
1677 {
1678     return arg1 == arg2 ? -1 : 0;
1679 }
1680 
1681 void helper_msa_ceq_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1682 {
1683     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1684     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1685     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1686 
1687     pwd->h[0]  = msa_ceq_h(pws->h[0],  pwt->h[0]);
1688     pwd->h[1]  = msa_ceq_h(pws->h[1],  pwt->h[1]);
1689     pwd->h[2]  = msa_ceq_h(pws->h[2],  pwt->h[2]);
1690     pwd->h[3]  = msa_ceq_h(pws->h[3],  pwt->h[3]);
1691     pwd->h[4]  = msa_ceq_h(pws->h[4],  pwt->h[4]);
1692     pwd->h[5]  = msa_ceq_h(pws->h[5],  pwt->h[5]);
1693     pwd->h[6]  = msa_ceq_h(pws->h[6],  pwt->h[6]);
1694     pwd->h[7]  = msa_ceq_h(pws->h[7],  pwt->h[7]);
1695 }
1696 
1697 static inline int32_t msa_ceq_w(int32_t arg1, int32_t arg2)
1698 {
1699     return arg1 == arg2 ? -1 : 0;
1700 }
1701 
1702 void helper_msa_ceq_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1703 {
1704     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1705     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1706     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1707 
1708     pwd->w[0]  = msa_ceq_w(pws->w[0],  pwt->w[0]);
1709     pwd->w[1]  = msa_ceq_w(pws->w[1],  pwt->w[1]);
1710     pwd->w[2]  = msa_ceq_w(pws->w[2],  pwt->w[2]);
1711     pwd->w[3]  = msa_ceq_w(pws->w[3],  pwt->w[3]);
1712 }
1713 
1714 static inline int64_t msa_ceq_d(int64_t arg1, int64_t arg2)
1715 {
1716     return arg1 == arg2 ? -1 : 0;
1717 }
1718 
1719 void helper_msa_ceq_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1720 {
1721     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1722     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1723     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1724 
1725     pwd->d[0]  = msa_ceq_d(pws->d[0],  pwt->d[0]);
1726     pwd->d[1]  = msa_ceq_d(pws->d[1],  pwt->d[1]);
1727 }
1728 
1729 static inline int64_t msa_cle_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1730 {
1731     return arg1 <= arg2 ? -1 : 0;
1732 }
1733 
1734 void helper_msa_cle_s_b(CPUMIPSState *env,
1735                         uint32_t wd, uint32_t ws, uint32_t wt)
1736 {
1737     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1738     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1739     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1740 
1741     pwd->b[0]  = msa_cle_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1742     pwd->b[1]  = msa_cle_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1743     pwd->b[2]  = msa_cle_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1744     pwd->b[3]  = msa_cle_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1745     pwd->b[4]  = msa_cle_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1746     pwd->b[5]  = msa_cle_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1747     pwd->b[6]  = msa_cle_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1748     pwd->b[7]  = msa_cle_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1749     pwd->b[8]  = msa_cle_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1750     pwd->b[9]  = msa_cle_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1751     pwd->b[10] = msa_cle_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
1752     pwd->b[11] = msa_cle_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
1753     pwd->b[12] = msa_cle_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
1754     pwd->b[13] = msa_cle_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
1755     pwd->b[14] = msa_cle_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
1756     pwd->b[15] = msa_cle_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
1757 }
1758 
1759 void helper_msa_cle_s_h(CPUMIPSState *env,
1760                         uint32_t wd, uint32_t ws, uint32_t wt)
1761 {
1762     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1763     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1764     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1765 
1766     pwd->h[0]  = msa_cle_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1767     pwd->h[1]  = msa_cle_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1768     pwd->h[2]  = msa_cle_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1769     pwd->h[3]  = msa_cle_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1770     pwd->h[4]  = msa_cle_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1771     pwd->h[5]  = msa_cle_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1772     pwd->h[6]  = msa_cle_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1773     pwd->h[7]  = msa_cle_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1774 }
1775 
1776 void helper_msa_cle_s_w(CPUMIPSState *env,
1777                         uint32_t wd, uint32_t ws, uint32_t wt)
1778 {
1779     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1780     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1781     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1782 
1783     pwd->w[0]  = msa_cle_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1784     pwd->w[1]  = msa_cle_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1785     pwd->w[2]  = msa_cle_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1786     pwd->w[3]  = msa_cle_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1787 }
1788 
1789 void helper_msa_cle_s_d(CPUMIPSState *env,
1790                         uint32_t wd, uint32_t ws, uint32_t wt)
1791 {
1792     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1793     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1794     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1795 
1796     pwd->d[0]  = msa_cle_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1797     pwd->d[1]  = msa_cle_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1798 }
1799 
1800 static inline int64_t msa_cle_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1801 {
1802     uint64_t u_arg1 = UNSIGNED(arg1, df);
1803     uint64_t u_arg2 = UNSIGNED(arg2, df);
1804     return u_arg1 <= u_arg2 ? -1 : 0;
1805 }
1806 
1807 void helper_msa_cle_u_b(CPUMIPSState *env,
1808                         uint32_t wd, uint32_t ws, uint32_t wt)
1809 {
1810     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1811     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1812     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1813 
1814     pwd->b[0]  = msa_cle_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1815     pwd->b[1]  = msa_cle_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1816     pwd->b[2]  = msa_cle_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1817     pwd->b[3]  = msa_cle_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1818     pwd->b[4]  = msa_cle_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1819     pwd->b[5]  = msa_cle_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1820     pwd->b[6]  = msa_cle_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1821     pwd->b[7]  = msa_cle_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1822     pwd->b[8]  = msa_cle_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1823     pwd->b[9]  = msa_cle_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1824     pwd->b[10] = msa_cle_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1825     pwd->b[11] = msa_cle_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1826     pwd->b[12] = msa_cle_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1827     pwd->b[13] = msa_cle_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1828     pwd->b[14] = msa_cle_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1829     pwd->b[15] = msa_cle_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1830 }
1831 
1832 void helper_msa_cle_u_h(CPUMIPSState *env,
1833                         uint32_t wd, uint32_t ws, uint32_t wt)
1834 {
1835     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1836     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1837     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1838 
1839     pwd->h[0]  = msa_cle_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1840     pwd->h[1]  = msa_cle_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1841     pwd->h[2]  = msa_cle_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1842     pwd->h[3]  = msa_cle_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1843     pwd->h[4]  = msa_cle_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1844     pwd->h[5]  = msa_cle_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1845     pwd->h[6]  = msa_cle_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1846     pwd->h[7]  = msa_cle_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1847 }
1848 
1849 void helper_msa_cle_u_w(CPUMIPSState *env,
1850                         uint32_t wd, uint32_t ws, uint32_t wt)
1851 {
1852     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1853     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1854     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1855 
1856     pwd->w[0]  = msa_cle_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1857     pwd->w[1]  = msa_cle_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1858     pwd->w[2]  = msa_cle_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1859     pwd->w[3]  = msa_cle_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1860 }
1861 
1862 void helper_msa_cle_u_d(CPUMIPSState *env,
1863                         uint32_t wd, uint32_t ws, uint32_t wt)
1864 {
1865     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1866     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1867     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1868 
1869     pwd->d[0]  = msa_cle_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1870     pwd->d[1]  = msa_cle_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1871 }
1872 
1873 static inline int64_t msa_clt_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1874 {
1875     return arg1 < arg2 ? -1 : 0;
1876 }
1877 
1878 static inline int8_t msa_clt_s_b(int8_t arg1, int8_t arg2)
1879 {
1880     return arg1 < arg2 ? -1 : 0;
1881 }
1882 
1883 void helper_msa_clt_s_b(CPUMIPSState *env,
1884                         uint32_t wd, uint32_t ws, uint32_t wt)
1885 {
1886     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1887     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1888     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1889 
1890     pwd->b[0]  = msa_clt_s_b(pws->b[0],  pwt->b[0]);
1891     pwd->b[1]  = msa_clt_s_b(pws->b[1],  pwt->b[1]);
1892     pwd->b[2]  = msa_clt_s_b(pws->b[2],  pwt->b[2]);
1893     pwd->b[3]  = msa_clt_s_b(pws->b[3],  pwt->b[3]);
1894     pwd->b[4]  = msa_clt_s_b(pws->b[4],  pwt->b[4]);
1895     pwd->b[5]  = msa_clt_s_b(pws->b[5],  pwt->b[5]);
1896     pwd->b[6]  = msa_clt_s_b(pws->b[6],  pwt->b[6]);
1897     pwd->b[7]  = msa_clt_s_b(pws->b[7],  pwt->b[7]);
1898     pwd->b[8]  = msa_clt_s_b(pws->b[8],  pwt->b[8]);
1899     pwd->b[9]  = msa_clt_s_b(pws->b[9],  pwt->b[9]);
1900     pwd->b[10] = msa_clt_s_b(pws->b[10], pwt->b[10]);
1901     pwd->b[11] = msa_clt_s_b(pws->b[11], pwt->b[11]);
1902     pwd->b[12] = msa_clt_s_b(pws->b[12], pwt->b[12]);
1903     pwd->b[13] = msa_clt_s_b(pws->b[13], pwt->b[13]);
1904     pwd->b[14] = msa_clt_s_b(pws->b[14], pwt->b[14]);
1905     pwd->b[15] = msa_clt_s_b(pws->b[15], pwt->b[15]);
1906 }
1907 
1908 static inline int16_t msa_clt_s_h(int16_t arg1, int16_t arg2)
1909 {
1910     return arg1 < arg2 ? -1 : 0;
1911 }
1912 
1913 void helper_msa_clt_s_h(CPUMIPSState *env,
1914                         uint32_t wd, uint32_t ws, uint32_t wt)
1915 {
1916     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1917     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1918     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1919 
1920     pwd->h[0]  = msa_clt_s_h(pws->h[0],  pwt->h[0]);
1921     pwd->h[1]  = msa_clt_s_h(pws->h[1],  pwt->h[1]);
1922     pwd->h[2]  = msa_clt_s_h(pws->h[2],  pwt->h[2]);
1923     pwd->h[3]  = msa_clt_s_h(pws->h[3],  pwt->h[3]);
1924     pwd->h[4]  = msa_clt_s_h(pws->h[4],  pwt->h[4]);
1925     pwd->h[5]  = msa_clt_s_h(pws->h[5],  pwt->h[5]);
1926     pwd->h[6]  = msa_clt_s_h(pws->h[6],  pwt->h[6]);
1927     pwd->h[7]  = msa_clt_s_h(pws->h[7],  pwt->h[7]);
1928 }
1929 
1930 static inline int32_t msa_clt_s_w(int32_t arg1, int32_t arg2)
1931 {
1932     return arg1 < arg2 ? -1 : 0;
1933 }
1934 
1935 void helper_msa_clt_s_w(CPUMIPSState *env,
1936                         uint32_t wd, uint32_t ws, uint32_t wt)
1937 {
1938     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1939     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1940     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1941 
1942     pwd->w[0]  = msa_clt_s_w(pws->w[0],  pwt->w[0]);
1943     pwd->w[1]  = msa_clt_s_w(pws->w[1],  pwt->w[1]);
1944     pwd->w[2]  = msa_clt_s_w(pws->w[2],  pwt->w[2]);
1945     pwd->w[3]  = msa_clt_s_w(pws->w[3],  pwt->w[3]);
1946 }
1947 
1948 static inline int64_t msa_clt_s_d(int64_t arg1, int64_t arg2)
1949 {
1950     return arg1 < arg2 ? -1 : 0;
1951 }
1952 
1953 void helper_msa_clt_s_d(CPUMIPSState *env,
1954                         uint32_t wd, uint32_t ws, uint32_t wt)
1955 {
1956     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1957     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1958     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1959 
1960     pwd->d[0]  = msa_clt_s_d(pws->d[0],  pwt->d[0]);
1961     pwd->d[1]  = msa_clt_s_d(pws->d[1],  pwt->d[1]);
1962 }
1963 
1964 static inline int64_t msa_clt_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1965 {
1966     uint64_t u_arg1 = UNSIGNED(arg1, df);
1967     uint64_t u_arg2 = UNSIGNED(arg2, df);
1968     return u_arg1 < u_arg2 ? -1 : 0;
1969 }
1970 
1971 void helper_msa_clt_u_b(CPUMIPSState *env,
1972                         uint32_t wd, uint32_t ws, uint32_t wt)
1973 {
1974     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1975     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1976     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1977 
1978     pwd->b[0]  = msa_clt_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1979     pwd->b[1]  = msa_clt_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1980     pwd->b[2]  = msa_clt_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1981     pwd->b[3]  = msa_clt_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1982     pwd->b[4]  = msa_clt_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1983     pwd->b[5]  = msa_clt_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1984     pwd->b[6]  = msa_clt_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1985     pwd->b[7]  = msa_clt_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1986     pwd->b[8]  = msa_clt_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1987     pwd->b[9]  = msa_clt_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1988     pwd->b[10] = msa_clt_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1989     pwd->b[11] = msa_clt_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1990     pwd->b[12] = msa_clt_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1991     pwd->b[13] = msa_clt_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1992     pwd->b[14] = msa_clt_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1993     pwd->b[15] = msa_clt_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1994 }
1995 
1996 void helper_msa_clt_u_h(CPUMIPSState *env,
1997                         uint32_t wd, uint32_t ws, uint32_t wt)
1998 {
1999     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2000     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2001     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2002 
2003     pwd->h[0]  = msa_clt_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
2004     pwd->h[1]  = msa_clt_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
2005     pwd->h[2]  = msa_clt_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
2006     pwd->h[3]  = msa_clt_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
2007     pwd->h[4]  = msa_clt_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
2008     pwd->h[5]  = msa_clt_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
2009     pwd->h[6]  = msa_clt_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
2010     pwd->h[7]  = msa_clt_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
2011 }
2012 
2013 void helper_msa_clt_u_w(CPUMIPSState *env,
2014                         uint32_t wd, uint32_t ws, uint32_t wt)
2015 {
2016     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2017     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2018     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2019 
2020     pwd->w[0]  = msa_clt_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
2021     pwd->w[1]  = msa_clt_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
2022     pwd->w[2]  = msa_clt_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
2023     pwd->w[3]  = msa_clt_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
2024 }
2025 
2026 void helper_msa_clt_u_d(CPUMIPSState *env,
2027                         uint32_t wd, uint32_t ws, uint32_t wt)
2028 {
2029     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2030     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2031     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2032 
2033     pwd->d[0]  = msa_clt_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2034     pwd->d[1]  = msa_clt_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2035 }
2036 
2037 
2038 /*
2039  * Int Divide
2040  * ----------
2041  *
2042  * +---------------+----------------------------------------------------------+
2043  * | DIV_S.B       | Vector Signed Divide (byte)                              |
2044  * | DIV_S.H       | Vector Signed Divide (halfword)                          |
2045  * | DIV_S.W       | Vector Signed Divide (word)                              |
2046  * | DIV_S.D       | Vector Signed Divide (doubleword)                        |
2047  * | DIV_U.B       | Vector Unsigned Divide (byte)                            |
2048  * | DIV_U.H       | Vector Unsigned Divide (halfword)                        |
2049  * | DIV_U.W       | Vector Unsigned Divide (word)                            |
2050  * | DIV_U.D       | Vector Unsigned Divide (doubleword)                      |
2051  * +---------------+----------------------------------------------------------+
2052  */
2053 
2054 
2055 static inline int64_t msa_div_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2056 {
2057     if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
2058         return DF_MIN_INT(df);
2059     }
2060     return arg2 ? arg1 / arg2
2061                 : arg1 >= 0 ? -1 : 1;
2062 }
2063 
2064 void helper_msa_div_s_b(CPUMIPSState *env,
2065                         uint32_t wd, uint32_t ws, uint32_t wt)
2066 {
2067     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2068     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2069     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2070 
2071     pwd->b[0]  = msa_div_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2072     pwd->b[1]  = msa_div_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2073     pwd->b[2]  = msa_div_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2074     pwd->b[3]  = msa_div_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2075     pwd->b[4]  = msa_div_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2076     pwd->b[5]  = msa_div_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2077     pwd->b[6]  = msa_div_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2078     pwd->b[7]  = msa_div_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2079     pwd->b[8]  = msa_div_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2080     pwd->b[9]  = msa_div_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2081     pwd->b[10] = msa_div_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2082     pwd->b[11] = msa_div_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2083     pwd->b[12] = msa_div_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2084     pwd->b[13] = msa_div_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2085     pwd->b[14] = msa_div_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2086     pwd->b[15] = msa_div_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2087 }
2088 
2089 void helper_msa_div_s_h(CPUMIPSState *env,
2090                         uint32_t wd, uint32_t ws, uint32_t wt)
2091 {
2092     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2093     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2094     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2095 
2096     pwd->h[0]  = msa_div_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
2097     pwd->h[1]  = msa_div_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
2098     pwd->h[2]  = msa_div_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
2099     pwd->h[3]  = msa_div_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
2100     pwd->h[4]  = msa_div_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
2101     pwd->h[5]  = msa_div_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
2102     pwd->h[6]  = msa_div_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
2103     pwd->h[7]  = msa_div_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
2104 }
2105 
2106 void helper_msa_div_s_w(CPUMIPSState *env,
2107                         uint32_t wd, uint32_t ws, uint32_t wt)
2108 {
2109     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2110     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2111     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2112 
2113     pwd->w[0]  = msa_div_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
2114     pwd->w[1]  = msa_div_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
2115     pwd->w[2]  = msa_div_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
2116     pwd->w[3]  = msa_div_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
2117 }
2118 
2119 void helper_msa_div_s_d(CPUMIPSState *env,
2120                         uint32_t wd, uint32_t ws, uint32_t wt)
2121 {
2122     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2123     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2124     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2125 
2126     pwd->d[0]  = msa_div_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2127     pwd->d[1]  = msa_div_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2128 }
2129 
2130 static inline int64_t msa_div_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2131 {
2132     uint64_t u_arg1 = UNSIGNED(arg1, df);
2133     uint64_t u_arg2 = UNSIGNED(arg2, df);
2134     return arg2 ? u_arg1 / u_arg2 : -1;
2135 }
2136 
2137 void helper_msa_div_u_b(CPUMIPSState *env,
2138                         uint32_t wd, uint32_t ws, uint32_t wt)
2139 {
2140     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2141     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2142     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2143 
2144     pwd->b[0]  = msa_div_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2145     pwd->b[1]  = msa_div_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2146     pwd->b[2]  = msa_div_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2147     pwd->b[3]  = msa_div_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2148     pwd->b[4]  = msa_div_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2149     pwd->b[5]  = msa_div_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2150     pwd->b[6]  = msa_div_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2151     pwd->b[7]  = msa_div_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2152     pwd->b[8]  = msa_div_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2153     pwd->b[9]  = msa_div_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2154     pwd->b[10] = msa_div_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2155     pwd->b[11] = msa_div_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2156     pwd->b[12] = msa_div_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2157     pwd->b[13] = msa_div_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2158     pwd->b[14] = msa_div_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2159     pwd->b[15] = msa_div_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2160 }
2161 
2162 void helper_msa_div_u_h(CPUMIPSState *env,
2163                         uint32_t wd, uint32_t ws, uint32_t wt)
2164 {
2165     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2166     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2167     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2168 
2169     pwd->h[0]  = msa_div_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
2170     pwd->h[1]  = msa_div_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
2171     pwd->h[2]  = msa_div_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
2172     pwd->h[3]  = msa_div_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
2173     pwd->h[4]  = msa_div_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
2174     pwd->h[5]  = msa_div_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
2175     pwd->h[6]  = msa_div_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
2176     pwd->h[7]  = msa_div_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
2177 }
2178 
2179 void helper_msa_div_u_w(CPUMIPSState *env,
2180                         uint32_t wd, uint32_t ws, uint32_t wt)
2181 {
2182     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2183     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2184     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2185 
2186     pwd->w[0]  = msa_div_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
2187     pwd->w[1]  = msa_div_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
2188     pwd->w[2]  = msa_div_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
2189     pwd->w[3]  = msa_div_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
2190 }
2191 
2192 void helper_msa_div_u_d(CPUMIPSState *env,
2193                         uint32_t wd, uint32_t ws, uint32_t wt)
2194 {
2195     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2196     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2197     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2198 
2199     pwd->d[0]  = msa_div_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2200     pwd->d[1]  = msa_div_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2201 }
2202 
2203 
2204 /*
2205  * Int Dot Product
2206  * ---------------
2207  *
2208  * +---------------+----------------------------------------------------------+
2209  * | DOTP_S.H      | Vector Signed Dot Product (halfword)                     |
2210  * | DOTP_S.W      | Vector Signed Dot Product (word)                         |
2211  * | DOTP_S.D      | Vector Signed Dot Product (doubleword)                   |
2212  * | DOTP_U.H      | Vector Unsigned Dot Product (halfword)                   |
2213  * | DOTP_U.W      | Vector Unsigned Dot Product (word)                       |
2214  * | DOTP_U.D      | Vector Unsigned Dot Product (doubleword)                 |
2215  * | DPADD_S.H     | Vector Signed Dot Product (halfword)                     |
2216  * | DPADD_S.W     | Vector Signed Dot Product (word)                         |
2217  * | DPADD_S.D     | Vector Signed Dot Product (doubleword)                   |
2218  * | DPADD_U.H     | Vector Unsigned Dot Product (halfword)                   |
2219  * | DPADD_U.W     | Vector Unsigned Dot Product (word)                       |
2220  * | DPADD_U.D     | Vector Unsigned Dot Product (doubleword)                 |
2221  * | DPSUB_S.H     | Vector Signed Dot Product (halfword)                     |
2222  * | DPSUB_S.W     | Vector Signed Dot Product (word)                         |
2223  * | DPSUB_S.D     | Vector Signed Dot Product (doubleword)                   |
2224  * | DPSUB_U.H     | Vector Unsigned Dot Product (halfword)                   |
2225  * | DPSUB_U.W     | Vector Unsigned Dot Product (word)                       |
2226  * | DPSUB_U.D     | Vector Unsigned Dot Product (doubleword)                 |
2227  * +---------------+----------------------------------------------------------+
2228  */
2229 
2230 #define SIGNED_EXTRACT(e, o, a, df)     \
2231     do {                                \
2232         e = SIGNED_EVEN(a, df);         \
2233         o = SIGNED_ODD(a, df);          \
2234     } while (0)
2235 
2236 #define UNSIGNED_EXTRACT(e, o, a, df)   \
2237     do {                                \
2238         e = UNSIGNED_EVEN(a, df);       \
2239         o = UNSIGNED_ODD(a, df);        \
2240     } while (0)
2241 
2242 
2243 static inline int64_t msa_dotp_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2244 {
2245     int64_t even_arg1;
2246     int64_t even_arg2;
2247     int64_t odd_arg1;
2248     int64_t odd_arg2;
2249     SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
2250     SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
2251     return (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
2252 }
2253 
2254 void helper_msa_dotp_s_h(CPUMIPSState *env,
2255                          uint32_t wd, uint32_t ws, uint32_t wt)
2256 {
2257     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2258     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2259     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2260 
2261     pwd->h[0]  = msa_dotp_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
2262     pwd->h[1]  = msa_dotp_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
2263     pwd->h[2]  = msa_dotp_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
2264     pwd->h[3]  = msa_dotp_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
2265     pwd->h[4]  = msa_dotp_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
2266     pwd->h[5]  = msa_dotp_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
2267     pwd->h[6]  = msa_dotp_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
2268     pwd->h[7]  = msa_dotp_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
2269 }
2270 
2271 void helper_msa_dotp_s_w(CPUMIPSState *env,
2272                          uint32_t wd, uint32_t ws, uint32_t wt)
2273 {
2274     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2275     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2276     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2277 
2278     pwd->w[0]  = msa_dotp_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
2279     pwd->w[1]  = msa_dotp_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
2280     pwd->w[2]  = msa_dotp_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
2281     pwd->w[3]  = msa_dotp_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
2282 }
2283 
2284 void helper_msa_dotp_s_d(CPUMIPSState *env,
2285                          uint32_t wd, uint32_t ws, uint32_t wt)
2286 {
2287     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2288     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2289     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2290 
2291     pwd->d[0]  = msa_dotp_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2292     pwd->d[1]  = msa_dotp_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2293 }
2294 
2295 
2296 static inline int64_t msa_dotp_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2297 {
2298     int64_t even_arg1;
2299     int64_t even_arg2;
2300     int64_t odd_arg1;
2301     int64_t odd_arg2;
2302     UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
2303     UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
2304     return (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
2305 }
2306 
2307 void helper_msa_dotp_u_h(CPUMIPSState *env,
2308                          uint32_t wd, uint32_t ws, uint32_t wt)
2309 {
2310     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2311     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2312     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2313 
2314     pwd->h[0]  = msa_dotp_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
2315     pwd->h[1]  = msa_dotp_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
2316     pwd->h[2]  = msa_dotp_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
2317     pwd->h[3]  = msa_dotp_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
2318     pwd->h[4]  = msa_dotp_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
2319     pwd->h[5]  = msa_dotp_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
2320     pwd->h[6]  = msa_dotp_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
2321     pwd->h[7]  = msa_dotp_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
2322 }
2323 
2324 void helper_msa_dotp_u_w(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->w[0]  = msa_dotp_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
2332     pwd->w[1]  = msa_dotp_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
2333     pwd->w[2]  = msa_dotp_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
2334     pwd->w[3]  = msa_dotp_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
2335 }
2336 
2337 void helper_msa_dotp_u_d(CPUMIPSState *env,
2338                          uint32_t wd, uint32_t ws, uint32_t wt)
2339 {
2340     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2341     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2342     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2343 
2344     pwd->d[0]  = msa_dotp_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2345     pwd->d[1]  = msa_dotp_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2346 }
2347 
2348 
2349 static inline int64_t msa_dpadd_s_df(uint32_t df, int64_t dest, int64_t arg1,
2350                                      int64_t arg2)
2351 {
2352     int64_t even_arg1;
2353     int64_t even_arg2;
2354     int64_t odd_arg1;
2355     int64_t odd_arg2;
2356     SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
2357     SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
2358     return dest + (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
2359 }
2360 
2361 void helper_msa_dpadd_s_h(CPUMIPSState *env,
2362                           uint32_t wd, uint32_t ws, uint32_t wt)
2363 {
2364     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2365     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2366     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2367 
2368     pwd->h[0]  = msa_dpadd_s_df(DF_HALF, pwd->h[0],  pws->h[0],  pwt->h[0]);
2369     pwd->h[1]  = msa_dpadd_s_df(DF_HALF, pwd->h[1],  pws->h[1],  pwt->h[1]);
2370     pwd->h[2]  = msa_dpadd_s_df(DF_HALF, pwd->h[2],  pws->h[2],  pwt->h[2]);
2371     pwd->h[3]  = msa_dpadd_s_df(DF_HALF, pwd->h[3],  pws->h[3],  pwt->h[3]);
2372     pwd->h[4]  = msa_dpadd_s_df(DF_HALF, pwd->h[4],  pws->h[4],  pwt->h[4]);
2373     pwd->h[5]  = msa_dpadd_s_df(DF_HALF, pwd->h[5],  pws->h[5],  pwt->h[5]);
2374     pwd->h[6]  = msa_dpadd_s_df(DF_HALF, pwd->h[6],  pws->h[6],  pwt->h[6]);
2375     pwd->h[7]  = msa_dpadd_s_df(DF_HALF, pwd->h[7],  pws->h[7],  pwt->h[7]);
2376 }
2377 
2378 void helper_msa_dpadd_s_w(CPUMIPSState *env,
2379                           uint32_t wd, uint32_t ws, uint32_t wt)
2380 {
2381     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2382     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2383     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2384 
2385     pwd->w[0]  = msa_dpadd_s_df(DF_WORD, pwd->w[0],  pws->w[0],  pwt->w[0]);
2386     pwd->w[1]  = msa_dpadd_s_df(DF_WORD, pwd->w[1],  pws->w[1],  pwt->w[1]);
2387     pwd->w[2]  = msa_dpadd_s_df(DF_WORD, pwd->w[2],  pws->w[2],  pwt->w[2]);
2388     pwd->w[3]  = msa_dpadd_s_df(DF_WORD, pwd->w[3],  pws->w[3],  pwt->w[3]);
2389 }
2390 
2391 void helper_msa_dpadd_s_d(CPUMIPSState *env,
2392                           uint32_t wd, uint32_t ws, uint32_t wt)
2393 {
2394     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2395     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2396     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2397 
2398     pwd->d[0]  = msa_dpadd_s_df(DF_DOUBLE, pwd->d[0],  pws->d[0],  pwt->d[0]);
2399     pwd->d[1]  = msa_dpadd_s_df(DF_DOUBLE, pwd->d[1],  pws->d[1],  pwt->d[1]);
2400 }
2401 
2402 
2403 static inline int64_t msa_dpadd_u_df(uint32_t df, int64_t dest, int64_t arg1,
2404                                      int64_t arg2)
2405 {
2406     int64_t even_arg1;
2407     int64_t even_arg2;
2408     int64_t odd_arg1;
2409     int64_t odd_arg2;
2410     UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
2411     UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
2412     return dest + (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
2413 }
2414 
2415 void helper_msa_dpadd_u_h(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->h[0]  = msa_dpadd_u_df(DF_HALF, pwd->h[0],  pws->h[0],  pwt->h[0]);
2423     pwd->h[1]  = msa_dpadd_u_df(DF_HALF, pwd->h[1],  pws->h[1],  pwt->h[1]);
2424     pwd->h[2]  = msa_dpadd_u_df(DF_HALF, pwd->h[2],  pws->h[2],  pwt->h[2]);
2425     pwd->h[3]  = msa_dpadd_u_df(DF_HALF, pwd->h[3],  pws->h[3],  pwt->h[3]);
2426     pwd->h[4]  = msa_dpadd_u_df(DF_HALF, pwd->h[4],  pws->h[4],  pwt->h[4]);
2427     pwd->h[5]  = msa_dpadd_u_df(DF_HALF, pwd->h[5],  pws->h[5],  pwt->h[5]);
2428     pwd->h[6]  = msa_dpadd_u_df(DF_HALF, pwd->h[6],  pws->h[6],  pwt->h[6]);
2429     pwd->h[7]  = msa_dpadd_u_df(DF_HALF, pwd->h[7],  pws->h[7],  pwt->h[7]);
2430 }
2431 
2432 void helper_msa_dpadd_u_w(CPUMIPSState *env,
2433                           uint32_t wd, uint32_t ws, uint32_t wt)
2434 {
2435     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2436     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2437     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2438 
2439     pwd->w[0]  = msa_dpadd_u_df(DF_WORD, pwd->w[0],  pws->w[0],  pwt->w[0]);
2440     pwd->w[1]  = msa_dpadd_u_df(DF_WORD, pwd->w[1],  pws->w[1],  pwt->w[1]);
2441     pwd->w[2]  = msa_dpadd_u_df(DF_WORD, pwd->w[2],  pws->w[2],  pwt->w[2]);
2442     pwd->w[3]  = msa_dpadd_u_df(DF_WORD, pwd->w[3],  pws->w[3],  pwt->w[3]);
2443 }
2444 
2445 void helper_msa_dpadd_u_d(CPUMIPSState *env,
2446                           uint32_t wd, uint32_t ws, uint32_t wt)
2447 {
2448     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2449     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2450     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2451 
2452     pwd->d[0]  = msa_dpadd_u_df(DF_DOUBLE, pwd->d[0],  pws->d[0],  pwt->d[0]);
2453     pwd->d[1]  = msa_dpadd_u_df(DF_DOUBLE, pwd->d[1],  pws->d[1],  pwt->d[1]);
2454 }
2455 
2456 
2457 static inline int64_t msa_dpsub_s_df(uint32_t df, int64_t dest, int64_t arg1,
2458                                      int64_t arg2)
2459 {
2460     int64_t even_arg1;
2461     int64_t even_arg2;
2462     int64_t odd_arg1;
2463     int64_t odd_arg2;
2464     SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
2465     SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
2466     return dest - ((even_arg1 * even_arg2) + (odd_arg1 * odd_arg2));
2467 }
2468 
2469 void helper_msa_dpsub_s_h(CPUMIPSState *env,
2470                           uint32_t wd, uint32_t ws, uint32_t wt)
2471 {
2472     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2473     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2474     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2475 
2476     pwd->h[0]  = msa_dpsub_s_df(DF_HALF, pwd->h[0],  pws->h[0],  pwt->h[0]);
2477     pwd->h[1]  = msa_dpsub_s_df(DF_HALF, pwd->h[1],  pws->h[1],  pwt->h[1]);
2478     pwd->h[2]  = msa_dpsub_s_df(DF_HALF, pwd->h[2],  pws->h[2],  pwt->h[2]);
2479     pwd->h[3]  = msa_dpsub_s_df(DF_HALF, pwd->h[3],  pws->h[3],  pwt->h[3]);
2480     pwd->h[4]  = msa_dpsub_s_df(DF_HALF, pwd->h[4],  pws->h[4],  pwt->h[4]);
2481     pwd->h[5]  = msa_dpsub_s_df(DF_HALF, pwd->h[5],  pws->h[5],  pwt->h[5]);
2482     pwd->h[6]  = msa_dpsub_s_df(DF_HALF, pwd->h[6],  pws->h[6],  pwt->h[6]);
2483     pwd->h[7]  = msa_dpsub_s_df(DF_HALF, pwd->h[7],  pws->h[7],  pwt->h[7]);
2484 }
2485 
2486 void helper_msa_dpsub_s_w(CPUMIPSState *env,
2487                           uint32_t wd, uint32_t ws, uint32_t wt)
2488 {
2489     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2490     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2491     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2492 
2493     pwd->w[0]  = msa_dpsub_s_df(DF_WORD, pwd->w[0],  pws->w[0],  pwt->w[0]);
2494     pwd->w[1]  = msa_dpsub_s_df(DF_WORD, pwd->w[1],  pws->w[1],  pwt->w[1]);
2495     pwd->w[2]  = msa_dpsub_s_df(DF_WORD, pwd->w[2],  pws->w[2],  pwt->w[2]);
2496     pwd->w[3]  = msa_dpsub_s_df(DF_WORD, pwd->w[3],  pws->w[3],  pwt->w[3]);
2497 }
2498 
2499 void helper_msa_dpsub_s_d(CPUMIPSState *env,
2500                           uint32_t wd, uint32_t ws, uint32_t wt)
2501 {
2502     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2503     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2504     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2505 
2506     pwd->d[0]  = msa_dpsub_s_df(DF_DOUBLE, pwd->d[0],  pws->d[0],  pwt->d[0]);
2507     pwd->d[1]  = msa_dpsub_s_df(DF_DOUBLE, pwd->d[1],  pws->d[1],  pwt->d[1]);
2508 }
2509 
2510 
2511 static inline int64_t msa_dpsub_u_df(uint32_t df, int64_t dest, int64_t arg1,
2512                                      int64_t arg2)
2513 {
2514     int64_t even_arg1;
2515     int64_t even_arg2;
2516     int64_t odd_arg1;
2517     int64_t odd_arg2;
2518     UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
2519     UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
2520     return dest - ((even_arg1 * even_arg2) + (odd_arg1 * odd_arg2));
2521 }
2522 
2523 void helper_msa_dpsub_u_h(CPUMIPSState *env,
2524                           uint32_t wd, uint32_t ws, uint32_t wt)
2525 {
2526     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2527     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2528     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2529 
2530     pwd->h[0]  = msa_dpsub_u_df(DF_HALF, pwd->h[0],  pws->h[0],  pwt->h[0]);
2531     pwd->h[1]  = msa_dpsub_u_df(DF_HALF, pwd->h[1],  pws->h[1],  pwt->h[1]);
2532     pwd->h[2]  = msa_dpsub_u_df(DF_HALF, pwd->h[2],  pws->h[2],  pwt->h[2]);
2533     pwd->h[3]  = msa_dpsub_u_df(DF_HALF, pwd->h[3],  pws->h[3],  pwt->h[3]);
2534     pwd->h[4]  = msa_dpsub_u_df(DF_HALF, pwd->h[4],  pws->h[4],  pwt->h[4]);
2535     pwd->h[5]  = msa_dpsub_u_df(DF_HALF, pwd->h[5],  pws->h[5],  pwt->h[5]);
2536     pwd->h[6]  = msa_dpsub_u_df(DF_HALF, pwd->h[6],  pws->h[6],  pwt->h[6]);
2537     pwd->h[7]  = msa_dpsub_u_df(DF_HALF, pwd->h[7],  pws->h[7],  pwt->h[7]);
2538 }
2539 
2540 void helper_msa_dpsub_u_w(CPUMIPSState *env,
2541                           uint32_t wd, uint32_t ws, uint32_t wt)
2542 {
2543     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2544     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2545     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2546 
2547     pwd->w[0]  = msa_dpsub_u_df(DF_WORD, pwd->w[0],  pws->w[0],  pwt->w[0]);
2548     pwd->w[1]  = msa_dpsub_u_df(DF_WORD, pwd->w[1],  pws->w[1],  pwt->w[1]);
2549     pwd->w[2]  = msa_dpsub_u_df(DF_WORD, pwd->w[2],  pws->w[2],  pwt->w[2]);
2550     pwd->w[3]  = msa_dpsub_u_df(DF_WORD, pwd->w[3],  pws->w[3],  pwt->w[3]);
2551 }
2552 
2553 void helper_msa_dpsub_u_d(CPUMIPSState *env,
2554                           uint32_t wd, uint32_t ws, uint32_t wt)
2555 {
2556     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2557     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2558     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2559 
2560     pwd->d[0]  = msa_dpsub_u_df(DF_DOUBLE, pwd->d[0],  pws->d[0],  pwt->d[0]);
2561     pwd->d[1]  = msa_dpsub_u_df(DF_DOUBLE, pwd->d[1],  pws->d[1],  pwt->d[1]);
2562 }
2563 
2564 
2565 /*
2566  * Int Max Min
2567  * -----------
2568  *
2569  * +---------------+----------------------------------------------------------+
2570  * | MAX_A.B       | Vector Maximum Based on Absolute Value (byte)            |
2571  * | MAX_A.H       | Vector Maximum Based on Absolute Value (halfword)        |
2572  * | MAX_A.W       | Vector Maximum Based on Absolute Value (word)            |
2573  * | MAX_A.D       | Vector Maximum Based on Absolute Value (doubleword)      |
2574  * | MAX_S.B       | Vector Signed Maximum (byte)                             |
2575  * | MAX_S.H       | Vector Signed Maximum (halfword)                         |
2576  * | MAX_S.W       | Vector Signed Maximum (word)                             |
2577  * | MAX_S.D       | Vector Signed Maximum (doubleword)                       |
2578  * | MAX_U.B       | Vector Unsigned Maximum (byte)                           |
2579  * | MAX_U.H       | Vector Unsigned Maximum (halfword)                       |
2580  * | MAX_U.W       | Vector Unsigned Maximum (word)                           |
2581  * | MAX_U.D       | Vector Unsigned Maximum (doubleword)                     |
2582  * | MIN_A.B       | Vector Minimum Based on Absolute Value (byte)            |
2583  * | MIN_A.H       | Vector Minimum Based on Absolute Value (halfword)        |
2584  * | MIN_A.W       | Vector Minimum Based on Absolute Value (word)            |
2585  * | MIN_A.D       | Vector Minimum Based on Absolute Value (doubleword)      |
2586  * | MIN_S.B       | Vector Signed Minimum (byte)                             |
2587  * | MIN_S.H       | Vector Signed Minimum (halfword)                         |
2588  * | MIN_S.W       | Vector Signed Minimum (word)                             |
2589  * | MIN_S.D       | Vector Signed Minimum (doubleword)                       |
2590  * | MIN_U.B       | Vector Unsigned Minimum (byte)                           |
2591  * | MIN_U.H       | Vector Unsigned Minimum (halfword)                       |
2592  * | MIN_U.W       | Vector Unsigned Minimum (word)                           |
2593  * | MIN_U.D       | Vector Unsigned Minimum (doubleword)                     |
2594  * +---------------+----------------------------------------------------------+
2595  */
2596 
2597 static inline int64_t msa_max_a_df(uint32_t df, int64_t arg1, int64_t arg2)
2598 {
2599     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
2600     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
2601     return abs_arg1 > abs_arg2 ? arg1 : arg2;
2602 }
2603 
2604 void helper_msa_max_a_b(CPUMIPSState *env,
2605                         uint32_t wd, uint32_t ws, uint32_t wt)
2606 {
2607     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2608     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2609     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2610 
2611     pwd->b[0]  = msa_max_a_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2612     pwd->b[1]  = msa_max_a_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2613     pwd->b[2]  = msa_max_a_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2614     pwd->b[3]  = msa_max_a_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2615     pwd->b[4]  = msa_max_a_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2616     pwd->b[5]  = msa_max_a_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2617     pwd->b[6]  = msa_max_a_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2618     pwd->b[7]  = msa_max_a_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2619     pwd->b[8]  = msa_max_a_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2620     pwd->b[9]  = msa_max_a_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2621     pwd->b[10] = msa_max_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
2622     pwd->b[11] = msa_max_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
2623     pwd->b[12] = msa_max_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
2624     pwd->b[13] = msa_max_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
2625     pwd->b[14] = msa_max_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
2626     pwd->b[15] = msa_max_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
2627 }
2628 
2629 void helper_msa_max_a_h(CPUMIPSState *env,
2630                         uint32_t wd, uint32_t ws, uint32_t wt)
2631 {
2632     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2633     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2634     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2635 
2636     pwd->h[0]  = msa_max_a_df(DF_HALF, pws->h[0],  pwt->h[0]);
2637     pwd->h[1]  = msa_max_a_df(DF_HALF, pws->h[1],  pwt->h[1]);
2638     pwd->h[2]  = msa_max_a_df(DF_HALF, pws->h[2],  pwt->h[2]);
2639     pwd->h[3]  = msa_max_a_df(DF_HALF, pws->h[3],  pwt->h[3]);
2640     pwd->h[4]  = msa_max_a_df(DF_HALF, pws->h[4],  pwt->h[4]);
2641     pwd->h[5]  = msa_max_a_df(DF_HALF, pws->h[5],  pwt->h[5]);
2642     pwd->h[6]  = msa_max_a_df(DF_HALF, pws->h[6],  pwt->h[6]);
2643     pwd->h[7]  = msa_max_a_df(DF_HALF, pws->h[7],  pwt->h[7]);
2644 }
2645 
2646 void helper_msa_max_a_w(CPUMIPSState *env,
2647                         uint32_t wd, uint32_t ws, uint32_t wt)
2648 {
2649     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2650     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2651     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2652 
2653     pwd->w[0]  = msa_max_a_df(DF_WORD, pws->w[0],  pwt->w[0]);
2654     pwd->w[1]  = msa_max_a_df(DF_WORD, pws->w[1],  pwt->w[1]);
2655     pwd->w[2]  = msa_max_a_df(DF_WORD, pws->w[2],  pwt->w[2]);
2656     pwd->w[3]  = msa_max_a_df(DF_WORD, pws->w[3],  pwt->w[3]);
2657 }
2658 
2659 void helper_msa_max_a_d(CPUMIPSState *env,
2660                         uint32_t wd, uint32_t ws, uint32_t wt)
2661 {
2662     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2663     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2664     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2665 
2666     pwd->d[0]  = msa_max_a_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2667     pwd->d[1]  = msa_max_a_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2668 }
2669 
2670 
2671 static inline int64_t msa_max_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2672 {
2673     return arg1 > arg2 ? arg1 : arg2;
2674 }
2675 
2676 void helper_msa_max_s_b(CPUMIPSState *env,
2677                         uint32_t wd, uint32_t ws, uint32_t wt)
2678 {
2679     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2680     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2681     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2682 
2683     pwd->b[0]  = msa_max_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2684     pwd->b[1]  = msa_max_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2685     pwd->b[2]  = msa_max_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2686     pwd->b[3]  = msa_max_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2687     pwd->b[4]  = msa_max_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2688     pwd->b[5]  = msa_max_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2689     pwd->b[6]  = msa_max_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2690     pwd->b[7]  = msa_max_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2691     pwd->b[8]  = msa_max_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2692     pwd->b[9]  = msa_max_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2693     pwd->b[10] = msa_max_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2694     pwd->b[11] = msa_max_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2695     pwd->b[12] = msa_max_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2696     pwd->b[13] = msa_max_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2697     pwd->b[14] = msa_max_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2698     pwd->b[15] = msa_max_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2699 }
2700 
2701 void helper_msa_max_s_h(CPUMIPSState *env,
2702                         uint32_t wd, uint32_t ws, uint32_t wt)
2703 {
2704     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2705     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2706     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2707 
2708     pwd->h[0]  = msa_max_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
2709     pwd->h[1]  = msa_max_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
2710     pwd->h[2]  = msa_max_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
2711     pwd->h[3]  = msa_max_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
2712     pwd->h[4]  = msa_max_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
2713     pwd->h[5]  = msa_max_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
2714     pwd->h[6]  = msa_max_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
2715     pwd->h[7]  = msa_max_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
2716 }
2717 
2718 void helper_msa_max_s_w(CPUMIPSState *env,
2719                         uint32_t wd, uint32_t ws, uint32_t wt)
2720 {
2721     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2722     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2723     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2724 
2725     pwd->w[0]  = msa_max_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
2726     pwd->w[1]  = msa_max_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
2727     pwd->w[2]  = msa_max_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
2728     pwd->w[3]  = msa_max_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
2729 }
2730 
2731 void helper_msa_max_s_d(CPUMIPSState *env,
2732                         uint32_t wd, uint32_t ws, uint32_t wt)
2733 {
2734     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2735     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2736     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2737 
2738     pwd->d[0]  = msa_max_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2739     pwd->d[1]  = msa_max_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2740 }
2741 
2742 
2743 static inline int64_t msa_max_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2744 {
2745     uint64_t u_arg1 = UNSIGNED(arg1, df);
2746     uint64_t u_arg2 = UNSIGNED(arg2, df);
2747     return u_arg1 > u_arg2 ? arg1 : arg2;
2748 }
2749 
2750 void helper_msa_max_u_b(CPUMIPSState *env,
2751                         uint32_t wd, uint32_t ws, uint32_t wt)
2752 {
2753     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2754     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2755     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2756 
2757     pwd->b[0]  = msa_max_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2758     pwd->b[1]  = msa_max_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2759     pwd->b[2]  = msa_max_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2760     pwd->b[3]  = msa_max_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2761     pwd->b[4]  = msa_max_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2762     pwd->b[5]  = msa_max_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2763     pwd->b[6]  = msa_max_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2764     pwd->b[7]  = msa_max_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2765     pwd->b[8]  = msa_max_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2766     pwd->b[9]  = msa_max_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2767     pwd->b[10] = msa_max_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2768     pwd->b[11] = msa_max_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2769     pwd->b[12] = msa_max_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2770     pwd->b[13] = msa_max_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2771     pwd->b[14] = msa_max_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2772     pwd->b[15] = msa_max_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2773 }
2774 
2775 void helper_msa_max_u_h(CPUMIPSState *env,
2776                         uint32_t wd, uint32_t ws, uint32_t wt)
2777 {
2778     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2779     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2780     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2781 
2782     pwd->h[0]  = msa_max_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
2783     pwd->h[1]  = msa_max_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
2784     pwd->h[2]  = msa_max_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
2785     pwd->h[3]  = msa_max_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
2786     pwd->h[4]  = msa_max_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
2787     pwd->h[5]  = msa_max_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
2788     pwd->h[6]  = msa_max_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
2789     pwd->h[7]  = msa_max_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
2790 }
2791 
2792 void helper_msa_max_u_w(CPUMIPSState *env,
2793                         uint32_t wd, uint32_t ws, uint32_t wt)
2794 {
2795     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2796     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2797     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2798 
2799     pwd->w[0]  = msa_max_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
2800     pwd->w[1]  = msa_max_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
2801     pwd->w[2]  = msa_max_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
2802     pwd->w[3]  = msa_max_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
2803 }
2804 
2805 void helper_msa_max_u_d(CPUMIPSState *env,
2806                         uint32_t wd, uint32_t ws, uint32_t wt)
2807 {
2808     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2809     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2810     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2811 
2812     pwd->d[0]  = msa_max_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2813     pwd->d[1]  = msa_max_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2814 }
2815 
2816 
2817 static inline int64_t msa_min_a_df(uint32_t df, int64_t arg1, int64_t arg2)
2818 {
2819     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
2820     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
2821     return abs_arg1 < abs_arg2 ? arg1 : arg2;
2822 }
2823 
2824 void helper_msa_min_a_b(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->b[0]  = msa_min_a_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2832     pwd->b[1]  = msa_min_a_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2833     pwd->b[2]  = msa_min_a_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2834     pwd->b[3]  = msa_min_a_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2835     pwd->b[4]  = msa_min_a_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2836     pwd->b[5]  = msa_min_a_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2837     pwd->b[6]  = msa_min_a_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2838     pwd->b[7]  = msa_min_a_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2839     pwd->b[8]  = msa_min_a_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2840     pwd->b[9]  = msa_min_a_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2841     pwd->b[10] = msa_min_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
2842     pwd->b[11] = msa_min_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
2843     pwd->b[12] = msa_min_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
2844     pwd->b[13] = msa_min_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
2845     pwd->b[14] = msa_min_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
2846     pwd->b[15] = msa_min_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
2847 }
2848 
2849 void helper_msa_min_a_h(CPUMIPSState *env,
2850                         uint32_t wd, uint32_t ws, uint32_t wt)
2851 {
2852     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2853     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2854     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2855 
2856     pwd->h[0]  = msa_min_a_df(DF_HALF, pws->h[0],  pwt->h[0]);
2857     pwd->h[1]  = msa_min_a_df(DF_HALF, pws->h[1],  pwt->h[1]);
2858     pwd->h[2]  = msa_min_a_df(DF_HALF, pws->h[2],  pwt->h[2]);
2859     pwd->h[3]  = msa_min_a_df(DF_HALF, pws->h[3],  pwt->h[3]);
2860     pwd->h[4]  = msa_min_a_df(DF_HALF, pws->h[4],  pwt->h[4]);
2861     pwd->h[5]  = msa_min_a_df(DF_HALF, pws->h[5],  pwt->h[5]);
2862     pwd->h[6]  = msa_min_a_df(DF_HALF, pws->h[6],  pwt->h[6]);
2863     pwd->h[7]  = msa_min_a_df(DF_HALF, pws->h[7],  pwt->h[7]);
2864 }
2865 
2866 void helper_msa_min_a_w(CPUMIPSState *env,
2867                         uint32_t wd, uint32_t ws, uint32_t wt)
2868 {
2869     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2870     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2871     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2872 
2873     pwd->w[0]  = msa_min_a_df(DF_WORD, pws->w[0],  pwt->w[0]);
2874     pwd->w[1]  = msa_min_a_df(DF_WORD, pws->w[1],  pwt->w[1]);
2875     pwd->w[2]  = msa_min_a_df(DF_WORD, pws->w[2],  pwt->w[2]);
2876     pwd->w[3]  = msa_min_a_df(DF_WORD, pws->w[3],  pwt->w[3]);
2877 }
2878 
2879 void helper_msa_min_a_d(CPUMIPSState *env,
2880                         uint32_t wd, uint32_t ws, uint32_t wt)
2881 {
2882     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2883     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2884     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2885 
2886     pwd->d[0]  = msa_min_a_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2887     pwd->d[1]  = msa_min_a_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2888 }
2889 
2890 
2891 static inline int64_t msa_min_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2892 {
2893     return arg1 < arg2 ? arg1 : arg2;
2894 }
2895 
2896 void helper_msa_min_s_b(CPUMIPSState *env,
2897                         uint32_t wd, uint32_t ws, uint32_t wt)
2898 {
2899     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2900     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2901     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2902 
2903     pwd->b[0]  = msa_min_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2904     pwd->b[1]  = msa_min_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2905     pwd->b[2]  = msa_min_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2906     pwd->b[3]  = msa_min_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2907     pwd->b[4]  = msa_min_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2908     pwd->b[5]  = msa_min_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2909     pwd->b[6]  = msa_min_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2910     pwd->b[7]  = msa_min_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2911     pwd->b[8]  = msa_min_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2912     pwd->b[9]  = msa_min_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2913     pwd->b[10] = msa_min_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2914     pwd->b[11] = msa_min_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2915     pwd->b[12] = msa_min_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2916     pwd->b[13] = msa_min_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2917     pwd->b[14] = msa_min_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2918     pwd->b[15] = msa_min_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2919 }
2920 
2921 void helper_msa_min_s_h(CPUMIPSState *env,
2922                         uint32_t wd, uint32_t ws, uint32_t wt)
2923 {
2924     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2925     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2926     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2927 
2928     pwd->h[0]  = msa_min_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
2929     pwd->h[1]  = msa_min_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
2930     pwd->h[2]  = msa_min_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
2931     pwd->h[3]  = msa_min_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
2932     pwd->h[4]  = msa_min_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
2933     pwd->h[5]  = msa_min_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
2934     pwd->h[6]  = msa_min_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
2935     pwd->h[7]  = msa_min_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
2936 }
2937 
2938 void helper_msa_min_s_w(CPUMIPSState *env,
2939                         uint32_t wd, uint32_t ws, uint32_t wt)
2940 {
2941     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2942     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2943     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2944 
2945     pwd->w[0]  = msa_min_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
2946     pwd->w[1]  = msa_min_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
2947     pwd->w[2]  = msa_min_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
2948     pwd->w[3]  = msa_min_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
2949 }
2950 
2951 void helper_msa_min_s_d(CPUMIPSState *env,
2952                         uint32_t wd, uint32_t ws, uint32_t wt)
2953 {
2954     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2955     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2956     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2957 
2958     pwd->d[0]  = msa_min_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2959     pwd->d[1]  = msa_min_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2960 }
2961 
2962 
2963 static inline int64_t msa_min_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2964 {
2965     uint64_t u_arg1 = UNSIGNED(arg1, df);
2966     uint64_t u_arg2 = UNSIGNED(arg2, df);
2967     return u_arg1 < u_arg2 ? arg1 : arg2;
2968 }
2969 
2970 void helper_msa_min_u_b(CPUMIPSState *env,
2971                         uint32_t wd, uint32_t ws, uint32_t wt)
2972 {
2973     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2974     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2975     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2976 
2977     pwd->b[0]  = msa_min_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2978     pwd->b[1]  = msa_min_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2979     pwd->b[2]  = msa_min_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2980     pwd->b[3]  = msa_min_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2981     pwd->b[4]  = msa_min_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2982     pwd->b[5]  = msa_min_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2983     pwd->b[6]  = msa_min_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2984     pwd->b[7]  = msa_min_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2985     pwd->b[8]  = msa_min_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2986     pwd->b[9]  = msa_min_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2987     pwd->b[10] = msa_min_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2988     pwd->b[11] = msa_min_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2989     pwd->b[12] = msa_min_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2990     pwd->b[13] = msa_min_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2991     pwd->b[14] = msa_min_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2992     pwd->b[15] = msa_min_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2993 }
2994 
2995 void helper_msa_min_u_h(CPUMIPSState *env,
2996                         uint32_t wd, uint32_t ws, uint32_t wt)
2997 {
2998     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2999     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3000     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3001 
3002     pwd->h[0]  = msa_min_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
3003     pwd->h[1]  = msa_min_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
3004     pwd->h[2]  = msa_min_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
3005     pwd->h[3]  = msa_min_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
3006     pwd->h[4]  = msa_min_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
3007     pwd->h[5]  = msa_min_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
3008     pwd->h[6]  = msa_min_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
3009     pwd->h[7]  = msa_min_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
3010 }
3011 
3012 void helper_msa_min_u_w(CPUMIPSState *env,
3013                         uint32_t wd, uint32_t ws, uint32_t wt)
3014 {
3015     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3016     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3017     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3018 
3019     pwd->w[0]  = msa_min_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
3020     pwd->w[1]  = msa_min_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
3021     pwd->w[2]  = msa_min_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
3022     pwd->w[3]  = msa_min_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
3023 }
3024 
3025 void helper_msa_min_u_d(CPUMIPSState *env,
3026                         uint32_t wd, uint32_t ws, uint32_t wt)
3027 {
3028     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3029     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3030     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3031 
3032     pwd->d[0]  = msa_min_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3033     pwd->d[1]  = msa_min_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3034 }
3035 
3036 
3037 /*
3038  * Int Modulo
3039  * ----------
3040  *
3041  * +---------------+----------------------------------------------------------+
3042  * | MOD_S.B       | Vector Signed Modulo (byte)                              |
3043  * | MOD_S.H       | Vector Signed Modulo (halfword)                          |
3044  * | MOD_S.W       | Vector Signed Modulo (word)                              |
3045  * | MOD_S.D       | Vector Signed Modulo (doubleword)                        |
3046  * | MOD_U.B       | Vector Unsigned Modulo (byte)                            |
3047  * | MOD_U.H       | Vector Unsigned Modulo (halfword)                        |
3048  * | MOD_U.W       | Vector Unsigned Modulo (word)                            |
3049  * | MOD_U.D       | Vector Unsigned Modulo (doubleword)                      |
3050  * +---------------+----------------------------------------------------------+
3051  */
3052 
3053 static inline int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2)
3054 {
3055     if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
3056         return 0;
3057     }
3058     return arg2 ? arg1 % arg2 : arg1;
3059 }
3060 
3061 void helper_msa_mod_s_b(CPUMIPSState *env,
3062                         uint32_t wd, uint32_t ws, uint32_t wt)
3063 {
3064     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3065     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3066     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3067 
3068     pwd->b[0]  = msa_mod_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
3069     pwd->b[1]  = msa_mod_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
3070     pwd->b[2]  = msa_mod_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
3071     pwd->b[3]  = msa_mod_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
3072     pwd->b[4]  = msa_mod_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
3073     pwd->b[5]  = msa_mod_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
3074     pwd->b[6]  = msa_mod_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
3075     pwd->b[7]  = msa_mod_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
3076     pwd->b[8]  = msa_mod_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
3077     pwd->b[9]  = msa_mod_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
3078     pwd->b[10] = msa_mod_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
3079     pwd->b[11] = msa_mod_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
3080     pwd->b[12] = msa_mod_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
3081     pwd->b[13] = msa_mod_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
3082     pwd->b[14] = msa_mod_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
3083     pwd->b[15] = msa_mod_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
3084 }
3085 
3086 void helper_msa_mod_s_h(CPUMIPSState *env,
3087                         uint32_t wd, uint32_t ws, uint32_t wt)
3088 {
3089     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3090     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3091     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3092 
3093     pwd->h[0]  = msa_mod_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
3094     pwd->h[1]  = msa_mod_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
3095     pwd->h[2]  = msa_mod_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
3096     pwd->h[3]  = msa_mod_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
3097     pwd->h[4]  = msa_mod_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
3098     pwd->h[5]  = msa_mod_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
3099     pwd->h[6]  = msa_mod_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
3100     pwd->h[7]  = msa_mod_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
3101 }
3102 
3103 void helper_msa_mod_s_w(CPUMIPSState *env,
3104                         uint32_t wd, uint32_t ws, uint32_t wt)
3105 {
3106     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3107     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3108     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3109 
3110     pwd->w[0]  = msa_mod_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
3111     pwd->w[1]  = msa_mod_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
3112     pwd->w[2]  = msa_mod_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
3113     pwd->w[3]  = msa_mod_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
3114 }
3115 
3116 void helper_msa_mod_s_d(CPUMIPSState *env,
3117                         uint32_t wd, uint32_t ws, uint32_t wt)
3118 {
3119     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3120     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3121     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3122 
3123     pwd->d[0]  = msa_mod_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3124     pwd->d[1]  = msa_mod_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3125 }
3126 
3127 static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2)
3128 {
3129     uint64_t u_arg1 = UNSIGNED(arg1, df);
3130     uint64_t u_arg2 = UNSIGNED(arg2, df);
3131     return u_arg2 ? u_arg1 % u_arg2 : u_arg1;
3132 }
3133 
3134 void helper_msa_mod_u_b(CPUMIPSState *env,
3135                         uint32_t wd, uint32_t ws, uint32_t wt)
3136 {
3137     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3138     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3139     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3140 
3141     pwd->b[0]  = msa_mod_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
3142     pwd->b[1]  = msa_mod_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
3143     pwd->b[2]  = msa_mod_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
3144     pwd->b[3]  = msa_mod_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
3145     pwd->b[4]  = msa_mod_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
3146     pwd->b[5]  = msa_mod_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
3147     pwd->b[6]  = msa_mod_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
3148     pwd->b[7]  = msa_mod_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
3149     pwd->b[8]  = msa_mod_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
3150     pwd->b[9]  = msa_mod_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
3151     pwd->b[10] = msa_mod_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
3152     pwd->b[11] = msa_mod_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
3153     pwd->b[12] = msa_mod_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
3154     pwd->b[13] = msa_mod_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
3155     pwd->b[14] = msa_mod_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
3156     pwd->b[15] = msa_mod_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
3157 }
3158 
3159 void helper_msa_mod_u_h(CPUMIPSState *env,
3160                         uint32_t wd, uint32_t ws, uint32_t wt)
3161 {
3162     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3163     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3164     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3165 
3166     pwd->h[0]  = msa_mod_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
3167     pwd->h[1]  = msa_mod_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
3168     pwd->h[2]  = msa_mod_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
3169     pwd->h[3]  = msa_mod_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
3170     pwd->h[4]  = msa_mod_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
3171     pwd->h[5]  = msa_mod_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
3172     pwd->h[6]  = msa_mod_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
3173     pwd->h[7]  = msa_mod_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
3174 }
3175 
3176 void helper_msa_mod_u_w(CPUMIPSState *env,
3177                         uint32_t wd, uint32_t ws, uint32_t wt)
3178 {
3179     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3180     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3181     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3182 
3183     pwd->w[0]  = msa_mod_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
3184     pwd->w[1]  = msa_mod_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
3185     pwd->w[2]  = msa_mod_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
3186     pwd->w[3]  = msa_mod_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
3187 }
3188 
3189 void helper_msa_mod_u_d(CPUMIPSState *env,
3190                         uint32_t wd, uint32_t ws, uint32_t wt)
3191 {
3192     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3193     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3194     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3195 
3196     pwd->d[0]  = msa_mod_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3197     pwd->d[1]  = msa_mod_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3198 }
3199 
3200 
3201 /*
3202  * Int Multiply
3203  * ------------
3204  *
3205  * +---------------+----------------------------------------------------------+
3206  * | MADDV.B       | Vector Multiply and Add (byte)                           |
3207  * | MADDV.H       | Vector Multiply and Add (halfword)                       |
3208  * | MADDV.W       | Vector Multiply and Add (word)                           |
3209  * | MADDV.D       | Vector Multiply and Add (doubleword)                     |
3210  * | MSUBV.B       | Vector Multiply and Subtract (byte)                      |
3211  * | MSUBV.H       | Vector Multiply and Subtract (halfword)                  |
3212  * | MSUBV.W       | Vector Multiply and Subtract (word)                      |
3213  * | MSUBV.D       | Vector Multiply and Subtract (doubleword)                |
3214  * | MULV.B        | Vector Multiply (byte)                                   |
3215  * | MULV.H        | Vector Multiply (halfword)                               |
3216  * | MULV.W        | Vector Multiply (word)                                   |
3217  * | MULV.D        | Vector Multiply (doubleword)                             |
3218  * +---------------+----------------------------------------------------------+
3219  */
3220 
3221 static inline int64_t msa_maddv_df(uint32_t df, int64_t dest, int64_t arg1,
3222                                    int64_t arg2)
3223 {
3224     return dest + arg1 * arg2;
3225 }
3226 
3227 void helper_msa_maddv_b(CPUMIPSState *env,
3228                         uint32_t wd, uint32_t ws, uint32_t wt)
3229 {
3230     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3231     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3232     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3233 
3234     pwd->b[0]  = msa_maddv_df(DF_BYTE, pwt->b[0],  pws->b[0],  pwt->b[0]);
3235     pwd->b[1]  = msa_maddv_df(DF_BYTE, pwt->b[1],  pws->b[1],  pwt->b[1]);
3236     pwd->b[2]  = msa_maddv_df(DF_BYTE, pwt->b[2],  pws->b[2],  pwt->b[2]);
3237     pwd->b[3]  = msa_maddv_df(DF_BYTE, pwt->b[3],  pws->b[3],  pwt->b[3]);
3238     pwd->b[4]  = msa_maddv_df(DF_BYTE, pwt->b[4],  pws->b[4],  pwt->b[4]);
3239     pwd->b[5]  = msa_maddv_df(DF_BYTE, pwt->b[5],  pws->b[5],  pwt->b[5]);
3240     pwd->b[6]  = msa_maddv_df(DF_BYTE, pwt->b[6],  pws->b[6],  pwt->b[6]);
3241     pwd->b[7]  = msa_maddv_df(DF_BYTE, pwt->b[7],  pws->b[7],  pwt->b[7]);
3242     pwd->b[8]  = msa_maddv_df(DF_BYTE, pwt->b[8],  pws->b[8],  pwt->b[8]);
3243     pwd->b[9]  = msa_maddv_df(DF_BYTE, pwt->b[9],  pws->b[9],  pwt->b[9]);
3244     pwd->b[10] = msa_maddv_df(DF_BYTE, pwt->b[10], pws->b[10], pwt->b[10]);
3245     pwd->b[11] = msa_maddv_df(DF_BYTE, pwt->b[11], pws->b[11], pwt->b[11]);
3246     pwd->b[12] = msa_maddv_df(DF_BYTE, pwt->b[12], pws->b[12], pwt->b[12]);
3247     pwd->b[13] = msa_maddv_df(DF_BYTE, pwt->b[13], pws->b[13], pwt->b[13]);
3248     pwd->b[14] = msa_maddv_df(DF_BYTE, pwt->b[14], pws->b[14], pwt->b[14]);
3249     pwd->b[15] = msa_maddv_df(DF_BYTE, pwt->b[15], pws->b[15], pwt->b[15]);
3250 }
3251 
3252 void helper_msa_maddv_h(CPUMIPSState *env,
3253                         uint32_t wd, uint32_t ws, uint32_t wt)
3254 {
3255     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3256     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3257     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3258 
3259     pwd->h[0]  = msa_maddv_df(DF_HALF, pwd->h[0],  pws->h[0],  pwt->h[0]);
3260     pwd->h[1]  = msa_maddv_df(DF_HALF, pwd->h[1],  pws->h[1],  pwt->h[1]);
3261     pwd->h[2]  = msa_maddv_df(DF_HALF, pwd->h[2],  pws->h[2],  pwt->h[2]);
3262     pwd->h[3]  = msa_maddv_df(DF_HALF, pwd->h[3],  pws->h[3],  pwt->h[3]);
3263     pwd->h[4]  = msa_maddv_df(DF_HALF, pwd->h[4],  pws->h[4],  pwt->h[4]);
3264     pwd->h[5]  = msa_maddv_df(DF_HALF, pwd->h[5],  pws->h[5],  pwt->h[5]);
3265     pwd->h[6]  = msa_maddv_df(DF_HALF, pwd->h[6],  pws->h[6],  pwt->h[6]);
3266     pwd->h[7]  = msa_maddv_df(DF_HALF, pwd->h[7],  pws->h[7],  pwt->h[7]);
3267 }
3268 
3269 void helper_msa_maddv_w(CPUMIPSState *env,
3270                         uint32_t wd, uint32_t ws, uint32_t wt)
3271 {
3272     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3273     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3274     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3275 
3276     pwd->w[0]  = msa_maddv_df(DF_WORD, pwd->w[0],  pws->w[0],  pwt->w[0]);
3277     pwd->w[1]  = msa_maddv_df(DF_WORD, pwd->w[1],  pws->w[1],  pwt->w[1]);
3278     pwd->w[2]  = msa_maddv_df(DF_WORD, pwd->w[2],  pws->w[2],  pwt->w[2]);
3279     pwd->w[3]  = msa_maddv_df(DF_WORD, pwd->w[3],  pws->w[3],  pwt->w[3]);
3280 }
3281 
3282 void helper_msa_maddv_d(CPUMIPSState *env,
3283                         uint32_t wd, uint32_t ws, uint32_t wt)
3284 {
3285     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3286     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3287     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3288 
3289     pwd->d[0]  = msa_maddv_df(DF_DOUBLE, pwd->d[0],  pws->d[0],  pwt->d[0]);
3290     pwd->d[1]  = msa_maddv_df(DF_DOUBLE, pwd->d[1],  pws->d[1],  pwt->d[1]);
3291 }
3292 
3293 static inline int64_t msa_msubv_df(uint32_t df, int64_t dest, int64_t arg1,
3294                                    int64_t arg2)
3295 {
3296     return dest - arg1 * arg2;
3297 }
3298 
3299 void helper_msa_msubv_b(CPUMIPSState *env,
3300                         uint32_t wd, uint32_t ws, uint32_t wt)
3301 {
3302     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3303     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3304     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3305 
3306     pwd->b[0]  = msa_msubv_df(DF_BYTE, pwt->b[0],  pws->b[0],  pwt->b[0]);
3307     pwd->b[1]  = msa_msubv_df(DF_BYTE, pwt->b[1],  pws->b[1],  pwt->b[1]);
3308     pwd->b[2]  = msa_msubv_df(DF_BYTE, pwt->b[2],  pws->b[2],  pwt->b[2]);
3309     pwd->b[3]  = msa_msubv_df(DF_BYTE, pwt->b[3],  pws->b[3],  pwt->b[3]);
3310     pwd->b[4]  = msa_msubv_df(DF_BYTE, pwt->b[4],  pws->b[4],  pwt->b[4]);
3311     pwd->b[5]  = msa_msubv_df(DF_BYTE, pwt->b[5],  pws->b[5],  pwt->b[5]);
3312     pwd->b[6]  = msa_msubv_df(DF_BYTE, pwt->b[6],  pws->b[6],  pwt->b[6]);
3313     pwd->b[7]  = msa_msubv_df(DF_BYTE, pwt->b[7],  pws->b[7],  pwt->b[7]);
3314     pwd->b[8]  = msa_msubv_df(DF_BYTE, pwt->b[8],  pws->b[8],  pwt->b[8]);
3315     pwd->b[9]  = msa_msubv_df(DF_BYTE, pwt->b[9],  pws->b[9],  pwt->b[9]);
3316     pwd->b[10] = msa_msubv_df(DF_BYTE, pwt->b[10], pws->b[10], pwt->b[10]);
3317     pwd->b[11] = msa_msubv_df(DF_BYTE, pwt->b[11], pws->b[11], pwt->b[11]);
3318     pwd->b[12] = msa_msubv_df(DF_BYTE, pwt->b[12], pws->b[12], pwt->b[12]);
3319     pwd->b[13] = msa_msubv_df(DF_BYTE, pwt->b[13], pws->b[13], pwt->b[13]);
3320     pwd->b[14] = msa_msubv_df(DF_BYTE, pwt->b[14], pws->b[14], pwt->b[14]);
3321     pwd->b[15] = msa_msubv_df(DF_BYTE, pwt->b[15], pws->b[15], pwt->b[15]);
3322 }
3323 
3324 void helper_msa_msubv_h(CPUMIPSState *env,
3325                         uint32_t wd, uint32_t ws, uint32_t wt)
3326 {
3327     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3328     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3329     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3330 
3331     pwd->h[0]  = msa_msubv_df(DF_HALF, pwd->h[0],  pws->h[0],  pwt->h[0]);
3332     pwd->h[1]  = msa_msubv_df(DF_HALF, pwd->h[1],  pws->h[1],  pwt->h[1]);
3333     pwd->h[2]  = msa_msubv_df(DF_HALF, pwd->h[2],  pws->h[2],  pwt->h[2]);
3334     pwd->h[3]  = msa_msubv_df(DF_HALF, pwd->h[3],  pws->h[3],  pwt->h[3]);
3335     pwd->h[4]  = msa_msubv_df(DF_HALF, pwd->h[4],  pws->h[4],  pwt->h[4]);
3336     pwd->h[5]  = msa_msubv_df(DF_HALF, pwd->h[5],  pws->h[5],  pwt->h[5]);
3337     pwd->h[6]  = msa_msubv_df(DF_HALF, pwd->h[6],  pws->h[6],  pwt->h[6]);
3338     pwd->h[7]  = msa_msubv_df(DF_HALF, pwd->h[7],  pws->h[7],  pwt->h[7]);
3339 }
3340 
3341 void helper_msa_msubv_w(CPUMIPSState *env,
3342                         uint32_t wd, uint32_t ws, uint32_t wt)
3343 {
3344     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3345     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3346     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3347 
3348     pwd->w[0]  = msa_msubv_df(DF_WORD, pwd->w[0],  pws->w[0],  pwt->w[0]);
3349     pwd->w[1]  = msa_msubv_df(DF_WORD, pwd->w[1],  pws->w[1],  pwt->w[1]);
3350     pwd->w[2]  = msa_msubv_df(DF_WORD, pwd->w[2],  pws->w[2],  pwt->w[2]);
3351     pwd->w[3]  = msa_msubv_df(DF_WORD, pwd->w[3],  pws->w[3],  pwt->w[3]);
3352 }
3353 
3354 void helper_msa_msubv_d(CPUMIPSState *env,
3355                         uint32_t wd, uint32_t ws, uint32_t wt)
3356 {
3357     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3358     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3359     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3360 
3361     pwd->d[0]  = msa_msubv_df(DF_DOUBLE, pwd->d[0],  pws->d[0],  pwt->d[0]);
3362     pwd->d[1]  = msa_msubv_df(DF_DOUBLE, pwd->d[1],  pws->d[1],  pwt->d[1]);
3363 }
3364 
3365 
3366 static inline int64_t msa_mulv_df(uint32_t df, int64_t arg1, int64_t arg2)
3367 {
3368     return arg1 * arg2;
3369 }
3370 
3371 void helper_msa_mulv_b(CPUMIPSState *env,
3372                        uint32_t wd, uint32_t ws, uint32_t wt)
3373 {
3374     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3375     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3376     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3377 
3378     pwd->b[0]  = msa_mulv_df(DF_BYTE, pws->b[0],  pwt->b[0]);
3379     pwd->b[1]  = msa_mulv_df(DF_BYTE, pws->b[1],  pwt->b[1]);
3380     pwd->b[2]  = msa_mulv_df(DF_BYTE, pws->b[2],  pwt->b[2]);
3381     pwd->b[3]  = msa_mulv_df(DF_BYTE, pws->b[3],  pwt->b[3]);
3382     pwd->b[4]  = msa_mulv_df(DF_BYTE, pws->b[4],  pwt->b[4]);
3383     pwd->b[5]  = msa_mulv_df(DF_BYTE, pws->b[5],  pwt->b[5]);
3384     pwd->b[6]  = msa_mulv_df(DF_BYTE, pws->b[6],  pwt->b[6]);
3385     pwd->b[7]  = msa_mulv_df(DF_BYTE, pws->b[7],  pwt->b[7]);
3386     pwd->b[8]  = msa_mulv_df(DF_BYTE, pws->b[8],  pwt->b[8]);
3387     pwd->b[9]  = msa_mulv_df(DF_BYTE, pws->b[9],  pwt->b[9]);
3388     pwd->b[10] = msa_mulv_df(DF_BYTE, pws->b[10], pwt->b[10]);
3389     pwd->b[11] = msa_mulv_df(DF_BYTE, pws->b[11], pwt->b[11]);
3390     pwd->b[12] = msa_mulv_df(DF_BYTE, pws->b[12], pwt->b[12]);
3391     pwd->b[13] = msa_mulv_df(DF_BYTE, pws->b[13], pwt->b[13]);
3392     pwd->b[14] = msa_mulv_df(DF_BYTE, pws->b[14], pwt->b[14]);
3393     pwd->b[15] = msa_mulv_df(DF_BYTE, pws->b[15], pwt->b[15]);
3394 }
3395 
3396 void helper_msa_mulv_h(CPUMIPSState *env,
3397                        uint32_t wd, uint32_t ws, uint32_t wt)
3398 {
3399     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3400     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3401     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3402 
3403     pwd->h[0]  = msa_mulv_df(DF_HALF, pws->h[0],  pwt->h[0]);
3404     pwd->h[1]  = msa_mulv_df(DF_HALF, pws->h[1],  pwt->h[1]);
3405     pwd->h[2]  = msa_mulv_df(DF_HALF, pws->h[2],  pwt->h[2]);
3406     pwd->h[3]  = msa_mulv_df(DF_HALF, pws->h[3],  pwt->h[3]);
3407     pwd->h[4]  = msa_mulv_df(DF_HALF, pws->h[4],  pwt->h[4]);
3408     pwd->h[5]  = msa_mulv_df(DF_HALF, pws->h[5],  pwt->h[5]);
3409     pwd->h[6]  = msa_mulv_df(DF_HALF, pws->h[6],  pwt->h[6]);
3410     pwd->h[7]  = msa_mulv_df(DF_HALF, pws->h[7],  pwt->h[7]);
3411 }
3412 
3413 void helper_msa_mulv_w(CPUMIPSState *env,
3414                        uint32_t wd, uint32_t ws, uint32_t wt)
3415 {
3416     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3417     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3418     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3419 
3420     pwd->w[0]  = msa_mulv_df(DF_WORD, pws->w[0],  pwt->w[0]);
3421     pwd->w[1]  = msa_mulv_df(DF_WORD, pws->w[1],  pwt->w[1]);
3422     pwd->w[2]  = msa_mulv_df(DF_WORD, pws->w[2],  pwt->w[2]);
3423     pwd->w[3]  = msa_mulv_df(DF_WORD, pws->w[3],  pwt->w[3]);
3424 }
3425 
3426 void helper_msa_mulv_d(CPUMIPSState *env,
3427                        uint32_t wd, uint32_t ws, uint32_t wt)
3428 {
3429     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3430     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3431     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3432 
3433     pwd->d[0]  = msa_mulv_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3434     pwd->d[1]  = msa_mulv_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3435 }
3436 
3437 
3438 /*
3439  * Int Subtract
3440  * ------------
3441  *
3442  * +---------------+----------------------------------------------------------+
3443  * | ASUB_S.B      | Vector Absolute Values of Signed Subtract (byte)         |
3444  * | ASUB_S.H      | Vector Absolute Values of Signed Subtract (halfword)     |
3445  * | ASUB_S.W      | Vector Absolute Values of Signed Subtract (word)         |
3446  * | ASUB_S.D      | Vector Absolute Values of Signed Subtract (doubleword)   |
3447  * | ASUB_U.B      | Vector Absolute Values of Unsigned Subtract (byte)       |
3448  * | ASUB_U.H      | Vector Absolute Values of Unsigned Subtract (halfword)   |
3449  * | ASUB_U.W      | Vector Absolute Values of Unsigned Subtract (word)       |
3450  * | ASUB_U.D      | Vector Absolute Values of Unsigned Subtract (doubleword) |
3451  * | HSUB_S.H      | Vector Signed Horizontal Subtract (halfword)             |
3452  * | HSUB_S.W      | Vector Signed Horizontal Subtract (word)                 |
3453  * | HSUB_S.D      | Vector Signed Horizontal Subtract (doubleword)           |
3454  * | HSUB_U.H      | Vector Unigned Horizontal Subtract (halfword)            |
3455  * | HSUB_U.W      | Vector Unigned Horizontal Subtract (word)                |
3456  * | HSUB_U.D      | Vector Unigned Horizontal Subtract (doubleword)          |
3457  * | SUBS_S.B      | Vector Signed Saturated Subtract (of Signed) (byte)      |
3458  * | SUBS_S.H      | Vector Signed Saturated Subtract (of Signed) (halfword)  |
3459  * | SUBS_S.W      | Vector Signed Saturated Subtract (of Signed) (word)      |
3460  * | SUBS_S.D      | Vector Signed Saturated Subtract (of Signed) (doubleword)|
3461  * | SUBS_U.B      | Vector Unsigned Saturated Subtract (of Uns.) (byte)      |
3462  * | SUBS_U.H      | Vector Unsigned Saturated Subtract (of Uns.) (halfword)  |
3463  * | SUBS_U.W      | Vector Unsigned Saturated Subtract (of Uns.) (word)      |
3464  * | SUBS_U.D      | Vector Unsigned Saturated Subtract (of Uns.) (doubleword)|
3465  * | SUBSUS_U.B    | Vector Uns. Sat. Subtract (of S. from Uns.) (byte)       |
3466  * | SUBSUS_U.H    | Vector Uns. Sat. Subtract (of S. from Uns.) (halfword)   |
3467  * | SUBSUS_U.W    | Vector Uns. Sat. Subtract (of S. from Uns.) (word)       |
3468  * | SUBSUS_U.D    | Vector Uns. Sat. Subtract (of S. from Uns.) (doubleword) |
3469  * | SUBSUU_S.B    | Vector Signed Saturated Subtract (of Uns.) (byte)        |
3470  * | SUBSUU_S.H    | Vector Signed Saturated Subtract (of Uns.) (halfword)    |
3471  * | SUBSUU_S.W    | Vector Signed Saturated Subtract (of Uns.) (word)        |
3472  * | SUBSUU_S.D    | Vector Signed Saturated Subtract (of Uns.) (doubleword)  |
3473  * | SUBV.B        | Vector Subtract (byte)                                   |
3474  * | SUBV.H        | Vector Subtract (halfword)                               |
3475  * | SUBV.W        | Vector Subtract (word)                                   |
3476  * | SUBV.D        | Vector Subtract (doubleword)                             |
3477  * +---------------+----------------------------------------------------------+
3478  */
3479 
3480 
3481 static inline int64_t msa_asub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
3482 {
3483     /* signed compare */
3484     return (arg1 < arg2) ?
3485         (uint64_t)(arg2 - arg1) : (uint64_t)(arg1 - arg2);
3486 }
3487 
3488 void helper_msa_asub_s_b(CPUMIPSState *env,
3489                          uint32_t wd, uint32_t ws, uint32_t wt)
3490 {
3491     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3492     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3493     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3494 
3495     pwd->b[0]  = msa_asub_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
3496     pwd->b[1]  = msa_asub_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
3497     pwd->b[2]  = msa_asub_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
3498     pwd->b[3]  = msa_asub_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
3499     pwd->b[4]  = msa_asub_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
3500     pwd->b[5]  = msa_asub_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
3501     pwd->b[6]  = msa_asub_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
3502     pwd->b[7]  = msa_asub_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
3503     pwd->b[8]  = msa_asub_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
3504     pwd->b[9]  = msa_asub_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
3505     pwd->b[10] = msa_asub_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
3506     pwd->b[11] = msa_asub_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
3507     pwd->b[12] = msa_asub_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
3508     pwd->b[13] = msa_asub_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
3509     pwd->b[14] = msa_asub_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
3510     pwd->b[15] = msa_asub_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
3511 }
3512 
3513 void helper_msa_asub_s_h(CPUMIPSState *env,
3514                          uint32_t wd, uint32_t ws, uint32_t wt)
3515 {
3516     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3517     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3518     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3519 
3520     pwd->h[0]  = msa_asub_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
3521     pwd->h[1]  = msa_asub_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
3522     pwd->h[2]  = msa_asub_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
3523     pwd->h[3]  = msa_asub_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
3524     pwd->h[4]  = msa_asub_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
3525     pwd->h[5]  = msa_asub_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
3526     pwd->h[6]  = msa_asub_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
3527     pwd->h[7]  = msa_asub_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
3528 }
3529 
3530 void helper_msa_asub_s_w(CPUMIPSState *env,
3531                          uint32_t wd, uint32_t ws, uint32_t wt)
3532 {
3533     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3534     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3535     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3536 
3537     pwd->w[0]  = msa_asub_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
3538     pwd->w[1]  = msa_asub_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
3539     pwd->w[2]  = msa_asub_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
3540     pwd->w[3]  = msa_asub_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
3541 }
3542 
3543 void helper_msa_asub_s_d(CPUMIPSState *env,
3544                          uint32_t wd, uint32_t ws, uint32_t wt)
3545 {
3546     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3547     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3548     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3549 
3550     pwd->d[0]  = msa_asub_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3551     pwd->d[1]  = msa_asub_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3552 }
3553 
3554 
3555 static inline uint64_t msa_asub_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
3556 {
3557     uint64_t u_arg1 = UNSIGNED(arg1, df);
3558     uint64_t u_arg2 = UNSIGNED(arg2, df);
3559     /* unsigned compare */
3560     return (u_arg1 < u_arg2) ?
3561         (uint64_t)(u_arg2 - u_arg1) : (uint64_t)(u_arg1 - u_arg2);
3562 }
3563 
3564 void helper_msa_asub_u_b(CPUMIPSState *env,
3565                          uint32_t wd, uint32_t ws, uint32_t wt)
3566 {
3567     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3568     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3569     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3570 
3571     pwd->b[0]  = msa_asub_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
3572     pwd->b[1]  = msa_asub_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
3573     pwd->b[2]  = msa_asub_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
3574     pwd->b[3]  = msa_asub_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
3575     pwd->b[4]  = msa_asub_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
3576     pwd->b[5]  = msa_asub_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
3577     pwd->b[6]  = msa_asub_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
3578     pwd->b[7]  = msa_asub_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
3579     pwd->b[8]  = msa_asub_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
3580     pwd->b[9]  = msa_asub_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
3581     pwd->b[10] = msa_asub_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
3582     pwd->b[11] = msa_asub_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
3583     pwd->b[12] = msa_asub_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
3584     pwd->b[13] = msa_asub_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
3585     pwd->b[14] = msa_asub_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
3586     pwd->b[15] = msa_asub_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
3587 }
3588 
3589 void helper_msa_asub_u_h(CPUMIPSState *env,
3590                          uint32_t wd, uint32_t ws, uint32_t wt)
3591 {
3592     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3593     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3594     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3595 
3596     pwd->h[0]  = msa_asub_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
3597     pwd->h[1]  = msa_asub_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
3598     pwd->h[2]  = msa_asub_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
3599     pwd->h[3]  = msa_asub_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
3600     pwd->h[4]  = msa_asub_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
3601     pwd->h[5]  = msa_asub_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
3602     pwd->h[6]  = msa_asub_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
3603     pwd->h[7]  = msa_asub_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
3604 }
3605 
3606 void helper_msa_asub_u_w(CPUMIPSState *env,
3607                          uint32_t wd, uint32_t ws, uint32_t wt)
3608 {
3609     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3610     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3611     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3612 
3613     pwd->w[0]  = msa_asub_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
3614     pwd->w[1]  = msa_asub_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
3615     pwd->w[2]  = msa_asub_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
3616     pwd->w[3]  = msa_asub_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
3617 }
3618 
3619 void helper_msa_asub_u_d(CPUMIPSState *env,
3620                          uint32_t wd, uint32_t ws, uint32_t wt)
3621 {
3622     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3623     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3624     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3625 
3626     pwd->d[0]  = msa_asub_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3627     pwd->d[1]  = msa_asub_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3628 }
3629 
3630 
3631 static inline int64_t msa_hsub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
3632 {
3633     return SIGNED_ODD(arg1, df) - SIGNED_EVEN(arg2, df);
3634 }
3635 
3636 void helper_msa_hsub_s_h(CPUMIPSState *env,
3637                          uint32_t wd, uint32_t ws, uint32_t wt)
3638 {
3639     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3640     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3641     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3642 
3643     pwd->h[0]  = msa_hsub_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
3644     pwd->h[1]  = msa_hsub_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
3645     pwd->h[2]  = msa_hsub_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
3646     pwd->h[3]  = msa_hsub_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
3647     pwd->h[4]  = msa_hsub_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
3648     pwd->h[5]  = msa_hsub_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
3649     pwd->h[6]  = msa_hsub_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
3650     pwd->h[7]  = msa_hsub_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
3651 }
3652 
3653 void helper_msa_hsub_s_w(CPUMIPSState *env,
3654                          uint32_t wd, uint32_t ws, uint32_t wt)
3655 {
3656     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3657     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3658     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3659 
3660     pwd->w[0]  = msa_hsub_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
3661     pwd->w[1]  = msa_hsub_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
3662     pwd->w[2]  = msa_hsub_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
3663     pwd->w[3]  = msa_hsub_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
3664 }
3665 
3666 void helper_msa_hsub_s_d(CPUMIPSState *env,
3667                          uint32_t wd, uint32_t ws, uint32_t wt)
3668 {
3669     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3670     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3671     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3672 
3673     pwd->d[0]  = msa_hsub_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3674     pwd->d[1]  = msa_hsub_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3675 }
3676 
3677 
3678 static inline int64_t msa_hsub_u_df(uint32_t df, int64_t arg1, int64_t arg2)
3679 {
3680     return UNSIGNED_ODD(arg1, df) - UNSIGNED_EVEN(arg2, df);
3681 }
3682 
3683 void helper_msa_hsub_u_h(CPUMIPSState *env,
3684                          uint32_t wd, uint32_t ws, uint32_t wt)
3685 {
3686     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3687     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3688     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3689 
3690     pwd->h[0]  = msa_hsub_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
3691     pwd->h[1]  = msa_hsub_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
3692     pwd->h[2]  = msa_hsub_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
3693     pwd->h[3]  = msa_hsub_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
3694     pwd->h[4]  = msa_hsub_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
3695     pwd->h[5]  = msa_hsub_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
3696     pwd->h[6]  = msa_hsub_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
3697     pwd->h[7]  = msa_hsub_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
3698 }
3699 
3700 void helper_msa_hsub_u_w(CPUMIPSState *env,
3701                          uint32_t wd, uint32_t ws, uint32_t wt)
3702 {
3703     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3704     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3705     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3706 
3707     pwd->w[0]  = msa_hsub_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
3708     pwd->w[1]  = msa_hsub_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
3709     pwd->w[2]  = msa_hsub_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
3710     pwd->w[3]  = msa_hsub_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
3711 }
3712 
3713 void helper_msa_hsub_u_d(CPUMIPSState *env,
3714                          uint32_t wd, uint32_t ws, uint32_t wt)
3715 {
3716     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3717     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3718     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3719 
3720     pwd->d[0]  = msa_hsub_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3721     pwd->d[1]  = msa_hsub_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3722 }
3723 
3724 
3725 static inline int64_t msa_subs_s_df(uint32_t df, int64_t arg1, int64_t arg2)
3726 {
3727     int64_t max_int = DF_MAX_INT(df);
3728     int64_t min_int = DF_MIN_INT(df);
3729     if (arg2 > 0) {
3730         return (min_int + arg2 < arg1) ? arg1 - arg2 : min_int;
3731     } else {
3732         return (arg1 < max_int + arg2) ? arg1 - arg2 : max_int;
3733     }
3734 }
3735 
3736 void helper_msa_subs_s_b(CPUMIPSState *env,
3737                          uint32_t wd, uint32_t ws, uint32_t wt)
3738 {
3739     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3740     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3741     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3742 
3743     pwd->b[0]  = msa_subs_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
3744     pwd->b[1]  = msa_subs_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
3745     pwd->b[2]  = msa_subs_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
3746     pwd->b[3]  = msa_subs_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
3747     pwd->b[4]  = msa_subs_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
3748     pwd->b[5]  = msa_subs_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
3749     pwd->b[6]  = msa_subs_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
3750     pwd->b[7]  = msa_subs_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
3751     pwd->b[8]  = msa_subs_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
3752     pwd->b[9]  = msa_subs_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
3753     pwd->b[10] = msa_subs_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
3754     pwd->b[11] = msa_subs_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
3755     pwd->b[12] = msa_subs_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
3756     pwd->b[13] = msa_subs_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
3757     pwd->b[14] = msa_subs_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
3758     pwd->b[15] = msa_subs_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
3759 }
3760 
3761 void helper_msa_subs_s_h(CPUMIPSState *env,
3762                          uint32_t wd, uint32_t ws, uint32_t wt)
3763 {
3764     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3765     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3766     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3767 
3768     pwd->h[0]  = msa_subs_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
3769     pwd->h[1]  = msa_subs_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
3770     pwd->h[2]  = msa_subs_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
3771     pwd->h[3]  = msa_subs_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
3772     pwd->h[4]  = msa_subs_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
3773     pwd->h[5]  = msa_subs_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
3774     pwd->h[6]  = msa_subs_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
3775     pwd->h[7]  = msa_subs_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
3776 }
3777 
3778 void helper_msa_subs_s_w(CPUMIPSState *env,
3779                          uint32_t wd, uint32_t ws, uint32_t wt)
3780 {
3781     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3782     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3783     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3784 
3785     pwd->w[0]  = msa_subs_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
3786     pwd->w[1]  = msa_subs_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
3787     pwd->w[2]  = msa_subs_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
3788     pwd->w[3]  = msa_subs_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
3789 }
3790 
3791 void helper_msa_subs_s_d(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     pwd->d[0]  = msa_subs_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3799     pwd->d[1]  = msa_subs_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3800 }
3801 
3802 
3803 static inline int64_t msa_subs_u_df(uint32_t df, int64_t arg1, int64_t arg2)
3804 {
3805     uint64_t u_arg1 = UNSIGNED(arg1, df);
3806     uint64_t u_arg2 = UNSIGNED(arg2, df);
3807     return (u_arg1 > u_arg2) ? u_arg1 - u_arg2 : 0;
3808 }
3809 
3810 void helper_msa_subs_u_b(CPUMIPSState *env,
3811                          uint32_t wd, uint32_t ws, uint32_t wt)
3812 {
3813     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3814     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3815     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3816 
3817     pwd->b[0]  = msa_subs_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
3818     pwd->b[1]  = msa_subs_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
3819     pwd->b[2]  = msa_subs_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
3820     pwd->b[3]  = msa_subs_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
3821     pwd->b[4]  = msa_subs_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
3822     pwd->b[5]  = msa_subs_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
3823     pwd->b[6]  = msa_subs_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
3824     pwd->b[7]  = msa_subs_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
3825     pwd->b[8]  = msa_subs_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
3826     pwd->b[9]  = msa_subs_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
3827     pwd->b[10] = msa_subs_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
3828     pwd->b[11] = msa_subs_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
3829     pwd->b[12] = msa_subs_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
3830     pwd->b[13] = msa_subs_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
3831     pwd->b[14] = msa_subs_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
3832     pwd->b[15] = msa_subs_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
3833 }
3834 
3835 void helper_msa_subs_u_h(CPUMIPSState *env,
3836                          uint32_t wd, uint32_t ws, uint32_t wt)
3837 {
3838     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3839     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3840     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3841 
3842     pwd->h[0]  = msa_subs_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
3843     pwd->h[1]  = msa_subs_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
3844     pwd->h[2]  = msa_subs_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
3845     pwd->h[3]  = msa_subs_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
3846     pwd->h[4]  = msa_subs_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
3847     pwd->h[5]  = msa_subs_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
3848     pwd->h[6]  = msa_subs_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
3849     pwd->h[7]  = msa_subs_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
3850 }
3851 
3852 void helper_msa_subs_u_w(CPUMIPSState *env,
3853                          uint32_t wd, uint32_t ws, uint32_t wt)
3854 {
3855     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3856     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3857     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3858 
3859     pwd->w[0]  = msa_subs_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
3860     pwd->w[1]  = msa_subs_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
3861     pwd->w[2]  = msa_subs_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
3862     pwd->w[3]  = msa_subs_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
3863 }
3864 
3865 void helper_msa_subs_u_d(CPUMIPSState *env,
3866                          uint32_t wd, uint32_t ws, uint32_t wt)
3867 {
3868     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3869     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3870     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3871 
3872     pwd->d[0]  = msa_subs_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3873     pwd->d[1]  = msa_subs_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3874 }
3875 
3876 
3877 static inline int64_t msa_subsus_u_df(uint32_t df, int64_t arg1, int64_t arg2)
3878 {
3879     uint64_t u_arg1 = UNSIGNED(arg1, df);
3880     uint64_t max_uint = DF_MAX_UINT(df);
3881     if (arg2 >= 0) {
3882         uint64_t u_arg2 = (uint64_t)arg2;
3883         return (u_arg1 > u_arg2) ?
3884             (int64_t)(u_arg1 - u_arg2) :
3885             0;
3886     } else {
3887         uint64_t u_arg2 = (uint64_t)(-arg2);
3888         return (u_arg1 < max_uint - u_arg2) ?
3889             (int64_t)(u_arg1 + u_arg2) :
3890             (int64_t)max_uint;
3891     }
3892 }
3893 
3894 void helper_msa_subsus_u_b(CPUMIPSState *env,
3895                            uint32_t wd, uint32_t ws, uint32_t wt)
3896 {
3897     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3898     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3899     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3900 
3901     pwd->b[0]  = msa_subsus_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
3902     pwd->b[1]  = msa_subsus_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
3903     pwd->b[2]  = msa_subsus_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
3904     pwd->b[3]  = msa_subsus_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
3905     pwd->b[4]  = msa_subsus_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
3906     pwd->b[5]  = msa_subsus_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
3907     pwd->b[6]  = msa_subsus_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
3908     pwd->b[7]  = msa_subsus_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
3909     pwd->b[8]  = msa_subsus_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
3910     pwd->b[9]  = msa_subsus_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
3911     pwd->b[10] = msa_subsus_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
3912     pwd->b[11] = msa_subsus_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
3913     pwd->b[12] = msa_subsus_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
3914     pwd->b[13] = msa_subsus_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
3915     pwd->b[14] = msa_subsus_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
3916     pwd->b[15] = msa_subsus_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
3917 }
3918 
3919 void helper_msa_subsus_u_h(CPUMIPSState *env,
3920                            uint32_t wd, uint32_t ws, uint32_t wt)
3921 {
3922     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3923     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3924     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3925 
3926     pwd->h[0]  = msa_subsus_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
3927     pwd->h[1]  = msa_subsus_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
3928     pwd->h[2]  = msa_subsus_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
3929     pwd->h[3]  = msa_subsus_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
3930     pwd->h[4]  = msa_subsus_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
3931     pwd->h[5]  = msa_subsus_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
3932     pwd->h[6]  = msa_subsus_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
3933     pwd->h[7]  = msa_subsus_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
3934 }
3935 
3936 void helper_msa_subsus_u_w(CPUMIPSState *env,
3937                            uint32_t wd, uint32_t ws, uint32_t wt)
3938 {
3939     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3940     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3941     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3942 
3943     pwd->w[0]  = msa_subsus_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
3944     pwd->w[1]  = msa_subsus_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
3945     pwd->w[2]  = msa_subsus_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
3946     pwd->w[3]  = msa_subsus_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
3947 }
3948 
3949 void helper_msa_subsus_u_d(CPUMIPSState *env,
3950                            uint32_t wd, uint32_t ws, uint32_t wt)
3951 {
3952     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3953     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3954     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3955 
3956     pwd->d[0]  = msa_subsus_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3957     pwd->d[1]  = msa_subsus_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3958 }
3959 
3960 
3961 static inline int64_t msa_subsuu_s_df(uint32_t df, int64_t arg1, int64_t arg2)
3962 {
3963     uint64_t u_arg1 = UNSIGNED(arg1, df);
3964     uint64_t u_arg2 = UNSIGNED(arg2, df);
3965     int64_t max_int = DF_MAX_INT(df);
3966     int64_t min_int = DF_MIN_INT(df);
3967     if (u_arg1 > u_arg2) {
3968         return u_arg1 - u_arg2 < (uint64_t)max_int ?
3969             (int64_t)(u_arg1 - u_arg2) :
3970             max_int;
3971     } else {
3972         return u_arg2 - u_arg1 < (uint64_t)(-min_int) ?
3973             (int64_t)(u_arg1 - u_arg2) :
3974             min_int;
3975     }
3976 }
3977 
3978 void helper_msa_subsuu_s_b(CPUMIPSState *env,
3979                            uint32_t wd, uint32_t ws, uint32_t wt)
3980 {
3981     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3982     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3983     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3984 
3985     pwd->b[0]  = msa_subsuu_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
3986     pwd->b[1]  = msa_subsuu_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
3987     pwd->b[2]  = msa_subsuu_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
3988     pwd->b[3]  = msa_subsuu_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
3989     pwd->b[4]  = msa_subsuu_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
3990     pwd->b[5]  = msa_subsuu_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
3991     pwd->b[6]  = msa_subsuu_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
3992     pwd->b[7]  = msa_subsuu_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
3993     pwd->b[8]  = msa_subsuu_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
3994     pwd->b[9]  = msa_subsuu_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
3995     pwd->b[10] = msa_subsuu_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
3996     pwd->b[11] = msa_subsuu_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
3997     pwd->b[12] = msa_subsuu_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
3998     pwd->b[13] = msa_subsuu_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
3999     pwd->b[14] = msa_subsuu_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
4000     pwd->b[15] = msa_subsuu_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
4001 }
4002 
4003 void helper_msa_subsuu_s_h(CPUMIPSState *env,
4004                            uint32_t wd, uint32_t ws, uint32_t wt)
4005 {
4006     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4007     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4008     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4009 
4010     pwd->h[0]  = msa_subsuu_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
4011     pwd->h[1]  = msa_subsuu_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
4012     pwd->h[2]  = msa_subsuu_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
4013     pwd->h[3]  = msa_subsuu_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
4014     pwd->h[4]  = msa_subsuu_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
4015     pwd->h[5]  = msa_subsuu_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
4016     pwd->h[6]  = msa_subsuu_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
4017     pwd->h[7]  = msa_subsuu_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
4018 }
4019 
4020 void helper_msa_subsuu_s_w(CPUMIPSState *env,
4021                            uint32_t wd, uint32_t ws, uint32_t wt)
4022 {
4023     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4024     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4025     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4026 
4027     pwd->w[0]  = msa_subsuu_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
4028     pwd->w[1]  = msa_subsuu_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
4029     pwd->w[2]  = msa_subsuu_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
4030     pwd->w[3]  = msa_subsuu_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
4031 }
4032 
4033 void helper_msa_subsuu_s_d(CPUMIPSState *env,
4034                            uint32_t wd, uint32_t ws, uint32_t wt)
4035 {
4036     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4037     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4038     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4039 
4040     pwd->d[0]  = msa_subsuu_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
4041     pwd->d[1]  = msa_subsuu_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
4042 }
4043 
4044 
4045 static inline int64_t msa_subv_df(uint32_t df, int64_t arg1, int64_t arg2)
4046 {
4047     return arg1 - arg2;
4048 }
4049 
4050 void helper_msa_subv_b(CPUMIPSState *env,
4051                        uint32_t wd, uint32_t ws, uint32_t wt)
4052 {
4053     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4054     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4055     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4056 
4057     pwd->b[0]  = msa_subv_df(DF_BYTE, pws->b[0],  pwt->b[0]);
4058     pwd->b[1]  = msa_subv_df(DF_BYTE, pws->b[1],  pwt->b[1]);
4059     pwd->b[2]  = msa_subv_df(DF_BYTE, pws->b[2],  pwt->b[2]);
4060     pwd->b[3]  = msa_subv_df(DF_BYTE, pws->b[3],  pwt->b[3]);
4061     pwd->b[4]  = msa_subv_df(DF_BYTE, pws->b[4],  pwt->b[4]);
4062     pwd->b[5]  = msa_subv_df(DF_BYTE, pws->b[5],  pwt->b[5]);
4063     pwd->b[6]  = msa_subv_df(DF_BYTE, pws->b[6],  pwt->b[6]);
4064     pwd->b[7]  = msa_subv_df(DF_BYTE, pws->b[7],  pwt->b[7]);
4065     pwd->b[8]  = msa_subv_df(DF_BYTE, pws->b[8],  pwt->b[8]);
4066     pwd->b[9]  = msa_subv_df(DF_BYTE, pws->b[9],  pwt->b[9]);
4067     pwd->b[10] = msa_subv_df(DF_BYTE, pws->b[10], pwt->b[10]);
4068     pwd->b[11] = msa_subv_df(DF_BYTE, pws->b[11], pwt->b[11]);
4069     pwd->b[12] = msa_subv_df(DF_BYTE, pws->b[12], pwt->b[12]);
4070     pwd->b[13] = msa_subv_df(DF_BYTE, pws->b[13], pwt->b[13]);
4071     pwd->b[14] = msa_subv_df(DF_BYTE, pws->b[14], pwt->b[14]);
4072     pwd->b[15] = msa_subv_df(DF_BYTE, pws->b[15], pwt->b[15]);
4073 }
4074 
4075 void helper_msa_subv_h(CPUMIPSState *env,
4076                        uint32_t wd, uint32_t ws, uint32_t wt)
4077 {
4078     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4079     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4080     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4081 
4082     pwd->h[0]  = msa_subv_df(DF_HALF, pws->h[0],  pwt->h[0]);
4083     pwd->h[1]  = msa_subv_df(DF_HALF, pws->h[1],  pwt->h[1]);
4084     pwd->h[2]  = msa_subv_df(DF_HALF, pws->h[2],  pwt->h[2]);
4085     pwd->h[3]  = msa_subv_df(DF_HALF, pws->h[3],  pwt->h[3]);
4086     pwd->h[4]  = msa_subv_df(DF_HALF, pws->h[4],  pwt->h[4]);
4087     pwd->h[5]  = msa_subv_df(DF_HALF, pws->h[5],  pwt->h[5]);
4088     pwd->h[6]  = msa_subv_df(DF_HALF, pws->h[6],  pwt->h[6]);
4089     pwd->h[7]  = msa_subv_df(DF_HALF, pws->h[7],  pwt->h[7]);
4090 }
4091 
4092 void helper_msa_subv_w(CPUMIPSState *env,
4093                        uint32_t wd, uint32_t ws, uint32_t wt)
4094 {
4095     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4096     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4097     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4098 
4099     pwd->w[0]  = msa_subv_df(DF_WORD, pws->w[0],  pwt->w[0]);
4100     pwd->w[1]  = msa_subv_df(DF_WORD, pws->w[1],  pwt->w[1]);
4101     pwd->w[2]  = msa_subv_df(DF_WORD, pws->w[2],  pwt->w[2]);
4102     pwd->w[3]  = msa_subv_df(DF_WORD, pws->w[3],  pwt->w[3]);
4103 }
4104 
4105 void helper_msa_subv_d(CPUMIPSState *env,
4106                        uint32_t wd, uint32_t ws, uint32_t wt)
4107 {
4108     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4109     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4110     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4111 
4112     pwd->d[0]  = msa_subv_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
4113     pwd->d[1]  = msa_subv_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
4114 }
4115 
4116 
4117 /*
4118  * Interleave
4119  * ----------
4120  *
4121  * +---------------+----------------------------------------------------------+
4122  * | ILVEV.B       | Vector Interleave Even (byte)                            |
4123  * | ILVEV.H       | Vector Interleave Even (halfword)                        |
4124  * | ILVEV.W       | Vector Interleave Even (word)                            |
4125  * | ILVEV.D       | Vector Interleave Even (doubleword)                      |
4126  * | ILVOD.B       | Vector Interleave Odd (byte)                             |
4127  * | ILVOD.H       | Vector Interleave Odd (halfword)                         |
4128  * | ILVOD.W       | Vector Interleave Odd (word)                             |
4129  * | ILVOD.D       | Vector Interleave Odd (doubleword)                       |
4130  * | ILVL.B        | Vector Interleave Left (byte)                            |
4131  * | ILVL.H        | Vector Interleave Left (halfword)                        |
4132  * | ILVL.W        | Vector Interleave Left (word)                            |
4133  * | ILVL.D        | Vector Interleave Left (doubleword)                      |
4134  * | ILVR.B        | Vector Interleave Right (byte)                           |
4135  * | ILVR.H        | Vector Interleave Right (halfword)                       |
4136  * | ILVR.W        | Vector Interleave Right (word)                           |
4137  * | ILVR.D        | Vector Interleave Right (doubleword)                     |
4138  * +---------------+----------------------------------------------------------+
4139  */
4140 
4141 
4142 void helper_msa_ilvev_b(CPUMIPSState *env,
4143                         uint32_t wd, uint32_t ws, uint32_t wt)
4144 {
4145     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4146     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4147     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4148 
4149 #if defined(HOST_WORDS_BIGENDIAN)
4150     pwd->b[8]  = pws->b[9];
4151     pwd->b[9]  = pwt->b[9];
4152     pwd->b[10] = pws->b[11];
4153     pwd->b[11] = pwt->b[11];
4154     pwd->b[12] = pws->b[13];
4155     pwd->b[13] = pwt->b[13];
4156     pwd->b[14] = pws->b[15];
4157     pwd->b[15] = pwt->b[15];
4158     pwd->b[0]  = pws->b[1];
4159     pwd->b[1]  = pwt->b[1];
4160     pwd->b[2]  = pws->b[3];
4161     pwd->b[3]  = pwt->b[3];
4162     pwd->b[4]  = pws->b[5];
4163     pwd->b[5]  = pwt->b[5];
4164     pwd->b[6]  = pws->b[7];
4165     pwd->b[7]  = pwt->b[7];
4166 #else
4167     pwd->b[15] = pws->b[14];
4168     pwd->b[14] = pwt->b[14];
4169     pwd->b[13] = pws->b[12];
4170     pwd->b[12] = pwt->b[12];
4171     pwd->b[11] = pws->b[10];
4172     pwd->b[10] = pwt->b[10];
4173     pwd->b[9]  = pws->b[8];
4174     pwd->b[8]  = pwt->b[8];
4175     pwd->b[7]  = pws->b[6];
4176     pwd->b[6]  = pwt->b[6];
4177     pwd->b[5]  = pws->b[4];
4178     pwd->b[4]  = pwt->b[4];
4179     pwd->b[3]  = pws->b[2];
4180     pwd->b[2]  = pwt->b[2];
4181     pwd->b[1]  = pws->b[0];
4182     pwd->b[0]  = pwt->b[0];
4183 #endif
4184 }
4185 
4186 void helper_msa_ilvev_h(CPUMIPSState *env,
4187                         uint32_t wd, uint32_t ws, uint32_t wt)
4188 {
4189     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4190     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4191     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4192 
4193 #if defined(HOST_WORDS_BIGENDIAN)
4194     pwd->h[4] = pws->h[5];
4195     pwd->h[5] = pwt->h[5];
4196     pwd->h[6] = pws->h[7];
4197     pwd->h[7] = pwt->h[7];
4198     pwd->h[0] = pws->h[1];
4199     pwd->h[1] = pwt->h[1];
4200     pwd->h[2] = pws->h[3];
4201     pwd->h[3] = pwt->h[3];
4202 #else
4203     pwd->h[7] = pws->h[6];
4204     pwd->h[6] = pwt->h[6];
4205     pwd->h[5] = pws->h[4];
4206     pwd->h[4] = pwt->h[4];
4207     pwd->h[3] = pws->h[2];
4208     pwd->h[2] = pwt->h[2];
4209     pwd->h[1] = pws->h[0];
4210     pwd->h[0] = pwt->h[0];
4211 #endif
4212 }
4213 
4214 void helper_msa_ilvev_w(CPUMIPSState *env,
4215                         uint32_t wd, uint32_t ws, uint32_t wt)
4216 {
4217     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4218     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4219     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4220 
4221 #if defined(HOST_WORDS_BIGENDIAN)
4222     pwd->w[2] = pws->w[3];
4223     pwd->w[3] = pwt->w[3];
4224     pwd->w[0] = pws->w[1];
4225     pwd->w[1] = pwt->w[1];
4226 #else
4227     pwd->w[3] = pws->w[2];
4228     pwd->w[2] = pwt->w[2];
4229     pwd->w[1] = pws->w[0];
4230     pwd->w[0] = pwt->w[0];
4231 #endif
4232 }
4233 
4234 void helper_msa_ilvev_d(CPUMIPSState *env,
4235                         uint32_t wd, uint32_t ws, uint32_t wt)
4236 {
4237     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4238     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4239     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4240 
4241     pwd->d[1] = pws->d[0];
4242     pwd->d[0] = pwt->d[0];
4243 }
4244 
4245 
4246 void helper_msa_ilvod_b(CPUMIPSState *env,
4247                         uint32_t wd, uint32_t ws, uint32_t wt)
4248 {
4249     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4250     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4251     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4252 
4253 #if defined(HOST_WORDS_BIGENDIAN)
4254     pwd->b[7]  = pwt->b[6];
4255     pwd->b[6]  = pws->b[6];
4256     pwd->b[5]  = pwt->b[4];
4257     pwd->b[4]  = pws->b[4];
4258     pwd->b[3]  = pwt->b[2];
4259     pwd->b[2]  = pws->b[2];
4260     pwd->b[1]  = pwt->b[0];
4261     pwd->b[0]  = pws->b[0];
4262     pwd->b[15] = pwt->b[14];
4263     pwd->b[14] = pws->b[14];
4264     pwd->b[13] = pwt->b[12];
4265     pwd->b[12] = pws->b[12];
4266     pwd->b[11] = pwt->b[10];
4267     pwd->b[10] = pws->b[10];
4268     pwd->b[9]  = pwt->b[8];
4269     pwd->b[8]  = pws->b[8];
4270 #else
4271     pwd->b[0]  = pwt->b[1];
4272     pwd->b[1]  = pws->b[1];
4273     pwd->b[2]  = pwt->b[3];
4274     pwd->b[3]  = pws->b[3];
4275     pwd->b[4]  = pwt->b[5];
4276     pwd->b[5]  = pws->b[5];
4277     pwd->b[6]  = pwt->b[7];
4278     pwd->b[7]  = pws->b[7];
4279     pwd->b[8]  = pwt->b[9];
4280     pwd->b[9]  = pws->b[9];
4281     pwd->b[10] = pwt->b[11];
4282     pwd->b[11] = pws->b[11];
4283     pwd->b[12] = pwt->b[13];
4284     pwd->b[13] = pws->b[13];
4285     pwd->b[14] = pwt->b[15];
4286     pwd->b[15] = pws->b[15];
4287 #endif
4288 }
4289 
4290 void helper_msa_ilvod_h(CPUMIPSState *env,
4291                         uint32_t wd, uint32_t ws, uint32_t wt)
4292 {
4293     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4294     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4295     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4296 
4297 #if defined(HOST_WORDS_BIGENDIAN)
4298     pwd->h[3] = pwt->h[2];
4299     pwd->h[2] = pws->h[2];
4300     pwd->h[1] = pwt->h[0];
4301     pwd->h[0] = pws->h[0];
4302     pwd->h[7] = pwt->h[6];
4303     pwd->h[6] = pws->h[6];
4304     pwd->h[5] = pwt->h[4];
4305     pwd->h[4] = pws->h[4];
4306 #else
4307     pwd->h[0] = pwt->h[1];
4308     pwd->h[1] = pws->h[1];
4309     pwd->h[2] = pwt->h[3];
4310     pwd->h[3] = pws->h[3];
4311     pwd->h[4] = pwt->h[5];
4312     pwd->h[5] = pws->h[5];
4313     pwd->h[6] = pwt->h[7];
4314     pwd->h[7] = pws->h[7];
4315 #endif
4316 }
4317 
4318 void helper_msa_ilvod_w(CPUMIPSState *env,
4319                         uint32_t wd, uint32_t ws, uint32_t wt)
4320 {
4321     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4322     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4323     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4324 
4325 #if defined(HOST_WORDS_BIGENDIAN)
4326     pwd->w[1] = pwt->w[0];
4327     pwd->w[0] = pws->w[0];
4328     pwd->w[3] = pwt->w[2];
4329     pwd->w[2] = pws->w[2];
4330 #else
4331     pwd->w[0] = pwt->w[1];
4332     pwd->w[1] = pws->w[1];
4333     pwd->w[2] = pwt->w[3];
4334     pwd->w[3] = pws->w[3];
4335 #endif
4336 }
4337 
4338 void helper_msa_ilvod_d(CPUMIPSState *env,
4339                         uint32_t wd, uint32_t ws, uint32_t wt)
4340 {
4341     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4342     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4343     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4344 
4345     pwd->d[0] = pwt->d[1];
4346     pwd->d[1] = pws->d[1];
4347 }
4348 
4349 
4350 void helper_msa_ilvl_b(CPUMIPSState *env,
4351                        uint32_t wd, uint32_t ws, uint32_t wt)
4352 {
4353     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4354     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4355     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4356 
4357 #if defined(HOST_WORDS_BIGENDIAN)
4358     pwd->b[7]  = pwt->b[15];
4359     pwd->b[6]  = pws->b[15];
4360     pwd->b[5]  = pwt->b[14];
4361     pwd->b[4]  = pws->b[14];
4362     pwd->b[3]  = pwt->b[13];
4363     pwd->b[2]  = pws->b[13];
4364     pwd->b[1]  = pwt->b[12];
4365     pwd->b[0]  = pws->b[12];
4366     pwd->b[15] = pwt->b[11];
4367     pwd->b[14] = pws->b[11];
4368     pwd->b[13] = pwt->b[10];
4369     pwd->b[12] = pws->b[10];
4370     pwd->b[11] = pwt->b[9];
4371     pwd->b[10] = pws->b[9];
4372     pwd->b[9]  = pwt->b[8];
4373     pwd->b[8]  = pws->b[8];
4374 #else
4375     pwd->b[0]  = pwt->b[8];
4376     pwd->b[1]  = pws->b[8];
4377     pwd->b[2]  = pwt->b[9];
4378     pwd->b[3]  = pws->b[9];
4379     pwd->b[4]  = pwt->b[10];
4380     pwd->b[5]  = pws->b[10];
4381     pwd->b[6]  = pwt->b[11];
4382     pwd->b[7]  = pws->b[11];
4383     pwd->b[8]  = pwt->b[12];
4384     pwd->b[9]  = pws->b[12];
4385     pwd->b[10] = pwt->b[13];
4386     pwd->b[11] = pws->b[13];
4387     pwd->b[12] = pwt->b[14];
4388     pwd->b[13] = pws->b[14];
4389     pwd->b[14] = pwt->b[15];
4390     pwd->b[15] = pws->b[15];
4391 #endif
4392 }
4393 
4394 void helper_msa_ilvl_h(CPUMIPSState *env,
4395                        uint32_t wd, uint32_t ws, uint32_t wt)
4396 {
4397     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4398     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4399     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4400 
4401 #if defined(HOST_WORDS_BIGENDIAN)
4402     pwd->h[3] = pwt->h[7];
4403     pwd->h[2] = pws->h[7];
4404     pwd->h[1] = pwt->h[6];
4405     pwd->h[0] = pws->h[6];
4406     pwd->h[7] = pwt->h[5];
4407     pwd->h[6] = pws->h[5];
4408     pwd->h[5] = pwt->h[4];
4409     pwd->h[4] = pws->h[4];
4410 #else
4411     pwd->h[0] = pwt->h[4];
4412     pwd->h[1] = pws->h[4];
4413     pwd->h[2] = pwt->h[5];
4414     pwd->h[3] = pws->h[5];
4415     pwd->h[4] = pwt->h[6];
4416     pwd->h[5] = pws->h[6];
4417     pwd->h[6] = pwt->h[7];
4418     pwd->h[7] = pws->h[7];
4419 #endif
4420 }
4421 
4422 void helper_msa_ilvl_w(CPUMIPSState *env,
4423                        uint32_t wd, uint32_t ws, uint32_t wt)
4424 {
4425     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4426     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4427     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4428 
4429 #if defined(HOST_WORDS_BIGENDIAN)
4430     pwd->w[1] = pwt->w[3];
4431     pwd->w[0] = pws->w[3];
4432     pwd->w[3] = pwt->w[2];
4433     pwd->w[2] = pws->w[2];
4434 #else
4435     pwd->w[0] = pwt->w[2];
4436     pwd->w[1] = pws->w[2];
4437     pwd->w[2] = pwt->w[3];
4438     pwd->w[3] = pws->w[3];
4439 #endif
4440 }
4441 
4442 void helper_msa_ilvl_d(CPUMIPSState *env,
4443                        uint32_t wd, uint32_t ws, uint32_t wt)
4444 {
4445     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4446     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4447     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4448 
4449     pwd->d[0] = pwt->d[1];
4450     pwd->d[1] = pws->d[1];
4451 }
4452 
4453 
4454 void helper_msa_ilvr_b(CPUMIPSState *env,
4455                        uint32_t wd, uint32_t ws, uint32_t wt)
4456 {
4457     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4458     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4459     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4460 
4461 #if defined(HOST_WORDS_BIGENDIAN)
4462     pwd->b[8]  = pws->b[0];
4463     pwd->b[9]  = pwt->b[0];
4464     pwd->b[10] = pws->b[1];
4465     pwd->b[11] = pwt->b[1];
4466     pwd->b[12] = pws->b[2];
4467     pwd->b[13] = pwt->b[2];
4468     pwd->b[14] = pws->b[3];
4469     pwd->b[15] = pwt->b[3];
4470     pwd->b[0]  = pws->b[4];
4471     pwd->b[1]  = pwt->b[4];
4472     pwd->b[2]  = pws->b[5];
4473     pwd->b[3]  = pwt->b[5];
4474     pwd->b[4]  = pws->b[6];
4475     pwd->b[5]  = pwt->b[6];
4476     pwd->b[6]  = pws->b[7];
4477     pwd->b[7]  = pwt->b[7];
4478 #else
4479     pwd->b[15] = pws->b[7];
4480     pwd->b[14] = pwt->b[7];
4481     pwd->b[13] = pws->b[6];
4482     pwd->b[12] = pwt->b[6];
4483     pwd->b[11] = pws->b[5];
4484     pwd->b[10] = pwt->b[5];
4485     pwd->b[9]  = pws->b[4];
4486     pwd->b[8]  = pwt->b[4];
4487     pwd->b[7]  = pws->b[3];
4488     pwd->b[6]  = pwt->b[3];
4489     pwd->b[5]  = pws->b[2];
4490     pwd->b[4]  = pwt->b[2];
4491     pwd->b[3]  = pws->b[1];
4492     pwd->b[2]  = pwt->b[1];
4493     pwd->b[1]  = pws->b[0];
4494     pwd->b[0]  = pwt->b[0];
4495 #endif
4496 }
4497 
4498 void helper_msa_ilvr_h(CPUMIPSState *env,
4499                        uint32_t wd, uint32_t ws, uint32_t wt)
4500 {
4501     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4502     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4503     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4504 
4505 #if defined(HOST_WORDS_BIGENDIAN)
4506     pwd->h[4] = pws->h[0];
4507     pwd->h[5] = pwt->h[0];
4508     pwd->h[6] = pws->h[1];
4509     pwd->h[7] = pwt->h[1];
4510     pwd->h[0] = pws->h[2];
4511     pwd->h[1] = pwt->h[2];
4512     pwd->h[2] = pws->h[3];
4513     pwd->h[3] = pwt->h[3];
4514 #else
4515     pwd->h[7] = pws->h[3];
4516     pwd->h[6] = pwt->h[3];
4517     pwd->h[5] = pws->h[2];
4518     pwd->h[4] = pwt->h[2];
4519     pwd->h[3] = pws->h[1];
4520     pwd->h[2] = pwt->h[1];
4521     pwd->h[1] = pws->h[0];
4522     pwd->h[0] = pwt->h[0];
4523 #endif
4524 }
4525 
4526 void helper_msa_ilvr_w(CPUMIPSState *env,
4527                        uint32_t wd, uint32_t ws, uint32_t wt)
4528 {
4529     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4530     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4531     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4532 
4533 #if defined(HOST_WORDS_BIGENDIAN)
4534     pwd->w[2] = pws->w[0];
4535     pwd->w[3] = pwt->w[0];
4536     pwd->w[0] = pws->w[1];
4537     pwd->w[1] = pwt->w[1];
4538 #else
4539     pwd->w[3] = pws->w[1];
4540     pwd->w[2] = pwt->w[1];
4541     pwd->w[1] = pws->w[0];
4542     pwd->w[0] = pwt->w[0];
4543 #endif
4544 }
4545 
4546 void helper_msa_ilvr_d(CPUMIPSState *env,
4547                        uint32_t wd, uint32_t ws, uint32_t wt)
4548 {
4549     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4550     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4551     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4552 
4553     pwd->d[1] = pws->d[0];
4554     pwd->d[0] = pwt->d[0];
4555 }
4556 
4557 
4558 /*
4559  * Logic
4560  * -----
4561  *
4562  * +---------------+----------------------------------------------------------+
4563  * | AND.V         | Vector Logical And                                       |
4564  * | NOR.V         | Vector Logical Negated Or                                |
4565  * | OR.V          | Vector Logical Or                                        |
4566  * | XOR.V         | Vector Logical Exclusive Or                              |
4567  * +---------------+----------------------------------------------------------+
4568  */
4569 
4570 
4571 void helper_msa_and_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
4572 {
4573     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4574     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4575     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4576 
4577     pwd->d[0] = pws->d[0] & pwt->d[0];
4578     pwd->d[1] = pws->d[1] & pwt->d[1];
4579 }
4580 
4581 void helper_msa_nor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
4582 {
4583     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4584     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4585     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4586 
4587     pwd->d[0] = ~(pws->d[0] | pwt->d[0]);
4588     pwd->d[1] = ~(pws->d[1] | pwt->d[1]);
4589 }
4590 
4591 void helper_msa_or_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
4592 {
4593     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4594     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4595     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4596 
4597     pwd->d[0] = pws->d[0] | pwt->d[0];
4598     pwd->d[1] = pws->d[1] | pwt->d[1];
4599 }
4600 
4601 void helper_msa_xor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
4602 {
4603     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4604     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4605     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4606 
4607     pwd->d[0] = pws->d[0] ^ pwt->d[0];
4608     pwd->d[1] = pws->d[1] ^ pwt->d[1];
4609 }
4610 
4611 
4612 /*
4613  * Move
4614  * ----
4615  *
4616  * +---------------+----------------------------------------------------------+
4617  * | MOVE.V        | Vector Move                                              |
4618  * +---------------+----------------------------------------------------------+
4619  */
4620 
4621 static inline void msa_move_v(wr_t *pwd, wr_t *pws)
4622 {
4623     pwd->d[0] = pws->d[0];
4624     pwd->d[1] = pws->d[1];
4625 }
4626 
4627 void helper_msa_move_v(CPUMIPSState *env, uint32_t wd, uint32_t ws)
4628 {
4629     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4630     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4631 
4632     msa_move_v(pwd, pws);
4633 }
4634 
4635 
4636 /*
4637  * Pack
4638  * ----
4639  *
4640  * +---------------+----------------------------------------------------------+
4641  * | PCKEV.B       | Vector Pack Even (byte)                                  |
4642  * | PCKEV.H       | Vector Pack Even (halfword)                              |
4643  * | PCKEV.W       | Vector Pack Even (word)                                  |
4644  * | PCKEV.D       | Vector Pack Even (doubleword)                            |
4645  * | PCKOD.B       | Vector Pack Odd (byte)                                   |
4646  * | PCKOD.H       | Vector Pack Odd (halfword)                               |
4647  * | PCKOD.W       | Vector Pack Odd (word)                                   |
4648  * | PCKOD.D       | Vector Pack Odd (doubleword)                             |
4649  * | VSHF.B        | Vector Data Preserving Shuffle (byte)                    |
4650  * | VSHF.H        | Vector Data Preserving Shuffle (halfword)                |
4651  * | VSHF.W        | Vector Data Preserving Shuffle (word)                    |
4652  * | VSHF.D        | Vector Data Preserving Shuffle (doubleword)              |
4653  * +---------------+----------------------------------------------------------+
4654  */
4655 
4656 
4657 void helper_msa_pckev_b(CPUMIPSState *env,
4658                         uint32_t wd, uint32_t ws, uint32_t wt)
4659 {
4660     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4661     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4662     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4663 
4664 #if defined(HOST_WORDS_BIGENDIAN)
4665     pwd->b[8]  = pws->b[9];
4666     pwd->b[10] = pws->b[13];
4667     pwd->b[12] = pws->b[1];
4668     pwd->b[14] = pws->b[5];
4669     pwd->b[0]  = pwt->b[9];
4670     pwd->b[2]  = pwt->b[13];
4671     pwd->b[4]  = pwt->b[1];
4672     pwd->b[6]  = pwt->b[5];
4673     pwd->b[9]  = pws->b[11];
4674     pwd->b[13] = pws->b[3];
4675     pwd->b[1]  = pwt->b[11];
4676     pwd->b[5]  = pwt->b[3];
4677     pwd->b[11] = pws->b[15];
4678     pwd->b[3]  = pwt->b[15];
4679     pwd->b[15] = pws->b[7];
4680     pwd->b[7]  = pwt->b[7];
4681 #else
4682     pwd->b[15] = pws->b[14];
4683     pwd->b[13] = pws->b[10];
4684     pwd->b[11] = pws->b[6];
4685     pwd->b[9]  = pws->b[2];
4686     pwd->b[7]  = pwt->b[14];
4687     pwd->b[5]  = pwt->b[10];
4688     pwd->b[3]  = pwt->b[6];
4689     pwd->b[1]  = pwt->b[2];
4690     pwd->b[14] = pws->b[12];
4691     pwd->b[10] = pws->b[4];
4692     pwd->b[6]  = pwt->b[12];
4693     pwd->b[2]  = pwt->b[4];
4694     pwd->b[12] = pws->b[8];
4695     pwd->b[4]  = pwt->b[8];
4696     pwd->b[8]  = pws->b[0];
4697     pwd->b[0]  = pwt->b[0];
4698 #endif
4699 }
4700 
4701 void helper_msa_pckev_h(CPUMIPSState *env,
4702                         uint32_t wd, uint32_t ws, uint32_t wt)
4703 {
4704     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4705     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4706     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4707 
4708 #if defined(HOST_WORDS_BIGENDIAN)
4709     pwd->h[4] = pws->h[5];
4710     pwd->h[6] = pws->h[1];
4711     pwd->h[0] = pwt->h[5];
4712     pwd->h[2] = pwt->h[1];
4713     pwd->h[5] = pws->h[7];
4714     pwd->h[1] = pwt->h[7];
4715     pwd->h[7] = pws->h[3];
4716     pwd->h[3] = pwt->h[3];
4717 #else
4718     pwd->h[7] = pws->h[6];
4719     pwd->h[5] = pws->h[2];
4720     pwd->h[3] = pwt->h[6];
4721     pwd->h[1] = pwt->h[2];
4722     pwd->h[6] = pws->h[4];
4723     pwd->h[2] = pwt->h[4];
4724     pwd->h[4] = pws->h[0];
4725     pwd->h[0] = pwt->h[0];
4726 #endif
4727 }
4728 
4729 void helper_msa_pckev_w(CPUMIPSState *env,
4730                         uint32_t wd, uint32_t ws, uint32_t wt)
4731 {
4732     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4733     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4734     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4735 
4736 #if defined(HOST_WORDS_BIGENDIAN)
4737     pwd->w[2] = pws->w[3];
4738     pwd->w[0] = pwt->w[3];
4739     pwd->w[3] = pws->w[1];
4740     pwd->w[1] = pwt->w[1];
4741 #else
4742     pwd->w[3] = pws->w[2];
4743     pwd->w[1] = pwt->w[2];
4744     pwd->w[2] = pws->w[0];
4745     pwd->w[0] = pwt->w[0];
4746 #endif
4747 }
4748 
4749 void helper_msa_pckev_d(CPUMIPSState *env,
4750                         uint32_t wd, uint32_t ws, uint32_t wt)
4751 {
4752     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4753     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4754     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4755 
4756     pwd->d[1] = pws->d[0];
4757     pwd->d[0] = pwt->d[0];
4758 }
4759 
4760 
4761 void helper_msa_pckod_b(CPUMIPSState *env,
4762                         uint32_t wd, uint32_t ws, uint32_t wt)
4763 {
4764     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4765     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4766     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4767 
4768 #if defined(HOST_WORDS_BIGENDIAN)
4769     pwd->b[7]  = pwt->b[6];
4770     pwd->b[5]  = pwt->b[2];
4771     pwd->b[3]  = pwt->b[14];
4772     pwd->b[1]  = pwt->b[10];
4773     pwd->b[15] = pws->b[6];
4774     pwd->b[13] = pws->b[2];
4775     pwd->b[11] = pws->b[14];
4776     pwd->b[9]  = pws->b[10];
4777     pwd->b[6]  = pwt->b[4];
4778     pwd->b[2]  = pwt->b[12];
4779     pwd->b[14] = pws->b[4];
4780     pwd->b[10] = pws->b[12];
4781     pwd->b[4]  = pwt->b[0];
4782     pwd->b[12] = pws->b[0];
4783     pwd->b[0]  = pwt->b[8];
4784     pwd->b[8]  = pws->b[8];
4785 #else
4786     pwd->b[0]  = pwt->b[1];
4787     pwd->b[2]  = pwt->b[5];
4788     pwd->b[4]  = pwt->b[9];
4789     pwd->b[6]  = pwt->b[13];
4790     pwd->b[8]  = pws->b[1];
4791     pwd->b[10] = pws->b[5];
4792     pwd->b[12] = pws->b[9];
4793     pwd->b[14] = pws->b[13];
4794     pwd->b[1]  = pwt->b[3];
4795     pwd->b[5]  = pwt->b[11];
4796     pwd->b[9]  = pws->b[3];
4797     pwd->b[13] = pws->b[11];
4798     pwd->b[3]  = pwt->b[7];
4799     pwd->b[11] = pws->b[7];
4800     pwd->b[7]  = pwt->b[15];
4801     pwd->b[15] = pws->b[15];
4802 #endif
4803 
4804 }
4805 
4806 void helper_msa_pckod_h(CPUMIPSState *env,
4807                         uint32_t wd, uint32_t ws, uint32_t wt)
4808 {
4809     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4810     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4811     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4812 
4813 #if defined(HOST_WORDS_BIGENDIAN)
4814     pwd->h[3] = pwt->h[2];
4815     pwd->h[1] = pwt->h[6];
4816     pwd->h[7] = pws->h[2];
4817     pwd->h[5] = pws->h[6];
4818     pwd->h[2] = pwt->h[0];
4819     pwd->h[6] = pws->h[0];
4820     pwd->h[0] = pwt->h[4];
4821     pwd->h[4] = pws->h[4];
4822 #else
4823     pwd->h[0] = pwt->h[1];
4824     pwd->h[2] = pwt->h[5];
4825     pwd->h[4] = pws->h[1];
4826     pwd->h[6] = pws->h[5];
4827     pwd->h[1] = pwt->h[3];
4828     pwd->h[5] = pws->h[3];
4829     pwd->h[3] = pwt->h[7];
4830     pwd->h[7] = pws->h[7];
4831 #endif
4832 }
4833 
4834 void helper_msa_pckod_w(CPUMIPSState *env,
4835                         uint32_t wd, uint32_t ws, uint32_t wt)
4836 {
4837     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4838     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4839     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4840 
4841 #if defined(HOST_WORDS_BIGENDIAN)
4842     pwd->w[1] = pwt->w[0];
4843     pwd->w[3] = pws->w[0];
4844     pwd->w[0] = pwt->w[2];
4845     pwd->w[2] = pws->w[2];
4846 #else
4847     pwd->w[0] = pwt->w[1];
4848     pwd->w[2] = pws->w[1];
4849     pwd->w[1] = pwt->w[3];
4850     pwd->w[3] = pws->w[3];
4851 #endif
4852 }
4853 
4854 void helper_msa_pckod_d(CPUMIPSState *env,
4855                         uint32_t wd, uint32_t ws, uint32_t wt)
4856 {
4857     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4858     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4859     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4860 
4861     pwd->d[0] = pwt->d[1];
4862     pwd->d[1] = pws->d[1];
4863 }
4864 
4865 
4866 /*
4867  * Shift
4868  * -----
4869  *
4870  * +---------------+----------------------------------------------------------+
4871  * | SLL.B         | Vector Shift Left (byte)                                 |
4872  * | SLL.H         | Vector Shift Left (halfword)                             |
4873  * | SLL.W         | Vector Shift Left (word)                                 |
4874  * | SLL.D         | Vector Shift Left (doubleword)                           |
4875  * | SRA.B         | Vector Shift Right Arithmetic (byte)                     |
4876  * | SRA.H         | Vector Shift Right Arithmetic (halfword)                 |
4877  * | SRA.W         | Vector Shift Right Arithmetic (word)                     |
4878  * | SRA.D         | Vector Shift Right Arithmetic (doubleword)               |
4879  * | SRAR.B        | Vector Shift Right Arithmetic Rounded (byte)             |
4880  * | SRAR.H        | Vector Shift Right Arithmetic Rounded (halfword)         |
4881  * | SRAR.W        | Vector Shift Right Arithmetic Rounded (word)             |
4882  * | SRAR.D        | Vector Shift Right Arithmetic Rounded (doubleword)       |
4883  * | SRL.B         | Vector Shift Right Logical (byte)                        |
4884  * | SRL.H         | Vector Shift Right Logical (halfword)                    |
4885  * | SRL.W         | Vector Shift Right Logical (word)                        |
4886  * | SRL.D         | Vector Shift Right Logical (doubleword)                  |
4887  * | SRLR.B        | Vector Shift Right Logical Rounded (byte)                |
4888  * | SRLR.H        | Vector Shift Right Logical Rounded (halfword)            |
4889  * | SRLR.W        | Vector Shift Right Logical Rounded (word)                |
4890  * | SRLR.D        | Vector Shift Right Logical Rounded (doubleword)          |
4891  * +---------------+----------------------------------------------------------+
4892  */
4893 
4894 
4895 static inline int64_t msa_sll_df(uint32_t df, int64_t arg1, int64_t arg2)
4896 {
4897     int32_t b_arg2 = BIT_POSITION(arg2, df);
4898     return arg1 << b_arg2;
4899 }
4900 
4901 void helper_msa_sll_b(CPUMIPSState *env,
4902                       uint32_t wd, uint32_t ws, uint32_t wt)
4903 {
4904     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4905     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4906     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4907 
4908     pwd->b[0]  = msa_sll_df(DF_BYTE, pws->b[0],  pwt->b[0]);
4909     pwd->b[1]  = msa_sll_df(DF_BYTE, pws->b[1],  pwt->b[1]);
4910     pwd->b[2]  = msa_sll_df(DF_BYTE, pws->b[2],  pwt->b[2]);
4911     pwd->b[3]  = msa_sll_df(DF_BYTE, pws->b[3],  pwt->b[3]);
4912     pwd->b[4]  = msa_sll_df(DF_BYTE, pws->b[4],  pwt->b[4]);
4913     pwd->b[5]  = msa_sll_df(DF_BYTE, pws->b[5],  pwt->b[5]);
4914     pwd->b[6]  = msa_sll_df(DF_BYTE, pws->b[6],  pwt->b[6]);
4915     pwd->b[7]  = msa_sll_df(DF_BYTE, pws->b[7],  pwt->b[7]);
4916     pwd->b[8]  = msa_sll_df(DF_BYTE, pws->b[8],  pwt->b[8]);
4917     pwd->b[9]  = msa_sll_df(DF_BYTE, pws->b[9],  pwt->b[9]);
4918     pwd->b[10] = msa_sll_df(DF_BYTE, pws->b[10], pwt->b[10]);
4919     pwd->b[11] = msa_sll_df(DF_BYTE, pws->b[11], pwt->b[11]);
4920     pwd->b[12] = msa_sll_df(DF_BYTE, pws->b[12], pwt->b[12]);
4921     pwd->b[13] = msa_sll_df(DF_BYTE, pws->b[13], pwt->b[13]);
4922     pwd->b[14] = msa_sll_df(DF_BYTE, pws->b[14], pwt->b[14]);
4923     pwd->b[15] = msa_sll_df(DF_BYTE, pws->b[15], pwt->b[15]);
4924 }
4925 
4926 void helper_msa_sll_h(CPUMIPSState *env,
4927                       uint32_t wd, uint32_t ws, uint32_t wt)
4928 {
4929     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4930     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4931     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4932 
4933     pwd->h[0]  = msa_sll_df(DF_HALF, pws->h[0],  pwt->h[0]);
4934     pwd->h[1]  = msa_sll_df(DF_HALF, pws->h[1],  pwt->h[1]);
4935     pwd->h[2]  = msa_sll_df(DF_HALF, pws->h[2],  pwt->h[2]);
4936     pwd->h[3]  = msa_sll_df(DF_HALF, pws->h[3],  pwt->h[3]);
4937     pwd->h[4]  = msa_sll_df(DF_HALF, pws->h[4],  pwt->h[4]);
4938     pwd->h[5]  = msa_sll_df(DF_HALF, pws->h[5],  pwt->h[5]);
4939     pwd->h[6]  = msa_sll_df(DF_HALF, pws->h[6],  pwt->h[6]);
4940     pwd->h[7]  = msa_sll_df(DF_HALF, pws->h[7],  pwt->h[7]);
4941 }
4942 
4943 void helper_msa_sll_w(CPUMIPSState *env,
4944                       uint32_t wd, uint32_t ws, uint32_t wt)
4945 {
4946     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4947     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4948     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4949 
4950     pwd->w[0]  = msa_sll_df(DF_WORD, pws->w[0],  pwt->w[0]);
4951     pwd->w[1]  = msa_sll_df(DF_WORD, pws->w[1],  pwt->w[1]);
4952     pwd->w[2]  = msa_sll_df(DF_WORD, pws->w[2],  pwt->w[2]);
4953     pwd->w[3]  = msa_sll_df(DF_WORD, pws->w[3],  pwt->w[3]);
4954 }
4955 
4956 void helper_msa_sll_d(CPUMIPSState *env,
4957                       uint32_t wd, uint32_t ws, uint32_t wt)
4958 {
4959     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4960     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4961     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4962 
4963     pwd->d[0]  = msa_sll_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
4964     pwd->d[1]  = msa_sll_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
4965 }
4966 
4967 
4968 static inline int64_t msa_sra_df(uint32_t df, int64_t arg1, int64_t arg2)
4969 {
4970     int32_t b_arg2 = BIT_POSITION(arg2, df);
4971     return arg1 >> b_arg2;
4972 }
4973 
4974 void helper_msa_sra_b(CPUMIPSState *env,
4975                       uint32_t wd, uint32_t ws, uint32_t wt)
4976 {
4977     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4978     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4979     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4980 
4981     pwd->b[0]  = msa_sra_df(DF_BYTE, pws->b[0],  pwt->b[0]);
4982     pwd->b[1]  = msa_sra_df(DF_BYTE, pws->b[1],  pwt->b[1]);
4983     pwd->b[2]  = msa_sra_df(DF_BYTE, pws->b[2],  pwt->b[2]);
4984     pwd->b[3]  = msa_sra_df(DF_BYTE, pws->b[3],  pwt->b[3]);
4985     pwd->b[4]  = msa_sra_df(DF_BYTE, pws->b[4],  pwt->b[4]);
4986     pwd->b[5]  = msa_sra_df(DF_BYTE, pws->b[5],  pwt->b[5]);
4987     pwd->b[6]  = msa_sra_df(DF_BYTE, pws->b[6],  pwt->b[6]);
4988     pwd->b[7]  = msa_sra_df(DF_BYTE, pws->b[7],  pwt->b[7]);
4989     pwd->b[8]  = msa_sra_df(DF_BYTE, pws->b[8],  pwt->b[8]);
4990     pwd->b[9]  = msa_sra_df(DF_BYTE, pws->b[9],  pwt->b[9]);
4991     pwd->b[10] = msa_sra_df(DF_BYTE, pws->b[10], pwt->b[10]);
4992     pwd->b[11] = msa_sra_df(DF_BYTE, pws->b[11], pwt->b[11]);
4993     pwd->b[12] = msa_sra_df(DF_BYTE, pws->b[12], pwt->b[12]);
4994     pwd->b[13] = msa_sra_df(DF_BYTE, pws->b[13], pwt->b[13]);
4995     pwd->b[14] = msa_sra_df(DF_BYTE, pws->b[14], pwt->b[14]);
4996     pwd->b[15] = msa_sra_df(DF_BYTE, pws->b[15], pwt->b[15]);
4997 }
4998 
4999 void helper_msa_sra_h(CPUMIPSState *env,
5000                       uint32_t wd, uint32_t ws, uint32_t wt)
5001 {
5002     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5003     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5004     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5005 
5006     pwd->h[0]  = msa_sra_df(DF_HALF, pws->h[0],  pwt->h[0]);
5007     pwd->h[1]  = msa_sra_df(DF_HALF, pws->h[1],  pwt->h[1]);
5008     pwd->h[2]  = msa_sra_df(DF_HALF, pws->h[2],  pwt->h[2]);
5009     pwd->h[3]  = msa_sra_df(DF_HALF, pws->h[3],  pwt->h[3]);
5010     pwd->h[4]  = msa_sra_df(DF_HALF, pws->h[4],  pwt->h[4]);
5011     pwd->h[5]  = msa_sra_df(DF_HALF, pws->h[5],  pwt->h[5]);
5012     pwd->h[6]  = msa_sra_df(DF_HALF, pws->h[6],  pwt->h[6]);
5013     pwd->h[7]  = msa_sra_df(DF_HALF, pws->h[7],  pwt->h[7]);
5014 }
5015 
5016 void helper_msa_sra_w(CPUMIPSState *env,
5017                       uint32_t wd, uint32_t ws, uint32_t wt)
5018 {
5019     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5020     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5021     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5022 
5023     pwd->w[0]  = msa_sra_df(DF_WORD, pws->w[0],  pwt->w[0]);
5024     pwd->w[1]  = msa_sra_df(DF_WORD, pws->w[1],  pwt->w[1]);
5025     pwd->w[2]  = msa_sra_df(DF_WORD, pws->w[2],  pwt->w[2]);
5026     pwd->w[3]  = msa_sra_df(DF_WORD, pws->w[3],  pwt->w[3]);
5027 }
5028 
5029 void helper_msa_sra_d(CPUMIPSState *env,
5030                       uint32_t wd, uint32_t ws, uint32_t wt)
5031 {
5032     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5033     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5034     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5035 
5036     pwd->d[0]  = msa_sra_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
5037     pwd->d[1]  = msa_sra_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
5038 }
5039 
5040 
5041 static inline int64_t msa_srar_df(uint32_t df, int64_t arg1, int64_t arg2)
5042 {
5043     int32_t b_arg2 = BIT_POSITION(arg2, df);
5044     if (b_arg2 == 0) {
5045         return arg1;
5046     } else {
5047         int64_t r_bit = (arg1 >> (b_arg2 - 1)) & 1;
5048         return (arg1 >> b_arg2) + r_bit;
5049     }
5050 }
5051 
5052 void helper_msa_srar_b(CPUMIPSState *env,
5053                        uint32_t wd, uint32_t ws, uint32_t wt)
5054 {
5055     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5056     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5057     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5058 
5059     pwd->b[0]  = msa_srar_df(DF_BYTE, pws->b[0],  pwt->b[0]);
5060     pwd->b[1]  = msa_srar_df(DF_BYTE, pws->b[1],  pwt->b[1]);
5061     pwd->b[2]  = msa_srar_df(DF_BYTE, pws->b[2],  pwt->b[2]);
5062     pwd->b[3]  = msa_srar_df(DF_BYTE, pws->b[3],  pwt->b[3]);
5063     pwd->b[4]  = msa_srar_df(DF_BYTE, pws->b[4],  pwt->b[4]);
5064     pwd->b[5]  = msa_srar_df(DF_BYTE, pws->b[5],  pwt->b[5]);
5065     pwd->b[6]  = msa_srar_df(DF_BYTE, pws->b[6],  pwt->b[6]);
5066     pwd->b[7]  = msa_srar_df(DF_BYTE, pws->b[7],  pwt->b[7]);
5067     pwd->b[8]  = msa_srar_df(DF_BYTE, pws->b[8],  pwt->b[8]);
5068     pwd->b[9]  = msa_srar_df(DF_BYTE, pws->b[9],  pwt->b[9]);
5069     pwd->b[10] = msa_srar_df(DF_BYTE, pws->b[10], pwt->b[10]);
5070     pwd->b[11] = msa_srar_df(DF_BYTE, pws->b[11], pwt->b[11]);
5071     pwd->b[12] = msa_srar_df(DF_BYTE, pws->b[12], pwt->b[12]);
5072     pwd->b[13] = msa_srar_df(DF_BYTE, pws->b[13], pwt->b[13]);
5073     pwd->b[14] = msa_srar_df(DF_BYTE, pws->b[14], pwt->b[14]);
5074     pwd->b[15] = msa_srar_df(DF_BYTE, pws->b[15], pwt->b[15]);
5075 }
5076 
5077 void helper_msa_srar_h(CPUMIPSState *env,
5078                        uint32_t wd, uint32_t ws, uint32_t wt)
5079 {
5080     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5081     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5082     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5083 
5084     pwd->h[0]  = msa_srar_df(DF_HALF, pws->h[0],  pwt->h[0]);
5085     pwd->h[1]  = msa_srar_df(DF_HALF, pws->h[1],  pwt->h[1]);
5086     pwd->h[2]  = msa_srar_df(DF_HALF, pws->h[2],  pwt->h[2]);
5087     pwd->h[3]  = msa_srar_df(DF_HALF, pws->h[3],  pwt->h[3]);
5088     pwd->h[4]  = msa_srar_df(DF_HALF, pws->h[4],  pwt->h[4]);
5089     pwd->h[5]  = msa_srar_df(DF_HALF, pws->h[5],  pwt->h[5]);
5090     pwd->h[6]  = msa_srar_df(DF_HALF, pws->h[6],  pwt->h[6]);
5091     pwd->h[7]  = msa_srar_df(DF_HALF, pws->h[7],  pwt->h[7]);
5092 }
5093 
5094 void helper_msa_srar_w(CPUMIPSState *env,
5095                        uint32_t wd, uint32_t ws, uint32_t wt)
5096 {
5097     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5098     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5099     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5100 
5101     pwd->w[0]  = msa_srar_df(DF_WORD, pws->w[0],  pwt->w[0]);
5102     pwd->w[1]  = msa_srar_df(DF_WORD, pws->w[1],  pwt->w[1]);
5103     pwd->w[2]  = msa_srar_df(DF_WORD, pws->w[2],  pwt->w[2]);
5104     pwd->w[3]  = msa_srar_df(DF_WORD, pws->w[3],  pwt->w[3]);
5105 }
5106 
5107 void helper_msa_srar_d(CPUMIPSState *env,
5108                        uint32_t wd, uint32_t ws, uint32_t wt)
5109 {
5110     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5111     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5112     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5113 
5114     pwd->d[0]  = msa_srar_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
5115     pwd->d[1]  = msa_srar_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
5116 }
5117 
5118 
5119 static inline int64_t msa_srl_df(uint32_t df, int64_t arg1, int64_t arg2)
5120 {
5121     uint64_t u_arg1 = UNSIGNED(arg1, df);
5122     int32_t b_arg2 = BIT_POSITION(arg2, df);
5123     return u_arg1 >> b_arg2;
5124 }
5125 
5126 void helper_msa_srl_b(CPUMIPSState *env,
5127                       uint32_t wd, uint32_t ws, uint32_t wt)
5128 {
5129     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5130     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5131     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5132 
5133     pwd->b[0]  = msa_srl_df(DF_BYTE, pws->b[0],  pwt->b[0]);
5134     pwd->b[1]  = msa_srl_df(DF_BYTE, pws->b[1],  pwt->b[1]);
5135     pwd->b[2]  = msa_srl_df(DF_BYTE, pws->b[2],  pwt->b[2]);
5136     pwd->b[3]  = msa_srl_df(DF_BYTE, pws->b[3],  pwt->b[3]);
5137     pwd->b[4]  = msa_srl_df(DF_BYTE, pws->b[4],  pwt->b[4]);
5138     pwd->b[5]  = msa_srl_df(DF_BYTE, pws->b[5],  pwt->b[5]);
5139     pwd->b[6]  = msa_srl_df(DF_BYTE, pws->b[6],  pwt->b[6]);
5140     pwd->b[7]  = msa_srl_df(DF_BYTE, pws->b[7],  pwt->b[7]);
5141     pwd->b[8]  = msa_srl_df(DF_BYTE, pws->b[8],  pwt->b[8]);
5142     pwd->b[9]  = msa_srl_df(DF_BYTE, pws->b[9],  pwt->b[9]);
5143     pwd->b[10] = msa_srl_df(DF_BYTE, pws->b[10], pwt->b[10]);
5144     pwd->b[11] = msa_srl_df(DF_BYTE, pws->b[11], pwt->b[11]);
5145     pwd->b[12] = msa_srl_df(DF_BYTE, pws->b[12], pwt->b[12]);
5146     pwd->b[13] = msa_srl_df(DF_BYTE, pws->b[13], pwt->b[13]);
5147     pwd->b[14] = msa_srl_df(DF_BYTE, pws->b[14], pwt->b[14]);
5148     pwd->b[15] = msa_srl_df(DF_BYTE, pws->b[15], pwt->b[15]);
5149 }
5150 
5151 void helper_msa_srl_h(CPUMIPSState *env,
5152                       uint32_t wd, uint32_t ws, uint32_t wt)
5153 {
5154     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5155     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5156     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5157 
5158     pwd->h[0]  = msa_srl_df(DF_HALF, pws->h[0],  pwt->h[0]);
5159     pwd->h[1]  = msa_srl_df(DF_HALF, pws->h[1],  pwt->h[1]);
5160     pwd->h[2]  = msa_srl_df(DF_HALF, pws->h[2],  pwt->h[2]);
5161     pwd->h[3]  = msa_srl_df(DF_HALF, pws->h[3],  pwt->h[3]);
5162     pwd->h[4]  = msa_srl_df(DF_HALF, pws->h[4],  pwt->h[4]);
5163     pwd->h[5]  = msa_srl_df(DF_HALF, pws->h[5],  pwt->h[5]);
5164     pwd->h[6]  = msa_srl_df(DF_HALF, pws->h[6],  pwt->h[6]);
5165     pwd->h[7]  = msa_srl_df(DF_HALF, pws->h[7],  pwt->h[7]);
5166 }
5167 
5168 void helper_msa_srl_w(CPUMIPSState *env,
5169                       uint32_t wd, uint32_t ws, uint32_t wt)
5170 {
5171     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5172     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5173     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5174 
5175     pwd->w[0]  = msa_srl_df(DF_WORD, pws->w[0],  pwt->w[0]);
5176     pwd->w[1]  = msa_srl_df(DF_WORD, pws->w[1],  pwt->w[1]);
5177     pwd->w[2]  = msa_srl_df(DF_WORD, pws->w[2],  pwt->w[2]);
5178     pwd->w[3]  = msa_srl_df(DF_WORD, pws->w[3],  pwt->w[3]);
5179 }
5180 
5181 void helper_msa_srl_d(CPUMIPSState *env,
5182                       uint32_t wd, uint32_t ws, uint32_t wt)
5183 {
5184     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5185     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5186     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5187 
5188     pwd->d[0]  = msa_srl_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
5189     pwd->d[1]  = msa_srl_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
5190 }
5191 
5192 
5193 static inline int64_t msa_srlr_df(uint32_t df, int64_t arg1, int64_t arg2)
5194 {
5195     uint64_t u_arg1 = UNSIGNED(arg1, df);
5196     int32_t b_arg2 = BIT_POSITION(arg2, df);
5197     if (b_arg2 == 0) {
5198         return u_arg1;
5199     } else {
5200         uint64_t r_bit = (u_arg1 >> (b_arg2 - 1)) & 1;
5201         return (u_arg1 >> b_arg2) + r_bit;
5202     }
5203 }
5204 
5205 void helper_msa_srlr_b(CPUMIPSState *env,
5206                        uint32_t wd, uint32_t ws, uint32_t wt)
5207 {
5208     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5209     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5210     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5211 
5212     pwd->b[0]  = msa_srlr_df(DF_BYTE, pws->b[0],  pwt->b[0]);
5213     pwd->b[1]  = msa_srlr_df(DF_BYTE, pws->b[1],  pwt->b[1]);
5214     pwd->b[2]  = msa_srlr_df(DF_BYTE, pws->b[2],  pwt->b[2]);
5215     pwd->b[3]  = msa_srlr_df(DF_BYTE, pws->b[3],  pwt->b[3]);
5216     pwd->b[4]  = msa_srlr_df(DF_BYTE, pws->b[4],  pwt->b[4]);
5217     pwd->b[5]  = msa_srlr_df(DF_BYTE, pws->b[5],  pwt->b[5]);
5218     pwd->b[6]  = msa_srlr_df(DF_BYTE, pws->b[6],  pwt->b[6]);
5219     pwd->b[7]  = msa_srlr_df(DF_BYTE, pws->b[7],  pwt->b[7]);
5220     pwd->b[8]  = msa_srlr_df(DF_BYTE, pws->b[8],  pwt->b[8]);
5221     pwd->b[9]  = msa_srlr_df(DF_BYTE, pws->b[9],  pwt->b[9]);
5222     pwd->b[10] = msa_srlr_df(DF_BYTE, pws->b[10], pwt->b[10]);
5223     pwd->b[11] = msa_srlr_df(DF_BYTE, pws->b[11], pwt->b[11]);
5224     pwd->b[12] = msa_srlr_df(DF_BYTE, pws->b[12], pwt->b[12]);
5225     pwd->b[13] = msa_srlr_df(DF_BYTE, pws->b[13], pwt->b[13]);
5226     pwd->b[14] = msa_srlr_df(DF_BYTE, pws->b[14], pwt->b[14]);
5227     pwd->b[15] = msa_srlr_df(DF_BYTE, pws->b[15], pwt->b[15]);
5228 }
5229 
5230 void helper_msa_srlr_h(CPUMIPSState *env,
5231                        uint32_t wd, uint32_t ws, uint32_t wt)
5232 {
5233     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5234     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5235     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5236 
5237     pwd->h[0]  = msa_srlr_df(DF_HALF, pws->h[0],  pwt->h[0]);
5238     pwd->h[1]  = msa_srlr_df(DF_HALF, pws->h[1],  pwt->h[1]);
5239     pwd->h[2]  = msa_srlr_df(DF_HALF, pws->h[2],  pwt->h[2]);
5240     pwd->h[3]  = msa_srlr_df(DF_HALF, pws->h[3],  pwt->h[3]);
5241     pwd->h[4]  = msa_srlr_df(DF_HALF, pws->h[4],  pwt->h[4]);
5242     pwd->h[5]  = msa_srlr_df(DF_HALF, pws->h[5],  pwt->h[5]);
5243     pwd->h[6]  = msa_srlr_df(DF_HALF, pws->h[6],  pwt->h[6]);
5244     pwd->h[7]  = msa_srlr_df(DF_HALF, pws->h[7],  pwt->h[7]);
5245 }
5246 
5247 void helper_msa_srlr_w(CPUMIPSState *env,
5248                        uint32_t wd, uint32_t ws, uint32_t wt)
5249 {
5250     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5251     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5252     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5253 
5254     pwd->w[0]  = msa_srlr_df(DF_WORD, pws->w[0],  pwt->w[0]);
5255     pwd->w[1]  = msa_srlr_df(DF_WORD, pws->w[1],  pwt->w[1]);
5256     pwd->w[2]  = msa_srlr_df(DF_WORD, pws->w[2],  pwt->w[2]);
5257     pwd->w[3]  = msa_srlr_df(DF_WORD, pws->w[3],  pwt->w[3]);
5258 }
5259 
5260 void helper_msa_srlr_d(CPUMIPSState *env,
5261                        uint32_t wd, uint32_t ws, uint32_t wt)
5262 {
5263     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5264     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5265     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
5266 
5267     pwd->d[0]  = msa_srlr_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
5268     pwd->d[1]  = msa_srlr_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
5269 }
5270 
5271 
5272 #define MSA_FN_IMM8(FUNC, DEST, OPERATION)                              \
5273 void helper_msa_ ## FUNC(CPUMIPSState *env, uint32_t wd, uint32_t ws,   \
5274         uint32_t i8)                                                    \
5275 {                                                                       \
5276     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
5277     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
5278     uint32_t i;                                                         \
5279     for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {                        \
5280         DEST = OPERATION;                                               \
5281     }                                                                   \
5282 }
5283 
5284 MSA_FN_IMM8(andi_b, pwd->b[i], pws->b[i] & i8)
5285 MSA_FN_IMM8(ori_b, pwd->b[i], pws->b[i] | i8)
5286 MSA_FN_IMM8(nori_b, pwd->b[i], ~(pws->b[i] | i8))
5287 MSA_FN_IMM8(xori_b, pwd->b[i], pws->b[i] ^ i8)
5288 
5289 #define BIT_MOVE_IF_NOT_ZERO(dest, arg1, arg2, df) \
5290             UNSIGNED(((dest & (~arg2)) | (arg1 & arg2)), df)
5291 MSA_FN_IMM8(bmnzi_b, pwd->b[i],
5292         BIT_MOVE_IF_NOT_ZERO(pwd->b[i], pws->b[i], i8, DF_BYTE))
5293 
5294 #define BIT_MOVE_IF_ZERO(dest, arg1, arg2, df) \
5295             UNSIGNED((dest & arg2) | (arg1 & (~arg2)), df)
5296 MSA_FN_IMM8(bmzi_b, pwd->b[i],
5297         BIT_MOVE_IF_ZERO(pwd->b[i], pws->b[i], i8, DF_BYTE))
5298 
5299 #define BIT_SELECT(dest, arg1, arg2, df) \
5300             UNSIGNED((arg1 & (~dest)) | (arg2 & dest), df)
5301 MSA_FN_IMM8(bseli_b, pwd->b[i],
5302         BIT_SELECT(pwd->b[i], pws->b[i], i8, DF_BYTE))
5303 
5304 #undef BIT_SELECT
5305 #undef BIT_MOVE_IF_ZERO
5306 #undef BIT_MOVE_IF_NOT_ZERO
5307 #undef MSA_FN_IMM8
5308 
5309 #define SHF_POS(i, imm) (((i) & 0xfc) + (((imm) >> (2 * ((i) & 0x03))) & 0x03))
5310 
5311 void helper_msa_shf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5312                        uint32_t ws, uint32_t imm)
5313 {
5314     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5315     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5316     wr_t wx, *pwx = &wx;
5317     uint32_t i;
5318 
5319     switch (df) {
5320     case DF_BYTE:
5321         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
5322             pwx->b[i] = pws->b[SHF_POS(i, imm)];
5323         }
5324         break;
5325     case DF_HALF:
5326         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
5327             pwx->h[i] = pws->h[SHF_POS(i, imm)];
5328         }
5329         break;
5330     case DF_WORD:
5331         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5332             pwx->w[i] = pws->w[SHF_POS(i, imm)];
5333         }
5334         break;
5335     default:
5336         assert(0);
5337     }
5338     msa_move_v(pwd, pwx);
5339 }
5340 
5341 #define MSA_BINOP_IMM_DF(helper, func)                                  \
5342 void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df,       \
5343                         uint32_t wd, uint32_t ws, int32_t u5)           \
5344 {                                                                       \
5345     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
5346     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
5347     uint32_t i;                                                         \
5348                                                                         \
5349     switch (df) {                                                       \
5350     case DF_BYTE:                                                       \
5351         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {                    \
5352             pwd->b[i] = msa_ ## func ## _df(df, pws->b[i], u5);         \
5353         }                                                               \
5354         break;                                                          \
5355     case DF_HALF:                                                       \
5356         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {                    \
5357             pwd->h[i] = msa_ ## func ## _df(df, pws->h[i], u5);         \
5358         }                                                               \
5359         break;                                                          \
5360     case DF_WORD:                                                       \
5361         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {                    \
5362             pwd->w[i] = msa_ ## func ## _df(df, pws->w[i], u5);         \
5363         }                                                               \
5364         break;                                                          \
5365     case DF_DOUBLE:                                                     \
5366         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {                  \
5367             pwd->d[i] = msa_ ## func ## _df(df, pws->d[i], u5);         \
5368         }                                                               \
5369         break;                                                          \
5370     default:                                                            \
5371         assert(0);                                                      \
5372     }                                                                   \
5373 }
5374 
5375 MSA_BINOP_IMM_DF(addvi, addv)
5376 MSA_BINOP_IMM_DF(subvi, subv)
5377 MSA_BINOP_IMM_DF(ceqi, ceq)
5378 MSA_BINOP_IMM_DF(clei_s, cle_s)
5379 MSA_BINOP_IMM_DF(clei_u, cle_u)
5380 MSA_BINOP_IMM_DF(clti_s, clt_s)
5381 MSA_BINOP_IMM_DF(clti_u, clt_u)
5382 MSA_BINOP_IMM_DF(maxi_s, max_s)
5383 MSA_BINOP_IMM_DF(maxi_u, max_u)
5384 MSA_BINOP_IMM_DF(mini_s, min_s)
5385 MSA_BINOP_IMM_DF(mini_u, min_u)
5386 #undef MSA_BINOP_IMM_DF
5387 
5388 void helper_msa_ldi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5389                        int32_t s10)
5390 {
5391     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5392     uint32_t i;
5393 
5394     switch (df) {
5395     case DF_BYTE:
5396         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
5397             pwd->b[i] = (int8_t)s10;
5398         }
5399         break;
5400     case DF_HALF:
5401         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
5402             pwd->h[i] = (int16_t)s10;
5403         }
5404         break;
5405     case DF_WORD:
5406         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5407             pwd->w[i] = (int32_t)s10;
5408         }
5409         break;
5410     case DF_DOUBLE:
5411         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5412             pwd->d[i] = (int64_t)s10;
5413         }
5414        break;
5415     default:
5416         assert(0);
5417     }
5418 }
5419 
5420 static inline int64_t msa_sat_s_df(uint32_t df, int64_t arg, uint32_t m)
5421 {
5422     return arg < M_MIN_INT(m + 1) ? M_MIN_INT(m + 1) :
5423                                     arg > M_MAX_INT(m + 1) ? M_MAX_INT(m + 1) :
5424                                                              arg;
5425 }
5426 
5427 static inline int64_t msa_sat_u_df(uint32_t df, int64_t arg, uint32_t m)
5428 {
5429     uint64_t u_arg = UNSIGNED(arg, df);
5430     return  u_arg < M_MAX_UINT(m + 1) ? u_arg :
5431                                         M_MAX_UINT(m + 1);
5432 }
5433 
5434 #define MSA_BINOP_IMMU_DF(helper, func)                                  \
5435 void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, uint32_t wd, \
5436                        uint32_t ws, uint32_t u5)                        \
5437 {                                                                       \
5438     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
5439     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
5440     uint32_t i;                                                         \
5441                                                                         \
5442     switch (df) {                                                       \
5443     case DF_BYTE:                                                       \
5444         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {                    \
5445             pwd->b[i] = msa_ ## func ## _df(df, pws->b[i], u5);         \
5446         }                                                               \
5447         break;                                                          \
5448     case DF_HALF:                                                       \
5449         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {                    \
5450             pwd->h[i] = msa_ ## func ## _df(df, pws->h[i], u5);         \
5451         }                                                               \
5452         break;                                                          \
5453     case DF_WORD:                                                       \
5454         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {                    \
5455             pwd->w[i] = msa_ ## func ## _df(df, pws->w[i], u5);         \
5456         }                                                               \
5457         break;                                                          \
5458     case DF_DOUBLE:                                                     \
5459         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {                  \
5460             pwd->d[i] = msa_ ## func ## _df(df, pws->d[i], u5);         \
5461         }                                                               \
5462         break;                                                          \
5463     default:                                                            \
5464         assert(0);                                                      \
5465     }                                                                   \
5466 }
5467 
5468 MSA_BINOP_IMMU_DF(slli, sll)
5469 MSA_BINOP_IMMU_DF(srai, sra)
5470 MSA_BINOP_IMMU_DF(srli, srl)
5471 MSA_BINOP_IMMU_DF(bclri, bclr)
5472 MSA_BINOP_IMMU_DF(bseti, bset)
5473 MSA_BINOP_IMMU_DF(bnegi, bneg)
5474 MSA_BINOP_IMMU_DF(sat_s, sat_s)
5475 MSA_BINOP_IMMU_DF(sat_u, sat_u)
5476 MSA_BINOP_IMMU_DF(srari, srar)
5477 MSA_BINOP_IMMU_DF(srlri, srlr)
5478 #undef MSA_BINOP_IMMU_DF
5479 
5480 #define MSA_TEROP_IMMU_DF(helper, func)                                  \
5481 void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df,       \
5482                                   uint32_t wd, uint32_t ws, uint32_t u5) \
5483 {                                                                       \
5484     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
5485     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
5486     uint32_t i;                                                         \
5487                                                                         \
5488     switch (df) {                                                       \
5489     case DF_BYTE:                                                       \
5490         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {                    \
5491             pwd->b[i] = msa_ ## func ## _df(df, pwd->b[i], pws->b[i],   \
5492                                             u5);                        \
5493         }                                                               \
5494         break;                                                          \
5495     case DF_HALF:                                                       \
5496         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {                    \
5497             pwd->h[i] = msa_ ## func ## _df(df, pwd->h[i], pws->h[i],   \
5498                                             u5);                        \
5499         }                                                               \
5500         break;                                                          \
5501     case DF_WORD:                                                       \
5502         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {                    \
5503             pwd->w[i] = msa_ ## func ## _df(df, pwd->w[i], pws->w[i],   \
5504                                             u5);                        \
5505         }                                                               \
5506         break;                                                          \
5507     case DF_DOUBLE:                                                     \
5508         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {                  \
5509             pwd->d[i] = msa_ ## func ## _df(df, pwd->d[i], pws->d[i],   \
5510                                             u5);                        \
5511         }                                                               \
5512         break;                                                          \
5513     default:                                                            \
5514         assert(0);                                                      \
5515     }                                                                   \
5516 }
5517 
5518 MSA_TEROP_IMMU_DF(binsli, binsl)
5519 MSA_TEROP_IMMU_DF(binsri, binsr)
5520 #undef MSA_TEROP_IMMU_DF
5521 
5522 #define CONCATENATE_AND_SLIDE(s, k)             \
5523     do {                                        \
5524         for (i = 0; i < s; i++) {               \
5525             v[i]     = pws->b[s * k + i];       \
5526             v[i + s] = pwd->b[s * k + i];       \
5527         }                                       \
5528         for (i = 0; i < s; i++) {               \
5529             pwd->b[s * k + i] = v[i + n];       \
5530         }                                       \
5531     } while (0)
5532 
5533 static inline void msa_sld_df(uint32_t df, wr_t *pwd,
5534                               wr_t *pws, target_ulong rt)
5535 {
5536     uint32_t n = rt % DF_ELEMENTS(df);
5537     uint8_t v[64];
5538     uint32_t i, k;
5539 
5540     switch (df) {
5541     case DF_BYTE:
5542         CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_BYTE), 0);
5543         break;
5544     case DF_HALF:
5545         for (k = 0; k < 2; k++) {
5546             CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_HALF), k);
5547         }
5548         break;
5549     case DF_WORD:
5550         for (k = 0; k < 4; k++) {
5551             CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_WORD), k);
5552         }
5553         break;
5554     case DF_DOUBLE:
5555         for (k = 0; k < 8; k++) {
5556             CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_DOUBLE), k);
5557         }
5558         break;
5559     default:
5560         assert(0);
5561     }
5562 }
5563 
5564 static inline int64_t msa_mul_q_df(uint32_t df, int64_t arg1, int64_t arg2)
5565 {
5566     int64_t q_min = DF_MIN_INT(df);
5567     int64_t q_max = DF_MAX_INT(df);
5568 
5569     if (arg1 == q_min && arg2 == q_min) {
5570         return q_max;
5571     }
5572     return (arg1 * arg2) >> (DF_BITS(df) - 1);
5573 }
5574 
5575 static inline int64_t msa_mulr_q_df(uint32_t df, int64_t arg1, int64_t arg2)
5576 {
5577     int64_t q_min = DF_MIN_INT(df);
5578     int64_t q_max = DF_MAX_INT(df);
5579     int64_t r_bit = 1 << (DF_BITS(df) - 2);
5580 
5581     if (arg1 == q_min && arg2 == q_min) {
5582         return q_max;
5583     }
5584     return (arg1 * arg2 + r_bit) >> (DF_BITS(df) - 1);
5585 }
5586 
5587 #define MSA_BINOP_DF(func) \
5588 void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df,         \
5589                                 uint32_t wd, uint32_t ws, uint32_t wt)  \
5590 {                                                                       \
5591     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
5592     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
5593     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);                          \
5594                                                                         \
5595     switch (df) {                                                       \
5596     case DF_BYTE:                                                       \
5597         pwd->b[0]  = msa_ ## func ## _df(df, pws->b[0],  pwt->b[0]);    \
5598         pwd->b[1]  = msa_ ## func ## _df(df, pws->b[1],  pwt->b[1]);    \
5599         pwd->b[2]  = msa_ ## func ## _df(df, pws->b[2],  pwt->b[2]);    \
5600         pwd->b[3]  = msa_ ## func ## _df(df, pws->b[3],  pwt->b[3]);    \
5601         pwd->b[4]  = msa_ ## func ## _df(df, pws->b[4],  pwt->b[4]);    \
5602         pwd->b[5]  = msa_ ## func ## _df(df, pws->b[5],  pwt->b[5]);    \
5603         pwd->b[6]  = msa_ ## func ## _df(df, pws->b[6],  pwt->b[6]);    \
5604         pwd->b[7]  = msa_ ## func ## _df(df, pws->b[7],  pwt->b[7]);    \
5605         pwd->b[8]  = msa_ ## func ## _df(df, pws->b[8],  pwt->b[8]);    \
5606         pwd->b[9]  = msa_ ## func ## _df(df, pws->b[9],  pwt->b[9]);    \
5607         pwd->b[10] = msa_ ## func ## _df(df, pws->b[10], pwt->b[10]);   \
5608         pwd->b[11] = msa_ ## func ## _df(df, pws->b[11], pwt->b[11]);   \
5609         pwd->b[12] = msa_ ## func ## _df(df, pws->b[12], pwt->b[12]);   \
5610         pwd->b[13] = msa_ ## func ## _df(df, pws->b[13], pwt->b[13]);   \
5611         pwd->b[14] = msa_ ## func ## _df(df, pws->b[14], pwt->b[14]);   \
5612         pwd->b[15] = msa_ ## func ## _df(df, pws->b[15], pwt->b[15]);   \
5613         break;                                                          \
5614     case DF_HALF:                                                       \
5615         pwd->h[0] = msa_ ## func ## _df(df, pws->h[0], pwt->h[0]);      \
5616         pwd->h[1] = msa_ ## func ## _df(df, pws->h[1], pwt->h[1]);      \
5617         pwd->h[2] = msa_ ## func ## _df(df, pws->h[2], pwt->h[2]);      \
5618         pwd->h[3] = msa_ ## func ## _df(df, pws->h[3], pwt->h[3]);      \
5619         pwd->h[4] = msa_ ## func ## _df(df, pws->h[4], pwt->h[4]);      \
5620         pwd->h[5] = msa_ ## func ## _df(df, pws->h[5], pwt->h[5]);      \
5621         pwd->h[6] = msa_ ## func ## _df(df, pws->h[6], pwt->h[6]);      \
5622         pwd->h[7] = msa_ ## func ## _df(df, pws->h[7], pwt->h[7]);      \
5623         break;                                                          \
5624     case DF_WORD:                                                       \
5625         pwd->w[0] = msa_ ## func ## _df(df, pws->w[0], pwt->w[0]);      \
5626         pwd->w[1] = msa_ ## func ## _df(df, pws->w[1], pwt->w[1]);      \
5627         pwd->w[2] = msa_ ## func ## _df(df, pws->w[2], pwt->w[2]);      \
5628         pwd->w[3] = msa_ ## func ## _df(df, pws->w[3], pwt->w[3]);      \
5629         break;                                                          \
5630     case DF_DOUBLE:                                                     \
5631         pwd->d[0] = msa_ ## func ## _df(df, pws->d[0], pwt->d[0]);      \
5632         pwd->d[1] = msa_ ## func ## _df(df, pws->d[1], pwt->d[1]);      \
5633         break;                                                          \
5634     default:                                                            \
5635         assert(0);                                                      \
5636     }                                                                   \
5637 }
5638 
5639 MSA_BINOP_DF(mul_q)
5640 MSA_BINOP_DF(mulr_q)
5641 #undef MSA_BINOP_DF
5642 
5643 void helper_msa_sld_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5644                        uint32_t ws, uint32_t rt)
5645 {
5646     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5647     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5648 
5649     msa_sld_df(df, pwd, pws, env->active_tc.gpr[rt]);
5650 }
5651 
5652 static inline int64_t msa_madd_q_df(uint32_t df, int64_t dest, int64_t arg1,
5653                                     int64_t arg2)
5654 {
5655     int64_t q_prod, q_ret;
5656 
5657     int64_t q_max = DF_MAX_INT(df);
5658     int64_t q_min = DF_MIN_INT(df);
5659 
5660     q_prod = arg1 * arg2;
5661     q_ret = ((dest << (DF_BITS(df) - 1)) + q_prod) >> (DF_BITS(df) - 1);
5662 
5663     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
5664 }
5665 
5666 static inline int64_t msa_msub_q_df(uint32_t df, int64_t dest, int64_t arg1,
5667                                     int64_t arg2)
5668 {
5669     int64_t q_prod, q_ret;
5670 
5671     int64_t q_max = DF_MAX_INT(df);
5672     int64_t q_min = DF_MIN_INT(df);
5673 
5674     q_prod = arg1 * arg2;
5675     q_ret = ((dest << (DF_BITS(df) - 1)) - q_prod) >> (DF_BITS(df) - 1);
5676 
5677     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
5678 }
5679 
5680 static inline int64_t msa_maddr_q_df(uint32_t df, int64_t dest, int64_t arg1,
5681                                      int64_t arg2)
5682 {
5683     int64_t q_prod, q_ret;
5684 
5685     int64_t q_max = DF_MAX_INT(df);
5686     int64_t q_min = DF_MIN_INT(df);
5687     int64_t r_bit = 1 << (DF_BITS(df) - 2);
5688 
5689     q_prod = arg1 * arg2;
5690     q_ret = ((dest << (DF_BITS(df) - 1)) + q_prod + r_bit) >> (DF_BITS(df) - 1);
5691 
5692     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
5693 }
5694 
5695 static inline int64_t msa_msubr_q_df(uint32_t df, int64_t dest, int64_t arg1,
5696                                      int64_t arg2)
5697 {
5698     int64_t q_prod, q_ret;
5699 
5700     int64_t q_max = DF_MAX_INT(df);
5701     int64_t q_min = DF_MIN_INT(df);
5702     int64_t r_bit = 1 << (DF_BITS(df) - 2);
5703 
5704     q_prod = arg1 * arg2;
5705     q_ret = ((dest << (DF_BITS(df) - 1)) - q_prod + r_bit) >> (DF_BITS(df) - 1);
5706 
5707     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
5708 }
5709 
5710 #define MSA_TEROP_DF(func) \
5711 void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, uint32_t wd,  \
5712                                 uint32_t ws, uint32_t wt)                     \
5713 {                                                                             \
5714     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                                \
5715     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                                \
5716     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);                                \
5717                                                                               \
5718     switch (df) {                                                             \
5719     case DF_BYTE:                                                             \
5720         pwd->b[0]  = msa_ ## func ## _df(df, pwd->b[0],  pws->b[0],           \
5721                                              pwt->b[0]);                      \
5722         pwd->b[1]  = msa_ ## func ## _df(df, pwd->b[1],  pws->b[1],           \
5723                                              pwt->b[1]);                      \
5724         pwd->b[2]  = msa_ ## func ## _df(df, pwd->b[2],  pws->b[2],           \
5725                                              pwt->b[2]);                      \
5726         pwd->b[3]  = msa_ ## func ## _df(df, pwd->b[3],  pws->b[3],           \
5727                                              pwt->b[3]);                      \
5728         pwd->b[4]  = msa_ ## func ## _df(df, pwd->b[4],  pws->b[4],           \
5729                                              pwt->b[4]);                      \
5730         pwd->b[5]  = msa_ ## func ## _df(df, pwd->b[5],  pws->b[5],           \
5731                                              pwt->b[5]);                      \
5732         pwd->b[6]  = msa_ ## func ## _df(df, pwd->b[6],  pws->b[6],           \
5733                                              pwt->b[6]);                      \
5734         pwd->b[7]  = msa_ ## func ## _df(df, pwd->b[7],  pws->b[7],           \
5735                                              pwt->b[7]);                      \
5736         pwd->b[8]  = msa_ ## func ## _df(df, pwd->b[8],  pws->b[8],           \
5737                                              pwt->b[8]);                      \
5738         pwd->b[9]  = msa_ ## func ## _df(df, pwd->b[9],  pws->b[9],           \
5739                                              pwt->b[9]);                      \
5740         pwd->b[10] = msa_ ## func ## _df(df, pwd->b[10], pws->b[10],          \
5741                                              pwt->b[10]);                     \
5742         pwd->b[11] = msa_ ## func ## _df(df, pwd->b[11], pws->b[11],          \
5743                                              pwt->b[11]);                     \
5744         pwd->b[12] = msa_ ## func ## _df(df, pwd->b[12], pws->b[12],          \
5745                                              pwt->b[12]);                     \
5746         pwd->b[13] = msa_ ## func ## _df(df, pwd->b[13], pws->b[13],          \
5747                                              pwt->b[13]);                     \
5748         pwd->b[14] = msa_ ## func ## _df(df, pwd->b[14], pws->b[14],          \
5749                                              pwt->b[14]);                     \
5750         pwd->b[15] = msa_ ## func ## _df(df, pwd->b[15], pws->b[15],          \
5751                                              pwt->b[15]);                     \
5752         break;                                                                \
5753     case DF_HALF:                                                             \
5754         pwd->h[0] = msa_ ## func ## _df(df, pwd->h[0], pws->h[0], pwt->h[0]); \
5755         pwd->h[1] = msa_ ## func ## _df(df, pwd->h[1], pws->h[1], pwt->h[1]); \
5756         pwd->h[2] = msa_ ## func ## _df(df, pwd->h[2], pws->h[2], pwt->h[2]); \
5757         pwd->h[3] = msa_ ## func ## _df(df, pwd->h[3], pws->h[3], pwt->h[3]); \
5758         pwd->h[4] = msa_ ## func ## _df(df, pwd->h[4], pws->h[4], pwt->h[4]); \
5759         pwd->h[5] = msa_ ## func ## _df(df, pwd->h[5], pws->h[5], pwt->h[5]); \
5760         pwd->h[6] = msa_ ## func ## _df(df, pwd->h[6], pws->h[6], pwt->h[6]); \
5761         pwd->h[7] = msa_ ## func ## _df(df, pwd->h[7], pws->h[7], pwt->h[7]); \
5762         break;                                                                \
5763     case DF_WORD:                                                             \
5764         pwd->w[0] = msa_ ## func ## _df(df, pwd->w[0], pws->w[0], pwt->w[0]); \
5765         pwd->w[1] = msa_ ## func ## _df(df, pwd->w[1], pws->w[1], pwt->w[1]); \
5766         pwd->w[2] = msa_ ## func ## _df(df, pwd->w[2], pws->w[2], pwt->w[2]); \
5767         pwd->w[3] = msa_ ## func ## _df(df, pwd->w[3], pws->w[3], pwt->w[3]); \
5768         break;                                                                \
5769     case DF_DOUBLE:                                                           \
5770         pwd->d[0] = msa_ ## func ## _df(df, pwd->d[0], pws->d[0], pwt->d[0]); \
5771         pwd->d[1] = msa_ ## func ## _df(df, pwd->d[1], pws->d[1], pwt->d[1]); \
5772         break;                                                                \
5773     default:                                                                  \
5774         assert(0);                                                            \
5775     }                                                                         \
5776 }
5777 
5778 MSA_TEROP_DF(binsl)
5779 MSA_TEROP_DF(binsr)
5780 MSA_TEROP_DF(madd_q)
5781 MSA_TEROP_DF(msub_q)
5782 MSA_TEROP_DF(maddr_q)
5783 MSA_TEROP_DF(msubr_q)
5784 #undef MSA_TEROP_DF
5785 
5786 static inline void msa_splat_df(uint32_t df, wr_t *pwd,
5787                                 wr_t *pws, target_ulong rt)
5788 {
5789     uint32_t n = rt % DF_ELEMENTS(df);
5790     uint32_t i;
5791 
5792     switch (df) {
5793     case DF_BYTE:
5794         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
5795             pwd->b[i] = pws->b[n];
5796         }
5797         break;
5798     case DF_HALF:
5799         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
5800             pwd->h[i] = pws->h[n];
5801         }
5802         break;
5803     case DF_WORD:
5804         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
5805             pwd->w[i] = pws->w[n];
5806         }
5807         break;
5808     case DF_DOUBLE:
5809         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
5810             pwd->d[i] = pws->d[n];
5811         }
5812        break;
5813     default:
5814         assert(0);
5815     }
5816 }
5817 
5818 void helper_msa_splat_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5819                          uint32_t ws, uint32_t rt)
5820 {
5821     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5822     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5823 
5824     msa_splat_df(df, pwd, pws, env->active_tc.gpr[rt]);
5825 }
5826 
5827 #define MSA_DO_B MSA_DO(b)
5828 #define MSA_DO_H MSA_DO(h)
5829 #define MSA_DO_W MSA_DO(w)
5830 #define MSA_DO_D MSA_DO(d)
5831 
5832 #define MSA_LOOP_B MSA_LOOP(B)
5833 #define MSA_LOOP_H MSA_LOOP(H)
5834 #define MSA_LOOP_W MSA_LOOP(W)
5835 #define MSA_LOOP_D MSA_LOOP(D)
5836 
5837 #define MSA_LOOP_COND_B MSA_LOOP_COND(DF_BYTE)
5838 #define MSA_LOOP_COND_H MSA_LOOP_COND(DF_HALF)
5839 #define MSA_LOOP_COND_W MSA_LOOP_COND(DF_WORD)
5840 #define MSA_LOOP_COND_D MSA_LOOP_COND(DF_DOUBLE)
5841 
5842 #define MSA_LOOP(DF) \
5843     do { \
5844         for (i = 0; i < (MSA_LOOP_COND_ ## DF) ; i++) { \
5845             MSA_DO_ ## DF; \
5846         } \
5847     } while (0)
5848 
5849 #define MSA_FN_DF(FUNC)                                             \
5850 void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
5851         uint32_t ws, uint32_t wt)                                   \
5852 {                                                                   \
5853     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                      \
5854     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                      \
5855     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);                      \
5856     wr_t wx, *pwx = &wx;                                            \
5857     uint32_t i;                                                     \
5858     switch (df) {                                                   \
5859     case DF_BYTE:                                                   \
5860         MSA_LOOP_B;                                                 \
5861         break;                                                      \
5862     case DF_HALF:                                                   \
5863         MSA_LOOP_H;                                                 \
5864         break;                                                      \
5865     case DF_WORD:                                                   \
5866         MSA_LOOP_W;                                                 \
5867         break;                                                      \
5868     case DF_DOUBLE:                                                 \
5869         MSA_LOOP_D;                                                 \
5870         break;                                                      \
5871     default:                                                        \
5872         assert(0);                                                  \
5873     }                                                               \
5874     msa_move_v(pwd, pwx);                                           \
5875 }
5876 
5877 #define MSA_LOOP_COND(DF) \
5878             (DF_ELEMENTS(DF) / 2)
5879 
5880 #define Rb(pwr, i) (pwr->b[i])
5881 #define Lb(pwr, i) (pwr->b[i + DF_ELEMENTS(DF_BYTE) / 2])
5882 #define Rh(pwr, i) (pwr->h[i])
5883 #define Lh(pwr, i) (pwr->h[i + DF_ELEMENTS(DF_HALF) / 2])
5884 #define Rw(pwr, i) (pwr->w[i])
5885 #define Lw(pwr, i) (pwr->w[i + DF_ELEMENTS(DF_WORD) / 2])
5886 #define Rd(pwr, i) (pwr->d[i])
5887 #define Ld(pwr, i) (pwr->d[i + DF_ELEMENTS(DF_DOUBLE) / 2])
5888 
5889 #undef MSA_LOOP_COND
5890 
5891 #define MSA_LOOP_COND(DF) \
5892             (DF_ELEMENTS(DF))
5893 
5894 #define MSA_DO(DF)                                                          \
5895     do {                                                                    \
5896         uint32_t n = DF_ELEMENTS(df);                                       \
5897         uint32_t k = (pwd->DF[i] & 0x3f) % (2 * n);                         \
5898         pwx->DF[i] =                                                        \
5899             (pwd->DF[i] & 0xc0) ? 0 : k < n ? pwt->DF[k] : pws->DF[k - n];  \
5900     } while (0)
5901 MSA_FN_DF(vshf_df)
5902 #undef MSA_DO
5903 #undef MSA_LOOP_COND
5904 #undef MSA_FN_DF
5905 
5906 
5907 void helper_msa_sldi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5908                         uint32_t ws, uint32_t n)
5909 {
5910     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5911     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5912 
5913     msa_sld_df(df, pwd, pws, n);
5914 }
5915 
5916 void helper_msa_splati_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
5917                           uint32_t ws, uint32_t n)
5918 {
5919     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
5920     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
5921 
5922     msa_splat_df(df, pwd, pws, n);
5923 }
5924 
5925 void helper_msa_copy_s_b(CPUMIPSState *env, uint32_t rd,
5926                          uint32_t ws, uint32_t n)
5927 {
5928     n %= 16;
5929 #if defined(HOST_WORDS_BIGENDIAN)
5930     if (n < 8) {
5931         n = 8 - n - 1;
5932     } else {
5933         n = 24 - n - 1;
5934     }
5935 #endif
5936     env->active_tc.gpr[rd] = (int8_t)env->active_fpu.fpr[ws].wr.b[n];
5937 }
5938 
5939 void helper_msa_copy_s_h(CPUMIPSState *env, uint32_t rd,
5940                          uint32_t ws, uint32_t n)
5941 {
5942     n %= 8;
5943 #if defined(HOST_WORDS_BIGENDIAN)
5944     if (n < 4) {
5945         n = 4 - n - 1;
5946     } else {
5947         n = 12 - n - 1;
5948     }
5949 #endif
5950     env->active_tc.gpr[rd] = (int16_t)env->active_fpu.fpr[ws].wr.h[n];
5951 }
5952 
5953 void helper_msa_copy_s_w(CPUMIPSState *env, uint32_t rd,
5954                          uint32_t ws, uint32_t n)
5955 {
5956     n %= 4;
5957 #if defined(HOST_WORDS_BIGENDIAN)
5958     if (n < 2) {
5959         n = 2 - n - 1;
5960     } else {
5961         n = 6 - n - 1;
5962     }
5963 #endif
5964     env->active_tc.gpr[rd] = (int32_t)env->active_fpu.fpr[ws].wr.w[n];
5965 }
5966 
5967 void helper_msa_copy_s_d(CPUMIPSState *env, uint32_t rd,
5968                          uint32_t ws, uint32_t n)
5969 {
5970     n %= 2;
5971     env->active_tc.gpr[rd] = (int64_t)env->active_fpu.fpr[ws].wr.d[n];
5972 }
5973 
5974 void helper_msa_copy_u_b(CPUMIPSState *env, uint32_t rd,
5975                          uint32_t ws, uint32_t n)
5976 {
5977     n %= 16;
5978 #if defined(HOST_WORDS_BIGENDIAN)
5979     if (n < 8) {
5980         n = 8 - n - 1;
5981     } else {
5982         n = 24 - n - 1;
5983     }
5984 #endif
5985     env->active_tc.gpr[rd] = (uint8_t)env->active_fpu.fpr[ws].wr.b[n];
5986 }
5987 
5988 void helper_msa_copy_u_h(CPUMIPSState *env, uint32_t rd,
5989                          uint32_t ws, uint32_t n)
5990 {
5991     n %= 8;
5992 #if defined(HOST_WORDS_BIGENDIAN)
5993     if (n < 4) {
5994         n = 4 - n - 1;
5995     } else {
5996         n = 12 - n - 1;
5997     }
5998 #endif
5999     env->active_tc.gpr[rd] = (uint16_t)env->active_fpu.fpr[ws].wr.h[n];
6000 }
6001 
6002 void helper_msa_copy_u_w(CPUMIPSState *env, uint32_t rd,
6003                          uint32_t ws, uint32_t n)
6004 {
6005     n %= 4;
6006 #if defined(HOST_WORDS_BIGENDIAN)
6007     if (n < 2) {
6008         n = 2 - n - 1;
6009     } else {
6010         n = 6 - n - 1;
6011     }
6012 #endif
6013     env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
6014 }
6015 
6016 void helper_msa_insert_b(CPUMIPSState *env, uint32_t wd,
6017                           uint32_t rs_num, uint32_t n)
6018 {
6019     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6020     target_ulong rs = env->active_tc.gpr[rs_num];
6021     n %= 16;
6022 #if defined(HOST_WORDS_BIGENDIAN)
6023     if (n < 8) {
6024         n = 8 - n - 1;
6025     } else {
6026         n = 24 - n - 1;
6027     }
6028 #endif
6029     pwd->b[n] = (int8_t)rs;
6030 }
6031 
6032 void helper_msa_insert_h(CPUMIPSState *env, uint32_t wd,
6033                           uint32_t rs_num, uint32_t n)
6034 {
6035     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6036     target_ulong rs = env->active_tc.gpr[rs_num];
6037     n %= 8;
6038 #if defined(HOST_WORDS_BIGENDIAN)
6039     if (n < 4) {
6040         n = 4 - n - 1;
6041     } else {
6042         n = 12 - n - 1;
6043     }
6044 #endif
6045     pwd->h[n] = (int16_t)rs;
6046 }
6047 
6048 void helper_msa_insert_w(CPUMIPSState *env, uint32_t wd,
6049                           uint32_t rs_num, uint32_t n)
6050 {
6051     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6052     target_ulong rs = env->active_tc.gpr[rs_num];
6053     n %= 4;
6054 #if defined(HOST_WORDS_BIGENDIAN)
6055     if (n < 2) {
6056         n = 2 - n - 1;
6057     } else {
6058         n = 6 - n - 1;
6059     }
6060 #endif
6061     pwd->w[n] = (int32_t)rs;
6062 }
6063 
6064 void helper_msa_insert_d(CPUMIPSState *env, uint32_t wd,
6065                           uint32_t rs_num, uint32_t n)
6066 {
6067     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6068     target_ulong rs = env->active_tc.gpr[rs_num];
6069     n %= 2;
6070     pwd->d[n] = (int64_t)rs;
6071 }
6072 
6073 void helper_msa_insve_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6074                          uint32_t ws, uint32_t n)
6075 {
6076     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6077     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6078 
6079     switch (df) {
6080     case DF_BYTE:
6081         pwd->b[n] = (int8_t)pws->b[0];
6082         break;
6083     case DF_HALF:
6084         pwd->h[n] = (int16_t)pws->h[0];
6085         break;
6086     case DF_WORD:
6087         pwd->w[n] = (int32_t)pws->w[0];
6088         break;
6089     case DF_DOUBLE:
6090         pwd->d[n] = (int64_t)pws->d[0];
6091         break;
6092     default:
6093         assert(0);
6094     }
6095 }
6096 
6097 void helper_msa_ctcmsa(CPUMIPSState *env, target_ulong elm, uint32_t cd)
6098 {
6099     switch (cd) {
6100     case 0:
6101         break;
6102     case 1:
6103         env->active_tc.msacsr = (int32_t)elm & MSACSR_MASK;
6104         restore_msa_fp_status(env);
6105         /* check exception */
6106         if ((GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)
6107             & GET_FP_CAUSE(env->active_tc.msacsr)) {
6108             do_raise_exception(env, EXCP_MSAFPE, GETPC());
6109         }
6110         break;
6111     }
6112 }
6113 
6114 target_ulong helper_msa_cfcmsa(CPUMIPSState *env, uint32_t cs)
6115 {
6116     switch (cs) {
6117     case 0:
6118         return env->msair;
6119     case 1:
6120         return env->active_tc.msacsr & MSACSR_MASK;
6121     }
6122     return 0;
6123 }
6124 
6125 void helper_msa_fill_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6126                         uint32_t rs)
6127 {
6128     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6129     uint32_t i;
6130 
6131     switch (df) {
6132     case DF_BYTE:
6133         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
6134             pwd->b[i] = (int8_t)env->active_tc.gpr[rs];
6135         }
6136         break;
6137     case DF_HALF:
6138         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
6139             pwd->h[i] = (int16_t)env->active_tc.gpr[rs];
6140         }
6141         break;
6142     case DF_WORD:
6143         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6144             pwd->w[i] = (int32_t)env->active_tc.gpr[rs];
6145         }
6146         break;
6147     case DF_DOUBLE:
6148         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6149             pwd->d[i] = (int64_t)env->active_tc.gpr[rs];
6150         }
6151        break;
6152     default:
6153         assert(0);
6154     }
6155 }
6156 
6157 
6158 #define FLOAT_ONE32 make_float32(0x3f8 << 20)
6159 #define FLOAT_ONE64 make_float64(0x3ffULL << 52)
6160 
6161 #define FLOAT_SNAN16(s) (float16_default_nan(s) ^ 0x0220)
6162         /* 0x7c20 */
6163 #define FLOAT_SNAN32(s) (float32_default_nan(s) ^ 0x00400020)
6164         /* 0x7f800020 */
6165 #define FLOAT_SNAN64(s) (float64_default_nan(s) ^ 0x0008000000000020ULL)
6166         /* 0x7ff0000000000020 */
6167 
6168 static inline void clear_msacsr_cause(CPUMIPSState *env)
6169 {
6170     SET_FP_CAUSE(env->active_tc.msacsr, 0);
6171 }
6172 
6173 static inline void check_msacsr_cause(CPUMIPSState *env, uintptr_t retaddr)
6174 {
6175     if ((GET_FP_CAUSE(env->active_tc.msacsr) &
6176             (GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)) == 0) {
6177         UPDATE_FP_FLAGS(env->active_tc.msacsr,
6178                 GET_FP_CAUSE(env->active_tc.msacsr));
6179     } else {
6180         do_raise_exception(env, EXCP_MSAFPE, retaddr);
6181     }
6182 }
6183 
6184 /* Flush-to-zero use cases for update_msacsr() */
6185 #define CLEAR_FS_UNDERFLOW 1
6186 #define CLEAR_IS_INEXACT   2
6187 #define RECIPROCAL_INEXACT 4
6188 
6189 
6190 static inline int ieee_to_mips_xcpt_msa(int ieee_xcpt)
6191 {
6192     int mips_xcpt = 0;
6193 
6194     if (ieee_xcpt & float_flag_invalid) {
6195         mips_xcpt |= FP_INVALID;
6196     }
6197     if (ieee_xcpt & float_flag_overflow) {
6198         mips_xcpt |= FP_OVERFLOW;
6199     }
6200     if (ieee_xcpt & float_flag_underflow) {
6201         mips_xcpt |= FP_UNDERFLOW;
6202     }
6203     if (ieee_xcpt & float_flag_divbyzero) {
6204         mips_xcpt |= FP_DIV0;
6205     }
6206     if (ieee_xcpt & float_flag_inexact) {
6207         mips_xcpt |= FP_INEXACT;
6208     }
6209 
6210     return mips_xcpt;
6211 }
6212 
6213 static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
6214 {
6215     int ieee_exception_flags;
6216     int mips_exception_flags = 0;
6217     int cause;
6218     int enable;
6219 
6220     ieee_exception_flags = get_float_exception_flags(
6221                                &env->active_tc.msa_fp_status);
6222 
6223     /* QEMU softfloat does not signal all underflow cases */
6224     if (denormal) {
6225         ieee_exception_flags |= float_flag_underflow;
6226     }
6227     if (ieee_exception_flags) {
6228         mips_exception_flags = ieee_to_mips_xcpt_msa(ieee_exception_flags);
6229     }
6230     enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
6231 
6232     /* Set Inexact (I) when flushing inputs to zero */
6233     if ((ieee_exception_flags & float_flag_input_denormal) &&
6234             (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
6235         if (action & CLEAR_IS_INEXACT) {
6236             mips_exception_flags &= ~FP_INEXACT;
6237         } else {
6238             mips_exception_flags |= FP_INEXACT;
6239         }
6240     }
6241 
6242     /* Set Inexact (I) and Underflow (U) when flushing outputs to zero */
6243     if ((ieee_exception_flags & float_flag_output_denormal) &&
6244             (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
6245         mips_exception_flags |= FP_INEXACT;
6246         if (action & CLEAR_FS_UNDERFLOW) {
6247             mips_exception_flags &= ~FP_UNDERFLOW;
6248         } else {
6249             mips_exception_flags |= FP_UNDERFLOW;
6250         }
6251     }
6252 
6253     /* Set Inexact (I) when Overflow (O) is not enabled */
6254     if ((mips_exception_flags & FP_OVERFLOW) != 0 &&
6255            (enable & FP_OVERFLOW) == 0) {
6256         mips_exception_flags |= FP_INEXACT;
6257     }
6258 
6259     /* Clear Exact Underflow when Underflow (U) is not enabled */
6260     if ((mips_exception_flags & FP_UNDERFLOW) != 0 &&
6261            (enable & FP_UNDERFLOW) == 0 &&
6262            (mips_exception_flags & FP_INEXACT) == 0) {
6263         mips_exception_flags &= ~FP_UNDERFLOW;
6264     }
6265 
6266     /*
6267      * Reciprocal operations set only Inexact when valid and not
6268      * divide by zero
6269      */
6270     if ((action & RECIPROCAL_INEXACT) &&
6271             (mips_exception_flags & (FP_INVALID | FP_DIV0)) == 0) {
6272         mips_exception_flags = FP_INEXACT;
6273     }
6274 
6275     cause = mips_exception_flags & enable; /* all current enabled exceptions */
6276 
6277     if (cause == 0) {
6278         /*
6279          * No enabled exception, update the MSACSR Cause
6280          * with all current exceptions
6281          */
6282         SET_FP_CAUSE(env->active_tc.msacsr,
6283             (GET_FP_CAUSE(env->active_tc.msacsr) | mips_exception_flags));
6284     } else {
6285         /* Current exceptions are enabled */
6286         if ((env->active_tc.msacsr & MSACSR_NX_MASK) == 0) {
6287             /*
6288              * Exception(s) will trap, update MSACSR Cause
6289              * with all enabled exceptions
6290              */
6291             SET_FP_CAUSE(env->active_tc.msacsr,
6292                 (GET_FP_CAUSE(env->active_tc.msacsr) | mips_exception_flags));
6293         }
6294     }
6295 
6296     return mips_exception_flags;
6297 }
6298 
6299 static inline int get_enabled_exceptions(const CPUMIPSState *env, int c)
6300 {
6301     int enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
6302     return c & enable;
6303 }
6304 
6305 static inline float16 float16_from_float32(int32_t a, bool ieee,
6306                                            float_status *status)
6307 {
6308       float16 f_val;
6309 
6310       f_val = float32_to_float16((float32)a, ieee, status);
6311 
6312       return a < 0 ? (f_val | (1 << 15)) : f_val;
6313 }
6314 
6315 static inline float32 float32_from_float64(int64_t a, float_status *status)
6316 {
6317       float32 f_val;
6318 
6319       f_val = float64_to_float32((float64)a, status);
6320 
6321       return a < 0 ? (f_val | (1 << 31)) : f_val;
6322 }
6323 
6324 static inline float32 float32_from_float16(int16_t a, bool ieee,
6325                                            float_status *status)
6326 {
6327       float32 f_val;
6328 
6329       f_val = float16_to_float32((float16)a, ieee, status);
6330 
6331       return a < 0 ? (f_val | (1 << 31)) : f_val;
6332 }
6333 
6334 static inline float64 float64_from_float32(int32_t a, float_status *status)
6335 {
6336       float64 f_val;
6337 
6338       f_val = float32_to_float64((float64)a, status);
6339 
6340       return a < 0 ? (f_val | (1ULL << 63)) : f_val;
6341 }
6342 
6343 static inline float32 float32_from_q16(int16_t a, float_status *status)
6344 {
6345     float32 f_val;
6346 
6347     /* conversion as integer and scaling */
6348     f_val = int32_to_float32(a, status);
6349     f_val = float32_scalbn(f_val, -15, status);
6350 
6351     return f_val;
6352 }
6353 
6354 static inline float64 float64_from_q32(int32_t a, float_status *status)
6355 {
6356     float64 f_val;
6357 
6358     /* conversion as integer and scaling */
6359     f_val = int32_to_float64(a, status);
6360     f_val = float64_scalbn(f_val, -31, status);
6361 
6362     return f_val;
6363 }
6364 
6365 static inline int16_t float32_to_q16(float32 a, float_status *status)
6366 {
6367     int32_t q_val;
6368     int32_t q_min = 0xffff8000;
6369     int32_t q_max = 0x00007fff;
6370 
6371     int ieee_ex;
6372 
6373     if (float32_is_any_nan(a)) {
6374         float_raise(float_flag_invalid, status);
6375         return 0;
6376     }
6377 
6378     /* scaling */
6379     a = float32_scalbn(a, 15, status);
6380 
6381     ieee_ex = get_float_exception_flags(status);
6382     set_float_exception_flags(ieee_ex & (~float_flag_underflow)
6383                              , status);
6384 
6385     if (ieee_ex & float_flag_overflow) {
6386         float_raise(float_flag_inexact, status);
6387         return (int32_t)a < 0 ? q_min : q_max;
6388     }
6389 
6390     /* conversion to int */
6391     q_val = float32_to_int32(a, status);
6392 
6393     ieee_ex = get_float_exception_flags(status);
6394     set_float_exception_flags(ieee_ex & (~float_flag_underflow)
6395                              , status);
6396 
6397     if (ieee_ex & float_flag_invalid) {
6398         set_float_exception_flags(ieee_ex & (~float_flag_invalid)
6399                                , status);
6400         float_raise(float_flag_overflow | float_flag_inexact, status);
6401         return (int32_t)a < 0 ? q_min : q_max;
6402     }
6403 
6404     if (q_val < q_min) {
6405         float_raise(float_flag_overflow | float_flag_inexact, status);
6406         return (int16_t)q_min;
6407     }
6408 
6409     if (q_max < q_val) {
6410         float_raise(float_flag_overflow | float_flag_inexact, status);
6411         return (int16_t)q_max;
6412     }
6413 
6414     return (int16_t)q_val;
6415 }
6416 
6417 static inline int32_t float64_to_q32(float64 a, float_status *status)
6418 {
6419     int64_t q_val;
6420     int64_t q_min = 0xffffffff80000000LL;
6421     int64_t q_max = 0x000000007fffffffLL;
6422 
6423     int ieee_ex;
6424 
6425     if (float64_is_any_nan(a)) {
6426         float_raise(float_flag_invalid, status);
6427         return 0;
6428     }
6429 
6430     /* scaling */
6431     a = float64_scalbn(a, 31, status);
6432 
6433     ieee_ex = get_float_exception_flags(status);
6434     set_float_exception_flags(ieee_ex & (~float_flag_underflow)
6435            , status);
6436 
6437     if (ieee_ex & float_flag_overflow) {
6438         float_raise(float_flag_inexact, status);
6439         return (int64_t)a < 0 ? q_min : q_max;
6440     }
6441 
6442     /* conversion to integer */
6443     q_val = float64_to_int64(a, status);
6444 
6445     ieee_ex = get_float_exception_flags(status);
6446     set_float_exception_flags(ieee_ex & (~float_flag_underflow)
6447            , status);
6448 
6449     if (ieee_ex & float_flag_invalid) {
6450         set_float_exception_flags(ieee_ex & (~float_flag_invalid)
6451                , status);
6452         float_raise(float_flag_overflow | float_flag_inexact, status);
6453         return (int64_t)a < 0 ? q_min : q_max;
6454     }
6455 
6456     if (q_val < q_min) {
6457         float_raise(float_flag_overflow | float_flag_inexact, status);
6458         return (int32_t)q_min;
6459     }
6460 
6461     if (q_max < q_val) {
6462         float_raise(float_flag_overflow | float_flag_inexact, status);
6463         return (int32_t)q_max;
6464     }
6465 
6466     return (int32_t)q_val;
6467 }
6468 
6469 #define MSA_FLOAT_COND(DEST, OP, ARG1, ARG2, BITS, QUIET)                   \
6470     do {                                                                    \
6471         float_status *status = &env->active_tc.msa_fp_status;               \
6472         int c;                                                              \
6473         int64_t cond;                                                       \
6474         set_float_exception_flags(0, status);                               \
6475         if (!QUIET) {                                                       \
6476             cond = float ## BITS ## _ ## OP(ARG1, ARG2, status);            \
6477         } else {                                                            \
6478             cond = float ## BITS ## _ ## OP ## _quiet(ARG1, ARG2, status);  \
6479         }                                                                   \
6480         DEST = cond ? M_MAX_UINT(BITS) : 0;                                 \
6481         c = update_msacsr(env, CLEAR_IS_INEXACT, 0);                        \
6482                                                                             \
6483         if (get_enabled_exceptions(env, c)) {                               \
6484             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
6485         }                                                                   \
6486     } while (0)
6487 
6488 #define MSA_FLOAT_AF(DEST, ARG1, ARG2, BITS, QUIET)                 \
6489     do {                                                            \
6490         MSA_FLOAT_COND(DEST, eq, ARG1, ARG2, BITS, QUIET);          \
6491         if ((DEST & M_MAX_UINT(BITS)) == M_MAX_UINT(BITS)) {        \
6492             DEST = 0;                                               \
6493         }                                                           \
6494     } while (0)
6495 
6496 #define MSA_FLOAT_UEQ(DEST, ARG1, ARG2, BITS, QUIET)                \
6497     do {                                                            \
6498         MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET);   \
6499         if (DEST == 0) {                                            \
6500             MSA_FLOAT_COND(DEST, eq, ARG1, ARG2, BITS, QUIET);      \
6501         }                                                           \
6502     } while (0)
6503 
6504 #define MSA_FLOAT_NE(DEST, ARG1, ARG2, BITS, QUIET)                 \
6505     do {                                                            \
6506         MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET);          \
6507         if (DEST == 0) {                                            \
6508             MSA_FLOAT_COND(DEST, lt, ARG2, ARG1, BITS, QUIET);      \
6509         }                                                           \
6510     } while (0)
6511 
6512 #define MSA_FLOAT_UNE(DEST, ARG1, ARG2, BITS, QUIET)                \
6513     do {                                                            \
6514         MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET);   \
6515         if (DEST == 0) {                                            \
6516             MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET);      \
6517             if (DEST == 0) {                                        \
6518                 MSA_FLOAT_COND(DEST, lt, ARG2, ARG1, BITS, QUIET);  \
6519             }                                                       \
6520         }                                                           \
6521     } while (0)
6522 
6523 #define MSA_FLOAT_ULE(DEST, ARG1, ARG2, BITS, QUIET)                \
6524     do {                                                            \
6525         MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET);   \
6526         if (DEST == 0) {                                            \
6527             MSA_FLOAT_COND(DEST, le, ARG1, ARG2, BITS, QUIET);      \
6528         }                                                           \
6529     } while (0)
6530 
6531 #define MSA_FLOAT_ULT(DEST, ARG1, ARG2, BITS, QUIET)                \
6532     do {                                                            \
6533         MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET);   \
6534         if (DEST == 0) {                                            \
6535             MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET);      \
6536         }                                                           \
6537     } while (0)
6538 
6539 #define MSA_FLOAT_OR(DEST, ARG1, ARG2, BITS, QUIET)                 \
6540     do {                                                            \
6541         MSA_FLOAT_COND(DEST, le, ARG1, ARG2, BITS, QUIET);          \
6542         if (DEST == 0) {                                            \
6543             MSA_FLOAT_COND(DEST, le, ARG2, ARG1, BITS, QUIET);      \
6544         }                                                           \
6545     } while (0)
6546 
6547 static inline void compare_af(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6548                               wr_t *pwt, uint32_t df, int quiet,
6549                               uintptr_t retaddr)
6550 {
6551     wr_t wx, *pwx = &wx;
6552     uint32_t i;
6553 
6554     clear_msacsr_cause(env);
6555 
6556     switch (df) {
6557     case DF_WORD:
6558         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6559             MSA_FLOAT_AF(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
6560         }
6561         break;
6562     case DF_DOUBLE:
6563         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6564             MSA_FLOAT_AF(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
6565         }
6566         break;
6567     default:
6568         assert(0);
6569     }
6570 
6571     check_msacsr_cause(env, retaddr);
6572 
6573     msa_move_v(pwd, pwx);
6574 }
6575 
6576 static inline void compare_un(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6577                               wr_t *pwt, uint32_t df, int quiet,
6578                               uintptr_t retaddr)
6579 {
6580     wr_t wx, *pwx = &wx;
6581     uint32_t i;
6582 
6583     clear_msacsr_cause(env);
6584 
6585     switch (df) {
6586     case DF_WORD:
6587         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6588             MSA_FLOAT_COND(pwx->w[i], unordered, pws->w[i], pwt->w[i], 32,
6589                     quiet);
6590         }
6591         break;
6592     case DF_DOUBLE:
6593         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6594             MSA_FLOAT_COND(pwx->d[i], unordered, pws->d[i], pwt->d[i], 64,
6595                     quiet);
6596         }
6597         break;
6598     default:
6599         assert(0);
6600     }
6601 
6602     check_msacsr_cause(env, retaddr);
6603 
6604     msa_move_v(pwd, pwx);
6605 }
6606 
6607 static inline void compare_eq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6608                               wr_t *pwt, uint32_t df, int quiet,
6609                               uintptr_t retaddr)
6610 {
6611     wr_t wx, *pwx = &wx;
6612     uint32_t i;
6613 
6614     clear_msacsr_cause(env);
6615 
6616     switch (df) {
6617     case DF_WORD:
6618         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6619             MSA_FLOAT_COND(pwx->w[i], eq, pws->w[i], pwt->w[i], 32, quiet);
6620         }
6621         break;
6622     case DF_DOUBLE:
6623         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6624             MSA_FLOAT_COND(pwx->d[i], eq, pws->d[i], pwt->d[i], 64, quiet);
6625         }
6626         break;
6627     default:
6628         assert(0);
6629     }
6630 
6631     check_msacsr_cause(env, retaddr);
6632 
6633     msa_move_v(pwd, pwx);
6634 }
6635 
6636 static inline void compare_ueq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6637                                wr_t *pwt, uint32_t df, int quiet,
6638                                uintptr_t retaddr)
6639 {
6640     wr_t wx, *pwx = &wx;
6641     uint32_t i;
6642 
6643     clear_msacsr_cause(env);
6644 
6645     switch (df) {
6646     case DF_WORD:
6647         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6648             MSA_FLOAT_UEQ(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
6649         }
6650         break;
6651     case DF_DOUBLE:
6652         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6653             MSA_FLOAT_UEQ(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
6654         }
6655         break;
6656     default:
6657         assert(0);
6658     }
6659 
6660     check_msacsr_cause(env, retaddr);
6661 
6662     msa_move_v(pwd, pwx);
6663 }
6664 
6665 static inline void compare_lt(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6666                               wr_t *pwt, uint32_t df, int quiet,
6667                               uintptr_t retaddr)
6668 {
6669     wr_t wx, *pwx = &wx;
6670     uint32_t i;
6671 
6672     clear_msacsr_cause(env);
6673 
6674     switch (df) {
6675     case DF_WORD:
6676         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6677             MSA_FLOAT_COND(pwx->w[i], lt, pws->w[i], pwt->w[i], 32, quiet);
6678         }
6679         break;
6680     case DF_DOUBLE:
6681         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6682             MSA_FLOAT_COND(pwx->d[i], lt, pws->d[i], pwt->d[i], 64, quiet);
6683         }
6684         break;
6685     default:
6686         assert(0);
6687     }
6688 
6689     check_msacsr_cause(env, retaddr);
6690 
6691     msa_move_v(pwd, pwx);
6692 }
6693 
6694 static inline void compare_ult(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6695                                wr_t *pwt, uint32_t df, int quiet,
6696                                uintptr_t retaddr)
6697 {
6698     wr_t wx, *pwx = &wx;
6699     uint32_t i;
6700 
6701     clear_msacsr_cause(env);
6702 
6703     switch (df) {
6704     case DF_WORD:
6705         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6706             MSA_FLOAT_ULT(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
6707         }
6708         break;
6709     case DF_DOUBLE:
6710         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6711             MSA_FLOAT_ULT(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
6712         }
6713         break;
6714     default:
6715         assert(0);
6716     }
6717 
6718     check_msacsr_cause(env, retaddr);
6719 
6720     msa_move_v(pwd, pwx);
6721 }
6722 
6723 static inline void compare_le(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6724                               wr_t *pwt, uint32_t df, int quiet,
6725                               uintptr_t retaddr)
6726 {
6727     wr_t wx, *pwx = &wx;
6728     uint32_t i;
6729 
6730     clear_msacsr_cause(env);
6731 
6732     switch (df) {
6733     case DF_WORD:
6734         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6735             MSA_FLOAT_COND(pwx->w[i], le, pws->w[i], pwt->w[i], 32, quiet);
6736         }
6737         break;
6738     case DF_DOUBLE:
6739         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6740             MSA_FLOAT_COND(pwx->d[i], le, pws->d[i], pwt->d[i], 64, quiet);
6741         }
6742         break;
6743     default:
6744         assert(0);
6745     }
6746 
6747     check_msacsr_cause(env, retaddr);
6748 
6749     msa_move_v(pwd, pwx);
6750 }
6751 
6752 static inline void compare_ule(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6753                                wr_t *pwt, uint32_t df, int quiet,
6754                                uintptr_t retaddr)
6755 {
6756     wr_t wx, *pwx = &wx;
6757     uint32_t i;
6758 
6759     clear_msacsr_cause(env);
6760 
6761     switch (df) {
6762     case DF_WORD:
6763         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6764             MSA_FLOAT_ULE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
6765         }
6766         break;
6767     case DF_DOUBLE:
6768         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6769             MSA_FLOAT_ULE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
6770         }
6771         break;
6772     default:
6773         assert(0);
6774     }
6775 
6776     check_msacsr_cause(env, retaddr);
6777 
6778     msa_move_v(pwd, pwx);
6779 }
6780 
6781 static inline void compare_or(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6782                               wr_t *pwt, uint32_t df, int quiet,
6783                               uintptr_t retaddr)
6784 {
6785     wr_t wx, *pwx = &wx;
6786     uint32_t i;
6787 
6788     clear_msacsr_cause(env);
6789 
6790     switch (df) {
6791     case DF_WORD:
6792         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6793             MSA_FLOAT_OR(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
6794         }
6795         break;
6796     case DF_DOUBLE:
6797         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6798             MSA_FLOAT_OR(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
6799         }
6800         break;
6801     default:
6802         assert(0);
6803     }
6804 
6805     check_msacsr_cause(env, retaddr);
6806 
6807     msa_move_v(pwd, pwx);
6808 }
6809 
6810 static inline void compare_une(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6811                                wr_t *pwt, uint32_t df, int quiet,
6812                                uintptr_t retaddr)
6813 {
6814     wr_t wx, *pwx = &wx;
6815     uint32_t i;
6816 
6817     clear_msacsr_cause(env);
6818 
6819     switch (df) {
6820     case DF_WORD:
6821         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6822             MSA_FLOAT_UNE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
6823         }
6824         break;
6825     case DF_DOUBLE:
6826         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6827             MSA_FLOAT_UNE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
6828         }
6829         break;
6830     default:
6831         assert(0);
6832     }
6833 
6834     check_msacsr_cause(env, retaddr);
6835 
6836     msa_move_v(pwd, pwx);
6837 }
6838 
6839 static inline void compare_ne(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
6840                               wr_t *pwt, uint32_t df, int quiet,
6841                               uintptr_t retaddr)
6842 {
6843     wr_t wx, *pwx = &wx;
6844     uint32_t i;
6845 
6846     clear_msacsr_cause(env);
6847 
6848     switch (df) {
6849     case DF_WORD:
6850         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
6851             MSA_FLOAT_NE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
6852         }
6853         break;
6854     case DF_DOUBLE:
6855         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
6856             MSA_FLOAT_NE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
6857         }
6858         break;
6859     default:
6860         assert(0);
6861     }
6862 
6863     check_msacsr_cause(env, retaddr);
6864 
6865     msa_move_v(pwd, pwx);
6866 }
6867 
6868 void helper_msa_fcaf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6869                         uint32_t ws, uint32_t wt)
6870 {
6871     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6872     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6873     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6874     compare_af(env, pwd, pws, pwt, df, 1, GETPC());
6875 }
6876 
6877 void helper_msa_fcun_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6878                         uint32_t ws, uint32_t wt)
6879 {
6880     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6881     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6882     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6883     compare_un(env, pwd, pws, pwt, df, 1, GETPC());
6884 }
6885 
6886 void helper_msa_fceq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6887                         uint32_t ws, uint32_t wt)
6888 {
6889     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6890     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6891     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6892     compare_eq(env, pwd, pws, pwt, df, 1, GETPC());
6893 }
6894 
6895 void helper_msa_fcueq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6896                          uint32_t ws, uint32_t wt)
6897 {
6898     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6899     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6900     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6901     compare_ueq(env, pwd, pws, pwt, df, 1, GETPC());
6902 }
6903 
6904 void helper_msa_fclt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6905                         uint32_t ws, uint32_t wt)
6906 {
6907     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6908     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6909     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6910     compare_lt(env, pwd, pws, pwt, df, 1, GETPC());
6911 }
6912 
6913 void helper_msa_fcult_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6914                          uint32_t ws, uint32_t wt)
6915 {
6916     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6917     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6918     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6919     compare_ult(env, pwd, pws, pwt, df, 1, GETPC());
6920 }
6921 
6922 void helper_msa_fcle_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6923                         uint32_t ws, uint32_t wt)
6924 {
6925     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6926     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6927     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6928     compare_le(env, pwd, pws, pwt, df, 1, GETPC());
6929 }
6930 
6931 void helper_msa_fcule_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6932                          uint32_t ws, uint32_t wt)
6933 {
6934     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6935     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6936     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6937     compare_ule(env, pwd, pws, pwt, df, 1, GETPC());
6938 }
6939 
6940 void helper_msa_fsaf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6941                         uint32_t ws, uint32_t wt)
6942 {
6943     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6944     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6945     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6946     compare_af(env, pwd, pws, pwt, df, 0, GETPC());
6947 }
6948 
6949 void helper_msa_fsun_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6950                         uint32_t ws, uint32_t wt)
6951 {
6952     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6953     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6954     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6955     compare_un(env, pwd, pws, pwt, df, 0, GETPC());
6956 }
6957 
6958 void helper_msa_fseq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6959                         uint32_t ws, uint32_t wt)
6960 {
6961     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6962     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6963     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6964     compare_eq(env, pwd, pws, pwt, df, 0, GETPC());
6965 }
6966 
6967 void helper_msa_fsueq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6968                          uint32_t ws, uint32_t wt)
6969 {
6970     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6971     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6972     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6973     compare_ueq(env, pwd, pws, pwt, df, 0, GETPC());
6974 }
6975 
6976 void helper_msa_fslt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6977                         uint32_t ws, uint32_t wt)
6978 {
6979     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6980     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6981     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6982     compare_lt(env, pwd, pws, pwt, df, 0, GETPC());
6983 }
6984 
6985 void helper_msa_fsult_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6986                          uint32_t ws, uint32_t wt)
6987 {
6988     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6989     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6990     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
6991     compare_ult(env, pwd, pws, pwt, df, 0, GETPC());
6992 }
6993 
6994 void helper_msa_fsle_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
6995                         uint32_t ws, uint32_t wt)
6996 {
6997     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
6998     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
6999     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7000     compare_le(env, pwd, pws, pwt, df, 0, GETPC());
7001 }
7002 
7003 void helper_msa_fsule_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7004                          uint32_t ws, uint32_t wt)
7005 {
7006     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7007     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7008     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7009     compare_ule(env, pwd, pws, pwt, df, 0, GETPC());
7010 }
7011 
7012 void helper_msa_fcor_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7013                         uint32_t ws, uint32_t wt)
7014 {
7015     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7016     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7017     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7018     compare_or(env, pwd, pws, pwt, df, 1, GETPC());
7019 }
7020 
7021 void helper_msa_fcune_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7022                          uint32_t ws, uint32_t wt)
7023 {
7024     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7025     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7026     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7027     compare_une(env, pwd, pws, pwt, df, 1, GETPC());
7028 }
7029 
7030 void helper_msa_fcne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7031                         uint32_t ws, uint32_t wt)
7032 {
7033     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7034     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7035     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7036     compare_ne(env, pwd, pws, pwt, df, 1, GETPC());
7037 }
7038 
7039 void helper_msa_fsor_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7040                         uint32_t ws, uint32_t wt)
7041 {
7042     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7043     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7044     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7045     compare_or(env, pwd, pws, pwt, df, 0, GETPC());
7046 }
7047 
7048 void helper_msa_fsune_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7049                          uint32_t ws, uint32_t wt)
7050 {
7051     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7052     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7053     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7054     compare_une(env, pwd, pws, pwt, df, 0, GETPC());
7055 }
7056 
7057 void helper_msa_fsne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7058                         uint32_t ws, uint32_t wt)
7059 {
7060     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7061     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7062     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7063     compare_ne(env, pwd, pws, pwt, df, 0, GETPC());
7064 }
7065 
7066 #define float16_is_zero(ARG) 0
7067 #define float16_is_zero_or_denormal(ARG) 0
7068 
7069 #define IS_DENORMAL(ARG, BITS)                      \
7070     (!float ## BITS ## _is_zero(ARG)                \
7071     && float ## BITS ## _is_zero_or_denormal(ARG))
7072 
7073 #define MSA_FLOAT_BINOP(DEST, OP, ARG1, ARG2, BITS)                         \
7074     do {                                                                    \
7075         float_status *status = &env->active_tc.msa_fp_status;               \
7076         int c;                                                              \
7077                                                                             \
7078         set_float_exception_flags(0, status);                               \
7079         DEST = float ## BITS ## _ ## OP(ARG1, ARG2, status);                \
7080         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
7081                                                                             \
7082         if (get_enabled_exceptions(env, c)) {                               \
7083             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
7084         }                                                                   \
7085     } while (0)
7086 
7087 void helper_msa_fadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7088         uint32_t ws, uint32_t wt)
7089 {
7090     wr_t wx, *pwx = &wx;
7091     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7092     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7093     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7094     uint32_t i;
7095 
7096     clear_msacsr_cause(env);
7097 
7098     switch (df) {
7099     case DF_WORD:
7100         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7101             MSA_FLOAT_BINOP(pwx->w[i], add, pws->w[i], pwt->w[i], 32);
7102         }
7103         break;
7104     case DF_DOUBLE:
7105         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7106             MSA_FLOAT_BINOP(pwx->d[i], add, pws->d[i], pwt->d[i], 64);
7107         }
7108         break;
7109     default:
7110         assert(0);
7111     }
7112 
7113     check_msacsr_cause(env, GETPC());
7114     msa_move_v(pwd, pwx);
7115 }
7116 
7117 void helper_msa_fsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7118         uint32_t ws, uint32_t wt)
7119 {
7120     wr_t wx, *pwx = &wx;
7121     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7122     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7123     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7124     uint32_t i;
7125 
7126     clear_msacsr_cause(env);
7127 
7128     switch (df) {
7129     case DF_WORD:
7130         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7131             MSA_FLOAT_BINOP(pwx->w[i], sub, pws->w[i], pwt->w[i], 32);
7132         }
7133         break;
7134     case DF_DOUBLE:
7135         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7136             MSA_FLOAT_BINOP(pwx->d[i], sub, pws->d[i], pwt->d[i], 64);
7137         }
7138         break;
7139     default:
7140         assert(0);
7141     }
7142 
7143     check_msacsr_cause(env, GETPC());
7144     msa_move_v(pwd, pwx);
7145 }
7146 
7147 void helper_msa_fmul_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7148         uint32_t ws, uint32_t wt)
7149 {
7150     wr_t wx, *pwx = &wx;
7151     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7152     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7153     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7154     uint32_t i;
7155 
7156     clear_msacsr_cause(env);
7157 
7158     switch (df) {
7159     case DF_WORD:
7160         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7161             MSA_FLOAT_BINOP(pwx->w[i], mul, pws->w[i], pwt->w[i], 32);
7162         }
7163         break;
7164     case DF_DOUBLE:
7165         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7166             MSA_FLOAT_BINOP(pwx->d[i], mul, pws->d[i], pwt->d[i], 64);
7167         }
7168         break;
7169     default:
7170         assert(0);
7171     }
7172 
7173     check_msacsr_cause(env, GETPC());
7174 
7175     msa_move_v(pwd, pwx);
7176 }
7177 
7178 void helper_msa_fdiv_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7179         uint32_t ws, uint32_t wt)
7180 {
7181     wr_t wx, *pwx = &wx;
7182     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7183     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7184     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7185     uint32_t i;
7186 
7187     clear_msacsr_cause(env);
7188 
7189     switch (df) {
7190     case DF_WORD:
7191         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7192             MSA_FLOAT_BINOP(pwx->w[i], div, pws->w[i], pwt->w[i], 32);
7193         }
7194         break;
7195     case DF_DOUBLE:
7196         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7197             MSA_FLOAT_BINOP(pwx->d[i], div, pws->d[i], pwt->d[i], 64);
7198         }
7199         break;
7200     default:
7201         assert(0);
7202     }
7203 
7204     check_msacsr_cause(env, GETPC());
7205 
7206     msa_move_v(pwd, pwx);
7207 }
7208 
7209 #define MSA_FLOAT_MULADD(DEST, ARG1, ARG2, ARG3, NEGATE, BITS)              \
7210     do {                                                                    \
7211         float_status *status = &env->active_tc.msa_fp_status;               \
7212         int c;                                                              \
7213                                                                             \
7214         set_float_exception_flags(0, status);                               \
7215         DEST = float ## BITS ## _muladd(ARG2, ARG3, ARG1, NEGATE, status);  \
7216         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
7217                                                                             \
7218         if (get_enabled_exceptions(env, c)) {                               \
7219             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
7220         }                                                                   \
7221     } while (0)
7222 
7223 void helper_msa_fmadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7224         uint32_t ws, uint32_t wt)
7225 {
7226     wr_t wx, *pwx = &wx;
7227     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7228     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7229     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7230     uint32_t i;
7231 
7232     clear_msacsr_cause(env);
7233 
7234     switch (df) {
7235     case DF_WORD:
7236         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7237             MSA_FLOAT_MULADD(pwx->w[i], pwd->w[i],
7238                            pws->w[i], pwt->w[i], 0, 32);
7239         }
7240         break;
7241     case DF_DOUBLE:
7242         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7243             MSA_FLOAT_MULADD(pwx->d[i], pwd->d[i],
7244                            pws->d[i], pwt->d[i], 0, 64);
7245         }
7246         break;
7247     default:
7248         assert(0);
7249     }
7250 
7251     check_msacsr_cause(env, GETPC());
7252 
7253     msa_move_v(pwd, pwx);
7254 }
7255 
7256 void helper_msa_fmsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7257         uint32_t ws, uint32_t wt)
7258 {
7259     wr_t wx, *pwx = &wx;
7260     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7261     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7262     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7263     uint32_t i;
7264 
7265     clear_msacsr_cause(env);
7266 
7267     switch (df) {
7268     case DF_WORD:
7269         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7270             MSA_FLOAT_MULADD(pwx->w[i], pwd->w[i],
7271                            pws->w[i], pwt->w[i],
7272                            float_muladd_negate_product, 32);
7273       }
7274       break;
7275     case DF_DOUBLE:
7276         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7277             MSA_FLOAT_MULADD(pwx->d[i], pwd->d[i],
7278                            pws->d[i], pwt->d[i],
7279                            float_muladd_negate_product, 64);
7280         }
7281         break;
7282     default:
7283         assert(0);
7284     }
7285 
7286     check_msacsr_cause(env, GETPC());
7287 
7288     msa_move_v(pwd, pwx);
7289 }
7290 
7291 void helper_msa_fexp2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7292         uint32_t ws, uint32_t wt)
7293 {
7294     wr_t wx, *pwx = &wx;
7295     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7296     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7297     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7298     uint32_t i;
7299 
7300     clear_msacsr_cause(env);
7301 
7302     switch (df) {
7303     case DF_WORD:
7304         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7305             MSA_FLOAT_BINOP(pwx->w[i], scalbn, pws->w[i],
7306                             pwt->w[i] >  0x200 ?  0x200 :
7307                             pwt->w[i] < -0x200 ? -0x200 : pwt->w[i],
7308                             32);
7309         }
7310         break;
7311     case DF_DOUBLE:
7312         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7313             MSA_FLOAT_BINOP(pwx->d[i], scalbn, pws->d[i],
7314                             pwt->d[i] >  0x1000 ?  0x1000 :
7315                             pwt->d[i] < -0x1000 ? -0x1000 : pwt->d[i],
7316                             64);
7317         }
7318         break;
7319     default:
7320         assert(0);
7321     }
7322 
7323     check_msacsr_cause(env, GETPC());
7324 
7325     msa_move_v(pwd, pwx);
7326 }
7327 
7328 #define MSA_FLOAT_UNOP(DEST, OP, ARG, BITS)                                 \
7329     do {                                                                    \
7330         float_status *status = &env->active_tc.msa_fp_status;               \
7331         int c;                                                              \
7332                                                                             \
7333         set_float_exception_flags(0, status);                               \
7334         DEST = float ## BITS ## _ ## OP(ARG, status);                       \
7335         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
7336                                                                             \
7337         if (get_enabled_exceptions(env, c)) {                               \
7338             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
7339         }                                                                   \
7340     } while (0)
7341 
7342 void helper_msa_fexdo_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7343                          uint32_t ws, uint32_t wt)
7344 {
7345     wr_t wx, *pwx = &wx;
7346     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7347     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7348     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7349     uint32_t i;
7350 
7351     clear_msacsr_cause(env);
7352 
7353     switch (df) {
7354     case DF_WORD:
7355         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7356             /*
7357              * Half precision floats come in two formats: standard
7358              * IEEE and "ARM" format.  The latter gains extra exponent
7359              * range by omitting the NaN/Inf encodings.
7360              */
7361             bool ieee = true;
7362 
7363             MSA_FLOAT_BINOP(Lh(pwx, i), from_float32, pws->w[i], ieee, 16);
7364             MSA_FLOAT_BINOP(Rh(pwx, i), from_float32, pwt->w[i], ieee, 16);
7365         }
7366         break;
7367     case DF_DOUBLE:
7368         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7369             MSA_FLOAT_UNOP(Lw(pwx, i), from_float64, pws->d[i], 32);
7370             MSA_FLOAT_UNOP(Rw(pwx, i), from_float64, pwt->d[i], 32);
7371         }
7372         break;
7373     default:
7374         assert(0);
7375     }
7376 
7377     check_msacsr_cause(env, GETPC());
7378     msa_move_v(pwd, pwx);
7379 }
7380 
7381 #define MSA_FLOAT_UNOP_XD(DEST, OP, ARG, BITS, XBITS)                       \
7382     do {                                                                    \
7383         float_status *status = &env->active_tc.msa_fp_status;               \
7384         int c;                                                              \
7385                                                                             \
7386         set_float_exception_flags(0, status);                               \
7387         DEST = float ## BITS ## _ ## OP(ARG, status);                       \
7388         c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0);                      \
7389                                                                             \
7390         if (get_enabled_exceptions(env, c)) {                               \
7391             DEST = ((FLOAT_SNAN ## XBITS(status) >> 6) << 6) | c;           \
7392         }                                                                   \
7393     } while (0)
7394 
7395 void helper_msa_ftq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7396                        uint32_t ws, uint32_t wt)
7397 {
7398     wr_t wx, *pwx = &wx;
7399     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7400     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7401     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7402     uint32_t i;
7403 
7404     clear_msacsr_cause(env);
7405 
7406     switch (df) {
7407     case DF_WORD:
7408         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7409             MSA_FLOAT_UNOP_XD(Lh(pwx, i), to_q16, pws->w[i], 32, 16);
7410             MSA_FLOAT_UNOP_XD(Rh(pwx, i), to_q16, pwt->w[i], 32, 16);
7411         }
7412         break;
7413     case DF_DOUBLE:
7414         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7415             MSA_FLOAT_UNOP_XD(Lw(pwx, i), to_q32, pws->d[i], 64, 32);
7416             MSA_FLOAT_UNOP_XD(Rw(pwx, i), to_q32, pwt->d[i], 64, 32);
7417         }
7418         break;
7419     default:
7420         assert(0);
7421     }
7422 
7423     check_msacsr_cause(env, GETPC());
7424 
7425     msa_move_v(pwd, pwx);
7426 }
7427 
7428 #define NUMBER_QNAN_PAIR(ARG1, ARG2, BITS, STATUS)      \
7429     !float ## BITS ## _is_any_nan(ARG1)                 \
7430     && float ## BITS ## _is_quiet_nan(ARG2, STATUS)
7431 
7432 #define MSA_FLOAT_MAXOP(DEST, OP, ARG1, ARG2, BITS)                         \
7433     do {                                                                    \
7434         float_status *status = &env->active_tc.msa_fp_status;               \
7435         int c;                                                              \
7436                                                                             \
7437         set_float_exception_flags(0, status);                               \
7438         DEST = float ## BITS ## _ ## OP(ARG1, ARG2, status);                \
7439         c = update_msacsr(env, 0, 0);                                       \
7440                                                                             \
7441         if (get_enabled_exceptions(env, c)) {                               \
7442             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
7443         }                                                                   \
7444     } while (0)
7445 
7446 #define FMAXMIN_A(F, G, X, _S, _T, BITS, STATUS)                    \
7447     do {                                                            \
7448         uint## BITS ##_t S = _S, T = _T;                            \
7449         uint## BITS ##_t as, at, xs, xt, xd;                        \
7450         if (NUMBER_QNAN_PAIR(S, T, BITS, STATUS)) {                 \
7451             T = S;                                                  \
7452         }                                                           \
7453         else if (NUMBER_QNAN_PAIR(T, S, BITS, STATUS)) {            \
7454             S = T;                                                  \
7455         }                                                           \
7456         as = float## BITS ##_abs(S);                                \
7457         at = float## BITS ##_abs(T);                                \
7458         MSA_FLOAT_MAXOP(xs, F,  S,  T, BITS);                       \
7459         MSA_FLOAT_MAXOP(xt, G,  S,  T, BITS);                       \
7460         MSA_FLOAT_MAXOP(xd, F, as, at, BITS);                       \
7461         X = (as == at || xd == float## BITS ##_abs(xs)) ? xs : xt;  \
7462     } while (0)
7463 
7464 void helper_msa_fmin_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7465         uint32_t ws, uint32_t wt)
7466 {
7467     float_status *status = &env->active_tc.msa_fp_status;
7468     wr_t wx, *pwx = &wx;
7469     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7470     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7471     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7472 
7473     clear_msacsr_cause(env);
7474 
7475     if (df == DF_WORD) {
7476 
7477         if (NUMBER_QNAN_PAIR(pws->w[0], pwt->w[0], 32, status)) {
7478             MSA_FLOAT_MAXOP(pwx->w[0], min, pws->w[0], pws->w[0], 32);
7479         } else if (NUMBER_QNAN_PAIR(pwt->w[0], pws->w[0], 32, status)) {
7480             MSA_FLOAT_MAXOP(pwx->w[0], min, pwt->w[0], pwt->w[0], 32);
7481         } else {
7482             MSA_FLOAT_MAXOP(pwx->w[0], min, pws->w[0], pwt->w[0], 32);
7483         }
7484 
7485         if (NUMBER_QNAN_PAIR(pws->w[1], pwt->w[1], 32, status)) {
7486             MSA_FLOAT_MAXOP(pwx->w[1], min, pws->w[1], pws->w[1], 32);
7487         } else if (NUMBER_QNAN_PAIR(pwt->w[1], pws->w[1], 32, status)) {
7488             MSA_FLOAT_MAXOP(pwx->w[1], min, pwt->w[1], pwt->w[1], 32);
7489         } else {
7490             MSA_FLOAT_MAXOP(pwx->w[1], min, pws->w[1], pwt->w[1], 32);
7491         }
7492 
7493         if (NUMBER_QNAN_PAIR(pws->w[2], pwt->w[2], 32, status)) {
7494             MSA_FLOAT_MAXOP(pwx->w[2], min, pws->w[2], pws->w[2], 32);
7495         } else if (NUMBER_QNAN_PAIR(pwt->w[2], pws->w[2], 32, status)) {
7496             MSA_FLOAT_MAXOP(pwx->w[2], min, pwt->w[2], pwt->w[2], 32);
7497         } else {
7498             MSA_FLOAT_MAXOP(pwx->w[2], min, pws->w[2], pwt->w[2], 32);
7499         }
7500 
7501         if (NUMBER_QNAN_PAIR(pws->w[3], pwt->w[3], 32, status)) {
7502             MSA_FLOAT_MAXOP(pwx->w[3], min, pws->w[3], pws->w[3], 32);
7503         } else if (NUMBER_QNAN_PAIR(pwt->w[3], pws->w[3], 32, status)) {
7504             MSA_FLOAT_MAXOP(pwx->w[3], min, pwt->w[3], pwt->w[3], 32);
7505         } else {
7506             MSA_FLOAT_MAXOP(pwx->w[3], min, pws->w[3], pwt->w[3], 32);
7507         }
7508 
7509     } else if (df == DF_DOUBLE) {
7510 
7511         if (NUMBER_QNAN_PAIR(pws->d[0], pwt->d[0], 64, status)) {
7512             MSA_FLOAT_MAXOP(pwx->d[0], min, pws->d[0], pws->d[0], 64);
7513         } else if (NUMBER_QNAN_PAIR(pwt->d[0], pws->d[0], 64, status)) {
7514             MSA_FLOAT_MAXOP(pwx->d[0], min, pwt->d[0], pwt->d[0], 64);
7515         } else {
7516             MSA_FLOAT_MAXOP(pwx->d[0], min, pws->d[0], pwt->d[0], 64);
7517         }
7518 
7519         if (NUMBER_QNAN_PAIR(pws->d[1], pwt->d[1], 64, status)) {
7520             MSA_FLOAT_MAXOP(pwx->d[1], min, pws->d[1], pws->d[1], 64);
7521         } else if (NUMBER_QNAN_PAIR(pwt->d[1], pws->d[1], 64, status)) {
7522             MSA_FLOAT_MAXOP(pwx->d[1], min, pwt->d[1], pwt->d[1], 64);
7523         } else {
7524             MSA_FLOAT_MAXOP(pwx->d[1], min, pws->d[1], pwt->d[1], 64);
7525         }
7526 
7527     } else {
7528 
7529         assert(0);
7530 
7531     }
7532 
7533     check_msacsr_cause(env, GETPC());
7534 
7535     msa_move_v(pwd, pwx);
7536 }
7537 
7538 void helper_msa_fmin_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7539         uint32_t ws, uint32_t wt)
7540 {
7541     float_status *status = &env->active_tc.msa_fp_status;
7542     wr_t wx, *pwx = &wx;
7543     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7544     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7545     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7546 
7547     clear_msacsr_cause(env);
7548 
7549     if (df == DF_WORD) {
7550         FMAXMIN_A(min, max, pwx->w[0], pws->w[0], pwt->w[0], 32, status);
7551         FMAXMIN_A(min, max, pwx->w[1], pws->w[1], pwt->w[1], 32, status);
7552         FMAXMIN_A(min, max, pwx->w[2], pws->w[2], pwt->w[2], 32, status);
7553         FMAXMIN_A(min, max, pwx->w[3], pws->w[3], pwt->w[3], 32, status);
7554     } else if (df == DF_DOUBLE) {
7555         FMAXMIN_A(min, max, pwx->d[0], pws->d[0], pwt->d[0], 64, status);
7556         FMAXMIN_A(min, max, pwx->d[1], pws->d[1], pwt->d[1], 64, status);
7557     } else {
7558         assert(0);
7559     }
7560 
7561     check_msacsr_cause(env, GETPC());
7562 
7563     msa_move_v(pwd, pwx);
7564 }
7565 
7566 void helper_msa_fmax_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7567         uint32_t ws, uint32_t wt)
7568 {
7569      float_status *status = &env->active_tc.msa_fp_status;
7570     wr_t wx, *pwx = &wx;
7571     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7572     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7573     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7574 
7575     clear_msacsr_cause(env);
7576 
7577     if (df == DF_WORD) {
7578 
7579         if (NUMBER_QNAN_PAIR(pws->w[0], pwt->w[0], 32, status)) {
7580             MSA_FLOAT_MAXOP(pwx->w[0], max, pws->w[0], pws->w[0], 32);
7581         } else if (NUMBER_QNAN_PAIR(pwt->w[0], pws->w[0], 32, status)) {
7582             MSA_FLOAT_MAXOP(pwx->w[0], max, pwt->w[0], pwt->w[0], 32);
7583         } else {
7584             MSA_FLOAT_MAXOP(pwx->w[0], max, pws->w[0], pwt->w[0], 32);
7585         }
7586 
7587         if (NUMBER_QNAN_PAIR(pws->w[1], pwt->w[1], 32, status)) {
7588             MSA_FLOAT_MAXOP(pwx->w[1], max, pws->w[1], pws->w[1], 32);
7589         } else if (NUMBER_QNAN_PAIR(pwt->w[1], pws->w[1], 32, status)) {
7590             MSA_FLOAT_MAXOP(pwx->w[1], max, pwt->w[1], pwt->w[1], 32);
7591         } else {
7592             MSA_FLOAT_MAXOP(pwx->w[1], max, pws->w[1], pwt->w[1], 32);
7593         }
7594 
7595         if (NUMBER_QNAN_PAIR(pws->w[2], pwt->w[2], 32, status)) {
7596             MSA_FLOAT_MAXOP(pwx->w[2], max, pws->w[2], pws->w[2], 32);
7597         } else if (NUMBER_QNAN_PAIR(pwt->w[2], pws->w[2], 32, status)) {
7598             MSA_FLOAT_MAXOP(pwx->w[2], max, pwt->w[2], pwt->w[2], 32);
7599         } else {
7600             MSA_FLOAT_MAXOP(pwx->w[2], max, pws->w[2], pwt->w[2], 32);
7601         }
7602 
7603         if (NUMBER_QNAN_PAIR(pws->w[3], pwt->w[3], 32, status)) {
7604             MSA_FLOAT_MAXOP(pwx->w[3], max, pws->w[3], pws->w[3], 32);
7605         } else if (NUMBER_QNAN_PAIR(pwt->w[3], pws->w[3], 32, status)) {
7606             MSA_FLOAT_MAXOP(pwx->w[3], max, pwt->w[3], pwt->w[3], 32);
7607         } else {
7608             MSA_FLOAT_MAXOP(pwx->w[3], max, pws->w[3], pwt->w[3], 32);
7609         }
7610 
7611     } else if (df == DF_DOUBLE) {
7612 
7613         if (NUMBER_QNAN_PAIR(pws->d[0], pwt->d[0], 64, status)) {
7614             MSA_FLOAT_MAXOP(pwx->d[0], max, pws->d[0], pws->d[0], 64);
7615         } else if (NUMBER_QNAN_PAIR(pwt->d[0], pws->d[0], 64, status)) {
7616             MSA_FLOAT_MAXOP(pwx->d[0], max, pwt->d[0], pwt->d[0], 64);
7617         } else {
7618             MSA_FLOAT_MAXOP(pwx->d[0], max, pws->d[0], pwt->d[0], 64);
7619         }
7620 
7621         if (NUMBER_QNAN_PAIR(pws->d[1], pwt->d[1], 64, status)) {
7622             MSA_FLOAT_MAXOP(pwx->d[1], max, pws->d[1], pws->d[1], 64);
7623         } else if (NUMBER_QNAN_PAIR(pwt->d[1], pws->d[1], 64, status)) {
7624             MSA_FLOAT_MAXOP(pwx->d[1], max, pwt->d[1], pwt->d[1], 64);
7625         } else {
7626             MSA_FLOAT_MAXOP(pwx->d[1], max, pws->d[1], pwt->d[1], 64);
7627         }
7628 
7629     } else {
7630 
7631         assert(0);
7632 
7633     }
7634 
7635     check_msacsr_cause(env, GETPC());
7636 
7637     msa_move_v(pwd, pwx);
7638 }
7639 
7640 void helper_msa_fmax_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7641         uint32_t ws, uint32_t wt)
7642 {
7643     float_status *status = &env->active_tc.msa_fp_status;
7644     wr_t wx, *pwx = &wx;
7645     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7646     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7647     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
7648 
7649     clear_msacsr_cause(env);
7650 
7651     if (df == DF_WORD) {
7652         FMAXMIN_A(max, min, pwx->w[0], pws->w[0], pwt->w[0], 32, status);
7653         FMAXMIN_A(max, min, pwx->w[1], pws->w[1], pwt->w[1], 32, status);
7654         FMAXMIN_A(max, min, pwx->w[2], pws->w[2], pwt->w[2], 32, status);
7655         FMAXMIN_A(max, min, pwx->w[3], pws->w[3], pwt->w[3], 32, status);
7656     } else if (df == DF_DOUBLE) {
7657         FMAXMIN_A(max, min, pwx->d[0], pws->d[0], pwt->d[0], 64, status);
7658         FMAXMIN_A(max, min, pwx->d[1], pws->d[1], pwt->d[1], 64, status);
7659     } else {
7660         assert(0);
7661     }
7662 
7663     check_msacsr_cause(env, GETPC());
7664 
7665     msa_move_v(pwd, pwx);
7666 }
7667 
7668 void helper_msa_fclass_df(CPUMIPSState *env, uint32_t df,
7669         uint32_t wd, uint32_t ws)
7670 {
7671     float_status *status = &env->active_tc.msa_fp_status;
7672 
7673     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7674     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7675     if (df == DF_WORD) {
7676         pwd->w[0] = float_class_s(pws->w[0], status);
7677         pwd->w[1] = float_class_s(pws->w[1], status);
7678         pwd->w[2] = float_class_s(pws->w[2], status);
7679         pwd->w[3] = float_class_s(pws->w[3], status);
7680     } else if (df == DF_DOUBLE) {
7681         pwd->d[0] = float_class_d(pws->d[0], status);
7682         pwd->d[1] = float_class_d(pws->d[1], status);
7683     } else {
7684         assert(0);
7685     }
7686 }
7687 
7688 #define MSA_FLOAT_UNOP0(DEST, OP, ARG, BITS)                                \
7689     do {                                                                    \
7690         float_status *status = &env->active_tc.msa_fp_status;               \
7691         int c;                                                              \
7692                                                                             \
7693         set_float_exception_flags(0, status);                               \
7694         DEST = float ## BITS ## _ ## OP(ARG, status);                       \
7695         c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0);                      \
7696                                                                             \
7697         if (get_enabled_exceptions(env, c)) {                               \
7698             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
7699         } else if (float ## BITS ## _is_any_nan(ARG)) {                     \
7700             DEST = 0;                                                       \
7701         }                                                                   \
7702     } while (0)
7703 
7704 void helper_msa_ftrunc_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7705                             uint32_t ws)
7706 {
7707     wr_t wx, *pwx = &wx;
7708     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7709     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7710     uint32_t i;
7711 
7712     clear_msacsr_cause(env);
7713 
7714     switch (df) {
7715     case DF_WORD:
7716         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7717             MSA_FLOAT_UNOP0(pwx->w[i], to_int32_round_to_zero, pws->w[i], 32);
7718         }
7719         break;
7720     case DF_DOUBLE:
7721         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7722             MSA_FLOAT_UNOP0(pwx->d[i], to_int64_round_to_zero, pws->d[i], 64);
7723         }
7724         break;
7725     default:
7726         assert(0);
7727     }
7728 
7729     check_msacsr_cause(env, GETPC());
7730 
7731     msa_move_v(pwd, pwx);
7732 }
7733 
7734 void helper_msa_ftrunc_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7735                             uint32_t ws)
7736 {
7737     wr_t wx, *pwx = &wx;
7738     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7739     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7740     uint32_t i;
7741 
7742     clear_msacsr_cause(env);
7743 
7744     switch (df) {
7745     case DF_WORD:
7746         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7747             MSA_FLOAT_UNOP0(pwx->w[i], to_uint32_round_to_zero, pws->w[i], 32);
7748         }
7749         break;
7750     case DF_DOUBLE:
7751         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7752             MSA_FLOAT_UNOP0(pwx->d[i], to_uint64_round_to_zero, pws->d[i], 64);
7753         }
7754         break;
7755     default:
7756         assert(0);
7757     }
7758 
7759     check_msacsr_cause(env, GETPC());
7760 
7761     msa_move_v(pwd, pwx);
7762 }
7763 
7764 void helper_msa_fsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7765                          uint32_t ws)
7766 {
7767     wr_t wx, *pwx = &wx;
7768     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7769     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7770     uint32_t i;
7771 
7772     clear_msacsr_cause(env);
7773 
7774     switch (df) {
7775     case DF_WORD:
7776         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7777             MSA_FLOAT_UNOP(pwx->w[i], sqrt, pws->w[i], 32);
7778         }
7779         break;
7780     case DF_DOUBLE:
7781         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7782             MSA_FLOAT_UNOP(pwx->d[i], sqrt, pws->d[i], 64);
7783         }
7784         break;
7785     default:
7786         assert(0);
7787     }
7788 
7789     check_msacsr_cause(env, GETPC());
7790 
7791     msa_move_v(pwd, pwx);
7792 }
7793 
7794 #define MSA_FLOAT_RECIPROCAL(DEST, ARG, BITS)                               \
7795     do {                                                                    \
7796         float_status *status = &env->active_tc.msa_fp_status;               \
7797         int c;                                                              \
7798                                                                             \
7799         set_float_exception_flags(0, status);                               \
7800         DEST = float ## BITS ## _ ## div(FLOAT_ONE ## BITS, ARG, status);   \
7801         c = update_msacsr(env, float ## BITS ## _is_infinity(ARG) ||        \
7802                           float ## BITS ## _is_quiet_nan(DEST, status) ?    \
7803                           0 : RECIPROCAL_INEXACT,                           \
7804                           IS_DENORMAL(DEST, BITS));                         \
7805                                                                             \
7806         if (get_enabled_exceptions(env, c)) {                               \
7807             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
7808         }                                                                   \
7809     } while (0)
7810 
7811 void helper_msa_frsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7812                           uint32_t ws)
7813 {
7814     wr_t wx, *pwx = &wx;
7815     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7816     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7817     uint32_t i;
7818 
7819     clear_msacsr_cause(env);
7820 
7821     switch (df) {
7822     case DF_WORD:
7823         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7824             MSA_FLOAT_RECIPROCAL(pwx->w[i], float32_sqrt(pws->w[i],
7825                     &env->active_tc.msa_fp_status), 32);
7826         }
7827         break;
7828     case DF_DOUBLE:
7829         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7830             MSA_FLOAT_RECIPROCAL(pwx->d[i], float64_sqrt(pws->d[i],
7831                     &env->active_tc.msa_fp_status), 64);
7832         }
7833         break;
7834     default:
7835         assert(0);
7836     }
7837 
7838     check_msacsr_cause(env, GETPC());
7839 
7840     msa_move_v(pwd, pwx);
7841 }
7842 
7843 void helper_msa_frcp_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7844                         uint32_t ws)
7845 {
7846     wr_t wx, *pwx = &wx;
7847     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7848     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7849     uint32_t i;
7850 
7851     clear_msacsr_cause(env);
7852 
7853     switch (df) {
7854     case DF_WORD:
7855         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7856             MSA_FLOAT_RECIPROCAL(pwx->w[i], pws->w[i], 32);
7857         }
7858         break;
7859     case DF_DOUBLE:
7860         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7861             MSA_FLOAT_RECIPROCAL(pwx->d[i], pws->d[i], 64);
7862         }
7863         break;
7864     default:
7865         assert(0);
7866     }
7867 
7868     check_msacsr_cause(env, GETPC());
7869 
7870     msa_move_v(pwd, pwx);
7871 }
7872 
7873 void helper_msa_frint_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7874                          uint32_t ws)
7875 {
7876     wr_t wx, *pwx = &wx;
7877     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7878     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7879     uint32_t i;
7880 
7881     clear_msacsr_cause(env);
7882 
7883     switch (df) {
7884     case DF_WORD:
7885         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7886             MSA_FLOAT_UNOP(pwx->w[i], round_to_int, pws->w[i], 32);
7887         }
7888         break;
7889     case DF_DOUBLE:
7890         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7891             MSA_FLOAT_UNOP(pwx->d[i], round_to_int, pws->d[i], 64);
7892         }
7893         break;
7894     default:
7895         assert(0);
7896     }
7897 
7898     check_msacsr_cause(env, GETPC());
7899 
7900     msa_move_v(pwd, pwx);
7901 }
7902 
7903 #define MSA_FLOAT_LOGB(DEST, ARG, BITS)                                     \
7904     do {                                                                    \
7905         float_status *status = &env->active_tc.msa_fp_status;               \
7906         int c;                                                              \
7907                                                                             \
7908         set_float_exception_flags(0, status);                               \
7909         set_float_rounding_mode(float_round_down, status);                  \
7910         DEST = float ## BITS ## _ ## log2(ARG, status);                     \
7911         DEST = float ## BITS ## _ ## round_to_int(DEST, status);            \
7912         set_float_rounding_mode(ieee_rm[(env->active_tc.msacsr &            \
7913                                          MSACSR_RM_MASK) >> MSACSR_RM],     \
7914                                 status);                                    \
7915                                                                             \
7916         set_float_exception_flags(get_float_exception_flags(status) &       \
7917                                   (~float_flag_inexact),                    \
7918                                   status);                                  \
7919                                                                             \
7920         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
7921                                                                             \
7922         if (get_enabled_exceptions(env, c)) {                               \
7923             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
7924         }                                                                   \
7925     } while (0)
7926 
7927 void helper_msa_flog2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7928                          uint32_t ws)
7929 {
7930     wr_t wx, *pwx = &wx;
7931     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7932     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7933     uint32_t i;
7934 
7935     clear_msacsr_cause(env);
7936 
7937     switch (df) {
7938     case DF_WORD:
7939         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7940             MSA_FLOAT_LOGB(pwx->w[i], pws->w[i], 32);
7941         }
7942         break;
7943     case DF_DOUBLE:
7944         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7945             MSA_FLOAT_LOGB(pwx->d[i], pws->d[i], 64);
7946         }
7947         break;
7948     default:
7949         assert(0);
7950     }
7951 
7952     check_msacsr_cause(env, GETPC());
7953 
7954     msa_move_v(pwd, pwx);
7955 }
7956 
7957 void helper_msa_fexupl_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7958                           uint32_t ws)
7959 {
7960     wr_t wx, *pwx = &wx;
7961     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7962     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7963     uint32_t i;
7964 
7965     clear_msacsr_cause(env);
7966 
7967     switch (df) {
7968     case DF_WORD:
7969         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
7970             /*
7971              * Half precision floats come in two formats: standard
7972              * IEEE and "ARM" format.  The latter gains extra exponent
7973              * range by omitting the NaN/Inf encodings.
7974              */
7975             bool ieee = true;
7976 
7977             MSA_FLOAT_BINOP(pwx->w[i], from_float16, Lh(pws, i), ieee, 32);
7978         }
7979         break;
7980     case DF_DOUBLE:
7981         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
7982             MSA_FLOAT_UNOP(pwx->d[i], from_float32, Lw(pws, i), 64);
7983         }
7984         break;
7985     default:
7986         assert(0);
7987     }
7988 
7989     check_msacsr_cause(env, GETPC());
7990     msa_move_v(pwd, pwx);
7991 }
7992 
7993 void helper_msa_fexupr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
7994                           uint32_t ws)
7995 {
7996     wr_t wx, *pwx = &wx;
7997     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
7998     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
7999     uint32_t i;
8000 
8001     clear_msacsr_cause(env);
8002 
8003     switch (df) {
8004     case DF_WORD:
8005         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
8006             /*
8007              * Half precision floats come in two formats: standard
8008              * IEEE and "ARM" format.  The latter gains extra exponent
8009              * range by omitting the NaN/Inf encodings.
8010              */
8011             bool ieee = true;
8012 
8013             MSA_FLOAT_BINOP(pwx->w[i], from_float16, Rh(pws, i), ieee, 32);
8014         }
8015         break;
8016     case DF_DOUBLE:
8017         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
8018             MSA_FLOAT_UNOP(pwx->d[i], from_float32, Rw(pws, i), 64);
8019         }
8020         break;
8021     default:
8022         assert(0);
8023     }
8024 
8025     check_msacsr_cause(env, GETPC());
8026     msa_move_v(pwd, pwx);
8027 }
8028 
8029 void helper_msa_ffql_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
8030                         uint32_t ws)
8031 {
8032     wr_t wx, *pwx = &wx;
8033     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
8034     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
8035     uint32_t i;
8036 
8037     switch (df) {
8038     case DF_WORD:
8039         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
8040             MSA_FLOAT_UNOP(pwx->w[i], from_q16, Lh(pws, i), 32);
8041         }
8042         break;
8043     case DF_DOUBLE:
8044         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
8045             MSA_FLOAT_UNOP(pwx->d[i], from_q32, Lw(pws, i), 64);
8046         }
8047         break;
8048     default:
8049         assert(0);
8050     }
8051 
8052     msa_move_v(pwd, pwx);
8053 }
8054 
8055 void helper_msa_ffqr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
8056                         uint32_t ws)
8057 {
8058     wr_t wx, *pwx = &wx;
8059     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
8060     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
8061     uint32_t i;
8062 
8063     switch (df) {
8064     case DF_WORD:
8065         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
8066             MSA_FLOAT_UNOP(pwx->w[i], from_q16, Rh(pws, i), 32);
8067         }
8068         break;
8069     case DF_DOUBLE:
8070         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
8071             MSA_FLOAT_UNOP(pwx->d[i], from_q32, Rw(pws, i), 64);
8072         }
8073         break;
8074     default:
8075         assert(0);
8076     }
8077 
8078     msa_move_v(pwd, pwx);
8079 }
8080 
8081 void helper_msa_ftint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
8082                            uint32_t ws)
8083 {
8084     wr_t wx, *pwx = &wx;
8085     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
8086     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
8087     uint32_t i;
8088 
8089     clear_msacsr_cause(env);
8090 
8091     switch (df) {
8092     case DF_WORD:
8093         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
8094             MSA_FLOAT_UNOP0(pwx->w[i], to_int32, pws->w[i], 32);
8095         }
8096         break;
8097     case DF_DOUBLE:
8098         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
8099             MSA_FLOAT_UNOP0(pwx->d[i], to_int64, pws->d[i], 64);
8100         }
8101         break;
8102     default:
8103         assert(0);
8104     }
8105 
8106     check_msacsr_cause(env, GETPC());
8107 
8108     msa_move_v(pwd, pwx);
8109 }
8110 
8111 void helper_msa_ftint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
8112                            uint32_t ws)
8113 {
8114     wr_t wx, *pwx = &wx;
8115     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
8116     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
8117     uint32_t i;
8118 
8119     clear_msacsr_cause(env);
8120 
8121     switch (df) {
8122     case DF_WORD:
8123         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
8124             MSA_FLOAT_UNOP0(pwx->w[i], to_uint32, pws->w[i], 32);
8125         }
8126         break;
8127     case DF_DOUBLE:
8128         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
8129             MSA_FLOAT_UNOP0(pwx->d[i], to_uint64, pws->d[i], 64);
8130         }
8131         break;
8132     default:
8133         assert(0);
8134     }
8135 
8136     check_msacsr_cause(env, GETPC());
8137 
8138     msa_move_v(pwd, pwx);
8139 }
8140 
8141 #define float32_from_int32 int32_to_float32
8142 #define float32_from_uint32 uint32_to_float32
8143 
8144 #define float64_from_int64 int64_to_float64
8145 #define float64_from_uint64 uint64_to_float64
8146 
8147 void helper_msa_ffint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
8148                            uint32_t ws)
8149 {
8150     wr_t wx, *pwx = &wx;
8151     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
8152     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
8153     uint32_t i;
8154 
8155     clear_msacsr_cause(env);
8156 
8157     switch (df) {
8158     case DF_WORD:
8159         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
8160             MSA_FLOAT_UNOP(pwx->w[i], from_int32, pws->w[i], 32);
8161         }
8162         break;
8163     case DF_DOUBLE:
8164         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
8165             MSA_FLOAT_UNOP(pwx->d[i], from_int64, pws->d[i], 64);
8166         }
8167         break;
8168     default:
8169         assert(0);
8170     }
8171 
8172     check_msacsr_cause(env, GETPC());
8173 
8174     msa_move_v(pwd, pwx);
8175 }
8176 
8177 void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
8178                            uint32_t ws)
8179 {
8180     wr_t wx, *pwx = &wx;
8181     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
8182     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
8183     uint32_t i;
8184 
8185     clear_msacsr_cause(env);
8186 
8187     switch (df) {
8188     case DF_WORD:
8189         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
8190             MSA_FLOAT_UNOP(pwx->w[i], from_uint32, pws->w[i], 32);
8191         }
8192         break;
8193     case DF_DOUBLE:
8194         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
8195             MSA_FLOAT_UNOP(pwx->d[i], from_uint64, pws->d[i], 64);
8196         }
8197         break;
8198     default:
8199         assert(0);
8200     }
8201 
8202     check_msacsr_cause(env, GETPC());
8203 
8204     msa_move_v(pwd, pwx);
8205 }
8206 
8207 /* Data format min and max values */
8208 #define DF_BITS(df) (1 << ((df) + 3))
8209 
8210 /* Element-by-element access macros */
8211 #define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df))
8212 
8213 #if !defined(CONFIG_USER_ONLY)
8214 #define MEMOP_IDX(DF)                                                   \
8215     MemOpIdx oi = make_memop_idx(MO_TE | DF | MO_UNALN,                 \
8216                                  cpu_mmu_index(env, false));
8217 #else
8218 #define MEMOP_IDX(DF)
8219 #endif
8220 
8221 #ifdef TARGET_WORDS_BIGENDIAN
8222 static inline uint64_t bswap16x4(uint64_t x)
8223 {
8224     uint64_t m = 0x00ff00ff00ff00ffull;
8225     return ((x & m) << 8) | ((x >> 8) & m);
8226 }
8227 
8228 static inline uint64_t bswap32x2(uint64_t x)
8229 {
8230     return ror64(bswap64(x), 32);
8231 }
8232 #endif
8233 
8234 void helper_msa_ld_b(CPUMIPSState *env, uint32_t wd,
8235                      target_ulong addr)
8236 {
8237     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
8238     uintptr_t ra = GETPC();
8239     uint64_t d0, d1;
8240 
8241     /* Load 8 bytes at a time.  Vector element ordering makes this LE.  */
8242     d0 = cpu_ldq_le_data_ra(env, addr + 0, ra);
8243     d1 = cpu_ldq_le_data_ra(env, addr + 8, ra);
8244     pwd->d[0] = d0;
8245     pwd->d[1] = d1;
8246 }
8247 
8248 void helper_msa_ld_h(CPUMIPSState *env, uint32_t wd,
8249                      target_ulong addr)
8250 {
8251     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
8252     uintptr_t ra = GETPC();
8253     uint64_t d0, d1;
8254 
8255     /*
8256      * Load 8 bytes at a time.  Use little-endian load, then for
8257      * big-endian target, we must then swap the four halfwords.
8258      */
8259     d0 = cpu_ldq_le_data_ra(env, addr + 0, ra);
8260     d1 = cpu_ldq_le_data_ra(env, addr + 8, ra);
8261 #ifdef TARGET_WORDS_BIGENDIAN
8262     d0 = bswap16x4(d0);
8263     d1 = bswap16x4(d1);
8264 #endif
8265     pwd->d[0] = d0;
8266     pwd->d[1] = d1;
8267 }
8268 
8269 void helper_msa_ld_w(CPUMIPSState *env, uint32_t wd,
8270                      target_ulong addr)
8271 {
8272     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
8273     uintptr_t ra = GETPC();
8274     uint64_t d0, d1;
8275 
8276     /*
8277      * Load 8 bytes at a time.  Use little-endian load, then for
8278      * big-endian target, we must then bswap the two words.
8279      */
8280     d0 = cpu_ldq_le_data_ra(env, addr + 0, ra);
8281     d1 = cpu_ldq_le_data_ra(env, addr + 8, ra);
8282 #ifdef TARGET_WORDS_BIGENDIAN
8283     d0 = bswap32x2(d0);
8284     d1 = bswap32x2(d1);
8285 #endif
8286     pwd->d[0] = d0;
8287     pwd->d[1] = d1;
8288 }
8289 
8290 void helper_msa_ld_d(CPUMIPSState *env, uint32_t wd,
8291                      target_ulong addr)
8292 {
8293     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
8294     uintptr_t ra = GETPC();
8295     uint64_t d0, d1;
8296 
8297     d0 = cpu_ldq_data_ra(env, addr + 0, ra);
8298     d1 = cpu_ldq_data_ra(env, addr + 8, ra);
8299     pwd->d[0] = d0;
8300     pwd->d[1] = d1;
8301 }
8302 
8303 #define MSA_PAGESPAN(x) \
8304         ((((x) & ~TARGET_PAGE_MASK) + MSA_WRLEN / 8 - 1) >= TARGET_PAGE_SIZE)
8305 
8306 static inline void ensure_writable_pages(CPUMIPSState *env,
8307                                          target_ulong addr,
8308                                          int mmu_idx,
8309                                          uintptr_t retaddr)
8310 {
8311     /* FIXME: Probe the actual accesses (pass and use a size) */
8312     if (unlikely(MSA_PAGESPAN(addr))) {
8313         /* first page */
8314         probe_write(env, addr, 0, mmu_idx, retaddr);
8315         /* second page */
8316         addr = (addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
8317         probe_write(env, addr, 0, mmu_idx, retaddr);
8318     }
8319 }
8320 
8321 void helper_msa_st_b(CPUMIPSState *env, uint32_t wd,
8322                      target_ulong addr)
8323 {
8324     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
8325     int mmu_idx = cpu_mmu_index(env, false);
8326     uintptr_t ra = GETPC();
8327 
8328     ensure_writable_pages(env, addr, mmu_idx, ra);
8329 
8330     /* Store 8 bytes at a time.  Vector element ordering makes this LE.  */
8331     cpu_stq_le_data_ra(env, addr + 0, pwd->d[0], ra);
8332     cpu_stq_le_data_ra(env, addr + 0, pwd->d[1], ra);
8333 }
8334 
8335 void helper_msa_st_h(CPUMIPSState *env, uint32_t wd,
8336                      target_ulong addr)
8337 {
8338     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
8339     int mmu_idx = cpu_mmu_index(env, false);
8340     uintptr_t ra = GETPC();
8341     uint64_t d0, d1;
8342 
8343     ensure_writable_pages(env, addr, mmu_idx, ra);
8344 
8345     /* Store 8 bytes at a time.  See helper_msa_ld_h. */
8346     d0 = pwd->d[0];
8347     d1 = pwd->d[1];
8348 #ifdef TARGET_WORDS_BIGENDIAN
8349     d0 = bswap16x4(d0);
8350     d1 = bswap16x4(d1);
8351 #endif
8352     cpu_stq_le_data_ra(env, addr + 0, d0, ra);
8353     cpu_stq_le_data_ra(env, addr + 8, d1, ra);
8354 }
8355 
8356 void helper_msa_st_w(CPUMIPSState *env, uint32_t wd,
8357                      target_ulong addr)
8358 {
8359     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
8360     int mmu_idx = cpu_mmu_index(env, false);
8361     uintptr_t ra = GETPC();
8362     uint64_t d0, d1;
8363 
8364     ensure_writable_pages(env, addr, mmu_idx, ra);
8365 
8366     /* Store 8 bytes at a time.  See helper_msa_ld_w. */
8367     d0 = pwd->d[0];
8368     d1 = pwd->d[1];
8369 #ifdef TARGET_WORDS_BIGENDIAN
8370     d0 = bswap32x2(d0);
8371     d1 = bswap32x2(d1);
8372 #endif
8373     cpu_stq_le_data_ra(env, addr + 0, d0, ra);
8374     cpu_stq_le_data_ra(env, addr + 8, d1, ra);
8375 }
8376 
8377 void helper_msa_st_d(CPUMIPSState *env, uint32_t wd,
8378                      target_ulong addr)
8379 {
8380     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
8381     int mmu_idx = cpu_mmu_index(env, false);
8382     uintptr_t ra = GETPC();
8383 
8384     ensure_writable_pages(env, addr, mmu_idx, GETPC());
8385 
8386     cpu_stq_data_ra(env, addr + 0, pwd->d[0], ra);
8387     cpu_stq_data_ra(env, addr + 8, pwd->d[1], ra);
8388 }
8389