]> Git Repo - qemu.git/blob - target/mips/msa_helper.c
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.1-20190612' into staging
[qemu.git] / target / mips / msa_helper.c
1 /*
2  * MIPS SIMD Architecture Module Instruction emulation helpers for QEMU.
3  *
4  * Copyright (c) 2014 Imagination Technologies
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "qemu/osdep.h"
21 #include "cpu.h"
22 #include "internal.h"
23 #include "exec/exec-all.h"
24 #include "exec/helper-proto.h"
25
26 /* Data format min and max values */
27 #define DF_BITS(df) (1 << ((df) + 3))
28
29 #define DF_MAX_INT(df)  (int64_t)((1LL << (DF_BITS(df) - 1)) - 1)
30 #define M_MAX_INT(m)    (int64_t)((1LL << ((m)         - 1)) - 1)
31
32 #define DF_MIN_INT(df)  (int64_t)(-(1LL << (DF_BITS(df) - 1)))
33 #define M_MIN_INT(m)    (int64_t)(-(1LL << ((m)         - 1)))
34
35 #define DF_MAX_UINT(df) (uint64_t)(-1ULL >> (64 - DF_BITS(df)))
36 #define M_MAX_UINT(m)   (uint64_t)(-1ULL >> (64 - (m)))
37
38 #define UNSIGNED(x, df) ((x) & DF_MAX_UINT(df))
39 #define SIGNED(x, df)                                                   \
40     ((((int64_t)x) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df)))
41
42 /* Element-by-element access macros */
43 #define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df))
44
45
46
47 /*
48  * Bit Count
49  * ---------
50  *
51  * +---------------+----------------------------------------------------------+
52  * | NLOC.B        | Vector Leading Ones Count (byte)                         |
53  * | NLOC.H        | Vector Leading Ones Count (halfword)                     |
54  * | NLOC.W        | Vector Leading Ones Count (word)                         |
55  * | NLOC.D        | Vector Leading Ones Count (doubleword)                   |
56  * | NLZC.B        | Vector Leading Zeros Count (byte)                        |
57  * | NLZC.H        | Vector Leading Zeros Count (halfword)                    |
58  * | NLZC.W        | Vector Leading Zeros Count (word)                        |
59  * | NLZC.D        | Vector Leading Zeros Count (doubleword)                  |
60  * | PCNT.B        | Vector Population Count (byte)                           |
61  * | PCNT.H        | Vector Population Count (halfword)                       |
62  * | PCNT.W        | Vector Population Count (word)                           |
63  * | PCNT.D        | Vector Population Count (doubleword)                     |
64  * +---------------+----------------------------------------------------------+
65  */
66
67 /* TODO: insert Bit Count group helpers here */
68
69
70 /*
71  * Bit Move
72  * --------
73  *
74  * +---------------+----------------------------------------------------------+
75  * | BMNZ.V        | Vector Bit Move If Not Zero                              |
76  * | BMZ.V         | Vector Bit Move If Zero                                  |
77  * | BSEL.V        | Vector Bit Select                                        |
78  * | BINSL.B       | Vector Bit Insert Left (byte)                            |
79  * | BINSL.H       | Vector Bit Insert Left (halfword)                        |
80  * | BINSL.W       | Vector Bit Insert Left (word)                            |
81  * | BINSL.D       | Vector Bit Insert Left (doubleword)                      |
82  * | BINSR.B       | Vector Bit Insert Right (byte)                           |
83  * | BINSR.H       | Vector Bit Insert Right (halfword)                       |
84  * | BINSR.W       | Vector Bit Insert Right (word)                           |
85  * | BINSR.D       | Vector Bit Insert Right (doubleword)                     |
86  * +---------------+----------------------------------------------------------+
87  */
88
89 /* TODO: insert Bit Move group helpers here */
90
91
92 /*
93  * Bit Set
94  * -------
95  *
96  * +---------------+----------------------------------------------------------+
97  * | BCLR.B        | Vector Bit Clear (byte)                                  |
98  * | BCLR.H        | Vector Bit Clear (halfword)                              |
99  * | BCLR.W        | Vector Bit Clear (word)                                  |
100  * | BCLR.D        | Vector Bit Clear (doubleword)                            |
101  * | BNEG.B        | Vector Bit Negate (byte)                                 |
102  * | BNEG.H        | Vector Bit Negate (halfword)                             |
103  * | BNEG.W        | Vector Bit Negate (word)                                 |
104  * | BNEG.D        | Vector Bit Negate (doubleword)                           |
105  * | BSET.B        | Vector Bit Set (byte)                                    |
106  * | BSET.H        | Vector Bit Set (halfword)                                |
107  * | BSET.W        | Vector Bit Set (word)                                    |
108  * | BSET.D        | Vector Bit Set (doubleword)                              |
109  * +---------------+----------------------------------------------------------+
110  */
111
112 /* TODO: insert Bit Set group helpers here */
113
114
115 /*
116  * Fixed Multiply
117  * --------------
118  *
119  * +---------------+----------------------------------------------------------+
120  * | MADD_Q.H      | Vector Fixed-Point Multiply and Add (halfword)           |
121  * | MADD_Q.W      | Vector Fixed-Point Multiply and Add (word)               |
122  * | MADDR_Q.H     | Vector Fixed-Point Multiply and Add Rounded (halfword)   |
123  * | MADDR_Q.W     | Vector Fixed-Point Multiply and Add Rounded (word)       |
124  * | MSUB_Q.H      | Vector Fixed-Point Multiply and Subtr. (halfword)        |
125  * | MSUB_Q.W      | Vector Fixed-Point Multiply and Subtr. (word)            |
126  * | MSUBR_Q.H     | Vector Fixed-Point Multiply and Subtr. Rounded (halfword)|
127  * | MSUBR_Q.W     | Vector Fixed-Point Multiply and Subtr. Rounded (word)    |
128  * | MUL_Q.H       | Vector Fixed-Point Multiply (halfword)                   |
129  * | MUL_Q.W       | Vector Fixed-Point Multiply (word)                       |
130  * | MULR_Q.H      | Vector Fixed-Point Multiply Rounded (halfword)           |
131  * | MULR_Q.W      | Vector Fixed-Point Multiply Rounded (word)               |
132  * +---------------+----------------------------------------------------------+
133  */
134
135 /* TODO: insert Fixed Multiply group helpers here */
136
137
138 /*
139  * Float Max Min
140  * -------------
141  *
142  * +---------------+----------------------------------------------------------+
143  * | FMAX_A.W      | Vector Floating-Point Maximum (Absolute) (word)          |
144  * | FMAX_A.D      | Vector Floating-Point Maximum (Absolute) (doubleword)    |
145  * | FMAX.W        | Vector Floating-Point Maximum (word)                     |
146  * | FMAX.D        | Vector Floating-Point Maximum (doubleword)               |
147  * | FMIN_A.W      | Vector Floating-Point Minimum (Absolute) (word)          |
148  * | FMIN_A.D      | Vector Floating-Point Minimum (Absolute) (doubleword)    |
149  * | FMIN.W        | Vector Floating-Point Minimum (word)                     |
150  * | FMIN.D        | Vector Floating-Point Minimum (doubleword)               |
151  * +---------------+----------------------------------------------------------+
152  */
153
154 /* TODO: insert Float Max Min group helpers here */
155
156
157 /*
158  * Int Add
159  * -------
160  *
161  * +---------------+----------------------------------------------------------+
162  * | ADD_A.B       | Vector Add Absolute Values (byte)                        |
163  * | ADD_A.H       | Vector Add Absolute Values (halfword)                    |
164  * | ADD_A.W       | Vector Add Absolute Values (word)                        |
165  * | ADD_A.D       | Vector Add Absolute Values (doubleword)                  |
166  * | ADDS_A.B      | Vector Signed Saturated Add (of Absolute) (byte)         |
167  * | ADDS_A.H      | Vector Signed Saturated Add (of Absolute) (halfword)     |
168  * | ADDS_A.W      | Vector Signed Saturated Add (of Absolute) (word)         |
169  * | ADDS_A.D      | Vector Signed Saturated Add (of Absolute) (doubleword)   |
170  * | ADDS_S.B      | Vector Signed Saturated Add (of Signed) (byte)           |
171  * | ADDS_S.H      | Vector Signed Saturated Add (of Signed) (halfword)       |
172  * | ADDS_S.W      | Vector Signed Saturated Add (of Signed) (word)           |
173  * | ADDS_S.D      | Vector Signed Saturated Add (of Signed) (doubleword)     |
174  * | ADDS_U.B      | Vector Unsigned Saturated Add (of Unsigned) (byte)       |
175  * | ADDS_U.H      | Vector Unsigned Saturated Add (of Unsigned) (halfword)   |
176  * | ADDS_U.W      | Vector Unsigned Saturated Add (of Unsigned) (word)       |
177  * | ADDS_U.D      | Vector Unsigned Saturated Add (of Unsigned) (doubleword) |
178  * | ADDV.B        | Vector Add (byte)                                        |
179  * | ADDV.H        | Vector Add (halfword)                                    |
180  * | ADDV.W        | Vector Add (word)                                        |
181  * | ADDV.D        | Vector Add (doubleword)                                  |
182  * | HSUB_S.H      | Vector Signed Horizontal Add (halfword)                  |
183  * | HSUB_S.W      | Vector Signed Horizontal Add (word)                      |
184  * | HSUB_S.D      | Vector Signed Horizontal Add (doubleword)                |
185  * | HSUB_U.H      | Vector Unigned Horizontal Add (halfword)                 |
186  * | HSUB_U.W      | Vector Unigned Horizontal Add (word)                     |
187  * | HSUB_U.D      | Vector Unigned Horizontal Add (doubleword)               |
188  * +---------------+----------------------------------------------------------+
189  */
190
191 /* TODO: insert Int Add group helpers here */
192
193
194 /*
195  * Int Average
196  * -----------
197  *
198  * +---------------+----------------------------------------------------------+
199  * | AVE_S.B       | Vector Signed Average (byte)                             |
200  * | AVE_S.H       | Vector Signed Average (halfword)                         |
201  * | AVE_S.W       | Vector Signed Average (word)                             |
202  * | AVE_S.D       | Vector Signed Average (doubleword)                       |
203  * | AVE_U.B       | Vector Unsigned Average (byte)                           |
204  * | AVE_U.H       | Vector Unsigned Average (halfword)                       |
205  * | AVE_U.W       | Vector Unsigned Average (word)                           |
206  * | AVE_U.D       | Vector Unsigned Average (doubleword)                     |
207  * | AVER_S.B      | Vector Signed Average Rounded (byte)                     |
208  * | AVER_S.H      | Vector Signed Average Rounded (halfword)                 |
209  * | AVER_S.W      | Vector Signed Average Rounded (word)                     |
210  * | AVER_S.D      | Vector Signed Average Rounded (doubleword)               |
211  * | AVER_U.B      | Vector Unsigned Average Rounded (byte)                   |
212  * | AVER_U.H      | Vector Unsigned Average Rounded (halfword)               |
213  * | AVER_U.W      | Vector Unsigned Average Rounded (word)                   |
214  * | AVER_U.D      | Vector Unsigned Average Rounded (doubleword)             |
215  * +---------------+----------------------------------------------------------+
216  */
217
218 /* TODO: insert Int Average group helpers here */
219
220
221 /*
222  * Int Compare
223  * -----------
224  *
225  * +---------------+----------------------------------------------------------+
226  * | CEQ.B         | Vector Compare Equal (byte)                              |
227  * | CEQ.H         | Vector Compare Equal (halfword)                          |
228  * | CEQ.W         | Vector Compare Equal (word)                              |
229  * | CEQ.D         | Vector Compare Equal (doubleword)                        |
230  * | CLE_S.B       | Vector Compare Signed Less Than or Equal (byte)          |
231  * | CLE_S.H       | Vector Compare Signed Less Than or Equal (halfword)      |
232  * | CLE_S.W       | Vector Compare Signed Less Than or Equal (word)          |
233  * | CLE_S.D       | Vector Compare Signed Less Than or Equal (doubleword)    |
234  * | CLE_U.B       | Vector Compare Unsigned Less Than or Equal (byte)        |
235  * | CLE_U.H       | Vector Compare Unsigned Less Than or Equal (halfword)    |
236  * | CLE_U.W       | Vector Compare Unsigned Less Than or Equal (word)        |
237  * | CLE_U.D       | Vector Compare Unsigned Less Than or Equal (doubleword)  |
238  * | CLT_S.B       | Vector Compare Signed Less Than (byte)                   |
239  * | CLT_S.H       | Vector Compare Signed Less Than (halfword)               |
240  * | CLT_S.W       | Vector Compare Signed Less Than (word)                   |
241  * | CLT_S.D       | Vector Compare Signed Less Than (doubleword)             |
242  * | CLT_U.B       | Vector Compare Unsigned Less Than (byte)                 |
243  * | CLT_U.H       | Vector Compare Unsigned Less Than (halfword)             |
244  * | CLT_U.W       | Vector Compare Unsigned Less Than (word)                 |
245  * | CLT_U.D       | Vector Compare Unsigned Less Than (doubleword)           |
246  * +---------------+----------------------------------------------------------+
247  */
248
249 /* TODO: insert Int Compare group helpers here */
250
251
252 /*
253  * Int Divide
254  * ----------
255  *
256  * +---------------+----------------------------------------------------------+
257  * | DIV_S.B       | Vector Signed Divide (byte)                              |
258  * | DIV_S.H       | Vector Signed Divide (halfword)                          |
259  * | DIV_S.W       | Vector Signed Divide (word)                              |
260  * | DIV_S.D       | Vector Signed Divide (doubleword)                        |
261  * | DIV_U.B       | Vector Unsigned Divide (byte)                            |
262  * | DIV_U.H       | Vector Unsigned Divide (halfword)                        |
263  * | DIV_U.W       | Vector Unsigned Divide (word)                            |
264  * | DIV_U.D       | Vector Unsigned Divide (doubleword)                      |
265  * +---------------+----------------------------------------------------------+
266  */
267
268 /* TODO: insert Int Divide group helpers here */
269
270
271 /*
272  * Int Dot Product
273  * ---------------
274  *
275  * +---------------+----------------------------------------------------------+
276  * | DOTP_S.H      | Vector Signed Dot Product (halfword)                     |
277  * | DOTP_S.W      | Vector Signed Dot Product (word)                         |
278  * | DOTP_S.D      | Vector Signed Dot Product (doubleword)                   |
279  * | DOTP_U.H      | Vector Unsigned Dot Product (halfword)                   |
280  * | DOTP_U.W      | Vector Unsigned Dot Product (word)                       |
281  * | DOTP_U.D      | Vector Unsigned Dot Product (doubleword)                 |
282  * +---------------+----------------------------------------------------------+
283  */
284
285 /* TODO: insert Int Dot Product group helpers here */
286
287
288 /*
289  * Int Max Min
290  * -----------
291  *
292  * +---------------+----------------------------------------------------------+
293  * | MAX_A.B       | Vector Maximum Based on Absolute Value (byte)            |
294  * | MAX_A.H       | Vector Maximum Based on Absolute Value (halfword)        |
295  * | MAX_A.W       | Vector Maximum Based on Absolute Value (word)            |
296  * | MAX_A.D       | Vector Maximum Based on Absolute Value (doubleword)      |
297  * | MAX_S.B       | Vector Signed Maximum (byte)                             |
298  * | MAX_S.H       | Vector Signed Maximum (halfword)                         |
299  * | MAX_S.W       | Vector Signed Maximum (word)                             |
300  * | MAX_S.D       | Vector Signed Maximum (doubleword)                       |
301  * | MAX_U.B       | Vector Unsigned Maximum (byte)                           |
302  * | MAX_U.H       | Vector Unsigned Maximum (halfword)                       |
303  * | MAX_U.W       | Vector Unsigned Maximum (word)                           |
304  * | MAX_U.D       | Vector Unsigned Maximum (doubleword)                     |
305  * | MIN_A.B       | Vector Minimum Based on Absolute Value (byte)            |
306  * | MIN_A.H       | Vector Minimum Based on Absolute Value (halfword)        |
307  * | MIN_A.W       | Vector Minimum Based on Absolute Value (word)            |
308  * | MIN_A.D       | Vector Minimum Based on Absolute Value (doubleword)      |
309  * | MIN_S.B       | Vector Signed Minimum (byte)                             |
310  * | MIN_S.H       | Vector Signed Minimum (halfword)                         |
311  * | MIN_S.W       | Vector Signed Minimum (word)                             |
312  * | MIN_S.D       | Vector Signed Minimum (doubleword)                       |
313  * | MIN_U.B       | Vector Unsigned Minimum (byte)                           |
314  * | MIN_U.H       | Vector Unsigned Minimum (halfword)                       |
315  * | MIN_U.W       | Vector Unsigned Minimum (word)                           |
316  * | MIN_U.D       | Vector Unsigned Minimum (doubleword)                     |
317  * +---------------+----------------------------------------------------------+
318  */
319
320 /* TODO: insert Int Max Min group helpers here */
321
322
323 /*
324  * Int Modulo
325  * ----------
326  *
327  * +---------------+----------------------------------------------------------+
328  * | MOD_S.B       | Vector Signed Modulo (byte)                              |
329  * | MOD_S.H       | Vector Signed Modulo (halfword)                          |
330  * | MOD_S.W       | Vector Signed Modulo (word)                              |
331  * | MOD_S.D       | Vector Signed Modulo (doubleword)                        |
332  * | MOD_U.B       | Vector Unsigned Modulo (byte)                            |
333  * | MOD_U.H       | Vector Unsigned Modulo (halfword)                        |
334  * | MOD_U.W       | Vector Unsigned Modulo (word)                            |
335  * | MOD_U.D       | Vector Unsigned Modulo (doubleword)                      |
336  * +---------------+----------------------------------------------------------+
337  */
338
339 /* TODO: insert Int Modulo group helpers here */
340
341
342 /*
343  * Int Multiply
344  * ------------
345  *
346  * +---------------+----------------------------------------------------------+
347  * | MADDV.B       | Vector Multiply and Add (byte)                           |
348  * | MADDV.H       | Vector Multiply and Add (halfword)                       |
349  * | MADDV.W       | Vector Multiply and Add (word)                           |
350  * | MADDV.D       | Vector Multiply and Add (doubleword)                     |
351  * | MSUBV.B       | Vector Multiply and Subtract (byte)                      |
352  * | MSUBV.H       | Vector Multiply and Subtract (halfword)                  |
353  * | MSUBV.W       | Vector Multiply and Subtract (word)                      |
354  * | MSUBV.D       | Vector Multiply and Subtract (doubleword)                |
355  * | MULV.B        | Vector Multiply (byte)                                   |
356  * | MULV.H        | Vector Multiply (halfword)                               |
357  * | MULV.W        | Vector Multiply (word)                                   |
358  * | MULV.D        | Vector Multiply (doubleword)                             |
359  * +---------------+----------------------------------------------------------+
360  */
361
362 /* TODO: insert Int Multiply group helpers here */
363
364
365 /*
366  * Int Subtract
367  * ------------
368  *
369  * +---------------+----------------------------------------------------------+
370  * | ASUB_S.B      | Vector Absolute Values of Signed Subtract (byte)         |
371  * | ASUB_S.H      | Vector Absolute Values of Signed Subtract (halfword)     |
372  * | ASUB_S.W      | Vector Absolute Values of Signed Subtract (word)         |
373  * | ASUB_S.D      | Vector Absolute Values of Signed Subtract (doubleword)   |
374  * | ASUB_U.B      | Vector Absolute Values of Unsigned Subtract (byte)       |
375  * | ASUB_U.H      | Vector Absolute Values of Unsigned Subtract (halfword)   |
376  * | ASUB_U.W      | Vector Absolute Values of Unsigned Subtract (word)       |
377  * | ASUB_U.D      | Vector Absolute Values of Unsigned Subtract (doubleword) |
378  * | HSUB_S.H      | Vector Signed Horizontal Subtract (halfword)             |
379  * | HSUB_S.W      | Vector Signed Horizontal Subtract (word)                 |
380  * | HSUB_S.D      | Vector Signed Horizontal Subtract (doubleword)           |
381  * | HSUB_U.H      | Vector Unigned Horizontal Subtract (halfword)            |
382  * | HSUB_U.W      | Vector Unigned Horizontal Subtract (word)                |
383  * | HSUB_U.D      | Vector Unigned Horizontal Subtract (doubleword)          |
384  * | SUBS_S.B      | Vector Signed Saturated Subtract (of Signed) (byte)      |
385  * | SUBS_S.H      | Vector Signed Saturated Subtract (of Signed) (halfword)  |
386  * | SUBS_S.W      | Vector Signed Saturated Subtract (of Signed) (word)      |
387  * | SUBS_S.D      | Vector Signed Saturated Subtract (of Signed) (doubleword)|
388  * | SUBS_U.B      | Vector Unsigned Saturated Subtract (of Uns.) (byte)      |
389  * | SUBS_U.H      | Vector Unsigned Saturated Subtract (of Uns.) (halfword)  |
390  * | SUBS_U.W      | Vector Unsigned Saturated Subtract (of Uns.) (word)      |
391  * | SUBS_U.D      | Vector Unsigned Saturated Subtract (of Uns.) (doubleword)|
392  * | SUBSUS_S.B    | Vector Uns. Sat. Subtract (of S. from Uns.) (byte)       |
393  * | SUBSUS_S.H    | Vector Uns. Sat. Subtract (of S. from Uns.) (halfword)   |
394  * | SUBSUS_S.W    | Vector Uns. Sat. Subtract (of S. from Uns.) (word)       |
395  * | SUBSUS_S.D    | Vector Uns. Sat. Subtract (of S. from Uns.) (doubleword) |
396  * | SUBSUU_U.B    | Vector Signed Saturated Subtract (of Uns.) (byte)        |
397  * | SUBSUU_U.H    | Vector Signed Saturated Subtract (of Uns.) (halfword)    |
398  * | SUBSUU_U.W    | Vector Signed Saturated Subtract (of Uns.) (word)        |
399  * | SUBSUU_U.D    | Vector Signed Saturated Subtract (of Uns.) (doubleword)  |
400  * | SUBV.B        | Vector Subtract (byte)                                   |
401  * | SUBV.H        | Vector Subtract (halfword)                               |
402  * | SUBV.W        | Vector Subtract (word)                                   |
403  * | SUBV.D        | Vector Subtract (doubleword)                             |
404  * +---------------+----------------------------------------------------------+
405  */
406
407 /* TODO: insert Int Subtract group helpers here */
408
409
410 /*
411  * Interleave
412  * ----------
413  *
414  * +---------------+----------------------------------------------------------+
415  * | ILVEV.B       | Vector Interleave Even (byte)                            |
416  * | ILVEV.H       | Vector Interleave Even (halfword)                        |
417  * | ILVEV.W       | Vector Interleave Even (word)                            |
418  * | ILVEV.D       | Vector Interleave Even (doubleword)                      |
419  * | ILVOD.B       | Vector Interleave Odd (byte)                             |
420  * | ILVOD.H       | Vector Interleave Odd (halfword)                         |
421  * | ILVOD.W       | Vector Interleave Odd (word)                             |
422  * | ILVOD.D       | Vector Interleave Odd (doubleword)                       |
423  * | ILVL.B        | Vector Interleave Left (byte)                            |
424  * | ILVL.H        | Vector Interleave Left (halfword)                        |
425  * | ILVL.W        | Vector Interleave Left (word)                            |
426  * | ILVL.D        | Vector Interleave Left (doubleword)                      |
427  * | ILVR.B        | Vector Interleave Right (byte)                           |
428  * | ILVR.H        | Vector Interleave Right (halfword)                       |
429  * | ILVR.W        | Vector Interleave Right (word)                           |
430  * | ILVR.D        | Vector Interleave Right (doubleword)                     |
431  * +---------------+----------------------------------------------------------+
432  */
433
434 /* TODO: insert Interleave group helpers here */
435
436
437 /*
438  * Logic
439  * -----
440  *
441  * +---------------+----------------------------------------------------------+
442  * | AND.V         | Vector Logical And                                       |
443  * | NOR.V         | Vector Logical Negated Or                                |
444  * | OR.V          | Vector Logical Or                                        |
445  * | XOR.V         | Vector Logical Exclusive Or                              |
446  * +---------------+----------------------------------------------------------+
447  */
448
449 /* TODO: insert Logic group helpers here */
450
451
452 /*
453  * Pack
454  * ----
455  *
456  * +---------------+----------------------------------------------------------+
457  * | PCKEV.B       | Vector Pack Even (byte)                                  |
458  * | PCKEV.H       | Vector Pack Even (halfword)                              |
459  * | PCKEV.W       | Vector Pack Even (word)                                  |
460  * | PCKEV.D       | Vector Pack Even (doubleword)                            |
461  * | PCKOD.B       | Vector Pack Odd (byte)                                   |
462  * | PCKOD.H       | Vector Pack Odd (halfword)                               |
463  * | PCKOD.W       | Vector Pack Odd (word)                                   |
464  * | PCKOD.D       | Vector Pack Odd (doubleword)                             |
465  * | VSHF.B        | Vector Data Preserving Shuffle (byte)                    |
466  * | VSHF.H        | Vector Data Preserving Shuffle (halfword)                |
467  * | VSHF.W        | Vector Data Preserving Shuffle (word)                    |
468  * | VSHF.D        | Vector Data Preserving Shuffle (doubleword)              |
469  * +---------------+----------------------------------------------------------+
470  */
471
472 /* TODO: insert Pack group helpers here */
473
474
475 /*
476  * Shift
477  * -----
478  *
479  * +---------------+----------------------------------------------------------+
480  * | SLL.B         | Vector Shift Left (byte)                                 |
481  * | SLL.H         | Vector Shift Left (halfword)                             |
482  * | SLL.W         | Vector Shift Left (word)                                 |
483  * | SLL.D         | Vector Shift Left (doubleword)                           |
484  * | SRA.B         | Vector Shift Right Arithmetic (byte)                     |
485  * | SRA.H         | Vector Shift Right Arithmetic (halfword)                 |
486  * | SRA.W         | Vector Shift Right Arithmetic (word)                     |
487  * | SRA.D         | Vector Shift Right Arithmetic (doubleword)               |
488  * | SRAR.B        | Vector Shift Right Arithmetic Rounded (byte)             |
489  * | SRAR.H        | Vector Shift Right Arithmetic Rounded (halfword)         |
490  * | SRAR.W        | Vector Shift Right Arithmetic Rounded (word)             |
491  * | SRAR.D        | Vector Shift Right Arithmetic Rounded (doubleword)       |
492  * | SRL.B         | Vector Shift Right Logical (byte)                        |
493  * | SRL.H         | Vector Shift Right Logical (halfword)                    |
494  * | SRL.W         | Vector Shift Right Logical (word)                        |
495  * | SRL.D         | Vector Shift Right Logical (doubleword)                  |
496  * | SRLR.B        | Vector Shift Right Logical Rounded (byte)                |
497  * | SRLR.H        | Vector Shift Right Logical Rounded (halfword)            |
498  * | SRLR.W        | Vector Shift Right Logical Rounded (word)                |
499  * | SRLR.D        | Vector Shift Right Logical Rounded (doubleword)          |
500  * +---------------+----------------------------------------------------------+
501  */
502
503 /* TODO: insert Shift group helpers here */
504
505
506 static inline void msa_move_v(wr_t *pwd, wr_t *pws)
507 {
508     uint32_t i;
509
510     for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
511         pwd->d[i] = pws->d[i];
512     }
513 }
514
515 #define MSA_FN_IMM8(FUNC, DEST, OPERATION)                              \
516 void helper_msa_ ## FUNC(CPUMIPSState *env, uint32_t wd, uint32_t ws,   \
517         uint32_t i8)                                                    \
518 {                                                                       \
519     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
520     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
521     uint32_t i;                                                         \
522     for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {                        \
523         DEST = OPERATION;                                               \
524     }                                                                   \
525 }
526
527 MSA_FN_IMM8(andi_b, pwd->b[i], pws->b[i] & i8)
528 MSA_FN_IMM8(ori_b, pwd->b[i], pws->b[i] | i8)
529 MSA_FN_IMM8(nori_b, pwd->b[i], ~(pws->b[i] | i8))
530 MSA_FN_IMM8(xori_b, pwd->b[i], pws->b[i] ^ i8)
531
532 #define BIT_MOVE_IF_NOT_ZERO(dest, arg1, arg2, df) \
533             UNSIGNED(((dest & (~arg2)) | (arg1 & arg2)), df)
534 MSA_FN_IMM8(bmnzi_b, pwd->b[i],
535         BIT_MOVE_IF_NOT_ZERO(pwd->b[i], pws->b[i], i8, DF_BYTE))
536
537 #define BIT_MOVE_IF_ZERO(dest, arg1, arg2, df) \
538             UNSIGNED((dest & arg2) | (arg1 & (~arg2)), df)
539 MSA_FN_IMM8(bmzi_b, pwd->b[i],
540         BIT_MOVE_IF_ZERO(pwd->b[i], pws->b[i], i8, DF_BYTE))
541
542 #define BIT_SELECT(dest, arg1, arg2, df) \
543             UNSIGNED((arg1 & (~dest)) | (arg2 & dest), df)
544 MSA_FN_IMM8(bseli_b, pwd->b[i],
545         BIT_SELECT(pwd->b[i], pws->b[i], i8, DF_BYTE))
546
547 #undef MSA_FN_IMM8
548
549 #define SHF_POS(i, imm) (((i) & 0xfc) + (((imm) >> (2 * ((i) & 0x03))) & 0x03))
550
551 void helper_msa_shf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
552                        uint32_t ws, uint32_t imm)
553 {
554     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
555     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
556     wr_t wx, *pwx = &wx;
557     uint32_t i;
558
559     switch (df) {
560     case DF_BYTE:
561         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
562             pwx->b[i] = pws->b[SHF_POS(i, imm)];
563         }
564         break;
565     case DF_HALF:
566         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
567             pwx->h[i] = pws->h[SHF_POS(i, imm)];
568         }
569         break;
570     case DF_WORD:
571         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
572             pwx->w[i] = pws->w[SHF_POS(i, imm)];
573         }
574         break;
575     default:
576         assert(0);
577     }
578     msa_move_v(pwd, pwx);
579 }
580
581 #define MSA_FN_VECTOR(FUNC, DEST, OPERATION)                            \
582 void helper_msa_ ## FUNC(CPUMIPSState *env, uint32_t wd, uint32_t ws,   \
583         uint32_t wt)                                                    \
584 {                                                                       \
585     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
586     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
587     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);                          \
588     uint32_t i;                                                         \
589     for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {                      \
590         DEST = OPERATION;                                               \
591     }                                                                   \
592 }
593
594 MSA_FN_VECTOR(bmnz_v, pwd->d[i],
595         BIT_MOVE_IF_NOT_ZERO(pwd->d[i], pws->d[i], pwt->d[i], DF_DOUBLE))
596 MSA_FN_VECTOR(bmz_v, pwd->d[i],
597         BIT_MOVE_IF_ZERO(pwd->d[i], pws->d[i], pwt->d[i], DF_DOUBLE))
598 MSA_FN_VECTOR(bsel_v, pwd->d[i],
599         BIT_SELECT(pwd->d[i], pws->d[i], pwt->d[i], DF_DOUBLE))
600 #undef BIT_MOVE_IF_NOT_ZERO
601 #undef BIT_MOVE_IF_ZERO
602 #undef BIT_SELECT
603 #undef MSA_FN_VECTOR
604
605 void helper_msa_and_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
606 {
607     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
608     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
609     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
610
611     pwd->d[0] = pws->d[0] & pwt->d[0];
612     pwd->d[1] = pws->d[1] & pwt->d[1];
613 }
614
615 void helper_msa_or_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
616 {
617     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
618     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
619     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
620
621     pwd->d[0] = pws->d[0] | pwt->d[0];
622     pwd->d[1] = pws->d[1] | pwt->d[1];
623 }
624
625 void helper_msa_nor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
626 {
627     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
628     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
629     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
630
631     pwd->d[0] = ~(pws->d[0] | pwt->d[0]);
632     pwd->d[1] = ~(pws->d[1] | pwt->d[1]);
633 }
634
635 void helper_msa_xor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
636 {
637     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
638     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
639     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
640
641     pwd->d[0] = pws->d[0] ^ pwt->d[0];
642     pwd->d[1] = pws->d[1] ^ pwt->d[1];
643 }
644
645 static inline int64_t msa_addv_df(uint32_t df, int64_t arg1, int64_t arg2)
646 {
647     return arg1 + arg2;
648 }
649
650 static inline int64_t msa_subv_df(uint32_t df, int64_t arg1, int64_t arg2)
651 {
652     return arg1 - arg2;
653 }
654
655 static inline int64_t msa_ceq_df(uint32_t df, int64_t arg1, int64_t arg2)
656 {
657     return arg1 == arg2 ? -1 : 0;
658 }
659
660 static inline int64_t msa_cle_s_df(uint32_t df, int64_t arg1, int64_t arg2)
661 {
662     return arg1 <= arg2 ? -1 : 0;
663 }
664
665 static inline int64_t msa_cle_u_df(uint32_t df, int64_t arg1, int64_t arg2)
666 {
667     uint64_t u_arg1 = UNSIGNED(arg1, df);
668     uint64_t u_arg2 = UNSIGNED(arg2, df);
669     return u_arg1 <= u_arg2 ? -1 : 0;
670 }
671
672 static inline int64_t msa_clt_s_df(uint32_t df, int64_t arg1, int64_t arg2)
673 {
674     return arg1 < arg2 ? -1 : 0;
675 }
676
677 static inline int64_t msa_clt_u_df(uint32_t df, int64_t arg1, int64_t arg2)
678 {
679     uint64_t u_arg1 = UNSIGNED(arg1, df);
680     uint64_t u_arg2 = UNSIGNED(arg2, df);
681     return u_arg1 < u_arg2 ? -1 : 0;
682 }
683
684 static inline int64_t msa_max_s_df(uint32_t df, int64_t arg1, int64_t arg2)
685 {
686     return arg1 > arg2 ? arg1 : arg2;
687 }
688
689 static inline int64_t msa_max_u_df(uint32_t df, int64_t arg1, int64_t arg2)
690 {
691     uint64_t u_arg1 = UNSIGNED(arg1, df);
692     uint64_t u_arg2 = UNSIGNED(arg2, df);
693     return u_arg1 > u_arg2 ? arg1 : arg2;
694 }
695
696 static inline int64_t msa_min_s_df(uint32_t df, int64_t arg1, int64_t arg2)
697 {
698     return arg1 < arg2 ? arg1 : arg2;
699 }
700
701 static inline int64_t msa_min_u_df(uint32_t df, int64_t arg1, int64_t arg2)
702 {
703     uint64_t u_arg1 = UNSIGNED(arg1, df);
704     uint64_t u_arg2 = UNSIGNED(arg2, df);
705     return u_arg1 < u_arg2 ? arg1 : arg2;
706 }
707
708 #define MSA_BINOP_IMM_DF(helper, func)                                  \
709 void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df,       \
710                         uint32_t wd, uint32_t ws, int32_t u5)           \
711 {                                                                       \
712     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
713     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
714     uint32_t i;                                                         \
715                                                                         \
716     switch (df) {                                                       \
717     case DF_BYTE:                                                       \
718         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {                    \
719             pwd->b[i] = msa_ ## func ## _df(df, pws->b[i], u5);         \
720         }                                                               \
721         break;                                                          \
722     case DF_HALF:                                                       \
723         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {                    \
724             pwd->h[i] = msa_ ## func ## _df(df, pws->h[i], u5);         \
725         }                                                               \
726         break;                                                          \
727     case DF_WORD:                                                       \
728         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {                    \
729             pwd->w[i] = msa_ ## func ## _df(df, pws->w[i], u5);         \
730         }                                                               \
731         break;                                                          \
732     case DF_DOUBLE:                                                     \
733         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {                  \
734             pwd->d[i] = msa_ ## func ## _df(df, pws->d[i], u5);         \
735         }                                                               \
736         break;                                                          \
737     default:                                                            \
738         assert(0);                                                      \
739     }                                                                   \
740 }
741
742 MSA_BINOP_IMM_DF(addvi, addv)
743 MSA_BINOP_IMM_DF(subvi, subv)
744 MSA_BINOP_IMM_DF(ceqi, ceq)
745 MSA_BINOP_IMM_DF(clei_s, cle_s)
746 MSA_BINOP_IMM_DF(clei_u, cle_u)
747 MSA_BINOP_IMM_DF(clti_s, clt_s)
748 MSA_BINOP_IMM_DF(clti_u, clt_u)
749 MSA_BINOP_IMM_DF(maxi_s, max_s)
750 MSA_BINOP_IMM_DF(maxi_u, max_u)
751 MSA_BINOP_IMM_DF(mini_s, min_s)
752 MSA_BINOP_IMM_DF(mini_u, min_u)
753 #undef MSA_BINOP_IMM_DF
754
755 void helper_msa_ldi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
756                        int32_t s10)
757 {
758     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
759     uint32_t i;
760
761     switch (df) {
762     case DF_BYTE:
763         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
764             pwd->b[i] = (int8_t)s10;
765         }
766         break;
767     case DF_HALF:
768         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
769             pwd->h[i] = (int16_t)s10;
770         }
771         break;
772     case DF_WORD:
773         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
774             pwd->w[i] = (int32_t)s10;
775         }
776         break;
777     case DF_DOUBLE:
778         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
779             pwd->d[i] = (int64_t)s10;
780         }
781        break;
782     default:
783         assert(0);
784     }
785 }
786
787 /* Data format bit position and unsigned values */
788 #define BIT_POSITION(x, df) ((uint64_t)(x) % DF_BITS(df))
789
790 static inline int64_t msa_sll_df(uint32_t df, int64_t arg1, int64_t arg2)
791 {
792     int32_t b_arg2 = BIT_POSITION(arg2, df);
793     return arg1 << b_arg2;
794 }
795
796 static inline int64_t msa_sra_df(uint32_t df, int64_t arg1, int64_t arg2)
797 {
798     int32_t b_arg2 = BIT_POSITION(arg2, df);
799     return arg1 >> b_arg2;
800 }
801
802 static inline int64_t msa_srl_df(uint32_t df, int64_t arg1, int64_t arg2)
803 {
804     uint64_t u_arg1 = UNSIGNED(arg1, df);
805     int32_t b_arg2 = BIT_POSITION(arg2, df);
806     return u_arg1 >> b_arg2;
807 }
808
809 static inline int64_t msa_bclr_df(uint32_t df, int64_t arg1, int64_t arg2)
810 {
811     int32_t b_arg2 = BIT_POSITION(arg2, df);
812     return UNSIGNED(arg1 & (~(1LL << b_arg2)), df);
813 }
814
815 static inline int64_t msa_bset_df(uint32_t df, int64_t arg1,
816         int64_t arg2)
817 {
818     int32_t b_arg2 = BIT_POSITION(arg2, df);
819     return UNSIGNED(arg1 | (1LL << b_arg2), df);
820 }
821
822 static inline int64_t msa_bneg_df(uint32_t df, int64_t arg1, int64_t arg2)
823 {
824     int32_t b_arg2 = BIT_POSITION(arg2, df);
825     return UNSIGNED(arg1 ^ (1LL << b_arg2), df);
826 }
827
828 static inline int64_t msa_binsl_df(uint32_t df, int64_t dest, int64_t arg1,
829                                    int64_t arg2)
830 {
831     uint64_t u_arg1 = UNSIGNED(arg1, df);
832     uint64_t u_dest = UNSIGNED(dest, df);
833     int32_t sh_d = BIT_POSITION(arg2, df) + 1;
834     int32_t sh_a = DF_BITS(df) - sh_d;
835     if (sh_d == DF_BITS(df)) {
836         return u_arg1;
837     } else {
838         return UNSIGNED(UNSIGNED(u_dest << sh_d, df) >> sh_d, df) |
839                UNSIGNED(UNSIGNED(u_arg1 >> sh_a, df) << sh_a, df);
840     }
841 }
842
843 static inline int64_t msa_binsr_df(uint32_t df, int64_t dest, int64_t arg1,
844                                    int64_t arg2)
845 {
846     uint64_t u_arg1 = UNSIGNED(arg1, df);
847     uint64_t u_dest = UNSIGNED(dest, df);
848     int32_t sh_d = BIT_POSITION(arg2, df) + 1;
849     int32_t sh_a = DF_BITS(df) - sh_d;
850     if (sh_d == DF_BITS(df)) {
851         return u_arg1;
852     } else {
853         return UNSIGNED(UNSIGNED(u_dest >> sh_d, df) << sh_d, df) |
854                UNSIGNED(UNSIGNED(u_arg1 << sh_a, df) >> sh_a, df);
855     }
856 }
857
858 static inline int64_t msa_sat_s_df(uint32_t df, int64_t arg, uint32_t m)
859 {
860     return arg < M_MIN_INT(m + 1) ? M_MIN_INT(m + 1) :
861                                     arg > M_MAX_INT(m + 1) ? M_MAX_INT(m + 1) :
862                                                              arg;
863 }
864
865 static inline int64_t msa_sat_u_df(uint32_t df, int64_t arg, uint32_t m)
866 {
867     uint64_t u_arg = UNSIGNED(arg, df);
868     return  u_arg < M_MAX_UINT(m + 1) ? u_arg :
869                                         M_MAX_UINT(m + 1);
870 }
871
872 static inline int64_t msa_srar_df(uint32_t df, int64_t arg1, int64_t arg2)
873 {
874     int32_t b_arg2 = BIT_POSITION(arg2, df);
875     if (b_arg2 == 0) {
876         return arg1;
877     } else {
878         int64_t r_bit = (arg1 >> (b_arg2 - 1)) & 1;
879         return (arg1 >> b_arg2) + r_bit;
880     }
881 }
882
883 static inline int64_t msa_srlr_df(uint32_t df, int64_t arg1, int64_t arg2)
884 {
885     uint64_t u_arg1 = UNSIGNED(arg1, df);
886     int32_t b_arg2 = BIT_POSITION(arg2, df);
887     if (b_arg2 == 0) {
888         return u_arg1;
889     } else {
890         uint64_t r_bit = (u_arg1 >> (b_arg2 - 1)) & 1;
891         return (u_arg1 >> b_arg2) + r_bit;
892     }
893 }
894
895 #define MSA_BINOP_IMMU_DF(helper, func)                                  \
896 void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, uint32_t wd, \
897                        uint32_t ws, uint32_t u5)                        \
898 {                                                                       \
899     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
900     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
901     uint32_t i;                                                         \
902                                                                         \
903     switch (df) {                                                       \
904     case DF_BYTE:                                                       \
905         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {                    \
906             pwd->b[i] = msa_ ## func ## _df(df, pws->b[i], u5);         \
907         }                                                               \
908         break;                                                          \
909     case DF_HALF:                                                       \
910         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {                    \
911             pwd->h[i] = msa_ ## func ## _df(df, pws->h[i], u5);         \
912         }                                                               \
913         break;                                                          \
914     case DF_WORD:                                                       \
915         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {                    \
916             pwd->w[i] = msa_ ## func ## _df(df, pws->w[i], u5);         \
917         }                                                               \
918         break;                                                          \
919     case DF_DOUBLE:                                                     \
920         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {                  \
921             pwd->d[i] = msa_ ## func ## _df(df, pws->d[i], u5);         \
922         }                                                               \
923         break;                                                          \
924     default:                                                            \
925         assert(0);                                                      \
926     }                                                                   \
927 }
928
929 MSA_BINOP_IMMU_DF(slli, sll)
930 MSA_BINOP_IMMU_DF(srai, sra)
931 MSA_BINOP_IMMU_DF(srli, srl)
932 MSA_BINOP_IMMU_DF(bclri, bclr)
933 MSA_BINOP_IMMU_DF(bseti, bset)
934 MSA_BINOP_IMMU_DF(bnegi, bneg)
935 MSA_BINOP_IMMU_DF(sat_s, sat_s)
936 MSA_BINOP_IMMU_DF(sat_u, sat_u)
937 MSA_BINOP_IMMU_DF(srari, srar)
938 MSA_BINOP_IMMU_DF(srlri, srlr)
939 #undef MSA_BINOP_IMMU_DF
940
941 #define MSA_TEROP_IMMU_DF(helper, func)                                  \
942 void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df,       \
943                                   uint32_t wd, uint32_t ws, uint32_t u5) \
944 {                                                                       \
945     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
946     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
947     uint32_t i;                                                         \
948                                                                         \
949     switch (df) {                                                       \
950     case DF_BYTE:                                                       \
951         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {                    \
952             pwd->b[i] = msa_ ## func ## _df(df, pwd->b[i], pws->b[i],   \
953                                             u5);                        \
954         }                                                               \
955         break;                                                          \
956     case DF_HALF:                                                       \
957         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {                    \
958             pwd->h[i] = msa_ ## func ## _df(df, pwd->h[i], pws->h[i],   \
959                                             u5);                        \
960         }                                                               \
961         break;                                                          \
962     case DF_WORD:                                                       \
963         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {                    \
964             pwd->w[i] = msa_ ## func ## _df(df, pwd->w[i], pws->w[i],   \
965                                             u5);                        \
966         }                                                               \
967         break;                                                          \
968     case DF_DOUBLE:                                                     \
969         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {                  \
970             pwd->d[i] = msa_ ## func ## _df(df, pwd->d[i], pws->d[i],   \
971                                             u5);                        \
972         }                                                               \
973         break;                                                          \
974     default:                                                            \
975         assert(0);                                                      \
976     }                                                                   \
977 }
978
979 MSA_TEROP_IMMU_DF(binsli, binsl)
980 MSA_TEROP_IMMU_DF(binsri, binsr)
981 #undef MSA_TEROP_IMMU_DF
982
983 static inline int64_t msa_max_a_df(uint32_t df, int64_t arg1, int64_t arg2)
984 {
985     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
986     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
987     return abs_arg1 > abs_arg2 ? arg1 : arg2;
988 }
989
990 static inline int64_t msa_min_a_df(uint32_t df, int64_t arg1, int64_t arg2)
991 {
992     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
993     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
994     return abs_arg1 < abs_arg2 ? arg1 : arg2;
995 }
996
997 static inline int64_t msa_add_a_df(uint32_t df, int64_t arg1, int64_t arg2)
998 {
999     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
1000     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
1001     return abs_arg1 + abs_arg2;
1002 }
1003
1004 static inline int64_t msa_adds_a_df(uint32_t df, int64_t arg1, int64_t arg2)
1005 {
1006     uint64_t max_int = (uint64_t)DF_MAX_INT(df);
1007     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
1008     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
1009     if (abs_arg1 > max_int || abs_arg2 > max_int) {
1010         return (int64_t)max_int;
1011     } else {
1012         return (abs_arg1 < max_int - abs_arg2) ? abs_arg1 + abs_arg2 : max_int;
1013     }
1014 }
1015
1016 static inline int64_t msa_adds_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1017 {
1018     int64_t max_int = DF_MAX_INT(df);
1019     int64_t min_int = DF_MIN_INT(df);
1020     if (arg1 < 0) {
1021         return (min_int - arg1 < arg2) ? arg1 + arg2 : min_int;
1022     } else {
1023         return (arg2 < max_int - arg1) ? arg1 + arg2 : max_int;
1024     }
1025 }
1026
1027 static inline uint64_t msa_adds_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1028 {
1029     uint64_t max_uint = DF_MAX_UINT(df);
1030     uint64_t u_arg1 = UNSIGNED(arg1, df);
1031     uint64_t u_arg2 = UNSIGNED(arg2, df);
1032     return (u_arg1 < max_uint - u_arg2) ? u_arg1 + u_arg2 : max_uint;
1033 }
1034
1035 static inline int64_t msa_ave_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1036 {
1037     /* signed shift */
1038     return (arg1 >> 1) + (arg2 >> 1) + (arg1 & arg2 & 1);
1039 }
1040
1041 static inline uint64_t msa_ave_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1042 {
1043     uint64_t u_arg1 = UNSIGNED(arg1, df);
1044     uint64_t u_arg2 = UNSIGNED(arg2, df);
1045     /* unsigned shift */
1046     return (u_arg1 >> 1) + (u_arg2 >> 1) + (u_arg1 & u_arg2 & 1);
1047 }
1048
1049 static inline int64_t msa_aver_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1050 {
1051     /* signed shift */
1052     return (arg1 >> 1) + (arg2 >> 1) + ((arg1 | arg2) & 1);
1053 }
1054
1055 static inline uint64_t msa_aver_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1056 {
1057     uint64_t u_arg1 = UNSIGNED(arg1, df);
1058     uint64_t u_arg2 = UNSIGNED(arg2, df);
1059     /* unsigned shift */
1060     return (u_arg1 >> 1) + (u_arg2 >> 1) + ((u_arg1 | u_arg2) & 1);
1061 }
1062
1063 static inline int64_t msa_subs_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1064 {
1065     int64_t max_int = DF_MAX_INT(df);
1066     int64_t min_int = DF_MIN_INT(df);
1067     if (arg2 > 0) {
1068         return (min_int + arg2 < arg1) ? arg1 - arg2 : min_int;
1069     } else {
1070         return (arg1 < max_int + arg2) ? arg1 - arg2 : max_int;
1071     }
1072 }
1073
1074 static inline int64_t msa_subs_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1075 {
1076     uint64_t u_arg1 = UNSIGNED(arg1, df);
1077     uint64_t u_arg2 = UNSIGNED(arg2, df);
1078     return (u_arg1 > u_arg2) ? u_arg1 - u_arg2 : 0;
1079 }
1080
1081 static inline int64_t msa_subsus_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1082 {
1083     uint64_t u_arg1 = UNSIGNED(arg1, df);
1084     uint64_t max_uint = DF_MAX_UINT(df);
1085     if (arg2 >= 0) {
1086         uint64_t u_arg2 = (uint64_t)arg2;
1087         return (u_arg1 > u_arg2) ?
1088             (int64_t)(u_arg1 - u_arg2) :
1089             0;
1090     } else {
1091         uint64_t u_arg2 = (uint64_t)(-arg2);
1092         return (u_arg1 < max_uint - u_arg2) ?
1093             (int64_t)(u_arg1 + u_arg2) :
1094             (int64_t)max_uint;
1095     }
1096 }
1097
1098 static inline int64_t msa_subsuu_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1099 {
1100     uint64_t u_arg1 = UNSIGNED(arg1, df);
1101     uint64_t u_arg2 = UNSIGNED(arg2, df);
1102     int64_t max_int = DF_MAX_INT(df);
1103     int64_t min_int = DF_MIN_INT(df);
1104     if (u_arg1 > u_arg2) {
1105         return u_arg1 - u_arg2 < (uint64_t)max_int ?
1106             (int64_t)(u_arg1 - u_arg2) :
1107             max_int;
1108     } else {
1109         return u_arg2 - u_arg1 < (uint64_t)(-min_int) ?
1110             (int64_t)(u_arg1 - u_arg2) :
1111             min_int;
1112     }
1113 }
1114
1115 static inline int64_t msa_asub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1116 {
1117     /* signed compare */
1118     return (arg1 < arg2) ?
1119         (uint64_t)(arg2 - arg1) : (uint64_t)(arg1 - arg2);
1120 }
1121
1122 static inline uint64_t msa_asub_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1123 {
1124     uint64_t u_arg1 = UNSIGNED(arg1, df);
1125     uint64_t u_arg2 = UNSIGNED(arg2, df);
1126     /* unsigned compare */
1127     return (u_arg1 < u_arg2) ?
1128         (uint64_t)(u_arg2 - u_arg1) : (uint64_t)(u_arg1 - u_arg2);
1129 }
1130
1131 static inline int64_t msa_mulv_df(uint32_t df, int64_t arg1, int64_t arg2)
1132 {
1133     return arg1 * arg2;
1134 }
1135
1136 static inline int64_t msa_div_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1137 {
1138     if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
1139         return DF_MIN_INT(df);
1140     }
1141     return arg2 ? arg1 / arg2
1142                 : arg1 >= 0 ? -1 : 1;
1143 }
1144
1145 static inline int64_t msa_div_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1146 {
1147     uint64_t u_arg1 = UNSIGNED(arg1, df);
1148     uint64_t u_arg2 = UNSIGNED(arg2, df);
1149     return arg2 ? u_arg1 / u_arg2 : -1;
1150 }
1151
1152 static inline int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1153 {
1154     if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
1155         return 0;
1156     }
1157     return arg2 ? arg1 % arg2 : arg1;
1158 }
1159
1160 static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1161 {
1162     uint64_t u_arg1 = UNSIGNED(arg1, df);
1163     uint64_t u_arg2 = UNSIGNED(arg2, df);
1164     return u_arg2 ? u_arg1 % u_arg2 : u_arg1;
1165 }
1166
1167 #define SIGNED_EVEN(a, df) \
1168         ((((int64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2))
1169
1170 #define UNSIGNED_EVEN(a, df) \
1171         ((((uint64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2))
1172
1173 #define SIGNED_ODD(a, df) \
1174         ((((int64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
1175
1176 #define UNSIGNED_ODD(a, df) \
1177         ((((uint64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
1178
1179 #define SIGNED_EXTRACT(e, o, a, df)     \
1180     do {                                \
1181         e = SIGNED_EVEN(a, df);         \
1182         o = SIGNED_ODD(a, df);          \
1183     } while (0)
1184
1185 #define UNSIGNED_EXTRACT(e, o, a, df)   \
1186     do {                                \
1187         e = UNSIGNED_EVEN(a, df);       \
1188         o = UNSIGNED_ODD(a, df);        \
1189     } while (0)
1190
1191 static inline int64_t msa_dotp_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1192 {
1193     int64_t even_arg1;
1194     int64_t even_arg2;
1195     int64_t odd_arg1;
1196     int64_t odd_arg2;
1197     SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
1198     SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
1199     return (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
1200 }
1201
1202 static inline int64_t msa_dotp_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1203 {
1204     int64_t even_arg1;
1205     int64_t even_arg2;
1206     int64_t odd_arg1;
1207     int64_t odd_arg2;
1208     UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
1209     UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
1210     return (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
1211 }
1212
1213 #define CONCATENATE_AND_SLIDE(s, k)             \
1214     do {                                        \
1215         for (i = 0; i < s; i++) {               \
1216             v[i]     = pws->b[s * k + i];       \
1217             v[i + s] = pwd->b[s * k + i];       \
1218         }                                       \
1219         for (i = 0; i < s; i++) {               \
1220             pwd->b[s * k + i] = v[i + n];       \
1221         }                                       \
1222     } while (0)
1223
1224 static inline void msa_sld_df(uint32_t df, wr_t *pwd,
1225                               wr_t *pws, target_ulong rt)
1226 {
1227     uint32_t n = rt % DF_ELEMENTS(df);
1228     uint8_t v[64];
1229     uint32_t i, k;
1230
1231     switch (df) {
1232     case DF_BYTE:
1233         CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_BYTE), 0);
1234         break;
1235     case DF_HALF:
1236         for (k = 0; k < 2; k++) {
1237             CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_HALF), k);
1238         }
1239         break;
1240     case DF_WORD:
1241         for (k = 0; k < 4; k++) {
1242             CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_WORD), k);
1243         }
1244         break;
1245     case DF_DOUBLE:
1246         for (k = 0; k < 8; k++) {
1247             CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_DOUBLE), k);
1248         }
1249         break;
1250     default:
1251         assert(0);
1252     }
1253 }
1254
1255 static inline int64_t msa_hadd_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1256 {
1257     return SIGNED_ODD(arg1, df) + SIGNED_EVEN(arg2, df);
1258 }
1259
1260 static inline int64_t msa_hadd_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1261 {
1262     return UNSIGNED_ODD(arg1, df) + UNSIGNED_EVEN(arg2, df);
1263 }
1264
1265 static inline int64_t msa_hsub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1266 {
1267     return SIGNED_ODD(arg1, df) - SIGNED_EVEN(arg2, df);
1268 }
1269
1270 static inline int64_t msa_hsub_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1271 {
1272     return UNSIGNED_ODD(arg1, df) - UNSIGNED_EVEN(arg2, df);
1273 }
1274
1275 static inline int64_t msa_mul_q_df(uint32_t df, int64_t arg1, int64_t arg2)
1276 {
1277     int64_t q_min = DF_MIN_INT(df);
1278     int64_t q_max = DF_MAX_INT(df);
1279
1280     if (arg1 == q_min && arg2 == q_min) {
1281         return q_max;
1282     }
1283     return (arg1 * arg2) >> (DF_BITS(df) - 1);
1284 }
1285
1286 static inline int64_t msa_mulr_q_df(uint32_t df, int64_t arg1, int64_t arg2)
1287 {
1288     int64_t q_min = DF_MIN_INT(df);
1289     int64_t q_max = DF_MAX_INT(df);
1290     int64_t r_bit = 1 << (DF_BITS(df) - 2);
1291
1292     if (arg1 == q_min && arg2 == q_min) {
1293         return q_max;
1294     }
1295     return (arg1 * arg2 + r_bit) >> (DF_BITS(df) - 1);
1296 }
1297
1298 #define MSA_BINOP_DF(func) \
1299 void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df,         \
1300                                 uint32_t wd, uint32_t ws, uint32_t wt)  \
1301 {                                                                       \
1302     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
1303     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
1304     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);                          \
1305                                                                         \
1306     switch (df) {                                                       \
1307     case DF_BYTE:                                                       \
1308         pwd->b[0]  = msa_ ## func ## _df(df, pws->b[0],  pwt->b[0]);    \
1309         pwd->b[1]  = msa_ ## func ## _df(df, pws->b[1],  pwt->b[1]);    \
1310         pwd->b[2]  = msa_ ## func ## _df(df, pws->b[2],  pwt->b[2]);    \
1311         pwd->b[3]  = msa_ ## func ## _df(df, pws->b[3],  pwt->b[3]);    \
1312         pwd->b[4]  = msa_ ## func ## _df(df, pws->b[4],  pwt->b[4]);    \
1313         pwd->b[5]  = msa_ ## func ## _df(df, pws->b[5],  pwt->b[5]);    \
1314         pwd->b[6]  = msa_ ## func ## _df(df, pws->b[6],  pwt->b[6]);    \
1315         pwd->b[7]  = msa_ ## func ## _df(df, pws->b[7],  pwt->b[7]);    \
1316         pwd->b[8]  = msa_ ## func ## _df(df, pws->b[8],  pwt->b[8]);    \
1317         pwd->b[9]  = msa_ ## func ## _df(df, pws->b[9],  pwt->b[9]);    \
1318         pwd->b[10] = msa_ ## func ## _df(df, pws->b[10], pwt->b[10]);   \
1319         pwd->b[11] = msa_ ## func ## _df(df, pws->b[11], pwt->b[11]);   \
1320         pwd->b[12] = msa_ ## func ## _df(df, pws->b[12], pwt->b[12]);   \
1321         pwd->b[13] = msa_ ## func ## _df(df, pws->b[13], pwt->b[13]);   \
1322         pwd->b[14] = msa_ ## func ## _df(df, pws->b[14], pwt->b[14]);   \
1323         pwd->b[15] = msa_ ## func ## _df(df, pws->b[15], pwt->b[15]);   \
1324         break;                                                          \
1325     case DF_HALF:                                                       \
1326         pwd->h[0] = msa_ ## func ## _df(df, pws->h[0], pwt->h[0]);      \
1327         pwd->h[1] = msa_ ## func ## _df(df, pws->h[1], pwt->h[1]);      \
1328         pwd->h[2] = msa_ ## func ## _df(df, pws->h[2], pwt->h[2]);      \
1329         pwd->h[3] = msa_ ## func ## _df(df, pws->h[3], pwt->h[3]);      \
1330         pwd->h[4] = msa_ ## func ## _df(df, pws->h[4], pwt->h[4]);      \
1331         pwd->h[5] = msa_ ## func ## _df(df, pws->h[5], pwt->h[5]);      \
1332         pwd->h[6] = msa_ ## func ## _df(df, pws->h[6], pwt->h[6]);      \
1333         pwd->h[7] = msa_ ## func ## _df(df, pws->h[7], pwt->h[7]);      \
1334         break;                                                          \
1335     case DF_WORD:                                                       \
1336         pwd->w[0] = msa_ ## func ## _df(df, pws->w[0], pwt->w[0]);      \
1337         pwd->w[1] = msa_ ## func ## _df(df, pws->w[1], pwt->w[1]);      \
1338         pwd->w[2] = msa_ ## func ## _df(df, pws->w[2], pwt->w[2]);      \
1339         pwd->w[3] = msa_ ## func ## _df(df, pws->w[3], pwt->w[3]);      \
1340         break;                                                          \
1341     case DF_DOUBLE:                                                     \
1342         pwd->d[0] = msa_ ## func ## _df(df, pws->d[0], pwt->d[0]);      \
1343         pwd->d[1] = msa_ ## func ## _df(df, pws->d[1], pwt->d[1]);      \
1344         break;                                                          \
1345     default:                                                            \
1346         assert(0);                                                      \
1347     }                                                                   \
1348 }
1349
1350 MSA_BINOP_DF(sll)
1351 MSA_BINOP_DF(sra)
1352 MSA_BINOP_DF(srl)
1353 MSA_BINOP_DF(bclr)
1354 MSA_BINOP_DF(bset)
1355 MSA_BINOP_DF(bneg)
1356 MSA_BINOP_DF(addv)
1357 MSA_BINOP_DF(subv)
1358 MSA_BINOP_DF(max_s)
1359 MSA_BINOP_DF(max_u)
1360 MSA_BINOP_DF(min_s)
1361 MSA_BINOP_DF(min_u)
1362 MSA_BINOP_DF(max_a)
1363 MSA_BINOP_DF(min_a)
1364 MSA_BINOP_DF(ceq)
1365 MSA_BINOP_DF(clt_s)
1366 MSA_BINOP_DF(clt_u)
1367 MSA_BINOP_DF(cle_s)
1368 MSA_BINOP_DF(cle_u)
1369 MSA_BINOP_DF(add_a)
1370 MSA_BINOP_DF(adds_a)
1371 MSA_BINOP_DF(adds_s)
1372 MSA_BINOP_DF(adds_u)
1373 MSA_BINOP_DF(ave_s)
1374 MSA_BINOP_DF(ave_u)
1375 MSA_BINOP_DF(aver_s)
1376 MSA_BINOP_DF(aver_u)
1377 MSA_BINOP_DF(subs_s)
1378 MSA_BINOP_DF(subs_u)
1379 MSA_BINOP_DF(subsus_u)
1380 MSA_BINOP_DF(subsuu_s)
1381 MSA_BINOP_DF(asub_s)
1382 MSA_BINOP_DF(asub_u)
1383 MSA_BINOP_DF(mulv)
1384 MSA_BINOP_DF(div_s)
1385 MSA_BINOP_DF(div_u)
1386 MSA_BINOP_DF(mod_s)
1387 MSA_BINOP_DF(mod_u)
1388 MSA_BINOP_DF(dotp_s)
1389 MSA_BINOP_DF(dotp_u)
1390 MSA_BINOP_DF(srar)
1391 MSA_BINOP_DF(srlr)
1392 MSA_BINOP_DF(hadd_s)
1393 MSA_BINOP_DF(hadd_u)
1394 MSA_BINOP_DF(hsub_s)
1395 MSA_BINOP_DF(hsub_u)
1396
1397 MSA_BINOP_DF(mul_q)
1398 MSA_BINOP_DF(mulr_q)
1399 #undef MSA_BINOP_DF
1400
1401 void helper_msa_sld_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
1402                        uint32_t ws, uint32_t rt)
1403 {
1404     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1405     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1406
1407     msa_sld_df(df, pwd, pws, env->active_tc.gpr[rt]);
1408 }
1409
1410 static inline int64_t msa_maddv_df(uint32_t df, int64_t dest, int64_t arg1,
1411                                    int64_t arg2)
1412 {
1413     return dest + arg1 * arg2;
1414 }
1415
1416 static inline int64_t msa_msubv_df(uint32_t df, int64_t dest, int64_t arg1,
1417                                    int64_t arg2)
1418 {
1419     return dest - arg1 * arg2;
1420 }
1421
1422 static inline int64_t msa_dpadd_s_df(uint32_t df, int64_t dest, int64_t arg1,
1423                                      int64_t arg2)
1424 {
1425     int64_t even_arg1;
1426     int64_t even_arg2;
1427     int64_t odd_arg1;
1428     int64_t odd_arg2;
1429     SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
1430     SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
1431     return dest + (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
1432 }
1433
1434 static inline int64_t msa_dpadd_u_df(uint32_t df, int64_t dest, int64_t arg1,
1435                                      int64_t arg2)
1436 {
1437     int64_t even_arg1;
1438     int64_t even_arg2;
1439     int64_t odd_arg1;
1440     int64_t odd_arg2;
1441     UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
1442     UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
1443     return dest + (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
1444 }
1445
1446 static inline int64_t msa_dpsub_s_df(uint32_t df, int64_t dest, int64_t arg1,
1447                                      int64_t arg2)
1448 {
1449     int64_t even_arg1;
1450     int64_t even_arg2;
1451     int64_t odd_arg1;
1452     int64_t odd_arg2;
1453     SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
1454     SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
1455     return dest - ((even_arg1 * even_arg2) + (odd_arg1 * odd_arg2));
1456 }
1457
1458 static inline int64_t msa_dpsub_u_df(uint32_t df, int64_t dest, int64_t arg1,
1459                                      int64_t arg2)
1460 {
1461     int64_t even_arg1;
1462     int64_t even_arg2;
1463     int64_t odd_arg1;
1464     int64_t odd_arg2;
1465     UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
1466     UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
1467     return dest - ((even_arg1 * even_arg2) + (odd_arg1 * odd_arg2));
1468 }
1469
1470 static inline int64_t msa_madd_q_df(uint32_t df, int64_t dest, int64_t arg1,
1471                                     int64_t arg2)
1472 {
1473     int64_t q_prod, q_ret;
1474
1475     int64_t q_max = DF_MAX_INT(df);
1476     int64_t q_min = DF_MIN_INT(df);
1477
1478     q_prod = arg1 * arg2;
1479     q_ret = ((dest << (DF_BITS(df) - 1)) + q_prod) >> (DF_BITS(df) - 1);
1480
1481     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
1482 }
1483
1484 static inline int64_t msa_msub_q_df(uint32_t df, int64_t dest, int64_t arg1,
1485                                     int64_t arg2)
1486 {
1487     int64_t q_prod, q_ret;
1488
1489     int64_t q_max = DF_MAX_INT(df);
1490     int64_t q_min = DF_MIN_INT(df);
1491
1492     q_prod = arg1 * arg2;
1493     q_ret = ((dest << (DF_BITS(df) - 1)) - q_prod) >> (DF_BITS(df) - 1);
1494
1495     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
1496 }
1497
1498 static inline int64_t msa_maddr_q_df(uint32_t df, int64_t dest, int64_t arg1,
1499                                      int64_t arg2)
1500 {
1501     int64_t q_prod, q_ret;
1502
1503     int64_t q_max = DF_MAX_INT(df);
1504     int64_t q_min = DF_MIN_INT(df);
1505     int64_t r_bit = 1 << (DF_BITS(df) - 2);
1506
1507     q_prod = arg1 * arg2;
1508     q_ret = ((dest << (DF_BITS(df) - 1)) + q_prod + r_bit) >> (DF_BITS(df) - 1);
1509
1510     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
1511 }
1512
1513 static inline int64_t msa_msubr_q_df(uint32_t df, int64_t dest, int64_t arg1,
1514                                      int64_t arg2)
1515 {
1516     int64_t q_prod, q_ret;
1517
1518     int64_t q_max = DF_MAX_INT(df);
1519     int64_t q_min = DF_MIN_INT(df);
1520     int64_t r_bit = 1 << (DF_BITS(df) - 2);
1521
1522     q_prod = arg1 * arg2;
1523     q_ret = ((dest << (DF_BITS(df) - 1)) - q_prod + r_bit) >> (DF_BITS(df) - 1);
1524
1525     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
1526 }
1527
1528 #define MSA_TEROP_DF(func) \
1529 void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, uint32_t wd,  \
1530                                 uint32_t ws, uint32_t wt)                     \
1531 {                                                                             \
1532     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                                \
1533     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                                \
1534     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);                                \
1535                                                                               \
1536     switch (df) {                                                             \
1537     case DF_BYTE:                                                             \
1538         pwd->b[0]  = msa_ ## func ## _df(df, pwd->b[0],  pws->b[0],           \
1539                                              pwt->b[0]);                      \
1540         pwd->b[1]  = msa_ ## func ## _df(df, pwd->b[1],  pws->b[1],           \
1541                                              pwt->b[1]);                      \
1542         pwd->b[2]  = msa_ ## func ## _df(df, pwd->b[2],  pws->b[2],           \
1543                                              pwt->b[2]);                      \
1544         pwd->b[3]  = msa_ ## func ## _df(df, pwd->b[3],  pws->b[3],           \
1545                                              pwt->b[3]);                      \
1546         pwd->b[4]  = msa_ ## func ## _df(df, pwd->b[4],  pws->b[4],           \
1547                                              pwt->b[4]);                      \
1548         pwd->b[5]  = msa_ ## func ## _df(df, pwd->b[5],  pws->b[5],           \
1549                                              pwt->b[5]);                      \
1550         pwd->b[6]  = msa_ ## func ## _df(df, pwd->b[6],  pws->b[6],           \
1551                                              pwt->b[6]);                      \
1552         pwd->b[7]  = msa_ ## func ## _df(df, pwd->b[7],  pws->b[7],           \
1553                                              pwt->b[7]);                      \
1554         pwd->b[8]  = msa_ ## func ## _df(df, pwd->b[8],  pws->b[8],           \
1555                                              pwt->b[8]);                      \
1556         pwd->b[9]  = msa_ ## func ## _df(df, pwd->b[9],  pws->b[9],           \
1557                                              pwt->b[9]);                      \
1558         pwd->b[10] = msa_ ## func ## _df(df, pwd->b[10], pws->b[10],          \
1559                                              pwt->b[10]);                     \
1560         pwd->b[11] = msa_ ## func ## _df(df, pwd->b[11], pws->b[11],          \
1561                                              pwt->b[11]);                     \
1562         pwd->b[12] = msa_ ## func ## _df(df, pwd->b[12], pws->b[12],          \
1563                                              pwt->b[12]);                     \
1564         pwd->b[13] = msa_ ## func ## _df(df, pwd->b[13], pws->b[13],          \
1565                                              pwt->b[13]);                     \
1566         pwd->b[14] = msa_ ## func ## _df(df, pwd->b[14], pws->b[14],          \
1567                                              pwt->b[14]);                     \
1568         pwd->b[15] = msa_ ## func ## _df(df, pwd->b[15], pws->b[15],          \
1569                                              pwt->b[15]);                     \
1570         break;                                                                \
1571     case DF_HALF:                                                             \
1572         pwd->h[0] = msa_ ## func ## _df(df, pwd->h[0], pws->h[0], pwt->h[0]); \
1573         pwd->h[1] = msa_ ## func ## _df(df, pwd->h[1], pws->h[1], pwt->h[1]); \
1574         pwd->h[2] = msa_ ## func ## _df(df, pwd->h[2], pws->h[2], pwt->h[2]); \
1575         pwd->h[3] = msa_ ## func ## _df(df, pwd->h[3], pws->h[3], pwt->h[3]); \
1576         pwd->h[4] = msa_ ## func ## _df(df, pwd->h[4], pws->h[4], pwt->h[4]); \
1577         pwd->h[5] = msa_ ## func ## _df(df, pwd->h[5], pws->h[5], pwt->h[5]); \
1578         pwd->h[6] = msa_ ## func ## _df(df, pwd->h[6], pws->h[6], pwt->h[6]); \
1579         pwd->h[7] = msa_ ## func ## _df(df, pwd->h[7], pws->h[7], pwt->h[7]); \
1580         break;                                                                \
1581     case DF_WORD:                                                             \
1582         pwd->w[0] = msa_ ## func ## _df(df, pwd->w[0], pws->w[0], pwt->w[0]); \
1583         pwd->w[1] = msa_ ## func ## _df(df, pwd->w[1], pws->w[1], pwt->w[1]); \
1584         pwd->w[2] = msa_ ## func ## _df(df, pwd->w[2], pws->w[2], pwt->w[2]); \
1585         pwd->w[3] = msa_ ## func ## _df(df, pwd->w[3], pws->w[3], pwt->w[3]); \
1586         break;                                                                \
1587     case DF_DOUBLE:                                                           \
1588         pwd->d[0] = msa_ ## func ## _df(df, pwd->d[0], pws->d[0], pwt->d[0]); \
1589         pwd->d[1] = msa_ ## func ## _df(df, pwd->d[1], pws->d[1], pwt->d[1]); \
1590         break;                                                                \
1591     default:                                                                  \
1592         assert(0);                                                            \
1593     }                                                                         \
1594 }
1595
1596 MSA_TEROP_DF(maddv)
1597 MSA_TEROP_DF(msubv)
1598 MSA_TEROP_DF(dpadd_s)
1599 MSA_TEROP_DF(dpadd_u)
1600 MSA_TEROP_DF(dpsub_s)
1601 MSA_TEROP_DF(dpsub_u)
1602 MSA_TEROP_DF(binsl)
1603 MSA_TEROP_DF(binsr)
1604 MSA_TEROP_DF(madd_q)
1605 MSA_TEROP_DF(msub_q)
1606 MSA_TEROP_DF(maddr_q)
1607 MSA_TEROP_DF(msubr_q)
1608 #undef MSA_TEROP_DF
1609
1610 static inline void msa_splat_df(uint32_t df, wr_t *pwd,
1611                                 wr_t *pws, target_ulong rt)
1612 {
1613     uint32_t n = rt % DF_ELEMENTS(df);
1614     uint32_t i;
1615
1616     switch (df) {
1617     case DF_BYTE:
1618         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
1619             pwd->b[i] = pws->b[n];
1620         }
1621         break;
1622     case DF_HALF:
1623         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
1624             pwd->h[i] = pws->h[n];
1625         }
1626         break;
1627     case DF_WORD:
1628         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
1629             pwd->w[i] = pws->w[n];
1630         }
1631         break;
1632     case DF_DOUBLE:
1633         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
1634             pwd->d[i] = pws->d[n];
1635         }
1636        break;
1637     default:
1638         assert(0);
1639     }
1640 }
1641
1642 void helper_msa_splat_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
1643                          uint32_t ws, uint32_t rt)
1644 {
1645     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1646     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1647
1648     msa_splat_df(df, pwd, pws, env->active_tc.gpr[rt]);
1649 }
1650
1651 #define MSA_DO_B MSA_DO(b)
1652 #define MSA_DO_H MSA_DO(h)
1653 #define MSA_DO_W MSA_DO(w)
1654 #define MSA_DO_D MSA_DO(d)
1655
1656 #define MSA_LOOP_B MSA_LOOP(B)
1657 #define MSA_LOOP_H MSA_LOOP(H)
1658 #define MSA_LOOP_W MSA_LOOP(W)
1659 #define MSA_LOOP_D MSA_LOOP(D)
1660
1661 #define MSA_LOOP_COND_B MSA_LOOP_COND(DF_BYTE)
1662 #define MSA_LOOP_COND_H MSA_LOOP_COND(DF_HALF)
1663 #define MSA_LOOP_COND_W MSA_LOOP_COND(DF_WORD)
1664 #define MSA_LOOP_COND_D MSA_LOOP_COND(DF_DOUBLE)
1665
1666 #define MSA_LOOP(DF) \
1667     do { \
1668         for (i = 0; i < (MSA_LOOP_COND_ ## DF) ; i++) { \
1669             MSA_DO_ ## DF; \
1670         } \
1671     } while (0)
1672
1673 #define MSA_FN_DF(FUNC)                                             \
1674 void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
1675         uint32_t ws, uint32_t wt)                                   \
1676 {                                                                   \
1677     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                      \
1678     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                      \
1679     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);                      \
1680     wr_t wx, *pwx = &wx;                                            \
1681     uint32_t i;                                                     \
1682     switch (df) {                                                   \
1683     case DF_BYTE:                                                   \
1684         MSA_LOOP_B;                                                 \
1685         break;                                                      \
1686     case DF_HALF:                                                   \
1687         MSA_LOOP_H;                                                 \
1688         break;                                                      \
1689     case DF_WORD:                                                   \
1690         MSA_LOOP_W;                                                 \
1691         break;                                                      \
1692     case DF_DOUBLE:                                                 \
1693         MSA_LOOP_D;                                                 \
1694         break;                                                      \
1695     default:                                                        \
1696         assert(0);                                                  \
1697     }                                                               \
1698     msa_move_v(pwd, pwx);                                           \
1699 }
1700
1701 #define MSA_LOOP_COND(DF) \
1702             (DF_ELEMENTS(DF) / 2)
1703
1704 #define Rb(pwr, i) (pwr->b[i])
1705 #define Lb(pwr, i) (pwr->b[i + DF_ELEMENTS(DF_BYTE) / 2])
1706 #define Rh(pwr, i) (pwr->h[i])
1707 #define Lh(pwr, i) (pwr->h[i + DF_ELEMENTS(DF_HALF) / 2])
1708 #define Rw(pwr, i) (pwr->w[i])
1709 #define Lw(pwr, i) (pwr->w[i + DF_ELEMENTS(DF_WORD) / 2])
1710 #define Rd(pwr, i) (pwr->d[i])
1711 #define Ld(pwr, i) (pwr->d[i + DF_ELEMENTS(DF_DOUBLE) / 2])
1712
1713 #undef MSA_LOOP_COND
1714
1715 #define MSA_LOOP_COND(DF) \
1716             (DF_ELEMENTS(DF))
1717
1718 #define MSA_DO(DF)                                                          \
1719     do {                                                                    \
1720         uint32_t n = DF_ELEMENTS(df);                                       \
1721         uint32_t k = (pwd->DF[i] & 0x3f) % (2 * n);                         \
1722         pwx->DF[i] =                                                        \
1723             (pwd->DF[i] & 0xc0) ? 0 : k < n ? pwt->DF[k] : pws->DF[k - n];  \
1724     } while (0)
1725 MSA_FN_DF(vshf_df)
1726 #undef MSA_DO
1727 #undef MSA_LOOP_COND
1728 #undef MSA_FN_DF
1729
1730
1731 void helper_msa_ilvev_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
1732                          uint32_t ws, uint32_t wt)
1733 {
1734     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1735     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1736     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1737
1738     switch (df) {
1739     case DF_BYTE:
1740         pwd->b[15] = pws->b[14];
1741         pwd->b[14] = pwt->b[14];
1742         pwd->b[13] = pws->b[12];
1743         pwd->b[12] = pwt->b[12];
1744         pwd->b[11] = pws->b[10];
1745         pwd->b[10] = pwt->b[10];
1746         pwd->b[9]  = pws->b[8];
1747         pwd->b[8]  = pwt->b[8];
1748         pwd->b[7]  = pws->b[6];
1749         pwd->b[6]  = pwt->b[6];
1750         pwd->b[5]  = pws->b[4];
1751         pwd->b[4]  = pwt->b[4];
1752         pwd->b[3]  = pws->b[2];
1753         pwd->b[2]  = pwt->b[2];
1754         pwd->b[1]  = pws->b[0];
1755         pwd->b[0]  = pwt->b[0];
1756         break;
1757     case DF_HALF:
1758         pwd->h[7] = pws->h[6];
1759         pwd->h[6] = pwt->h[6];
1760         pwd->h[5] = pws->h[4];
1761         pwd->h[4] = pwt->h[4];
1762         pwd->h[3] = pws->h[2];
1763         pwd->h[2] = pwt->h[2];
1764         pwd->h[1] = pws->h[0];
1765         pwd->h[0] = pwt->h[0];
1766         break;
1767     case DF_WORD:
1768         pwd->w[3] = pws->w[2];
1769         pwd->w[2] = pwt->w[2];
1770         pwd->w[1] = pws->w[0];
1771         pwd->w[0] = pwt->w[0];
1772         break;
1773     case DF_DOUBLE:
1774         pwd->d[1] = pws->d[0];
1775         pwd->d[0] = pwt->d[0];
1776         break;
1777     default:
1778         assert(0);
1779     }
1780 }
1781
1782 void helper_msa_ilvod_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
1783                          uint32_t ws, uint32_t wt)
1784 {
1785     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1786     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1787     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1788
1789     switch (df) {
1790     case DF_BYTE:
1791         pwd->b[0]  = pwt->b[1];
1792         pwd->b[1]  = pws->b[1];
1793         pwd->b[2]  = pwt->b[3];
1794         pwd->b[3]  = pws->b[3];
1795         pwd->b[4]  = pwt->b[5];
1796         pwd->b[5]  = pws->b[5];
1797         pwd->b[6]  = pwt->b[7];
1798         pwd->b[7]  = pws->b[7];
1799         pwd->b[8]  = pwt->b[9];
1800         pwd->b[9]  = pws->b[9];
1801         pwd->b[10] = pwt->b[11];
1802         pwd->b[11] = pws->b[11];
1803         pwd->b[12] = pwt->b[13];
1804         pwd->b[13] = pws->b[13];
1805         pwd->b[14] = pwt->b[15];
1806         pwd->b[15] = pws->b[15];
1807         break;
1808     case DF_HALF:
1809         pwd->h[0] = pwt->h[1];
1810         pwd->h[1] = pws->h[1];
1811         pwd->h[2] = pwt->h[3];
1812         pwd->h[3] = pws->h[3];
1813         pwd->h[4] = pwt->h[5];
1814         pwd->h[5] = pws->h[5];
1815         pwd->h[6] = pwt->h[7];
1816         pwd->h[7] = pws->h[7];
1817         break;
1818     case DF_WORD:
1819         pwd->w[0] = pwt->w[1];
1820         pwd->w[1] = pws->w[1];
1821         pwd->w[2] = pwt->w[3];
1822         pwd->w[3] = pws->w[3];
1823         break;
1824     case DF_DOUBLE:
1825         pwd->d[0] = pwt->d[1];
1826         pwd->d[1] = pws->d[1];
1827         break;
1828     default:
1829         assert(0);
1830     }
1831 }
1832
1833 void helper_msa_ilvl_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
1834                         uint32_t ws, uint32_t wt)
1835 {
1836     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1837     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1838     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1839
1840     switch (df) {
1841     case DF_BYTE:
1842         pwd->b[0]  = pwt->b[8];
1843         pwd->b[1]  = pws->b[8];
1844         pwd->b[2]  = pwt->b[9];
1845         pwd->b[3]  = pws->b[9];
1846         pwd->b[4]  = pwt->b[10];
1847         pwd->b[5]  = pws->b[10];
1848         pwd->b[6]  = pwt->b[11];
1849         pwd->b[7]  = pws->b[11];
1850         pwd->b[8]  = pwt->b[12];
1851         pwd->b[9]  = pws->b[12];
1852         pwd->b[10] = pwt->b[13];
1853         pwd->b[11] = pws->b[13];
1854         pwd->b[12] = pwt->b[14];
1855         pwd->b[13] = pws->b[14];
1856         pwd->b[14] = pwt->b[15];
1857         pwd->b[15] = pws->b[15];
1858         break;
1859     case DF_HALF:
1860         pwd->h[0] = pwt->h[4];
1861         pwd->h[1] = pws->h[4];
1862         pwd->h[2] = pwt->h[5];
1863         pwd->h[3] = pws->h[5];
1864         pwd->h[4] = pwt->h[6];
1865         pwd->h[5] = pws->h[6];
1866         pwd->h[6] = pwt->h[7];
1867         pwd->h[7] = pws->h[7];
1868         break;
1869     case DF_WORD:
1870         pwd->w[0] = pwt->w[2];
1871         pwd->w[1] = pws->w[2];
1872         pwd->w[2] = pwt->w[3];
1873         pwd->w[3] = pws->w[3];
1874         break;
1875     case DF_DOUBLE:
1876         pwd->d[0] = pwt->d[1];
1877         pwd->d[1] = pws->d[1];
1878         break;
1879     default:
1880         assert(0);
1881     }
1882 }
1883
1884 void helper_msa_ilvr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
1885                         uint32_t ws, uint32_t wt)
1886 {
1887     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1888     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1889     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1890
1891     switch (df) {
1892     case DF_BYTE:
1893         pwd->b[15] = pws->b[7];
1894         pwd->b[14] = pwt->b[7];
1895         pwd->b[13] = pws->b[6];
1896         pwd->b[12] = pwt->b[6];
1897         pwd->b[11] = pws->b[5];
1898         pwd->b[10] = pwt->b[5];
1899         pwd->b[9]  = pws->b[4];
1900         pwd->b[8]  = pwt->b[4];
1901         pwd->b[7]  = pws->b[3];
1902         pwd->b[6]  = pwt->b[3];
1903         pwd->b[5]  = pws->b[2];
1904         pwd->b[4]  = pwt->b[2];
1905         pwd->b[3]  = pws->b[1];
1906         pwd->b[2]  = pwt->b[1];
1907         pwd->b[1]  = pws->b[0];
1908         pwd->b[0]  = pwt->b[0];
1909         break;
1910     case DF_HALF:
1911         pwd->h[7] = pws->h[3];
1912         pwd->h[6] = pwt->h[3];
1913         pwd->h[5] = pws->h[2];
1914         pwd->h[4] = pwt->h[2];
1915         pwd->h[3] = pws->h[1];
1916         pwd->h[2] = pwt->h[1];
1917         pwd->h[1] = pws->h[0];
1918         pwd->h[0] = pwt->h[0];
1919         break;
1920     case DF_WORD:
1921         pwd->w[3] = pws->w[1];
1922         pwd->w[2] = pwt->w[1];
1923         pwd->w[1] = pws->w[0];
1924         pwd->w[0] = pwt->w[0];
1925         break;
1926     case DF_DOUBLE:
1927         pwd->d[1] = pws->d[0];
1928         pwd->d[0] = pwt->d[0];
1929         break;
1930     default:
1931         assert(0);
1932     }
1933 }
1934
1935 void helper_msa_pckev_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
1936                          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     switch (df) {
1943     case DF_BYTE:
1944         pwd->b[15] = pws->b[14];
1945         pwd->b[13] = pws->b[10];
1946         pwd->b[11] = pws->b[6];
1947         pwd->b[9]  = pws->b[2];
1948         pwd->b[7]  = pwt->b[14];
1949         pwd->b[5]  = pwt->b[10];
1950         pwd->b[3]  = pwt->b[6];
1951         pwd->b[1]  = pwt->b[2];
1952         pwd->b[14] = pws->b[12];
1953         pwd->b[10] = pws->b[4];
1954         pwd->b[6]  = pwt->b[12];
1955         pwd->b[2]  = pwt->b[4];
1956         pwd->b[12] = pws->b[8];
1957         pwd->b[4]  = pwt->b[8];
1958         pwd->b[8]  = pws->b[0];
1959         pwd->b[0]  = pwt->b[0];
1960         break;
1961     case DF_HALF:
1962         pwd->h[7] = pws->h[6];
1963         pwd->h[5] = pws->h[2];
1964         pwd->h[3] = pwt->h[6];
1965         pwd->h[1] = pwt->h[2];
1966         pwd->h[6] = pws->h[4];
1967         pwd->h[2] = pwt->h[4];
1968         pwd->h[4] = pws->h[0];
1969         pwd->h[0] = pwt->h[0];
1970         break;
1971     case DF_WORD:
1972         pwd->w[3] = pws->w[2];
1973         pwd->w[1] = pwt->w[2];
1974         pwd->w[2] = pws->w[0];
1975         pwd->w[0] = pwt->w[0];
1976         break;
1977     case DF_DOUBLE:
1978         pwd->d[1] = pws->d[0];
1979         pwd->d[0] = pwt->d[0];
1980         break;
1981     default:
1982         assert(0);
1983     }
1984 }
1985
1986 void helper_msa_pckod_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
1987                          uint32_t ws, uint32_t wt)
1988 {
1989     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1990     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1991     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1992
1993     switch (df) {
1994     case DF_BYTE:
1995         pwd->b[0]  = pwt->b[1];
1996         pwd->b[2]  = pwt->b[5];
1997         pwd->b[4]  = pwt->b[9];
1998         pwd->b[6]  = pwt->b[13];
1999         pwd->b[8]  = pws->b[1];
2000         pwd->b[10] = pws->b[5];
2001         pwd->b[12] = pws->b[9];
2002         pwd->b[14] = pws->b[13];
2003         pwd->b[1]  = pwt->b[3];
2004         pwd->b[5]  = pwt->b[11];
2005         pwd->b[9]  = pws->b[3];
2006         pwd->b[13] = pws->b[11];
2007         pwd->b[3]  = pwt->b[7];
2008         pwd->b[11] = pws->b[7];
2009         pwd->b[7]  = pwt->b[15];
2010         pwd->b[15] = pws->b[15];
2011         break;
2012     case DF_HALF:
2013         pwd->h[0] = pwt->h[1];
2014         pwd->h[2] = pwt->h[5];
2015         pwd->h[4] = pws->h[1];
2016         pwd->h[6] = pws->h[5];
2017         pwd->h[1] = pwt->h[3];
2018         pwd->h[5] = pws->h[3];
2019         pwd->h[3] = pwt->h[7];
2020         pwd->h[7] = pws->h[7];
2021         break;
2022     case DF_WORD:
2023         pwd->w[0] = pwt->w[1];
2024         pwd->w[2] = pws->w[1];
2025         pwd->w[1] = pwt->w[3];
2026         pwd->w[3] = pws->w[3];
2027         break;
2028     case DF_DOUBLE:
2029         pwd->d[0] = pwt->d[1];
2030         pwd->d[1] = pws->d[1];
2031         break;
2032     default:
2033         assert(0);
2034     }
2035 }
2036
2037
2038 void helper_msa_sldi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
2039                         uint32_t ws, uint32_t n)
2040 {
2041     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2042     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2043
2044     msa_sld_df(df, pwd, pws, n);
2045 }
2046
2047 void helper_msa_splati_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
2048                           uint32_t ws, uint32_t n)
2049 {
2050     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2051     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2052
2053     msa_splat_df(df, pwd, pws, n);
2054 }
2055
2056 void helper_msa_copy_s_b(CPUMIPSState *env, uint32_t rd,
2057                          uint32_t ws, uint32_t n)
2058 {
2059     n %= 16;
2060 #if defined(HOST_WORDS_BIGENDIAN)
2061     if (n < 8) {
2062         n = 8 - n - 1;
2063     } else {
2064         n = 24 - n - 1;
2065     }
2066 #endif
2067     env->active_tc.gpr[rd] = (int8_t)env->active_fpu.fpr[ws].wr.b[n];
2068 }
2069
2070 void helper_msa_copy_s_h(CPUMIPSState *env, uint32_t rd,
2071                          uint32_t ws, uint32_t n)
2072 {
2073     n %= 8;
2074 #if defined(HOST_WORDS_BIGENDIAN)
2075     if (n < 4) {
2076         n = 4 - n - 1;
2077     } else {
2078         n = 12 - n - 1;
2079     }
2080 #endif
2081     env->active_tc.gpr[rd] = (int16_t)env->active_fpu.fpr[ws].wr.h[n];
2082 }
2083
2084 void helper_msa_copy_s_w(CPUMIPSState *env, uint32_t rd,
2085                          uint32_t ws, uint32_t n)
2086 {
2087     n %= 4;
2088 #if defined(HOST_WORDS_BIGENDIAN)
2089     if (n < 2) {
2090         n = 2 - n - 1;
2091     } else {
2092         n = 6 - n - 1;
2093     }
2094 #endif
2095     env->active_tc.gpr[rd] = (int32_t)env->active_fpu.fpr[ws].wr.w[n];
2096 }
2097
2098 void helper_msa_copy_s_d(CPUMIPSState *env, uint32_t rd,
2099                          uint32_t ws, uint32_t n)
2100 {
2101     n %= 2;
2102     env->active_tc.gpr[rd] = (int64_t)env->active_fpu.fpr[ws].wr.d[n];
2103 }
2104
2105 void helper_msa_copy_u_b(CPUMIPSState *env, uint32_t rd,
2106                          uint32_t ws, uint32_t n)
2107 {
2108     n %= 16;
2109 #if defined(HOST_WORDS_BIGENDIAN)
2110     if (n < 8) {
2111         n = 8 - n - 1;
2112     } else {
2113         n = 24 - n - 1;
2114     }
2115 #endif
2116     env->active_tc.gpr[rd] = (uint8_t)env->active_fpu.fpr[ws].wr.b[n];
2117 }
2118
2119 void helper_msa_copy_u_h(CPUMIPSState *env, uint32_t rd,
2120                          uint32_t ws, uint32_t n)
2121 {
2122     n %= 8;
2123 #if defined(HOST_WORDS_BIGENDIAN)
2124     if (n < 4) {
2125         n = 4 - n - 1;
2126     } else {
2127         n = 12 - n - 1;
2128     }
2129 #endif
2130     env->active_tc.gpr[rd] = (uint16_t)env->active_fpu.fpr[ws].wr.h[n];
2131 }
2132
2133 void helper_msa_copy_u_w(CPUMIPSState *env, uint32_t rd,
2134                          uint32_t ws, uint32_t n)
2135 {
2136     n %= 4;
2137 #if defined(HOST_WORDS_BIGENDIAN)
2138     if (n < 2) {
2139         n = 2 - n - 1;
2140     } else {
2141         n = 6 - n - 1;
2142     }
2143 #endif
2144     env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
2145 }
2146
2147 void helper_msa_insert_b(CPUMIPSState *env, uint32_t wd,
2148                           uint32_t rs_num, uint32_t n)
2149 {
2150     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2151     target_ulong rs = env->active_tc.gpr[rs_num];
2152     n %= 16;
2153 #if defined(HOST_WORDS_BIGENDIAN)
2154     if (n < 8) {
2155         n = 8 - n - 1;
2156     } else {
2157         n = 24 - n - 1;
2158     }
2159 #endif
2160     pwd->b[n] = (int8_t)rs;
2161 }
2162
2163 void helper_msa_insert_h(CPUMIPSState *env, uint32_t wd,
2164                           uint32_t rs_num, uint32_t n)
2165 {
2166     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2167     target_ulong rs = env->active_tc.gpr[rs_num];
2168     n %= 8;
2169 #if defined(HOST_WORDS_BIGENDIAN)
2170     if (n < 4) {
2171         n = 4 - n - 1;
2172     } else {
2173         n = 12 - n - 1;
2174     }
2175 #endif
2176     pwd->h[n] = (int16_t)rs;
2177 }
2178
2179 void helper_msa_insert_w(CPUMIPSState *env, uint32_t wd,
2180                           uint32_t rs_num, uint32_t n)
2181 {
2182     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2183     target_ulong rs = env->active_tc.gpr[rs_num];
2184     n %= 4;
2185 #if defined(HOST_WORDS_BIGENDIAN)
2186     if (n < 2) {
2187         n = 2 - n - 1;
2188     } else {
2189         n = 6 - n - 1;
2190     }
2191 #endif
2192     pwd->w[n] = (int32_t)rs;
2193 }
2194
2195 void helper_msa_insert_d(CPUMIPSState *env, uint32_t wd,
2196                           uint32_t rs_num, uint32_t n)
2197 {
2198     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2199     target_ulong rs = env->active_tc.gpr[rs_num];
2200     n %= 2;
2201     pwd->d[n] = (int64_t)rs;
2202 }
2203
2204 void helper_msa_insve_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
2205                          uint32_t ws, uint32_t n)
2206 {
2207     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2208     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2209
2210     switch (df) {
2211     case DF_BYTE:
2212         pwd->b[n] = (int8_t)pws->b[0];
2213         break;
2214     case DF_HALF:
2215         pwd->h[n] = (int16_t)pws->h[0];
2216         break;
2217     case DF_WORD:
2218         pwd->w[n] = (int32_t)pws->w[0];
2219         break;
2220     case DF_DOUBLE:
2221         pwd->d[n] = (int64_t)pws->d[0];
2222         break;
2223     default:
2224         assert(0);
2225     }
2226 }
2227
2228 void helper_msa_ctcmsa(CPUMIPSState *env, target_ulong elm, uint32_t cd)
2229 {
2230     switch (cd) {
2231     case 0:
2232         break;
2233     case 1:
2234         env->active_tc.msacsr = (int32_t)elm & MSACSR_MASK;
2235         restore_msa_fp_status(env);
2236         /* check exception */
2237         if ((GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)
2238             & GET_FP_CAUSE(env->active_tc.msacsr)) {
2239             do_raise_exception(env, EXCP_MSAFPE, GETPC());
2240         }
2241         break;
2242     }
2243 }
2244
2245 target_ulong helper_msa_cfcmsa(CPUMIPSState *env, uint32_t cs)
2246 {
2247     switch (cs) {
2248     case 0:
2249         return env->msair;
2250     case 1:
2251         return env->active_tc.msacsr & MSACSR_MASK;
2252     }
2253     return 0;
2254 }
2255
2256 void helper_msa_move_v(CPUMIPSState *env, uint32_t wd, uint32_t ws)
2257 {
2258     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2259     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2260
2261     msa_move_v(pwd, pws);
2262 }
2263
2264 static inline int64_t msa_pcnt_df(uint32_t df, int64_t arg)
2265 {
2266     uint64_t x;
2267
2268     x = UNSIGNED(arg, df);
2269
2270     x = (x & 0x5555555555555555ULL) + ((x >>  1) & 0x5555555555555555ULL);
2271     x = (x & 0x3333333333333333ULL) + ((x >>  2) & 0x3333333333333333ULL);
2272     x = (x & 0x0F0F0F0F0F0F0F0FULL) + ((x >>  4) & 0x0F0F0F0F0F0F0F0FULL);
2273     x = (x & 0x00FF00FF00FF00FFULL) + ((x >>  8) & 0x00FF00FF00FF00FFULL);
2274     x = (x & 0x0000FFFF0000FFFFULL) + ((x >> 16) & 0x0000FFFF0000FFFFULL);
2275     x = (x & 0x00000000FFFFFFFFULL) + ((x >> 32));
2276
2277     return x;
2278 }
2279
2280 static inline int64_t msa_nlzc_df(uint32_t df, int64_t arg)
2281 {
2282     uint64_t x, y;
2283     int n, c;
2284
2285     x = UNSIGNED(arg, df);
2286     n = DF_BITS(df);
2287     c = DF_BITS(df) / 2;
2288
2289     do {
2290         y = x >> c;
2291         if (y != 0) {
2292             n = n - c;
2293             x = y;
2294         }
2295         c = c >> 1;
2296     } while (c != 0);
2297
2298     return n - x;
2299 }
2300
2301 static inline int64_t msa_nloc_df(uint32_t df, int64_t arg)
2302 {
2303     return msa_nlzc_df(df, UNSIGNED((~arg), df));
2304 }
2305
2306 void helper_msa_fill_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
2307                         uint32_t rs)
2308 {
2309     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2310     uint32_t i;
2311
2312     switch (df) {
2313     case DF_BYTE:
2314         for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
2315             pwd->b[i] = (int8_t)env->active_tc.gpr[rs];
2316         }
2317         break;
2318     case DF_HALF:
2319         for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
2320             pwd->h[i] = (int16_t)env->active_tc.gpr[rs];
2321         }
2322         break;
2323     case DF_WORD:
2324         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
2325             pwd->w[i] = (int32_t)env->active_tc.gpr[rs];
2326         }
2327         break;
2328     case DF_DOUBLE:
2329         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
2330             pwd->d[i] = (int64_t)env->active_tc.gpr[rs];
2331         }
2332        break;
2333     default:
2334         assert(0);
2335     }
2336 }
2337
2338 #define MSA_UNOP_DF(func) \
2339 void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df,         \
2340                               uint32_t wd, uint32_t ws)                 \
2341 {                                                                       \
2342     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
2343     wr_t *pws = &(env->active_fpu.fpr[ws].wr);                          \
2344                                                                         \
2345     switch (df) {                                                       \
2346     case DF_BYTE:                                                       \
2347         pwd->b[0]  = msa_ ## func ## _df(df, pws->b[0]);                \
2348         pwd->b[1]  = msa_ ## func ## _df(df, pws->b[1]);                \
2349         pwd->b[2]  = msa_ ## func ## _df(df, pws->b[2]);                \
2350         pwd->b[3]  = msa_ ## func ## _df(df, pws->b[3]);                \
2351         pwd->b[4]  = msa_ ## func ## _df(df, pws->b[4]);                \
2352         pwd->b[5]  = msa_ ## func ## _df(df, pws->b[5]);                \
2353         pwd->b[6]  = msa_ ## func ## _df(df, pws->b[6]);                \
2354         pwd->b[7]  = msa_ ## func ## _df(df, pws->b[7]);                \
2355         pwd->b[8]  = msa_ ## func ## _df(df, pws->b[8]);                \
2356         pwd->b[9]  = msa_ ## func ## _df(df, pws->b[9]);                \
2357         pwd->b[10] = msa_ ## func ## _df(df, pws->b[10]);               \
2358         pwd->b[11] = msa_ ## func ## _df(df, pws->b[11]);               \
2359         pwd->b[12] = msa_ ## func ## _df(df, pws->b[12]);               \
2360         pwd->b[13] = msa_ ## func ## _df(df, pws->b[13]);               \
2361         pwd->b[14] = msa_ ## func ## _df(df, pws->b[14]);               \
2362         pwd->b[15] = msa_ ## func ## _df(df, pws->b[15]);               \
2363         break;                                                          \
2364     case DF_HALF:                                                       \
2365         pwd->h[0] = msa_ ## func ## _df(df, pws->h[0]);                 \
2366         pwd->h[1] = msa_ ## func ## _df(df, pws->h[1]);                 \
2367         pwd->h[2] = msa_ ## func ## _df(df, pws->h[2]);                 \
2368         pwd->h[3] = msa_ ## func ## _df(df, pws->h[3]);                 \
2369         pwd->h[4] = msa_ ## func ## _df(df, pws->h[4]);                 \
2370         pwd->h[5] = msa_ ## func ## _df(df, pws->h[5]);                 \
2371         pwd->h[6] = msa_ ## func ## _df(df, pws->h[6]);                 \
2372         pwd->h[7] = msa_ ## func ## _df(df, pws->h[7]);                 \
2373         break;                                                          \
2374     case DF_WORD:                                                       \
2375         pwd->w[0] = msa_ ## func ## _df(df, pws->w[0]);                 \
2376         pwd->w[1] = msa_ ## func ## _df(df, pws->w[1]);                 \
2377         pwd->w[2] = msa_ ## func ## _df(df, pws->w[2]);                 \
2378         pwd->w[3] = msa_ ## func ## _df(df, pws->w[3]);                 \
2379         break;                                                          \
2380     case DF_DOUBLE:                                                     \
2381         pwd->d[0] = msa_ ## func ## _df(df, pws->d[0]);                 \
2382         pwd->d[1] = msa_ ## func ## _df(df, pws->d[1]);                 \
2383         break;                                                          \
2384     default:                                                            \
2385         assert(0);                                                      \
2386     }                                                                   \
2387 }
2388
2389 MSA_UNOP_DF(nlzc)
2390 MSA_UNOP_DF(nloc)
2391 MSA_UNOP_DF(pcnt)
2392 #undef MSA_UNOP_DF
2393
2394 #define FLOAT_ONE32 make_float32(0x3f8 << 20)
2395 #define FLOAT_ONE64 make_float64(0x3ffULL << 52)
2396
2397 #define FLOAT_SNAN16(s) (float16_default_nan(s) ^ 0x0220)
2398         /* 0x7c20 */
2399 #define FLOAT_SNAN32(s) (float32_default_nan(s) ^ 0x00400020)
2400         /* 0x7f800020 */
2401 #define FLOAT_SNAN64(s) (float64_default_nan(s) ^ 0x0008000000000020ULL)
2402         /* 0x7ff0000000000020 */
2403
2404 static inline void clear_msacsr_cause(CPUMIPSState *env)
2405 {
2406     SET_FP_CAUSE(env->active_tc.msacsr, 0);
2407 }
2408
2409 static inline void check_msacsr_cause(CPUMIPSState *env, uintptr_t retaddr)
2410 {
2411     if ((GET_FP_CAUSE(env->active_tc.msacsr) &
2412             (GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)) == 0) {
2413         UPDATE_FP_FLAGS(env->active_tc.msacsr,
2414                 GET_FP_CAUSE(env->active_tc.msacsr));
2415     } else {
2416         do_raise_exception(env, EXCP_MSAFPE, retaddr);
2417     }
2418 }
2419
2420 /* Flush-to-zero use cases for update_msacsr() */
2421 #define CLEAR_FS_UNDERFLOW 1
2422 #define CLEAR_IS_INEXACT   2
2423 #define RECIPROCAL_INEXACT 4
2424
2425 static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
2426 {
2427     int ieee_ex;
2428
2429     int c;
2430     int cause;
2431     int enable;
2432
2433     ieee_ex = get_float_exception_flags(&env->active_tc.msa_fp_status);
2434
2435     /* QEMU softfloat does not signal all underflow cases */
2436     if (denormal) {
2437         ieee_ex |= float_flag_underflow;
2438     }
2439
2440     c = ieee_ex_to_mips(ieee_ex);
2441     enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
2442
2443     /* Set Inexact (I) when flushing inputs to zero */
2444     if ((ieee_ex & float_flag_input_denormal) &&
2445             (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
2446         if (action & CLEAR_IS_INEXACT) {
2447             c &= ~FP_INEXACT;
2448         } else {
2449             c |=  FP_INEXACT;
2450         }
2451     }
2452
2453     /* Set Inexact (I) and Underflow (U) when flushing outputs to zero */
2454     if ((ieee_ex & float_flag_output_denormal) &&
2455             (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
2456         c |= FP_INEXACT;
2457         if (action & CLEAR_FS_UNDERFLOW) {
2458             c &= ~FP_UNDERFLOW;
2459         } else {
2460             c |=  FP_UNDERFLOW;
2461         }
2462     }
2463
2464     /* Set Inexact (I) when Overflow (O) is not enabled */
2465     if ((c & FP_OVERFLOW) != 0 && (enable & FP_OVERFLOW) == 0) {
2466         c |= FP_INEXACT;
2467     }
2468
2469     /* Clear Exact Underflow when Underflow (U) is not enabled */
2470     if ((c & FP_UNDERFLOW) != 0 && (enable & FP_UNDERFLOW) == 0 &&
2471             (c & FP_INEXACT) == 0) {
2472         c &= ~FP_UNDERFLOW;
2473     }
2474
2475     /*
2476      * Reciprocal operations set only Inexact when valid and not
2477      * divide by zero
2478      */
2479     if ((action & RECIPROCAL_INEXACT) &&
2480             (c & (FP_INVALID | FP_DIV0)) == 0) {
2481         c = FP_INEXACT;
2482     }
2483
2484     cause = c & enable;    /* all current enabled exceptions */
2485
2486     if (cause == 0) {
2487         /*
2488          * No enabled exception, update the MSACSR Cause
2489          * with all current exceptions
2490          */
2491         SET_FP_CAUSE(env->active_tc.msacsr,
2492                 (GET_FP_CAUSE(env->active_tc.msacsr) | c));
2493     } else {
2494         /* Current exceptions are enabled */
2495         if ((env->active_tc.msacsr & MSACSR_NX_MASK) == 0) {
2496             /*
2497              * Exception(s) will trap, update MSACSR Cause
2498              * with all enabled exceptions
2499              */
2500             SET_FP_CAUSE(env->active_tc.msacsr,
2501                     (GET_FP_CAUSE(env->active_tc.msacsr) | c));
2502         }
2503     }
2504
2505     return c;
2506 }
2507
2508 static inline int get_enabled_exceptions(const CPUMIPSState *env, int c)
2509 {
2510     int enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
2511     return c & enable;
2512 }
2513
2514 static inline float16 float16_from_float32(int32_t a, flag ieee,
2515                                            float_status *status)
2516 {
2517       float16 f_val;
2518
2519       f_val = float32_to_float16((float32)a, ieee, status);
2520
2521       return a < 0 ? (f_val | (1 << 15)) : f_val;
2522 }
2523
2524 static inline float32 float32_from_float64(int64_t a, float_status *status)
2525 {
2526       float32 f_val;
2527
2528       f_val = float64_to_float32((float64)a, status);
2529
2530       return a < 0 ? (f_val | (1 << 31)) : f_val;
2531 }
2532
2533 static inline float32 float32_from_float16(int16_t a, flag ieee,
2534                                            float_status *status)
2535 {
2536       float32 f_val;
2537
2538       f_val = float16_to_float32((float16)a, ieee, status);
2539
2540       return a < 0 ? (f_val | (1 << 31)) : f_val;
2541 }
2542
2543 static inline float64 float64_from_float32(int32_t a, float_status *status)
2544 {
2545       float64 f_val;
2546
2547       f_val = float32_to_float64((float64)a, status);
2548
2549       return a < 0 ? (f_val | (1ULL << 63)) : f_val;
2550 }
2551
2552 static inline float32 float32_from_q16(int16_t a, float_status *status)
2553 {
2554     float32 f_val;
2555
2556     /* conversion as integer and scaling */
2557     f_val = int32_to_float32(a, status);
2558     f_val = float32_scalbn(f_val, -15, status);
2559
2560     return f_val;
2561 }
2562
2563 static inline float64 float64_from_q32(int32_t a, float_status *status)
2564 {
2565     float64 f_val;
2566
2567     /* conversion as integer and scaling */
2568     f_val = int32_to_float64(a, status);
2569     f_val = float64_scalbn(f_val, -31, status);
2570
2571     return f_val;
2572 }
2573
2574 static inline int16_t float32_to_q16(float32 a, float_status *status)
2575 {
2576     int32_t q_val;
2577     int32_t q_min = 0xffff8000;
2578     int32_t q_max = 0x00007fff;
2579
2580     int ieee_ex;
2581
2582     if (float32_is_any_nan(a)) {
2583         float_raise(float_flag_invalid, status);
2584         return 0;
2585     }
2586
2587     /* scaling */
2588     a = float32_scalbn(a, 15, status);
2589
2590     ieee_ex = get_float_exception_flags(status);
2591     set_float_exception_flags(ieee_ex & (~float_flag_underflow)
2592                              , status);
2593
2594     if (ieee_ex & float_flag_overflow) {
2595         float_raise(float_flag_inexact, status);
2596         return (int32_t)a < 0 ? q_min : q_max;
2597     }
2598
2599     /* conversion to int */
2600     q_val = float32_to_int32(a, status);
2601
2602     ieee_ex = get_float_exception_flags(status);
2603     set_float_exception_flags(ieee_ex & (~float_flag_underflow)
2604                              , status);
2605
2606     if (ieee_ex & float_flag_invalid) {
2607         set_float_exception_flags(ieee_ex & (~float_flag_invalid)
2608                                , status);
2609         float_raise(float_flag_overflow | float_flag_inexact, status);
2610         return (int32_t)a < 0 ? q_min : q_max;
2611     }
2612
2613     if (q_val < q_min) {
2614         float_raise(float_flag_overflow | float_flag_inexact, status);
2615         return (int16_t)q_min;
2616     }
2617
2618     if (q_max < q_val) {
2619         float_raise(float_flag_overflow | float_flag_inexact, status);
2620         return (int16_t)q_max;
2621     }
2622
2623     return (int16_t)q_val;
2624 }
2625
2626 static inline int32_t float64_to_q32(float64 a, float_status *status)
2627 {
2628     int64_t q_val;
2629     int64_t q_min = 0xffffffff80000000LL;
2630     int64_t q_max = 0x000000007fffffffLL;
2631
2632     int ieee_ex;
2633
2634     if (float64_is_any_nan(a)) {
2635         float_raise(float_flag_invalid, status);
2636         return 0;
2637     }
2638
2639     /* scaling */
2640     a = float64_scalbn(a, 31, status);
2641
2642     ieee_ex = get_float_exception_flags(status);
2643     set_float_exception_flags(ieee_ex & (~float_flag_underflow)
2644            , status);
2645
2646     if (ieee_ex & float_flag_overflow) {
2647         float_raise(float_flag_inexact, status);
2648         return (int64_t)a < 0 ? q_min : q_max;
2649     }
2650
2651     /* conversion to integer */
2652     q_val = float64_to_int64(a, status);
2653
2654     ieee_ex = get_float_exception_flags(status);
2655     set_float_exception_flags(ieee_ex & (~float_flag_underflow)
2656            , status);
2657
2658     if (ieee_ex & float_flag_invalid) {
2659         set_float_exception_flags(ieee_ex & (~float_flag_invalid)
2660                , status);
2661         float_raise(float_flag_overflow | float_flag_inexact, status);
2662         return (int64_t)a < 0 ? q_min : q_max;
2663     }
2664
2665     if (q_val < q_min) {
2666         float_raise(float_flag_overflow | float_flag_inexact, status);
2667         return (int32_t)q_min;
2668     }
2669
2670     if (q_max < q_val) {
2671         float_raise(float_flag_overflow | float_flag_inexact, status);
2672         return (int32_t)q_max;
2673     }
2674
2675     return (int32_t)q_val;
2676 }
2677
2678 #define MSA_FLOAT_COND(DEST, OP, ARG1, ARG2, BITS, QUIET)                   \
2679     do {                                                                    \
2680         float_status *status = &env->active_tc.msa_fp_status;               \
2681         int c;                                                              \
2682         int64_t cond;                                                       \
2683         set_float_exception_flags(0, status);                               \
2684         if (!QUIET) {                                                       \
2685             cond = float ## BITS ## _ ## OP(ARG1, ARG2, status);            \
2686         } else {                                                            \
2687             cond = float ## BITS ## _ ## OP ## _quiet(ARG1, ARG2, status);  \
2688         }                                                                   \
2689         DEST = cond ? M_MAX_UINT(BITS) : 0;                                 \
2690         c = update_msacsr(env, CLEAR_IS_INEXACT, 0);                        \
2691                                                                             \
2692         if (get_enabled_exceptions(env, c)) {                               \
2693             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
2694         }                                                                   \
2695     } while (0)
2696
2697 #define MSA_FLOAT_AF(DEST, ARG1, ARG2, BITS, QUIET)                 \
2698     do {                                                            \
2699         MSA_FLOAT_COND(DEST, eq, ARG1, ARG2, BITS, QUIET);          \
2700         if ((DEST & M_MAX_UINT(BITS)) == M_MAX_UINT(BITS)) {        \
2701             DEST = 0;                                               \
2702         }                                                           \
2703     } while (0)
2704
2705 #define MSA_FLOAT_UEQ(DEST, ARG1, ARG2, BITS, QUIET)                \
2706     do {                                                            \
2707         MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET);   \
2708         if (DEST == 0) {                                            \
2709             MSA_FLOAT_COND(DEST, eq, ARG1, ARG2, BITS, QUIET);      \
2710         }                                                           \
2711     } while (0)
2712
2713 #define MSA_FLOAT_NE(DEST, ARG1, ARG2, BITS, QUIET)                 \
2714     do {                                                            \
2715         MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET);          \
2716         if (DEST == 0) {                                            \
2717             MSA_FLOAT_COND(DEST, lt, ARG2, ARG1, BITS, QUIET);      \
2718         }                                                           \
2719     } while (0)
2720
2721 #define MSA_FLOAT_UNE(DEST, ARG1, ARG2, BITS, QUIET)                \
2722     do {                                                            \
2723         MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET);   \
2724         if (DEST == 0) {                                            \
2725             MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET);      \
2726             if (DEST == 0) {                                        \
2727                 MSA_FLOAT_COND(DEST, lt, ARG2, ARG1, BITS, QUIET);  \
2728             }                                                       \
2729         }                                                           \
2730     } while (0)
2731
2732 #define MSA_FLOAT_ULE(DEST, ARG1, ARG2, BITS, QUIET)                \
2733     do {                                                            \
2734         MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET);   \
2735         if (DEST == 0) {                                            \
2736             MSA_FLOAT_COND(DEST, le, ARG1, ARG2, BITS, QUIET);      \
2737         }                                                           \
2738     } while (0)
2739
2740 #define MSA_FLOAT_ULT(DEST, ARG1, ARG2, BITS, QUIET)                \
2741     do {                                                            \
2742         MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET);   \
2743         if (DEST == 0) {                                            \
2744             MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET);      \
2745         }                                                           \
2746     } while (0)
2747
2748 #define MSA_FLOAT_OR(DEST, ARG1, ARG2, BITS, QUIET)                 \
2749     do {                                                            \
2750         MSA_FLOAT_COND(DEST, le, ARG1, ARG2, BITS, QUIET);          \
2751         if (DEST == 0) {                                            \
2752             MSA_FLOAT_COND(DEST, le, ARG2, ARG1, BITS, QUIET);      \
2753         }                                                           \
2754     } while (0)
2755
2756 static inline void compare_af(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
2757                               wr_t *pwt, uint32_t df, int quiet,
2758                               uintptr_t retaddr)
2759 {
2760     wr_t wx, *pwx = &wx;
2761     uint32_t i;
2762
2763     clear_msacsr_cause(env);
2764
2765     switch (df) {
2766     case DF_WORD:
2767         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
2768             MSA_FLOAT_AF(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
2769         }
2770         break;
2771     case DF_DOUBLE:
2772         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
2773             MSA_FLOAT_AF(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
2774         }
2775         break;
2776     default:
2777         assert(0);
2778     }
2779
2780     check_msacsr_cause(env, retaddr);
2781
2782     msa_move_v(pwd, pwx);
2783 }
2784
2785 static inline void compare_un(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
2786                               wr_t *pwt, uint32_t df, int quiet,
2787                               uintptr_t retaddr)
2788 {
2789     wr_t wx, *pwx = &wx;
2790     uint32_t i;
2791
2792     clear_msacsr_cause(env);
2793
2794     switch (df) {
2795     case DF_WORD:
2796         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
2797             MSA_FLOAT_COND(pwx->w[i], unordered, pws->w[i], pwt->w[i], 32,
2798                     quiet);
2799         }
2800         break;
2801     case DF_DOUBLE:
2802         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
2803             MSA_FLOAT_COND(pwx->d[i], unordered, pws->d[i], pwt->d[i], 64,
2804                     quiet);
2805         }
2806         break;
2807     default:
2808         assert(0);
2809     }
2810
2811     check_msacsr_cause(env, retaddr);
2812
2813     msa_move_v(pwd, pwx);
2814 }
2815
2816 static inline void compare_eq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
2817                               wr_t *pwt, uint32_t df, int quiet,
2818                               uintptr_t retaddr)
2819 {
2820     wr_t wx, *pwx = &wx;
2821     uint32_t i;
2822
2823     clear_msacsr_cause(env);
2824
2825     switch (df) {
2826     case DF_WORD:
2827         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
2828             MSA_FLOAT_COND(pwx->w[i], eq, pws->w[i], pwt->w[i], 32, quiet);
2829         }
2830         break;
2831     case DF_DOUBLE:
2832         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
2833             MSA_FLOAT_COND(pwx->d[i], eq, pws->d[i], pwt->d[i], 64, quiet);
2834         }
2835         break;
2836     default:
2837         assert(0);
2838     }
2839
2840     check_msacsr_cause(env, retaddr);
2841
2842     msa_move_v(pwd, pwx);
2843 }
2844
2845 static inline void compare_ueq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
2846                                wr_t *pwt, uint32_t df, int quiet,
2847                                uintptr_t retaddr)
2848 {
2849     wr_t wx, *pwx = &wx;
2850     uint32_t i;
2851
2852     clear_msacsr_cause(env);
2853
2854     switch (df) {
2855     case DF_WORD:
2856         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
2857             MSA_FLOAT_UEQ(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
2858         }
2859         break;
2860     case DF_DOUBLE:
2861         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
2862             MSA_FLOAT_UEQ(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
2863         }
2864         break;
2865     default:
2866         assert(0);
2867     }
2868
2869     check_msacsr_cause(env, retaddr);
2870
2871     msa_move_v(pwd, pwx);
2872 }
2873
2874 static inline void compare_lt(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
2875                               wr_t *pwt, uint32_t df, int quiet,
2876                               uintptr_t retaddr)
2877 {
2878     wr_t wx, *pwx = &wx;
2879     uint32_t i;
2880
2881     clear_msacsr_cause(env);
2882
2883     switch (df) {
2884     case DF_WORD:
2885         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
2886             MSA_FLOAT_COND(pwx->w[i], lt, pws->w[i], pwt->w[i], 32, quiet);
2887         }
2888         break;
2889     case DF_DOUBLE:
2890         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
2891             MSA_FLOAT_COND(pwx->d[i], lt, pws->d[i], pwt->d[i], 64, quiet);
2892         }
2893         break;
2894     default:
2895         assert(0);
2896     }
2897
2898     check_msacsr_cause(env, retaddr);
2899
2900     msa_move_v(pwd, pwx);
2901 }
2902
2903 static inline void compare_ult(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
2904                                wr_t *pwt, uint32_t df, int quiet,
2905                                uintptr_t retaddr)
2906 {
2907     wr_t wx, *pwx = &wx;
2908     uint32_t i;
2909
2910     clear_msacsr_cause(env);
2911
2912     switch (df) {
2913     case DF_WORD:
2914         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
2915             MSA_FLOAT_ULT(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
2916         }
2917         break;
2918     case DF_DOUBLE:
2919         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
2920             MSA_FLOAT_ULT(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
2921         }
2922         break;
2923     default:
2924         assert(0);
2925     }
2926
2927     check_msacsr_cause(env, retaddr);
2928
2929     msa_move_v(pwd, pwx);
2930 }
2931
2932 static inline void compare_le(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
2933                               wr_t *pwt, uint32_t df, int quiet,
2934                               uintptr_t retaddr)
2935 {
2936     wr_t wx, *pwx = &wx;
2937     uint32_t i;
2938
2939     clear_msacsr_cause(env);
2940
2941     switch (df) {
2942     case DF_WORD:
2943         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
2944             MSA_FLOAT_COND(pwx->w[i], le, pws->w[i], pwt->w[i], 32, quiet);
2945         }
2946         break;
2947     case DF_DOUBLE:
2948         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
2949             MSA_FLOAT_COND(pwx->d[i], le, pws->d[i], pwt->d[i], 64, quiet);
2950         }
2951         break;
2952     default:
2953         assert(0);
2954     }
2955
2956     check_msacsr_cause(env, retaddr);
2957
2958     msa_move_v(pwd, pwx);
2959 }
2960
2961 static inline void compare_ule(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
2962                                wr_t *pwt, uint32_t df, int quiet,
2963                                uintptr_t retaddr)
2964 {
2965     wr_t wx, *pwx = &wx;
2966     uint32_t i;
2967
2968     clear_msacsr_cause(env);
2969
2970     switch (df) {
2971     case DF_WORD:
2972         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
2973             MSA_FLOAT_ULE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
2974         }
2975         break;
2976     case DF_DOUBLE:
2977         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
2978             MSA_FLOAT_ULE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
2979         }
2980         break;
2981     default:
2982         assert(0);
2983     }
2984
2985     check_msacsr_cause(env, retaddr);
2986
2987     msa_move_v(pwd, pwx);
2988 }
2989
2990 static inline void compare_or(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
2991                               wr_t *pwt, uint32_t df, int quiet,
2992                               uintptr_t retaddr)
2993 {
2994     wr_t wx, *pwx = &wx;
2995     uint32_t i;
2996
2997     clear_msacsr_cause(env);
2998
2999     switch (df) {
3000     case DF_WORD:
3001         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3002             MSA_FLOAT_OR(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
3003         }
3004         break;
3005     case DF_DOUBLE:
3006         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3007             MSA_FLOAT_OR(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
3008         }
3009         break;
3010     default:
3011         assert(0);
3012     }
3013
3014     check_msacsr_cause(env, retaddr);
3015
3016     msa_move_v(pwd, pwx);
3017 }
3018
3019 static inline void compare_une(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
3020                                wr_t *pwt, uint32_t df, int quiet,
3021                                uintptr_t retaddr)
3022 {
3023     wr_t wx, *pwx = &wx;
3024     uint32_t i;
3025
3026     clear_msacsr_cause(env);
3027
3028     switch (df) {
3029     case DF_WORD:
3030         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3031             MSA_FLOAT_UNE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
3032         }
3033         break;
3034     case DF_DOUBLE:
3035         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3036             MSA_FLOAT_UNE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
3037         }
3038         break;
3039     default:
3040         assert(0);
3041     }
3042
3043     check_msacsr_cause(env, retaddr);
3044
3045     msa_move_v(pwd, pwx);
3046 }
3047
3048 static inline void compare_ne(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
3049                               wr_t *pwt, uint32_t df, int quiet,
3050                               uintptr_t retaddr)
3051 {
3052     wr_t wx, *pwx = &wx;
3053     uint32_t i;
3054
3055     clear_msacsr_cause(env);
3056
3057     switch (df) {
3058     case DF_WORD:
3059         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3060             MSA_FLOAT_NE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
3061         }
3062         break;
3063     case DF_DOUBLE:
3064         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3065             MSA_FLOAT_NE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
3066         }
3067         break;
3068     default:
3069         assert(0);
3070     }
3071
3072     check_msacsr_cause(env, retaddr);
3073
3074     msa_move_v(pwd, pwx);
3075 }
3076
3077 void helper_msa_fcaf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3078                         uint32_t ws, uint32_t wt)
3079 {
3080     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3081     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3082     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3083     compare_af(env, pwd, pws, pwt, df, 1, GETPC());
3084 }
3085
3086 void helper_msa_fcun_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3087                         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     compare_un(env, pwd, pws, pwt, df, 1, GETPC());
3093 }
3094
3095 void helper_msa_fceq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3096                         uint32_t ws, uint32_t wt)
3097 {
3098     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3099     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3100     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3101     compare_eq(env, pwd, pws, pwt, df, 1, GETPC());
3102 }
3103
3104 void helper_msa_fcueq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3105                          uint32_t ws, uint32_t wt)
3106 {
3107     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3108     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3109     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3110     compare_ueq(env, pwd, pws, pwt, df, 1, GETPC());
3111 }
3112
3113 void helper_msa_fclt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3114                         uint32_t ws, uint32_t wt)
3115 {
3116     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3117     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3118     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3119     compare_lt(env, pwd, pws, pwt, df, 1, GETPC());
3120 }
3121
3122 void helper_msa_fcult_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3123                          uint32_t ws, uint32_t wt)
3124 {
3125     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3126     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3127     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3128     compare_ult(env, pwd, pws, pwt, df, 1, GETPC());
3129 }
3130
3131 void helper_msa_fcle_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3132                         uint32_t ws, uint32_t wt)
3133 {
3134     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3135     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3136     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3137     compare_le(env, pwd, pws, pwt, df, 1, GETPC());
3138 }
3139
3140 void helper_msa_fcule_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3141                          uint32_t ws, uint32_t wt)
3142 {
3143     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3144     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3145     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3146     compare_ule(env, pwd, pws, pwt, df, 1, GETPC());
3147 }
3148
3149 void helper_msa_fsaf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3150                         uint32_t ws, uint32_t wt)
3151 {
3152     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3153     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3154     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3155     compare_af(env, pwd, pws, pwt, df, 0, GETPC());
3156 }
3157
3158 void helper_msa_fsun_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3159                         uint32_t ws, uint32_t wt)
3160 {
3161     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3162     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3163     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3164     compare_un(env, pwd, pws, pwt, df, 0, GETPC());
3165 }
3166
3167 void helper_msa_fseq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3168                         uint32_t ws, uint32_t wt)
3169 {
3170     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3171     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3172     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3173     compare_eq(env, pwd, pws, pwt, df, 0, GETPC());
3174 }
3175
3176 void helper_msa_fsueq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3177                          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     compare_ueq(env, pwd, pws, pwt, df, 0, GETPC());
3183 }
3184
3185 void helper_msa_fslt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3186                         uint32_t ws, uint32_t wt)
3187 {
3188     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3189     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3190     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3191     compare_lt(env, pwd, pws, pwt, df, 0, GETPC());
3192 }
3193
3194 void helper_msa_fsult_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3195                          uint32_t ws, uint32_t wt)
3196 {
3197     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3198     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3199     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3200     compare_ult(env, pwd, pws, pwt, df, 0, GETPC());
3201 }
3202
3203 void helper_msa_fsle_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3204                         uint32_t ws, uint32_t wt)
3205 {
3206     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3207     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3208     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3209     compare_le(env, pwd, pws, pwt, df, 0, GETPC());
3210 }
3211
3212 void helper_msa_fsule_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3213                          uint32_t ws, uint32_t wt)
3214 {
3215     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3216     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3217     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3218     compare_ule(env, pwd, pws, pwt, df, 0, GETPC());
3219 }
3220
3221 void helper_msa_fcor_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3222                         uint32_t ws, uint32_t wt)
3223 {
3224     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3225     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3226     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3227     compare_or(env, pwd, pws, pwt, df, 1, GETPC());
3228 }
3229
3230 void helper_msa_fcune_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3231                          uint32_t ws, uint32_t wt)
3232 {
3233     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3234     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3235     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3236     compare_une(env, pwd, pws, pwt, df, 1, GETPC());
3237 }
3238
3239 void helper_msa_fcne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3240                         uint32_t ws, uint32_t wt)
3241 {
3242     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3243     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3244     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3245     compare_ne(env, pwd, pws, pwt, df, 1, GETPC());
3246 }
3247
3248 void helper_msa_fsor_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3249                         uint32_t ws, uint32_t wt)
3250 {
3251     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3252     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3253     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3254     compare_or(env, pwd, pws, pwt, df, 0, GETPC());
3255 }
3256
3257 void helper_msa_fsune_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3258                          uint32_t ws, uint32_t wt)
3259 {
3260     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3261     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3262     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3263     compare_une(env, pwd, pws, pwt, df, 0, GETPC());
3264 }
3265
3266 void helper_msa_fsne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3267                         uint32_t ws, uint32_t wt)
3268 {
3269     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3270     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3271     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3272     compare_ne(env, pwd, pws, pwt, df, 0, GETPC());
3273 }
3274
3275 #define float16_is_zero(ARG) 0
3276 #define float16_is_zero_or_denormal(ARG) 0
3277
3278 #define IS_DENORMAL(ARG, BITS)                      \
3279     (!float ## BITS ## _is_zero(ARG)                \
3280     && float ## BITS ## _is_zero_or_denormal(ARG))
3281
3282 #define MSA_FLOAT_BINOP(DEST, OP, ARG1, ARG2, BITS)                         \
3283     do {                                                                    \
3284         float_status *status = &env->active_tc.msa_fp_status;               \
3285         int c;                                                              \
3286                                                                             \
3287         set_float_exception_flags(0, status);                               \
3288         DEST = float ## BITS ## _ ## OP(ARG1, ARG2, status);                \
3289         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
3290                                                                             \
3291         if (get_enabled_exceptions(env, c)) {                               \
3292             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
3293         }                                                                   \
3294     } while (0)
3295
3296 void helper_msa_fadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3297         uint32_t ws, uint32_t wt)
3298 {
3299     wr_t wx, *pwx = &wx;
3300     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3301     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3302     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3303     uint32_t i;
3304
3305     clear_msacsr_cause(env);
3306
3307     switch (df) {
3308     case DF_WORD:
3309         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3310             MSA_FLOAT_BINOP(pwx->w[i], add, pws->w[i], pwt->w[i], 32);
3311         }
3312         break;
3313     case DF_DOUBLE:
3314         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3315             MSA_FLOAT_BINOP(pwx->d[i], add, pws->d[i], pwt->d[i], 64);
3316         }
3317         break;
3318     default:
3319         assert(0);
3320     }
3321
3322     check_msacsr_cause(env, GETPC());
3323     msa_move_v(pwd, pwx);
3324 }
3325
3326 void helper_msa_fsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3327         uint32_t ws, uint32_t wt)
3328 {
3329     wr_t wx, *pwx = &wx;
3330     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3331     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3332     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3333     uint32_t i;
3334
3335     clear_msacsr_cause(env);
3336
3337     switch (df) {
3338     case DF_WORD:
3339         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3340             MSA_FLOAT_BINOP(pwx->w[i], sub, pws->w[i], pwt->w[i], 32);
3341         }
3342         break;
3343     case DF_DOUBLE:
3344         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3345             MSA_FLOAT_BINOP(pwx->d[i], sub, pws->d[i], pwt->d[i], 64);
3346         }
3347         break;
3348     default:
3349         assert(0);
3350     }
3351
3352     check_msacsr_cause(env, GETPC());
3353     msa_move_v(pwd, pwx);
3354 }
3355
3356 void helper_msa_fmul_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3357         uint32_t ws, uint32_t wt)
3358 {
3359     wr_t wx, *pwx = &wx;
3360     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3361     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3362     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3363     uint32_t i;
3364
3365     clear_msacsr_cause(env);
3366
3367     switch (df) {
3368     case DF_WORD:
3369         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3370             MSA_FLOAT_BINOP(pwx->w[i], mul, pws->w[i], pwt->w[i], 32);
3371         }
3372         break;
3373     case DF_DOUBLE:
3374         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3375             MSA_FLOAT_BINOP(pwx->d[i], mul, pws->d[i], pwt->d[i], 64);
3376         }
3377         break;
3378     default:
3379         assert(0);
3380     }
3381
3382     check_msacsr_cause(env, GETPC());
3383
3384     msa_move_v(pwd, pwx);
3385 }
3386
3387 void helper_msa_fdiv_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3388         uint32_t ws, uint32_t wt)
3389 {
3390     wr_t wx, *pwx = &wx;
3391     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3392     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3393     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3394     uint32_t i;
3395
3396     clear_msacsr_cause(env);
3397
3398     switch (df) {
3399     case DF_WORD:
3400         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3401             MSA_FLOAT_BINOP(pwx->w[i], div, pws->w[i], pwt->w[i], 32);
3402         }
3403         break;
3404     case DF_DOUBLE:
3405         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3406             MSA_FLOAT_BINOP(pwx->d[i], div, pws->d[i], pwt->d[i], 64);
3407         }
3408         break;
3409     default:
3410         assert(0);
3411     }
3412
3413     check_msacsr_cause(env, GETPC());
3414
3415     msa_move_v(pwd, pwx);
3416 }
3417
3418 #define MSA_FLOAT_MULADD(DEST, ARG1, ARG2, ARG3, NEGATE, BITS)              \
3419     do {                                                                    \
3420         float_status *status = &env->active_tc.msa_fp_status;               \
3421         int c;                                                              \
3422                                                                             \
3423         set_float_exception_flags(0, status);                               \
3424         DEST = float ## BITS ## _muladd(ARG2, ARG3, ARG1, NEGATE, status);  \
3425         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
3426                                                                             \
3427         if (get_enabled_exceptions(env, c)) {                               \
3428             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
3429         }                                                                   \
3430     } while (0)
3431
3432 void helper_msa_fmadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3433         uint32_t ws, uint32_t wt)
3434 {
3435     wr_t wx, *pwx = &wx;
3436     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3437     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3438     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3439     uint32_t i;
3440
3441     clear_msacsr_cause(env);
3442
3443     switch (df) {
3444     case DF_WORD:
3445         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3446             MSA_FLOAT_MULADD(pwx->w[i], pwd->w[i],
3447                            pws->w[i], pwt->w[i], 0, 32);
3448         }
3449         break;
3450     case DF_DOUBLE:
3451         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3452             MSA_FLOAT_MULADD(pwx->d[i], pwd->d[i],
3453                            pws->d[i], pwt->d[i], 0, 64);
3454         }
3455         break;
3456     default:
3457         assert(0);
3458     }
3459
3460     check_msacsr_cause(env, GETPC());
3461
3462     msa_move_v(pwd, pwx);
3463 }
3464
3465 void helper_msa_fmsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3466         uint32_t ws, uint32_t wt)
3467 {
3468     wr_t wx, *pwx = &wx;
3469     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3470     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3471     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3472     uint32_t i;
3473
3474     clear_msacsr_cause(env);
3475
3476     switch (df) {
3477     case DF_WORD:
3478         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3479             MSA_FLOAT_MULADD(pwx->w[i], pwd->w[i],
3480                            pws->w[i], pwt->w[i],
3481                            float_muladd_negate_product, 32);
3482       }
3483       break;
3484     case DF_DOUBLE:
3485         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3486             MSA_FLOAT_MULADD(pwx->d[i], pwd->d[i],
3487                            pws->d[i], pwt->d[i],
3488                            float_muladd_negate_product, 64);
3489         }
3490         break;
3491     default:
3492         assert(0);
3493     }
3494
3495     check_msacsr_cause(env, GETPC());
3496
3497     msa_move_v(pwd, pwx);
3498 }
3499
3500 void helper_msa_fexp2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3501         uint32_t ws, uint32_t wt)
3502 {
3503     wr_t wx, *pwx = &wx;
3504     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3505     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3506     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3507     uint32_t i;
3508
3509     clear_msacsr_cause(env);
3510
3511     switch (df) {
3512     case DF_WORD:
3513         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3514             MSA_FLOAT_BINOP(pwx->w[i], scalbn, pws->w[i],
3515                             pwt->w[i] >  0x200 ?  0x200 :
3516                             pwt->w[i] < -0x200 ? -0x200 : pwt->w[i],
3517                             32);
3518         }
3519         break;
3520     case DF_DOUBLE:
3521         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3522             MSA_FLOAT_BINOP(pwx->d[i], scalbn, pws->d[i],
3523                             pwt->d[i] >  0x1000 ?  0x1000 :
3524                             pwt->d[i] < -0x1000 ? -0x1000 : pwt->d[i],
3525                             64);
3526         }
3527         break;
3528     default:
3529         assert(0);
3530     }
3531
3532     check_msacsr_cause(env, GETPC());
3533
3534     msa_move_v(pwd, pwx);
3535 }
3536
3537 #define MSA_FLOAT_UNOP(DEST, OP, ARG, BITS)                                 \
3538     do {                                                                    \
3539         float_status *status = &env->active_tc.msa_fp_status;               \
3540         int c;                                                              \
3541                                                                             \
3542         set_float_exception_flags(0, status);                               \
3543         DEST = float ## BITS ## _ ## OP(ARG, status);                       \
3544         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
3545                                                                             \
3546         if (get_enabled_exceptions(env, c)) {                               \
3547             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
3548         }                                                                   \
3549     } while (0)
3550
3551 void helper_msa_fexdo_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3552                          uint32_t ws, uint32_t wt)
3553 {
3554     wr_t wx, *pwx = &wx;
3555     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3556     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3557     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3558     uint32_t i;
3559
3560     clear_msacsr_cause(env);
3561
3562     switch (df) {
3563     case DF_WORD:
3564         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3565             /*
3566              * Half precision floats come in two formats: standard
3567              * IEEE and "ARM" format.  The latter gains extra exponent
3568              * range by omitting the NaN/Inf encodings.
3569              */
3570             flag ieee = 1;
3571
3572             MSA_FLOAT_BINOP(Lh(pwx, i), from_float32, pws->w[i], ieee, 16);
3573             MSA_FLOAT_BINOP(Rh(pwx, i), from_float32, pwt->w[i], ieee, 16);
3574         }
3575         break;
3576     case DF_DOUBLE:
3577         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3578             MSA_FLOAT_UNOP(Lw(pwx, i), from_float64, pws->d[i], 32);
3579             MSA_FLOAT_UNOP(Rw(pwx, i), from_float64, pwt->d[i], 32);
3580         }
3581         break;
3582     default:
3583         assert(0);
3584     }
3585
3586     check_msacsr_cause(env, GETPC());
3587     msa_move_v(pwd, pwx);
3588 }
3589
3590 #define MSA_FLOAT_UNOP_XD(DEST, OP, ARG, BITS, XBITS)                       \
3591     do {                                                                    \
3592         float_status *status = &env->active_tc.msa_fp_status;               \
3593         int c;                                                              \
3594                                                                             \
3595         set_float_exception_flags(0, status);                               \
3596         DEST = float ## BITS ## _ ## OP(ARG, status);                       \
3597         c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0);                      \
3598                                                                             \
3599         if (get_enabled_exceptions(env, c)) {                               \
3600             DEST = ((FLOAT_SNAN ## XBITS(status) >> 6) << 6) | c;           \
3601         }                                                                   \
3602     } while (0)
3603
3604 void helper_msa_ftq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3605                        uint32_t ws, uint32_t wt)
3606 {
3607     wr_t wx, *pwx = &wx;
3608     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3609     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3610     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3611     uint32_t i;
3612
3613     clear_msacsr_cause(env);
3614
3615     switch (df) {
3616     case DF_WORD:
3617         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3618             MSA_FLOAT_UNOP_XD(Lh(pwx, i), to_q16, pws->w[i], 32, 16);
3619             MSA_FLOAT_UNOP_XD(Rh(pwx, i), to_q16, pwt->w[i], 32, 16);
3620         }
3621         break;
3622     case DF_DOUBLE:
3623         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3624             MSA_FLOAT_UNOP_XD(Lw(pwx, i), to_q32, pws->d[i], 64, 32);
3625             MSA_FLOAT_UNOP_XD(Rw(pwx, i), to_q32, pwt->d[i], 64, 32);
3626         }
3627         break;
3628     default:
3629         assert(0);
3630     }
3631
3632     check_msacsr_cause(env, GETPC());
3633
3634     msa_move_v(pwd, pwx);
3635 }
3636
3637 #define NUMBER_QNAN_PAIR(ARG1, ARG2, BITS, STATUS)      \
3638     !float ## BITS ## _is_any_nan(ARG1)                 \
3639     && float ## BITS ## _is_quiet_nan(ARG2, STATUS)
3640
3641 #define MSA_FLOAT_MAXOP(DEST, OP, ARG1, ARG2, BITS)                         \
3642     do {                                                                    \
3643         float_status *status = &env->active_tc.msa_fp_status;               \
3644         int c;                                                              \
3645                                                                             \
3646         set_float_exception_flags(0, status);                               \
3647         DEST = float ## BITS ## _ ## OP(ARG1, ARG2, status);                \
3648         c = update_msacsr(env, 0, 0);                                       \
3649                                                                             \
3650         if (get_enabled_exceptions(env, c)) {                               \
3651             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
3652         }                                                                   \
3653     } while (0)
3654
3655 #define FMAXMIN_A(F, G, X, _S, _T, BITS, STATUS)                    \
3656     do {                                                            \
3657         uint## BITS ##_t S = _S, T = _T;                            \
3658         uint## BITS ##_t as, at, xs, xt, xd;                        \
3659         if (NUMBER_QNAN_PAIR(S, T, BITS, STATUS)) {                 \
3660             T = S;                                                  \
3661         }                                                           \
3662         else if (NUMBER_QNAN_PAIR(T, S, BITS, STATUS)) {            \
3663             S = T;                                                  \
3664         }                                                           \
3665         as = float## BITS ##_abs(S);                                \
3666         at = float## BITS ##_abs(T);                                \
3667         MSA_FLOAT_MAXOP(xs, F,  S,  T, BITS);                       \
3668         MSA_FLOAT_MAXOP(xt, G,  S,  T, BITS);                       \
3669         MSA_FLOAT_MAXOP(xd, F, as, at, BITS);                       \
3670         X = (as == at || xd == float## BITS ##_abs(xs)) ? xs : xt;  \
3671     } while (0)
3672
3673 void helper_msa_fmin_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3674         uint32_t ws, uint32_t wt)
3675 {
3676     float_status *status = &env->active_tc.msa_fp_status;
3677     wr_t wx, *pwx = &wx;
3678     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3679     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3680     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3681     uint32_t i;
3682
3683     clear_msacsr_cause(env);
3684
3685     switch (df) {
3686     case DF_WORD:
3687         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3688             if (NUMBER_QNAN_PAIR(pws->w[i], pwt->w[i], 32, status)) {
3689                 MSA_FLOAT_MAXOP(pwx->w[i], min, pws->w[i], pws->w[i], 32);
3690             } else if (NUMBER_QNAN_PAIR(pwt->w[i], pws->w[i], 32, status)) {
3691                 MSA_FLOAT_MAXOP(pwx->w[i], min, pwt->w[i], pwt->w[i], 32);
3692             } else {
3693                 MSA_FLOAT_MAXOP(pwx->w[i], min, pws->w[i], pwt->w[i], 32);
3694             }
3695         }
3696         break;
3697     case DF_DOUBLE:
3698         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3699             if (NUMBER_QNAN_PAIR(pws->d[i], pwt->d[i], 64, status)) {
3700                 MSA_FLOAT_MAXOP(pwx->d[i], min, pws->d[i], pws->d[i], 64);
3701             } else if (NUMBER_QNAN_PAIR(pwt->d[i], pws->d[i], 64, status)) {
3702                 MSA_FLOAT_MAXOP(pwx->d[i], min, pwt->d[i], pwt->d[i], 64);
3703             } else {
3704                 MSA_FLOAT_MAXOP(pwx->d[i], min, pws->d[i], pwt->d[i], 64);
3705             }
3706         }
3707         break;
3708     default:
3709         assert(0);
3710     }
3711
3712     check_msacsr_cause(env, GETPC());
3713
3714     msa_move_v(pwd, pwx);
3715 }
3716
3717 void helper_msa_fmin_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3718         uint32_t ws, uint32_t wt)
3719 {
3720     float_status *status = &env->active_tc.msa_fp_status;
3721     wr_t wx, *pwx = &wx;
3722     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3723     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3724     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3725     uint32_t i;
3726
3727     clear_msacsr_cause(env);
3728
3729     switch (df) {
3730     case DF_WORD:
3731         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3732             FMAXMIN_A(min, max, pwx->w[i], pws->w[i], pwt->w[i], 32, status);
3733         }
3734         break;
3735     case DF_DOUBLE:
3736         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3737             FMAXMIN_A(min, max, pwx->d[i], pws->d[i], pwt->d[i], 64, status);
3738         }
3739         break;
3740     default:
3741         assert(0);
3742     }
3743
3744     check_msacsr_cause(env, GETPC());
3745
3746     msa_move_v(pwd, pwx);
3747 }
3748
3749 void helper_msa_fmax_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3750         uint32_t ws, uint32_t wt)
3751 {
3752     float_status *status = &env->active_tc.msa_fp_status;
3753     wr_t wx, *pwx = &wx;
3754     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3755     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3756     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3757     uint32_t i;
3758
3759     clear_msacsr_cause(env);
3760
3761     switch (df) {
3762     case DF_WORD:
3763         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3764             if (NUMBER_QNAN_PAIR(pws->w[i], pwt->w[i], 32, status)) {
3765                 MSA_FLOAT_MAXOP(pwx->w[i], max, pws->w[i], pws->w[i], 32);
3766             } else if (NUMBER_QNAN_PAIR(pwt->w[i], pws->w[i], 32, status)) {
3767                 MSA_FLOAT_MAXOP(pwx->w[i], max, pwt->w[i], pwt->w[i], 32);
3768             } else {
3769                 MSA_FLOAT_MAXOP(pwx->w[i], max, pws->w[i], pwt->w[i], 32);
3770             }
3771         }
3772         break;
3773     case DF_DOUBLE:
3774         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3775             if (NUMBER_QNAN_PAIR(pws->d[i], pwt->d[i], 64, status)) {
3776                 MSA_FLOAT_MAXOP(pwx->d[i], max, pws->d[i], pws->d[i], 64);
3777             } else if (NUMBER_QNAN_PAIR(pwt->d[i], pws->d[i], 64, status)) {
3778                 MSA_FLOAT_MAXOP(pwx->d[i], max, pwt->d[i], pwt->d[i], 64);
3779             } else {
3780                 MSA_FLOAT_MAXOP(pwx->d[i], max, pws->d[i], pwt->d[i], 64);
3781             }
3782         }
3783         break;
3784     default:
3785         assert(0);
3786     }
3787
3788     check_msacsr_cause(env, GETPC());
3789
3790     msa_move_v(pwd, pwx);
3791 }
3792
3793 void helper_msa_fmax_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3794         uint32_t ws, uint32_t wt)
3795 {
3796     float_status *status = &env->active_tc.msa_fp_status;
3797     wr_t wx, *pwx = &wx;
3798     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3799     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3800     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3801     uint32_t i;
3802
3803     clear_msacsr_cause(env);
3804
3805     switch (df) {
3806     case DF_WORD:
3807         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3808             FMAXMIN_A(max, min, pwx->w[i], pws->w[i], pwt->w[i], 32, status);
3809         }
3810         break;
3811     case DF_DOUBLE:
3812         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3813             FMAXMIN_A(max, min, pwx->d[i], pws->d[i], pwt->d[i], 64, status);
3814         }
3815         break;
3816     default:
3817         assert(0);
3818     }
3819
3820     check_msacsr_cause(env, GETPC());
3821
3822     msa_move_v(pwd, pwx);
3823 }
3824
3825 void helper_msa_fclass_df(CPUMIPSState *env, uint32_t df,
3826         uint32_t wd, uint32_t ws)
3827 {
3828     float_status *status = &env->active_tc.msa_fp_status;
3829
3830     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3831     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3832     if (df == DF_WORD) {
3833         pwd->w[0] = float_class_s(pws->w[0], status);
3834         pwd->w[1] = float_class_s(pws->w[1], status);
3835         pwd->w[2] = float_class_s(pws->w[2], status);
3836         pwd->w[3] = float_class_s(pws->w[3], status);
3837     } else {
3838         pwd->d[0] = float_class_d(pws->d[0], status);
3839         pwd->d[1] = float_class_d(pws->d[1], status);
3840     }
3841 }
3842
3843 #define MSA_FLOAT_UNOP0(DEST, OP, ARG, BITS)                                \
3844     do {                                                                    \
3845         float_status *status = &env->active_tc.msa_fp_status;               \
3846         int c;                                                              \
3847                                                                             \
3848         set_float_exception_flags(0, status);                               \
3849         DEST = float ## BITS ## _ ## OP(ARG, status);                       \
3850         c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0);                      \
3851                                                                             \
3852         if (get_enabled_exceptions(env, c)) {                               \
3853             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
3854         } else if (float ## BITS ## _is_any_nan(ARG)) {                     \
3855             DEST = 0;                                                       \
3856         }                                                                   \
3857     } while (0)
3858
3859 void helper_msa_ftrunc_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3860                             uint32_t ws)
3861 {
3862     wr_t wx, *pwx = &wx;
3863     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3864     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3865     uint32_t i;
3866
3867     clear_msacsr_cause(env);
3868
3869     switch (df) {
3870     case DF_WORD:
3871         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3872             MSA_FLOAT_UNOP0(pwx->w[i], to_int32_round_to_zero, pws->w[i], 32);
3873         }
3874         break;
3875     case DF_DOUBLE:
3876         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3877             MSA_FLOAT_UNOP0(pwx->d[i], to_int64_round_to_zero, pws->d[i], 64);
3878         }
3879         break;
3880     default:
3881         assert(0);
3882     }
3883
3884     check_msacsr_cause(env, GETPC());
3885
3886     msa_move_v(pwd, pwx);
3887 }
3888
3889 void helper_msa_ftrunc_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3890                             uint32_t ws)
3891 {
3892     wr_t wx, *pwx = &wx;
3893     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3894     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3895     uint32_t i;
3896
3897     clear_msacsr_cause(env);
3898
3899     switch (df) {
3900     case DF_WORD:
3901         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3902             MSA_FLOAT_UNOP0(pwx->w[i], to_uint32_round_to_zero, pws->w[i], 32);
3903         }
3904         break;
3905     case DF_DOUBLE:
3906         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3907             MSA_FLOAT_UNOP0(pwx->d[i], to_uint64_round_to_zero, pws->d[i], 64);
3908         }
3909         break;
3910     default:
3911         assert(0);
3912     }
3913
3914     check_msacsr_cause(env, GETPC());
3915
3916     msa_move_v(pwd, pwx);
3917 }
3918
3919 void helper_msa_fsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3920                          uint32_t ws)
3921 {
3922     wr_t wx, *pwx = &wx;
3923     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3924     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3925     uint32_t i;
3926
3927     clear_msacsr_cause(env);
3928
3929     switch (df) {
3930     case DF_WORD:
3931         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3932             MSA_FLOAT_UNOP(pwx->w[i], sqrt, pws->w[i], 32);
3933         }
3934         break;
3935     case DF_DOUBLE:
3936         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3937             MSA_FLOAT_UNOP(pwx->d[i], sqrt, pws->d[i], 64);
3938         }
3939         break;
3940     default:
3941         assert(0);
3942     }
3943
3944     check_msacsr_cause(env, GETPC());
3945
3946     msa_move_v(pwd, pwx);
3947 }
3948
3949 #define MSA_FLOAT_RECIPROCAL(DEST, ARG, BITS)                               \
3950     do {                                                                    \
3951         float_status *status = &env->active_tc.msa_fp_status;               \
3952         int c;                                                              \
3953                                                                             \
3954         set_float_exception_flags(0, status);                               \
3955         DEST = float ## BITS ## _ ## div(FLOAT_ONE ## BITS, ARG, status);   \
3956         c = update_msacsr(env, float ## BITS ## _is_infinity(ARG) ||        \
3957                           float ## BITS ## _is_quiet_nan(DEST, status) ?    \
3958                           0 : RECIPROCAL_INEXACT,                           \
3959                           IS_DENORMAL(DEST, BITS));                         \
3960                                                                             \
3961         if (get_enabled_exceptions(env, c)) {                               \
3962             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
3963         }                                                                   \
3964     } while (0)
3965
3966 void helper_msa_frsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3967                           uint32_t ws)
3968 {
3969     wr_t wx, *pwx = &wx;
3970     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3971     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3972     uint32_t i;
3973
3974     clear_msacsr_cause(env);
3975
3976     switch (df) {
3977     case DF_WORD:
3978         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3979             MSA_FLOAT_RECIPROCAL(pwx->w[i], float32_sqrt(pws->w[i],
3980                     &env->active_tc.msa_fp_status), 32);
3981         }
3982         break;
3983     case DF_DOUBLE:
3984         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3985             MSA_FLOAT_RECIPROCAL(pwx->d[i], float64_sqrt(pws->d[i],
3986                     &env->active_tc.msa_fp_status), 64);
3987         }
3988         break;
3989     default:
3990         assert(0);
3991     }
3992
3993     check_msacsr_cause(env, GETPC());
3994
3995     msa_move_v(pwd, pwx);
3996 }
3997
3998 void helper_msa_frcp_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3999                         uint32_t ws)
4000 {
4001     wr_t wx, *pwx = &wx;
4002     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4003     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4004     uint32_t i;
4005
4006     clear_msacsr_cause(env);
4007
4008     switch (df) {
4009     case DF_WORD:
4010         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4011             MSA_FLOAT_RECIPROCAL(pwx->w[i], pws->w[i], 32);
4012         }
4013         break;
4014     case DF_DOUBLE:
4015         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4016             MSA_FLOAT_RECIPROCAL(pwx->d[i], pws->d[i], 64);
4017         }
4018         break;
4019     default:
4020         assert(0);
4021     }
4022
4023     check_msacsr_cause(env, GETPC());
4024
4025     msa_move_v(pwd, pwx);
4026 }
4027
4028 void helper_msa_frint_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4029                          uint32_t ws)
4030 {
4031     wr_t wx, *pwx = &wx;
4032     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4033     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4034     uint32_t i;
4035
4036     clear_msacsr_cause(env);
4037
4038     switch (df) {
4039     case DF_WORD:
4040         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4041             MSA_FLOAT_UNOP(pwx->w[i], round_to_int, pws->w[i], 32);
4042         }
4043         break;
4044     case DF_DOUBLE:
4045         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4046             MSA_FLOAT_UNOP(pwx->d[i], round_to_int, pws->d[i], 64);
4047         }
4048         break;
4049     default:
4050         assert(0);
4051     }
4052
4053     check_msacsr_cause(env, GETPC());
4054
4055     msa_move_v(pwd, pwx);
4056 }
4057
4058 #define MSA_FLOAT_LOGB(DEST, ARG, BITS)                                     \
4059     do {                                                                    \
4060         float_status *status = &env->active_tc.msa_fp_status;               \
4061         int c;                                                              \
4062                                                                             \
4063         set_float_exception_flags(0, status);                               \
4064         set_float_rounding_mode(float_round_down, status);                  \
4065         DEST = float ## BITS ## _ ## log2(ARG, status);                     \
4066         DEST = float ## BITS ## _ ## round_to_int(DEST, status);            \
4067         set_float_rounding_mode(ieee_rm[(env->active_tc.msacsr &            \
4068                                          MSACSR_RM_MASK) >> MSACSR_RM],     \
4069                                 status);                                    \
4070                                                                             \
4071         set_float_exception_flags(get_float_exception_flags(status) &       \
4072                                   (~float_flag_inexact),                    \
4073                                   status);                                  \
4074                                                                             \
4075         c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
4076                                                                             \
4077         if (get_enabled_exceptions(env, c)) {                               \
4078             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
4079         }                                                                   \
4080     } while (0)
4081
4082 void helper_msa_flog2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4083                          uint32_t ws)
4084 {
4085     wr_t wx, *pwx = &wx;
4086     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4087     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4088     uint32_t i;
4089
4090     clear_msacsr_cause(env);
4091
4092     switch (df) {
4093     case DF_WORD:
4094         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4095             MSA_FLOAT_LOGB(pwx->w[i], pws->w[i], 32);
4096         }
4097         break;
4098     case DF_DOUBLE:
4099         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4100             MSA_FLOAT_LOGB(pwx->d[i], pws->d[i], 64);
4101         }
4102         break;
4103     default:
4104         assert(0);
4105     }
4106
4107     check_msacsr_cause(env, GETPC());
4108
4109     msa_move_v(pwd, pwx);
4110 }
4111
4112 void helper_msa_fexupl_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4113                           uint32_t ws)
4114 {
4115     wr_t wx, *pwx = &wx;
4116     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4117     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4118     uint32_t i;
4119
4120     clear_msacsr_cause(env);
4121
4122     switch (df) {
4123     case DF_WORD:
4124         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4125             /*
4126              * Half precision floats come in two formats: standard
4127              * IEEE and "ARM" format.  The latter gains extra exponent
4128              * range by omitting the NaN/Inf encodings.
4129              */
4130             flag ieee = 1;
4131
4132             MSA_FLOAT_BINOP(pwx->w[i], from_float16, Lh(pws, i), ieee, 32);
4133         }
4134         break;
4135     case DF_DOUBLE:
4136         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4137             MSA_FLOAT_UNOP(pwx->d[i], from_float32, Lw(pws, i), 64);
4138         }
4139         break;
4140     default:
4141         assert(0);
4142     }
4143
4144     check_msacsr_cause(env, GETPC());
4145     msa_move_v(pwd, pwx);
4146 }
4147
4148 void helper_msa_fexupr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4149                           uint32_t ws)
4150 {
4151     wr_t wx, *pwx = &wx;
4152     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4153     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4154     uint32_t i;
4155
4156     clear_msacsr_cause(env);
4157
4158     switch (df) {
4159     case DF_WORD:
4160         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4161             /*
4162              * Half precision floats come in two formats: standard
4163              * IEEE and "ARM" format.  The latter gains extra exponent
4164              * range by omitting the NaN/Inf encodings.
4165              */
4166             flag ieee = 1;
4167
4168             MSA_FLOAT_BINOP(pwx->w[i], from_float16, Rh(pws, i), ieee, 32);
4169         }
4170         break;
4171     case DF_DOUBLE:
4172         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4173             MSA_FLOAT_UNOP(pwx->d[i], from_float32, Rw(pws, i), 64);
4174         }
4175         break;
4176     default:
4177         assert(0);
4178     }
4179
4180     check_msacsr_cause(env, GETPC());
4181     msa_move_v(pwd, pwx);
4182 }
4183
4184 void helper_msa_ffql_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4185                         uint32_t ws)
4186 {
4187     wr_t wx, *pwx = &wx;
4188     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4189     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4190     uint32_t i;
4191
4192     switch (df) {
4193     case DF_WORD:
4194         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4195             MSA_FLOAT_UNOP(pwx->w[i], from_q16, Lh(pws, i), 32);
4196         }
4197         break;
4198     case DF_DOUBLE:
4199         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4200             MSA_FLOAT_UNOP(pwx->d[i], from_q32, Lw(pws, i), 64);
4201         }
4202         break;
4203     default:
4204         assert(0);
4205     }
4206
4207     msa_move_v(pwd, pwx);
4208 }
4209
4210 void helper_msa_ffqr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4211                         uint32_t ws)
4212 {
4213     wr_t wx, *pwx = &wx;
4214     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4215     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4216     uint32_t i;
4217
4218     switch (df) {
4219     case DF_WORD:
4220         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4221             MSA_FLOAT_UNOP(pwx->w[i], from_q16, Rh(pws, i), 32);
4222         }
4223         break;
4224     case DF_DOUBLE:
4225         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4226             MSA_FLOAT_UNOP(pwx->d[i], from_q32, Rw(pws, i), 64);
4227         }
4228         break;
4229     default:
4230         assert(0);
4231     }
4232
4233     msa_move_v(pwd, pwx);
4234 }
4235
4236 void helper_msa_ftint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4237                            uint32_t ws)
4238 {
4239     wr_t wx, *pwx = &wx;
4240     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4241     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4242     uint32_t i;
4243
4244     clear_msacsr_cause(env);
4245
4246     switch (df) {
4247     case DF_WORD:
4248         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4249             MSA_FLOAT_UNOP0(pwx->w[i], to_int32, pws->w[i], 32);
4250         }
4251         break;
4252     case DF_DOUBLE:
4253         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4254             MSA_FLOAT_UNOP0(pwx->d[i], to_int64, pws->d[i], 64);
4255         }
4256         break;
4257     default:
4258         assert(0);
4259     }
4260
4261     check_msacsr_cause(env, GETPC());
4262
4263     msa_move_v(pwd, pwx);
4264 }
4265
4266 void helper_msa_ftint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4267                            uint32_t ws)
4268 {
4269     wr_t wx, *pwx = &wx;
4270     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4271     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4272     uint32_t i;
4273
4274     clear_msacsr_cause(env);
4275
4276     switch (df) {
4277     case DF_WORD:
4278         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4279             MSA_FLOAT_UNOP0(pwx->w[i], to_uint32, pws->w[i], 32);
4280         }
4281         break;
4282     case DF_DOUBLE:
4283         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4284             MSA_FLOAT_UNOP0(pwx->d[i], to_uint64, pws->d[i], 64);
4285         }
4286         break;
4287     default:
4288         assert(0);
4289     }
4290
4291     check_msacsr_cause(env, GETPC());
4292
4293     msa_move_v(pwd, pwx);
4294 }
4295
4296 #define float32_from_int32 int32_to_float32
4297 #define float32_from_uint32 uint32_to_float32
4298
4299 #define float64_from_int64 int64_to_float64
4300 #define float64_from_uint64 uint64_to_float64
4301
4302 void helper_msa_ffint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4303                            uint32_t ws)
4304 {
4305     wr_t wx, *pwx = &wx;
4306     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4307     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4308     uint32_t i;
4309
4310     clear_msacsr_cause(env);
4311
4312     switch (df) {
4313     case DF_WORD:
4314         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4315             MSA_FLOAT_UNOP(pwx->w[i], from_int32, pws->w[i], 32);
4316         }
4317         break;
4318     case DF_DOUBLE:
4319         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4320             MSA_FLOAT_UNOP(pwx->d[i], from_int64, pws->d[i], 64);
4321         }
4322         break;
4323     default:
4324         assert(0);
4325     }
4326
4327     check_msacsr_cause(env, GETPC());
4328
4329     msa_move_v(pwd, pwx);
4330 }
4331
4332 void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4333                            uint32_t ws)
4334 {
4335     wr_t wx, *pwx = &wx;
4336     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4337     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4338     uint32_t i;
4339
4340     clear_msacsr_cause(env);
4341
4342     switch (df) {
4343     case DF_WORD:
4344         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4345             MSA_FLOAT_UNOP(pwx->w[i], from_uint32, pws->w[i], 32);
4346         }
4347         break;
4348     case DF_DOUBLE:
4349         for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4350             MSA_FLOAT_UNOP(pwx->d[i], from_uint64, pws->d[i], 64);
4351         }
4352         break;
4353     default:
4354         assert(0);
4355     }
4356
4357     check_msacsr_cause(env, GETPC());
4358
4359     msa_move_v(pwd, pwx);
4360 }
This page took 0.266523 seconds and 4 git commands to generate.