xref: /qemu/target/mips/tcg/msa_translate.c (revision e91a7227)
1 /*
2  *  MIPS SIMD Architecture (MSA) translation routines
3  *
4  *  Copyright (c) 2004-2005 Jocelyn Mayer
5  *  Copyright (c) 2006 Marius Groeger (FPU operations)
6  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8  *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9  *  Copyright (c) 2020 Philippe Mathieu-Daudé
10  *
11  * SPDX-License-Identifier: LGPL-2.1-or-later
12  */
13 #include "qemu/osdep.h"
14 #include "tcg/tcg-op.h"
15 #include "exec/helper-gen.h"
16 #include "translate.h"
17 #include "fpu_helper.h"
18 #include "internal.h"
19 
20 /* Include the auto-generated decoder.  */
21 #include "decode-msa.c.inc"
22 
23 #define OPC_MSA (0x1E << 26)
24 
25 #define MASK_MSA_MINOR(op)          (MASK_OP_MAJOR(op) | (op & 0x3F))
26 enum {
27     OPC_MSA_I8_00   = 0x00 | OPC_MSA,
28     OPC_MSA_I8_01   = 0x01 | OPC_MSA,
29     OPC_MSA_I8_02   = 0x02 | OPC_MSA,
30     OPC_MSA_I5_06   = 0x06 | OPC_MSA,
31     OPC_MSA_I5_07   = 0x07 | OPC_MSA,
32     OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
33     OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
34     OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
35     OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
36     OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
37     OPC_MSA_3R_10   = 0x10 | OPC_MSA,
38     OPC_MSA_3R_11   = 0x11 | OPC_MSA,
39     OPC_MSA_3R_12   = 0x12 | OPC_MSA,
40     OPC_MSA_3R_13   = 0x13 | OPC_MSA,
41     OPC_MSA_3R_14   = 0x14 | OPC_MSA,
42     OPC_MSA_3R_15   = 0x15 | OPC_MSA,
43     OPC_MSA_ELM     = 0x19 | OPC_MSA,
44     OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
45     OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
46     OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
47     OPC_MSA_VEC     = 0x1E | OPC_MSA,
48 
49     /* MI10 instruction */
50     OPC_LD_B        = (0x20) | OPC_MSA,
51     OPC_LD_H        = (0x21) | OPC_MSA,
52     OPC_LD_W        = (0x22) | OPC_MSA,
53     OPC_LD_D        = (0x23) | OPC_MSA,
54     OPC_ST_B        = (0x24) | OPC_MSA,
55     OPC_ST_H        = (0x25) | OPC_MSA,
56     OPC_ST_W        = (0x26) | OPC_MSA,
57     OPC_ST_D        = (0x27) | OPC_MSA,
58 };
59 
60 enum {
61     /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
62     OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
63     OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
64     OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
65     OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
66     OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
67     OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
68     OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
69     OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
70     OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
71     OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
72     OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
73     OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
74 
75     /* I8 instruction */
76     OPC_ANDI_B      = (0x0 << 24) | OPC_MSA_I8_00,
77     OPC_BMNZI_B     = (0x0 << 24) | OPC_MSA_I8_01,
78     OPC_SHF_B       = (0x0 << 24) | OPC_MSA_I8_02,
79     OPC_ORI_B       = (0x1 << 24) | OPC_MSA_I8_00,
80     OPC_BMZI_B      = (0x1 << 24) | OPC_MSA_I8_01,
81     OPC_SHF_H       = (0x1 << 24) | OPC_MSA_I8_02,
82     OPC_NORI_B      = (0x2 << 24) | OPC_MSA_I8_00,
83     OPC_BSELI_B     = (0x2 << 24) | OPC_MSA_I8_01,
84     OPC_SHF_W       = (0x2 << 24) | OPC_MSA_I8_02,
85     OPC_XORI_B      = (0x3 << 24) | OPC_MSA_I8_00,
86 
87     /* VEC/2R/2RF instruction */
88     OPC_AND_V       = (0x00 << 21) | OPC_MSA_VEC,
89     OPC_OR_V        = (0x01 << 21) | OPC_MSA_VEC,
90     OPC_NOR_V       = (0x02 << 21) | OPC_MSA_VEC,
91     OPC_XOR_V       = (0x03 << 21) | OPC_MSA_VEC,
92     OPC_BMNZ_V      = (0x04 << 21) | OPC_MSA_VEC,
93     OPC_BMZ_V       = (0x05 << 21) | OPC_MSA_VEC,
94     OPC_BSEL_V      = (0x06 << 21) | OPC_MSA_VEC,
95 
96     OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
97     OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
98 
99     /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
100     OPC_FILL_df     = (0x00 << 18) | OPC_MSA_2R,
101     OPC_PCNT_df     = (0x01 << 18) | OPC_MSA_2R,
102     OPC_NLOC_df     = (0x02 << 18) | OPC_MSA_2R,
103     OPC_NLZC_df     = (0x03 << 18) | OPC_MSA_2R,
104 
105     /* 2RF instruction df(bit 16) = _w, _d */
106     OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
107     OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
108     OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
109     OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
110     OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
111     OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
112     OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
113     OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
114     OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
115     OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
116     OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
117     OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
118     OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
119     OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
120     OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
121     OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
122 
123     /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
124     OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
125     OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
126     OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
127     OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
128     OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
129     OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
130     OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
131     OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
132     OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
133     OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
134     OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
135     OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
136     OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
137     OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
138     OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
139     OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
140     OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
141     OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
142     OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
143     OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
144     OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
145     OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
146     OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
147     OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
148     OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
149     OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
150     OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
151     OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
152     OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
153     OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
154     OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
155     OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
156     OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
157     OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
158     OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
159     OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
160     OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
161     OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
162     OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
163     OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
164     OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
165     OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
166     OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
167     OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
168     OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
169     OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
170     OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
171     OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
172     OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
173     OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
174     OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
175     OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
176     OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
177     OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
178     OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
179     OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
180     OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
181     OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
182     OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
183     OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
184     OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
185     OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
186     OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
187 
188     /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
189     OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
190     OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
191     OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
192     OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
193     OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
194     OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
195     OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
196     OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
197     OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
198 
199     /* 3RF instruction _df(bit 21) = _w, _d */
200     OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
201     OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
202     OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
203     OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
204     OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
205     OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
206     OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
207     OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
208     OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
209     OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
210     OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
211     OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
212     OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
213     OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
214     OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
215     OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
216     OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
217     OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
218     OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
219     OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
220     OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
221     OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
222     OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
223     OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
224     OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
225     OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
226     OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
227     OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
228     OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
229     OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
230     OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
231     OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
232     OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
233     OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
234     OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
235     OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
236     OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
237     OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
238     OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
239     OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
240     OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
241 
242     /* BIT instruction df(bits 22..16) = _B _H _W _D */
243     OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
244     OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
245     OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
246     OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
247     OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
248     OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
249     OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
250     OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
251     OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
252     OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
253     OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
254     OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
255 };
256 
257 static const char msaregnames[][6] = {
258     "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
259     "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
260     "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
261     "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
262     "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
263     "w10.d0", "w10.d1", "w11.d0", "w11.d1",
264     "w12.d0", "w12.d1", "w13.d0", "w13.d1",
265     "w14.d0", "w14.d1", "w15.d0", "w15.d1",
266     "w16.d0", "w16.d1", "w17.d0", "w17.d1",
267     "w18.d0", "w18.d1", "w19.d0", "w19.d1",
268     "w20.d0", "w20.d1", "w21.d0", "w21.d1",
269     "w22.d0", "w22.d1", "w23.d0", "w23.d1",
270     "w24.d0", "w24.d1", "w25.d0", "w25.d1",
271     "w26.d0", "w26.d1", "w27.d0", "w27.d1",
272     "w28.d0", "w28.d1", "w29.d0", "w29.d1",
273     "w30.d0", "w30.d1", "w31.d0", "w31.d1",
274 };
275 
276 static TCGv_i64 msa_wr_d[64];
277 
278 void msa_translate_init(void)
279 {
280     int i;
281 
282     for (i = 0; i < 32; i++) {
283         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
284 
285         /*
286          * The MSA vector registers are mapped on the
287          * scalar floating-point unit (FPU) registers.
288          */
289         msa_wr_d[i * 2] = fpu_f64[i];
290         off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
291         msa_wr_d[i * 2 + 1] =
292                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
293     }
294 }
295 
296 static inline int check_msa_access(DisasContext *ctx)
297 {
298     if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
299                  !(ctx->hflags & MIPS_HFLAG_F64))) {
300         gen_reserved_instruction(ctx);
301         return 0;
302     }
303 
304     if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
305         generate_exception_end(ctx, EXCP_MSADIS);
306         return 0;
307     }
308     return 1;
309 }
310 
311 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt,
312                                    TCGCond cond)
313 {
314     /* generates tcg ops to check if any element is 0 */
315     /* Note this function only works with MSA_WRLEN = 128 */
316     uint64_t eval_zero_or_big = 0;
317     uint64_t eval_big = 0;
318     TCGv_i64 t0 = tcg_temp_new_i64();
319     TCGv_i64 t1 = tcg_temp_new_i64();
320     switch (df) {
321     case DF_BYTE:
322         eval_zero_or_big = 0x0101010101010101ULL;
323         eval_big = 0x8080808080808080ULL;
324         break;
325     case DF_HALF:
326         eval_zero_or_big = 0x0001000100010001ULL;
327         eval_big = 0x8000800080008000ULL;
328         break;
329     case DF_WORD:
330         eval_zero_or_big = 0x0000000100000001ULL;
331         eval_big = 0x8000000080000000ULL;
332         break;
333     case DF_DOUBLE:
334         eval_zero_or_big = 0x0000000000000001ULL;
335         eval_big = 0x8000000000000000ULL;
336         break;
337     }
338     tcg_gen_subi_i64(t0, msa_wr_d[wt << 1], eval_zero_or_big);
339     tcg_gen_andc_i64(t0, t0, msa_wr_d[wt << 1]);
340     tcg_gen_andi_i64(t0, t0, eval_big);
341     tcg_gen_subi_i64(t1, msa_wr_d[(wt << 1) + 1], eval_zero_or_big);
342     tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt << 1) + 1]);
343     tcg_gen_andi_i64(t1, t1, eval_big);
344     tcg_gen_or_i64(t0, t0, t1);
345     /* if all bits are zero then all elements are not zero */
346     /* if some bit is non-zero then some element is zero */
347     tcg_gen_setcondi_i64(cond, t0, t0, 0);
348     tcg_gen_trunc_i64_tl(tresult, t0);
349     tcg_temp_free_i64(t0);
350     tcg_temp_free_i64(t1);
351 }
352 
353 static bool gen_msa_BxZ_V(DisasContext *ctx, int wt, int s16, TCGCond cond)
354 {
355     TCGv_i64 t0;
356 
357     check_msa_access(ctx);
358 
359     if (ctx->hflags & MIPS_HFLAG_BMASK) {
360         gen_reserved_instruction(ctx);
361         return true;
362     }
363     t0 = tcg_temp_new_i64();
364     tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]);
365     tcg_gen_setcondi_i64(cond, t0, t0, 0);
366     tcg_gen_trunc_i64_tl(bcond, t0);
367     tcg_temp_free_i64(t0);
368 
369     ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
370 
371     ctx->hflags |= MIPS_HFLAG_BC;
372     ctx->hflags |= MIPS_HFLAG_BDS32;
373 
374     return true;
375 }
376 
377 static bool trans_BZ_V(DisasContext *ctx, arg_msa_bz *a)
378 {
379     return gen_msa_BxZ_V(ctx, a->wt, a->s16, TCG_COND_EQ);
380 }
381 
382 static bool trans_BNZ_V(DisasContext *ctx, arg_msa_bz *a)
383 {
384     return gen_msa_BxZ_V(ctx, a->wt, a->s16, TCG_COND_NE);
385 }
386 
387 static bool gen_msa_BxZ(DisasContext *ctx, int df, int wt, int s16, bool if_not)
388 {
389     check_msa_access(ctx);
390 
391     if (ctx->hflags & MIPS_HFLAG_BMASK) {
392         gen_reserved_instruction(ctx);
393         return true;
394     }
395 
396     gen_check_zero_element(bcond, df, wt, if_not ? TCG_COND_EQ : TCG_COND_NE);
397 
398     ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
399     ctx->hflags |= MIPS_HFLAG_BC;
400     ctx->hflags |= MIPS_HFLAG_BDS32;
401 
402     return true;
403 }
404 
405 static bool trans_BZ_x(DisasContext *ctx, arg_msa_bz *a)
406 {
407     return gen_msa_BxZ(ctx, a->df, a->wt, a->s16, false);
408 }
409 
410 static bool trans_BNZ_x(DisasContext *ctx, arg_msa_bz *a)
411 {
412     return gen_msa_BxZ(ctx, a->df, a->wt, a->s16, true);
413 }
414 
415 static void gen_msa_i8(DisasContext *ctx)
416 {
417 #define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
418     uint8_t i8 = (ctx->opcode >> 16) & 0xff;
419     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
420     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
421 
422     TCGv_i32 twd = tcg_const_i32(wd);
423     TCGv_i32 tws = tcg_const_i32(ws);
424     TCGv_i32 ti8 = tcg_const_i32(i8);
425 
426     switch (MASK_MSA_I8(ctx->opcode)) {
427     case OPC_ANDI_B:
428         gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
429         break;
430     case OPC_ORI_B:
431         gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
432         break;
433     case OPC_NORI_B:
434         gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
435         break;
436     case OPC_XORI_B:
437         gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
438         break;
439     case OPC_BMNZI_B:
440         gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
441         break;
442     case OPC_BMZI_B:
443         gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
444         break;
445     case OPC_BSELI_B:
446         gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
447         break;
448     case OPC_SHF_B:
449     case OPC_SHF_H:
450     case OPC_SHF_W:
451         {
452             uint8_t df = (ctx->opcode >> 24) & 0x3;
453             if (df == DF_DOUBLE) {
454                 gen_reserved_instruction(ctx);
455             } else {
456                 TCGv_i32 tdf = tcg_const_i32(df);
457                 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
458                 tcg_temp_free_i32(tdf);
459             }
460         }
461         break;
462     default:
463         MIPS_INVAL("MSA instruction");
464         gen_reserved_instruction(ctx);
465         break;
466     }
467 
468     tcg_temp_free_i32(twd);
469     tcg_temp_free_i32(tws);
470     tcg_temp_free_i32(ti8);
471 }
472 
473 static void gen_msa_i5(DisasContext *ctx)
474 {
475 #define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
476     int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
477     uint8_t u5 = extract32(ctx->opcode, 16, 5);
478 
479     TCGv_i32 tdf = tcg_const_i32(extract32(ctx->opcode, 21, 2));
480     TCGv_i32 twd = tcg_const_i32(extract32(ctx->opcode, 11, 5));
481     TCGv_i32 tws = tcg_const_i32(extract32(ctx->opcode, 6, 5));
482     TCGv_i32 timm = tcg_temp_new_i32();
483     tcg_gen_movi_i32(timm, u5);
484 
485     switch (MASK_MSA_I5(ctx->opcode)) {
486     case OPC_ADDVI_df:
487         gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
488         break;
489     case OPC_SUBVI_df:
490         gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
491         break;
492     case OPC_MAXI_S_df:
493         tcg_gen_movi_i32(timm, s5);
494         gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
495         break;
496     case OPC_MAXI_U_df:
497         gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
498         break;
499     case OPC_MINI_S_df:
500         tcg_gen_movi_i32(timm, s5);
501         gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
502         break;
503     case OPC_MINI_U_df:
504         gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
505         break;
506     case OPC_CEQI_df:
507         tcg_gen_movi_i32(timm, s5);
508         gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
509         break;
510     case OPC_CLTI_S_df:
511         tcg_gen_movi_i32(timm, s5);
512         gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
513         break;
514     case OPC_CLTI_U_df:
515         gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
516         break;
517     case OPC_CLEI_S_df:
518         tcg_gen_movi_i32(timm, s5);
519         gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
520         break;
521     case OPC_CLEI_U_df:
522         gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
523         break;
524     case OPC_LDI_df:
525         {
526             int32_t s10 = sextract32(ctx->opcode, 11, 10);
527             tcg_gen_movi_i32(timm, s10);
528             gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
529         }
530         break;
531     default:
532         MIPS_INVAL("MSA instruction");
533         gen_reserved_instruction(ctx);
534         break;
535     }
536 
537     tcg_temp_free_i32(tdf);
538     tcg_temp_free_i32(twd);
539     tcg_temp_free_i32(tws);
540     tcg_temp_free_i32(timm);
541 }
542 
543 static void gen_msa_bit(DisasContext *ctx)
544 {
545 #define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
546     uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
547     uint32_t df = 0, m = 0;
548     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
549     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
550 
551     TCGv_i32 tdf;
552     TCGv_i32 tm;
553     TCGv_i32 twd;
554     TCGv_i32 tws;
555 
556     if ((dfm & 0x40) == 0x00) {
557         m = dfm & 0x3f;
558         df = DF_DOUBLE;
559     } else if ((dfm & 0x60) == 0x40) {
560         m = dfm & 0x1f;
561         df = DF_WORD;
562     } else if ((dfm & 0x70) == 0x60) {
563         m = dfm & 0x0f;
564         df = DF_HALF;
565     } else if ((dfm & 0x78) == 0x70) {
566         m = dfm & 0x7;
567         df = DF_BYTE;
568     } else {
569         gen_reserved_instruction(ctx);
570         return;
571     }
572 
573     tdf = tcg_const_i32(df);
574     tm  = tcg_const_i32(m);
575     twd = tcg_const_i32(wd);
576     tws = tcg_const_i32(ws);
577 
578     switch (MASK_MSA_BIT(ctx->opcode)) {
579     case OPC_SLLI_df:
580         gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
581         break;
582     case OPC_SRAI_df:
583         gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
584         break;
585     case OPC_SRLI_df:
586         gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
587         break;
588     case OPC_BCLRI_df:
589         gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
590         break;
591     case OPC_BSETI_df:
592         gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
593         break;
594     case OPC_BNEGI_df:
595         gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
596         break;
597     case OPC_BINSLI_df:
598         gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
599         break;
600     case OPC_BINSRI_df:
601         gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
602         break;
603     case OPC_SAT_S_df:
604         gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
605         break;
606     case OPC_SAT_U_df:
607         gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
608         break;
609     case OPC_SRARI_df:
610         gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
611         break;
612     case OPC_SRLRI_df:
613         gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
614         break;
615     default:
616         MIPS_INVAL("MSA instruction");
617         gen_reserved_instruction(ctx);
618         break;
619     }
620 
621     tcg_temp_free_i32(tdf);
622     tcg_temp_free_i32(tm);
623     tcg_temp_free_i32(twd);
624     tcg_temp_free_i32(tws);
625 }
626 
627 static void gen_msa_3r(DisasContext *ctx)
628 {
629 #define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
630     uint8_t df = (ctx->opcode >> 21) & 0x3;
631     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
632     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
633     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
634 
635     TCGv_i32 tdf = tcg_const_i32(df);
636     TCGv_i32 twd = tcg_const_i32(wd);
637     TCGv_i32 tws = tcg_const_i32(ws);
638     TCGv_i32 twt = tcg_const_i32(wt);
639 
640     switch (MASK_MSA_3R(ctx->opcode)) {
641     case OPC_BINSL_df:
642         switch (df) {
643         case DF_BYTE:
644             gen_helper_msa_binsl_b(cpu_env, twd, tws, twt);
645             break;
646         case DF_HALF:
647             gen_helper_msa_binsl_h(cpu_env, twd, tws, twt);
648             break;
649         case DF_WORD:
650             gen_helper_msa_binsl_w(cpu_env, twd, tws, twt);
651             break;
652         case DF_DOUBLE:
653             gen_helper_msa_binsl_d(cpu_env, twd, tws, twt);
654             break;
655         }
656         break;
657     case OPC_BINSR_df:
658         switch (df) {
659         case DF_BYTE:
660             gen_helper_msa_binsr_b(cpu_env, twd, tws, twt);
661             break;
662         case DF_HALF:
663             gen_helper_msa_binsr_h(cpu_env, twd, tws, twt);
664             break;
665         case DF_WORD:
666             gen_helper_msa_binsr_w(cpu_env, twd, tws, twt);
667             break;
668         case DF_DOUBLE:
669             gen_helper_msa_binsr_d(cpu_env, twd, tws, twt);
670             break;
671         }
672         break;
673     case OPC_BCLR_df:
674         switch (df) {
675         case DF_BYTE:
676             gen_helper_msa_bclr_b(cpu_env, twd, tws, twt);
677             break;
678         case DF_HALF:
679             gen_helper_msa_bclr_h(cpu_env, twd, tws, twt);
680             break;
681         case DF_WORD:
682             gen_helper_msa_bclr_w(cpu_env, twd, tws, twt);
683             break;
684         case DF_DOUBLE:
685             gen_helper_msa_bclr_d(cpu_env, twd, tws, twt);
686             break;
687         }
688         break;
689     case OPC_BNEG_df:
690         switch (df) {
691         case DF_BYTE:
692             gen_helper_msa_bneg_b(cpu_env, twd, tws, twt);
693             break;
694         case DF_HALF:
695             gen_helper_msa_bneg_h(cpu_env, twd, tws, twt);
696             break;
697         case DF_WORD:
698             gen_helper_msa_bneg_w(cpu_env, twd, tws, twt);
699             break;
700         case DF_DOUBLE:
701             gen_helper_msa_bneg_d(cpu_env, twd, tws, twt);
702             break;
703         }
704         break;
705     case OPC_BSET_df:
706         switch (df) {
707         case DF_BYTE:
708             gen_helper_msa_bset_b(cpu_env, twd, tws, twt);
709             break;
710         case DF_HALF:
711             gen_helper_msa_bset_h(cpu_env, twd, tws, twt);
712             break;
713         case DF_WORD:
714             gen_helper_msa_bset_w(cpu_env, twd, tws, twt);
715             break;
716         case DF_DOUBLE:
717             gen_helper_msa_bset_d(cpu_env, twd, tws, twt);
718             break;
719         }
720         break;
721     case OPC_ADD_A_df:
722         switch (df) {
723         case DF_BYTE:
724             gen_helper_msa_add_a_b(cpu_env, twd, tws, twt);
725             break;
726         case DF_HALF:
727             gen_helper_msa_add_a_h(cpu_env, twd, tws, twt);
728             break;
729         case DF_WORD:
730             gen_helper_msa_add_a_w(cpu_env, twd, tws, twt);
731             break;
732         case DF_DOUBLE:
733             gen_helper_msa_add_a_d(cpu_env, twd, tws, twt);
734             break;
735         }
736         break;
737     case OPC_ADDS_A_df:
738         switch (df) {
739         case DF_BYTE:
740             gen_helper_msa_adds_a_b(cpu_env, twd, tws, twt);
741             break;
742         case DF_HALF:
743             gen_helper_msa_adds_a_h(cpu_env, twd, tws, twt);
744             break;
745         case DF_WORD:
746             gen_helper_msa_adds_a_w(cpu_env, twd, tws, twt);
747             break;
748         case DF_DOUBLE:
749             gen_helper_msa_adds_a_d(cpu_env, twd, tws, twt);
750             break;
751         }
752         break;
753     case OPC_ADDS_S_df:
754         switch (df) {
755         case DF_BYTE:
756             gen_helper_msa_adds_s_b(cpu_env, twd, tws, twt);
757             break;
758         case DF_HALF:
759             gen_helper_msa_adds_s_h(cpu_env, twd, tws, twt);
760             break;
761         case DF_WORD:
762             gen_helper_msa_adds_s_w(cpu_env, twd, tws, twt);
763             break;
764         case DF_DOUBLE:
765             gen_helper_msa_adds_s_d(cpu_env, twd, tws, twt);
766             break;
767         }
768         break;
769     case OPC_ADDS_U_df:
770         switch (df) {
771         case DF_BYTE:
772             gen_helper_msa_adds_u_b(cpu_env, twd, tws, twt);
773             break;
774         case DF_HALF:
775             gen_helper_msa_adds_u_h(cpu_env, twd, tws, twt);
776             break;
777         case DF_WORD:
778             gen_helper_msa_adds_u_w(cpu_env, twd, tws, twt);
779             break;
780         case DF_DOUBLE:
781             gen_helper_msa_adds_u_d(cpu_env, twd, tws, twt);
782             break;
783         }
784         break;
785     case OPC_ADDV_df:
786         switch (df) {
787         case DF_BYTE:
788             gen_helper_msa_addv_b(cpu_env, twd, tws, twt);
789             break;
790         case DF_HALF:
791             gen_helper_msa_addv_h(cpu_env, twd, tws, twt);
792             break;
793         case DF_WORD:
794             gen_helper_msa_addv_w(cpu_env, twd, tws, twt);
795             break;
796         case DF_DOUBLE:
797             gen_helper_msa_addv_d(cpu_env, twd, tws, twt);
798             break;
799         }
800         break;
801     case OPC_AVE_S_df:
802         switch (df) {
803         case DF_BYTE:
804             gen_helper_msa_ave_s_b(cpu_env, twd, tws, twt);
805             break;
806         case DF_HALF:
807             gen_helper_msa_ave_s_h(cpu_env, twd, tws, twt);
808             break;
809         case DF_WORD:
810             gen_helper_msa_ave_s_w(cpu_env, twd, tws, twt);
811             break;
812         case DF_DOUBLE:
813             gen_helper_msa_ave_s_d(cpu_env, twd, tws, twt);
814             break;
815         }
816         break;
817     case OPC_AVE_U_df:
818         switch (df) {
819         case DF_BYTE:
820             gen_helper_msa_ave_u_b(cpu_env, twd, tws, twt);
821             break;
822         case DF_HALF:
823             gen_helper_msa_ave_u_h(cpu_env, twd, tws, twt);
824             break;
825         case DF_WORD:
826             gen_helper_msa_ave_u_w(cpu_env, twd, tws, twt);
827             break;
828         case DF_DOUBLE:
829             gen_helper_msa_ave_u_d(cpu_env, twd, tws, twt);
830             break;
831         }
832         break;
833     case OPC_AVER_S_df:
834         switch (df) {
835         case DF_BYTE:
836             gen_helper_msa_aver_s_b(cpu_env, twd, tws, twt);
837             break;
838         case DF_HALF:
839             gen_helper_msa_aver_s_h(cpu_env, twd, tws, twt);
840             break;
841         case DF_WORD:
842             gen_helper_msa_aver_s_w(cpu_env, twd, tws, twt);
843             break;
844         case DF_DOUBLE:
845             gen_helper_msa_aver_s_d(cpu_env, twd, tws, twt);
846             break;
847         }
848         break;
849     case OPC_AVER_U_df:
850         switch (df) {
851         case DF_BYTE:
852             gen_helper_msa_aver_u_b(cpu_env, twd, tws, twt);
853             break;
854         case DF_HALF:
855             gen_helper_msa_aver_u_h(cpu_env, twd, tws, twt);
856             break;
857         case DF_WORD:
858             gen_helper_msa_aver_u_w(cpu_env, twd, tws, twt);
859             break;
860         case DF_DOUBLE:
861             gen_helper_msa_aver_u_d(cpu_env, twd, tws, twt);
862             break;
863         }
864         break;
865     case OPC_CEQ_df:
866         switch (df) {
867         case DF_BYTE:
868             gen_helper_msa_ceq_b(cpu_env, twd, tws, twt);
869             break;
870         case DF_HALF:
871             gen_helper_msa_ceq_h(cpu_env, twd, tws, twt);
872             break;
873         case DF_WORD:
874             gen_helper_msa_ceq_w(cpu_env, twd, tws, twt);
875             break;
876         case DF_DOUBLE:
877             gen_helper_msa_ceq_d(cpu_env, twd, tws, twt);
878             break;
879         }
880         break;
881     case OPC_CLE_S_df:
882         switch (df) {
883         case DF_BYTE:
884             gen_helper_msa_cle_s_b(cpu_env, twd, tws, twt);
885             break;
886         case DF_HALF:
887             gen_helper_msa_cle_s_h(cpu_env, twd, tws, twt);
888             break;
889         case DF_WORD:
890             gen_helper_msa_cle_s_w(cpu_env, twd, tws, twt);
891             break;
892         case DF_DOUBLE:
893             gen_helper_msa_cle_s_d(cpu_env, twd, tws, twt);
894             break;
895         }
896         break;
897     case OPC_CLE_U_df:
898         switch (df) {
899         case DF_BYTE:
900             gen_helper_msa_cle_u_b(cpu_env, twd, tws, twt);
901             break;
902         case DF_HALF:
903             gen_helper_msa_cle_u_h(cpu_env, twd, tws, twt);
904             break;
905         case DF_WORD:
906             gen_helper_msa_cle_u_w(cpu_env, twd, tws, twt);
907             break;
908         case DF_DOUBLE:
909             gen_helper_msa_cle_u_d(cpu_env, twd, tws, twt);
910             break;
911         }
912         break;
913     case OPC_CLT_S_df:
914         switch (df) {
915         case DF_BYTE:
916             gen_helper_msa_clt_s_b(cpu_env, twd, tws, twt);
917             break;
918         case DF_HALF:
919             gen_helper_msa_clt_s_h(cpu_env, twd, tws, twt);
920             break;
921         case DF_WORD:
922             gen_helper_msa_clt_s_w(cpu_env, twd, tws, twt);
923             break;
924         case DF_DOUBLE:
925             gen_helper_msa_clt_s_d(cpu_env, twd, tws, twt);
926             break;
927         }
928         break;
929     case OPC_CLT_U_df:
930         switch (df) {
931         case DF_BYTE:
932             gen_helper_msa_clt_u_b(cpu_env, twd, tws, twt);
933             break;
934         case DF_HALF:
935             gen_helper_msa_clt_u_h(cpu_env, twd, tws, twt);
936             break;
937         case DF_WORD:
938             gen_helper_msa_clt_u_w(cpu_env, twd, tws, twt);
939             break;
940         case DF_DOUBLE:
941             gen_helper_msa_clt_u_d(cpu_env, twd, tws, twt);
942             break;
943         }
944         break;
945     case OPC_DIV_S_df:
946         switch (df) {
947         case DF_BYTE:
948             gen_helper_msa_div_s_b(cpu_env, twd, tws, twt);
949             break;
950         case DF_HALF:
951             gen_helper_msa_div_s_h(cpu_env, twd, tws, twt);
952             break;
953         case DF_WORD:
954             gen_helper_msa_div_s_w(cpu_env, twd, tws, twt);
955             break;
956         case DF_DOUBLE:
957             gen_helper_msa_div_s_d(cpu_env, twd, tws, twt);
958             break;
959         }
960         break;
961     case OPC_DIV_U_df:
962         switch (df) {
963         case DF_BYTE:
964             gen_helper_msa_div_u_b(cpu_env, twd, tws, twt);
965             break;
966         case DF_HALF:
967             gen_helper_msa_div_u_h(cpu_env, twd, tws, twt);
968             break;
969         case DF_WORD:
970             gen_helper_msa_div_u_w(cpu_env, twd, tws, twt);
971             break;
972         case DF_DOUBLE:
973             gen_helper_msa_div_u_d(cpu_env, twd, tws, twt);
974             break;
975         }
976         break;
977     case OPC_MAX_A_df:
978         switch (df) {
979         case DF_BYTE:
980             gen_helper_msa_max_a_b(cpu_env, twd, tws, twt);
981             break;
982         case DF_HALF:
983             gen_helper_msa_max_a_h(cpu_env, twd, tws, twt);
984             break;
985         case DF_WORD:
986             gen_helper_msa_max_a_w(cpu_env, twd, tws, twt);
987             break;
988         case DF_DOUBLE:
989             gen_helper_msa_max_a_d(cpu_env, twd, tws, twt);
990             break;
991         }
992         break;
993     case OPC_MAX_S_df:
994         switch (df) {
995         case DF_BYTE:
996             gen_helper_msa_max_s_b(cpu_env, twd, tws, twt);
997             break;
998         case DF_HALF:
999             gen_helper_msa_max_s_h(cpu_env, twd, tws, twt);
1000             break;
1001         case DF_WORD:
1002             gen_helper_msa_max_s_w(cpu_env, twd, tws, twt);
1003             break;
1004         case DF_DOUBLE:
1005             gen_helper_msa_max_s_d(cpu_env, twd, tws, twt);
1006             break;
1007         }
1008         break;
1009     case OPC_MAX_U_df:
1010         switch (df) {
1011         case DF_BYTE:
1012             gen_helper_msa_max_u_b(cpu_env, twd, tws, twt);
1013             break;
1014         case DF_HALF:
1015             gen_helper_msa_max_u_h(cpu_env, twd, tws, twt);
1016             break;
1017         case DF_WORD:
1018             gen_helper_msa_max_u_w(cpu_env, twd, tws, twt);
1019             break;
1020         case DF_DOUBLE:
1021             gen_helper_msa_max_u_d(cpu_env, twd, tws, twt);
1022             break;
1023         }
1024         break;
1025     case OPC_MIN_A_df:
1026         switch (df) {
1027         case DF_BYTE:
1028             gen_helper_msa_min_a_b(cpu_env, twd, tws, twt);
1029             break;
1030         case DF_HALF:
1031             gen_helper_msa_min_a_h(cpu_env, twd, tws, twt);
1032             break;
1033         case DF_WORD:
1034             gen_helper_msa_min_a_w(cpu_env, twd, tws, twt);
1035             break;
1036         case DF_DOUBLE:
1037             gen_helper_msa_min_a_d(cpu_env, twd, tws, twt);
1038             break;
1039         }
1040         break;
1041     case OPC_MIN_S_df:
1042         switch (df) {
1043         case DF_BYTE:
1044             gen_helper_msa_min_s_b(cpu_env, twd, tws, twt);
1045             break;
1046         case DF_HALF:
1047             gen_helper_msa_min_s_h(cpu_env, twd, tws, twt);
1048             break;
1049         case DF_WORD:
1050             gen_helper_msa_min_s_w(cpu_env, twd, tws, twt);
1051             break;
1052         case DF_DOUBLE:
1053             gen_helper_msa_min_s_d(cpu_env, twd, tws, twt);
1054             break;
1055         }
1056         break;
1057     case OPC_MIN_U_df:
1058         switch (df) {
1059         case DF_BYTE:
1060             gen_helper_msa_min_u_b(cpu_env, twd, tws, twt);
1061             break;
1062         case DF_HALF:
1063             gen_helper_msa_min_u_h(cpu_env, twd, tws, twt);
1064             break;
1065         case DF_WORD:
1066             gen_helper_msa_min_u_w(cpu_env, twd, tws, twt);
1067             break;
1068         case DF_DOUBLE:
1069             gen_helper_msa_min_u_d(cpu_env, twd, tws, twt);
1070             break;
1071         }
1072         break;
1073     case OPC_MOD_S_df:
1074         switch (df) {
1075         case DF_BYTE:
1076             gen_helper_msa_mod_s_b(cpu_env, twd, tws, twt);
1077             break;
1078         case DF_HALF:
1079             gen_helper_msa_mod_s_h(cpu_env, twd, tws, twt);
1080             break;
1081         case DF_WORD:
1082             gen_helper_msa_mod_s_w(cpu_env, twd, tws, twt);
1083             break;
1084         case DF_DOUBLE:
1085             gen_helper_msa_mod_s_d(cpu_env, twd, tws, twt);
1086             break;
1087         }
1088         break;
1089     case OPC_MOD_U_df:
1090         switch (df) {
1091         case DF_BYTE:
1092             gen_helper_msa_mod_u_b(cpu_env, twd, tws, twt);
1093             break;
1094         case DF_HALF:
1095             gen_helper_msa_mod_u_h(cpu_env, twd, tws, twt);
1096             break;
1097         case DF_WORD:
1098             gen_helper_msa_mod_u_w(cpu_env, twd, tws, twt);
1099             break;
1100         case DF_DOUBLE:
1101             gen_helper_msa_mod_u_d(cpu_env, twd, tws, twt);
1102             break;
1103         }
1104         break;
1105     case OPC_MADDV_df:
1106         switch (df) {
1107         case DF_BYTE:
1108             gen_helper_msa_maddv_b(cpu_env, twd, tws, twt);
1109             break;
1110         case DF_HALF:
1111             gen_helper_msa_maddv_h(cpu_env, twd, tws, twt);
1112             break;
1113         case DF_WORD:
1114             gen_helper_msa_maddv_w(cpu_env, twd, tws, twt);
1115             break;
1116         case DF_DOUBLE:
1117             gen_helper_msa_maddv_d(cpu_env, twd, tws, twt);
1118             break;
1119         }
1120         break;
1121     case OPC_MSUBV_df:
1122         switch (df) {
1123         case DF_BYTE:
1124             gen_helper_msa_msubv_b(cpu_env, twd, tws, twt);
1125             break;
1126         case DF_HALF:
1127             gen_helper_msa_msubv_h(cpu_env, twd, tws, twt);
1128             break;
1129         case DF_WORD:
1130             gen_helper_msa_msubv_w(cpu_env, twd, tws, twt);
1131             break;
1132         case DF_DOUBLE:
1133             gen_helper_msa_msubv_d(cpu_env, twd, tws, twt);
1134             break;
1135         }
1136         break;
1137     case OPC_ASUB_S_df:
1138         switch (df) {
1139         case DF_BYTE:
1140             gen_helper_msa_asub_s_b(cpu_env, twd, tws, twt);
1141             break;
1142         case DF_HALF:
1143             gen_helper_msa_asub_s_h(cpu_env, twd, tws, twt);
1144             break;
1145         case DF_WORD:
1146             gen_helper_msa_asub_s_w(cpu_env, twd, tws, twt);
1147             break;
1148         case DF_DOUBLE:
1149             gen_helper_msa_asub_s_d(cpu_env, twd, tws, twt);
1150             break;
1151         }
1152         break;
1153     case OPC_ASUB_U_df:
1154         switch (df) {
1155         case DF_BYTE:
1156             gen_helper_msa_asub_u_b(cpu_env, twd, tws, twt);
1157             break;
1158         case DF_HALF:
1159             gen_helper_msa_asub_u_h(cpu_env, twd, tws, twt);
1160             break;
1161         case DF_WORD:
1162             gen_helper_msa_asub_u_w(cpu_env, twd, tws, twt);
1163             break;
1164         case DF_DOUBLE:
1165             gen_helper_msa_asub_u_d(cpu_env, twd, tws, twt);
1166             break;
1167         }
1168         break;
1169     case OPC_ILVEV_df:
1170         switch (df) {
1171         case DF_BYTE:
1172             gen_helper_msa_ilvev_b(cpu_env, twd, tws, twt);
1173             break;
1174         case DF_HALF:
1175             gen_helper_msa_ilvev_h(cpu_env, twd, tws, twt);
1176             break;
1177         case DF_WORD:
1178             gen_helper_msa_ilvev_w(cpu_env, twd, tws, twt);
1179             break;
1180         case DF_DOUBLE:
1181             gen_helper_msa_ilvev_d(cpu_env, twd, tws, twt);
1182             break;
1183         }
1184         break;
1185     case OPC_ILVOD_df:
1186         switch (df) {
1187         case DF_BYTE:
1188             gen_helper_msa_ilvod_b(cpu_env, twd, tws, twt);
1189             break;
1190         case DF_HALF:
1191             gen_helper_msa_ilvod_h(cpu_env, twd, tws, twt);
1192             break;
1193         case DF_WORD:
1194             gen_helper_msa_ilvod_w(cpu_env, twd, tws, twt);
1195             break;
1196         case DF_DOUBLE:
1197             gen_helper_msa_ilvod_d(cpu_env, twd, tws, twt);
1198             break;
1199         }
1200         break;
1201     case OPC_ILVL_df:
1202         switch (df) {
1203         case DF_BYTE:
1204             gen_helper_msa_ilvl_b(cpu_env, twd, tws, twt);
1205             break;
1206         case DF_HALF:
1207             gen_helper_msa_ilvl_h(cpu_env, twd, tws, twt);
1208             break;
1209         case DF_WORD:
1210             gen_helper_msa_ilvl_w(cpu_env, twd, tws, twt);
1211             break;
1212         case DF_DOUBLE:
1213             gen_helper_msa_ilvl_d(cpu_env, twd, tws, twt);
1214             break;
1215         }
1216         break;
1217     case OPC_ILVR_df:
1218         switch (df) {
1219         case DF_BYTE:
1220             gen_helper_msa_ilvr_b(cpu_env, twd, tws, twt);
1221             break;
1222         case DF_HALF:
1223             gen_helper_msa_ilvr_h(cpu_env, twd, tws, twt);
1224             break;
1225         case DF_WORD:
1226             gen_helper_msa_ilvr_w(cpu_env, twd, tws, twt);
1227             break;
1228         case DF_DOUBLE:
1229             gen_helper_msa_ilvr_d(cpu_env, twd, tws, twt);
1230             break;
1231         }
1232         break;
1233     case OPC_PCKEV_df:
1234         switch (df) {
1235         case DF_BYTE:
1236             gen_helper_msa_pckev_b(cpu_env, twd, tws, twt);
1237             break;
1238         case DF_HALF:
1239             gen_helper_msa_pckev_h(cpu_env, twd, tws, twt);
1240             break;
1241         case DF_WORD:
1242             gen_helper_msa_pckev_w(cpu_env, twd, tws, twt);
1243             break;
1244         case DF_DOUBLE:
1245             gen_helper_msa_pckev_d(cpu_env, twd, tws, twt);
1246             break;
1247         }
1248         break;
1249     case OPC_PCKOD_df:
1250         switch (df) {
1251         case DF_BYTE:
1252             gen_helper_msa_pckod_b(cpu_env, twd, tws, twt);
1253             break;
1254         case DF_HALF:
1255             gen_helper_msa_pckod_h(cpu_env, twd, tws, twt);
1256             break;
1257         case DF_WORD:
1258             gen_helper_msa_pckod_w(cpu_env, twd, tws, twt);
1259             break;
1260         case DF_DOUBLE:
1261             gen_helper_msa_pckod_d(cpu_env, twd, tws, twt);
1262             break;
1263         }
1264         break;
1265     case OPC_SLL_df:
1266         switch (df) {
1267         case DF_BYTE:
1268             gen_helper_msa_sll_b(cpu_env, twd, tws, twt);
1269             break;
1270         case DF_HALF:
1271             gen_helper_msa_sll_h(cpu_env, twd, tws, twt);
1272             break;
1273         case DF_WORD:
1274             gen_helper_msa_sll_w(cpu_env, twd, tws, twt);
1275             break;
1276         case DF_DOUBLE:
1277             gen_helper_msa_sll_d(cpu_env, twd, tws, twt);
1278             break;
1279         }
1280         break;
1281     case OPC_SRA_df:
1282         switch (df) {
1283         case DF_BYTE:
1284             gen_helper_msa_sra_b(cpu_env, twd, tws, twt);
1285             break;
1286         case DF_HALF:
1287             gen_helper_msa_sra_h(cpu_env, twd, tws, twt);
1288             break;
1289         case DF_WORD:
1290             gen_helper_msa_sra_w(cpu_env, twd, tws, twt);
1291             break;
1292         case DF_DOUBLE:
1293             gen_helper_msa_sra_d(cpu_env, twd, tws, twt);
1294             break;
1295         }
1296         break;
1297     case OPC_SRAR_df:
1298         switch (df) {
1299         case DF_BYTE:
1300             gen_helper_msa_srar_b(cpu_env, twd, tws, twt);
1301             break;
1302         case DF_HALF:
1303             gen_helper_msa_srar_h(cpu_env, twd, tws, twt);
1304             break;
1305         case DF_WORD:
1306             gen_helper_msa_srar_w(cpu_env, twd, tws, twt);
1307             break;
1308         case DF_DOUBLE:
1309             gen_helper_msa_srar_d(cpu_env, twd, tws, twt);
1310             break;
1311         }
1312         break;
1313     case OPC_SRL_df:
1314         switch (df) {
1315         case DF_BYTE:
1316             gen_helper_msa_srl_b(cpu_env, twd, tws, twt);
1317             break;
1318         case DF_HALF:
1319             gen_helper_msa_srl_h(cpu_env, twd, tws, twt);
1320             break;
1321         case DF_WORD:
1322             gen_helper_msa_srl_w(cpu_env, twd, tws, twt);
1323             break;
1324         case DF_DOUBLE:
1325             gen_helper_msa_srl_d(cpu_env, twd, tws, twt);
1326             break;
1327         }
1328         break;
1329     case OPC_SRLR_df:
1330         switch (df) {
1331         case DF_BYTE:
1332             gen_helper_msa_srlr_b(cpu_env, twd, tws, twt);
1333             break;
1334         case DF_HALF:
1335             gen_helper_msa_srlr_h(cpu_env, twd, tws, twt);
1336             break;
1337         case DF_WORD:
1338             gen_helper_msa_srlr_w(cpu_env, twd, tws, twt);
1339             break;
1340         case DF_DOUBLE:
1341             gen_helper_msa_srlr_d(cpu_env, twd, tws, twt);
1342             break;
1343         }
1344         break;
1345     case OPC_SUBS_S_df:
1346         switch (df) {
1347         case DF_BYTE:
1348             gen_helper_msa_subs_s_b(cpu_env, twd, tws, twt);
1349             break;
1350         case DF_HALF:
1351             gen_helper_msa_subs_s_h(cpu_env, twd, tws, twt);
1352             break;
1353         case DF_WORD:
1354             gen_helper_msa_subs_s_w(cpu_env, twd, tws, twt);
1355             break;
1356         case DF_DOUBLE:
1357             gen_helper_msa_subs_s_d(cpu_env, twd, tws, twt);
1358             break;
1359         }
1360         break;
1361     case OPC_MULV_df:
1362         switch (df) {
1363         case DF_BYTE:
1364             gen_helper_msa_mulv_b(cpu_env, twd, tws, twt);
1365             break;
1366         case DF_HALF:
1367             gen_helper_msa_mulv_h(cpu_env, twd, tws, twt);
1368             break;
1369         case DF_WORD:
1370             gen_helper_msa_mulv_w(cpu_env, twd, tws, twt);
1371             break;
1372         case DF_DOUBLE:
1373             gen_helper_msa_mulv_d(cpu_env, twd, tws, twt);
1374             break;
1375         }
1376         break;
1377     case OPC_SLD_df:
1378         gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
1379         break;
1380     case OPC_VSHF_df:
1381         gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
1382         break;
1383     case OPC_SUBV_df:
1384         switch (df) {
1385         case DF_BYTE:
1386             gen_helper_msa_subv_b(cpu_env, twd, tws, twt);
1387             break;
1388         case DF_HALF:
1389             gen_helper_msa_subv_h(cpu_env, twd, tws, twt);
1390             break;
1391         case DF_WORD:
1392             gen_helper_msa_subv_w(cpu_env, twd, tws, twt);
1393             break;
1394         case DF_DOUBLE:
1395             gen_helper_msa_subv_d(cpu_env, twd, tws, twt);
1396             break;
1397         }
1398         break;
1399     case OPC_SUBS_U_df:
1400         switch (df) {
1401         case DF_BYTE:
1402             gen_helper_msa_subs_u_b(cpu_env, twd, tws, twt);
1403             break;
1404         case DF_HALF:
1405             gen_helper_msa_subs_u_h(cpu_env, twd, tws, twt);
1406             break;
1407         case DF_WORD:
1408             gen_helper_msa_subs_u_w(cpu_env, twd, tws, twt);
1409             break;
1410         case DF_DOUBLE:
1411             gen_helper_msa_subs_u_d(cpu_env, twd, tws, twt);
1412             break;
1413         }
1414         break;
1415     case OPC_SPLAT_df:
1416         gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
1417         break;
1418     case OPC_SUBSUS_U_df:
1419         switch (df) {
1420         case DF_BYTE:
1421             gen_helper_msa_subsus_u_b(cpu_env, twd, tws, twt);
1422             break;
1423         case DF_HALF:
1424             gen_helper_msa_subsus_u_h(cpu_env, twd, tws, twt);
1425             break;
1426         case DF_WORD:
1427             gen_helper_msa_subsus_u_w(cpu_env, twd, tws, twt);
1428             break;
1429         case DF_DOUBLE:
1430             gen_helper_msa_subsus_u_d(cpu_env, twd, tws, twt);
1431             break;
1432         }
1433         break;
1434     case OPC_SUBSUU_S_df:
1435         switch (df) {
1436         case DF_BYTE:
1437             gen_helper_msa_subsuu_s_b(cpu_env, twd, tws, twt);
1438             break;
1439         case DF_HALF:
1440             gen_helper_msa_subsuu_s_h(cpu_env, twd, tws, twt);
1441             break;
1442         case DF_WORD:
1443             gen_helper_msa_subsuu_s_w(cpu_env, twd, tws, twt);
1444             break;
1445         case DF_DOUBLE:
1446             gen_helper_msa_subsuu_s_d(cpu_env, twd, tws, twt);
1447             break;
1448         }
1449         break;
1450 
1451     case OPC_DOTP_S_df:
1452     case OPC_DOTP_U_df:
1453     case OPC_DPADD_S_df:
1454     case OPC_DPADD_U_df:
1455     case OPC_DPSUB_S_df:
1456     case OPC_HADD_S_df:
1457     case OPC_DPSUB_U_df:
1458     case OPC_HADD_U_df:
1459     case OPC_HSUB_S_df:
1460     case OPC_HSUB_U_df:
1461         if (df == DF_BYTE) {
1462             gen_reserved_instruction(ctx);
1463             break;
1464         }
1465         switch (MASK_MSA_3R(ctx->opcode)) {
1466         case OPC_HADD_S_df:
1467             switch (df) {
1468             case DF_HALF:
1469                 gen_helper_msa_hadd_s_h(cpu_env, twd, tws, twt);
1470                 break;
1471             case DF_WORD:
1472                 gen_helper_msa_hadd_s_w(cpu_env, twd, tws, twt);
1473                 break;
1474             case DF_DOUBLE:
1475                 gen_helper_msa_hadd_s_d(cpu_env, twd, tws, twt);
1476                 break;
1477             }
1478             break;
1479         case OPC_HADD_U_df:
1480             switch (df) {
1481             case DF_HALF:
1482                 gen_helper_msa_hadd_u_h(cpu_env, twd, tws, twt);
1483                 break;
1484             case DF_WORD:
1485                 gen_helper_msa_hadd_u_w(cpu_env, twd, tws, twt);
1486                 break;
1487             case DF_DOUBLE:
1488                 gen_helper_msa_hadd_u_d(cpu_env, twd, tws, twt);
1489                 break;
1490             }
1491             break;
1492         case OPC_HSUB_S_df:
1493             switch (df) {
1494             case DF_HALF:
1495                 gen_helper_msa_hsub_s_h(cpu_env, twd, tws, twt);
1496                 break;
1497             case DF_WORD:
1498                 gen_helper_msa_hsub_s_w(cpu_env, twd, tws, twt);
1499                 break;
1500             case DF_DOUBLE:
1501                 gen_helper_msa_hsub_s_d(cpu_env, twd, tws, twt);
1502                 break;
1503             }
1504             break;
1505         case OPC_HSUB_U_df:
1506             switch (df) {
1507             case DF_HALF:
1508                 gen_helper_msa_hsub_u_h(cpu_env, twd, tws, twt);
1509                 break;
1510             case DF_WORD:
1511                 gen_helper_msa_hsub_u_w(cpu_env, twd, tws, twt);
1512                 break;
1513             case DF_DOUBLE:
1514                 gen_helper_msa_hsub_u_d(cpu_env, twd, tws, twt);
1515                 break;
1516             }
1517             break;
1518         case OPC_DOTP_S_df:
1519             switch (df) {
1520             case DF_HALF:
1521                 gen_helper_msa_dotp_s_h(cpu_env, twd, tws, twt);
1522                 break;
1523             case DF_WORD:
1524                 gen_helper_msa_dotp_s_w(cpu_env, twd, tws, twt);
1525                 break;
1526             case DF_DOUBLE:
1527                 gen_helper_msa_dotp_s_d(cpu_env, twd, tws, twt);
1528                 break;
1529             }
1530             break;
1531         case OPC_DOTP_U_df:
1532             switch (df) {
1533             case DF_HALF:
1534                 gen_helper_msa_dotp_u_h(cpu_env, twd, tws, twt);
1535                 break;
1536             case DF_WORD:
1537                 gen_helper_msa_dotp_u_w(cpu_env, twd, tws, twt);
1538                 break;
1539             case DF_DOUBLE:
1540                 gen_helper_msa_dotp_u_d(cpu_env, twd, tws, twt);
1541                 break;
1542             }
1543             break;
1544         case OPC_DPADD_S_df:
1545             switch (df) {
1546             case DF_HALF:
1547                 gen_helper_msa_dpadd_s_h(cpu_env, twd, tws, twt);
1548                 break;
1549             case DF_WORD:
1550                 gen_helper_msa_dpadd_s_w(cpu_env, twd, tws, twt);
1551                 break;
1552             case DF_DOUBLE:
1553                 gen_helper_msa_dpadd_s_d(cpu_env, twd, tws, twt);
1554                 break;
1555             }
1556             break;
1557         case OPC_DPADD_U_df:
1558             switch (df) {
1559             case DF_HALF:
1560                 gen_helper_msa_dpadd_u_h(cpu_env, twd, tws, twt);
1561                 break;
1562             case DF_WORD:
1563                 gen_helper_msa_dpadd_u_w(cpu_env, twd, tws, twt);
1564                 break;
1565             case DF_DOUBLE:
1566                 gen_helper_msa_dpadd_u_d(cpu_env, twd, tws, twt);
1567                 break;
1568             }
1569             break;
1570         case OPC_DPSUB_S_df:
1571             switch (df) {
1572             case DF_HALF:
1573                 gen_helper_msa_dpsub_s_h(cpu_env, twd, tws, twt);
1574                 break;
1575             case DF_WORD:
1576                 gen_helper_msa_dpsub_s_w(cpu_env, twd, tws, twt);
1577                 break;
1578             case DF_DOUBLE:
1579                 gen_helper_msa_dpsub_s_d(cpu_env, twd, tws, twt);
1580                 break;
1581             }
1582             break;
1583         case OPC_DPSUB_U_df:
1584             switch (df) {
1585             case DF_HALF:
1586                 gen_helper_msa_dpsub_u_h(cpu_env, twd, tws, twt);
1587                 break;
1588             case DF_WORD:
1589                 gen_helper_msa_dpsub_u_w(cpu_env, twd, tws, twt);
1590                 break;
1591             case DF_DOUBLE:
1592                 gen_helper_msa_dpsub_u_d(cpu_env, twd, tws, twt);
1593                 break;
1594             }
1595             break;
1596         }
1597         break;
1598     default:
1599         MIPS_INVAL("MSA instruction");
1600         gen_reserved_instruction(ctx);
1601         break;
1602     }
1603     tcg_temp_free_i32(twd);
1604     tcg_temp_free_i32(tws);
1605     tcg_temp_free_i32(twt);
1606     tcg_temp_free_i32(tdf);
1607 }
1608 
1609 static void gen_msa_elm_3e(DisasContext *ctx)
1610 {
1611 #define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
1612     uint8_t source = (ctx->opcode >> 11) & 0x1f;
1613     uint8_t dest = (ctx->opcode >> 6) & 0x1f;
1614     TCGv telm = tcg_temp_new();
1615     TCGv_i32 tsr = tcg_const_i32(source);
1616     TCGv_i32 tdt = tcg_const_i32(dest);
1617 
1618     switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
1619     case OPC_CTCMSA:
1620         gen_load_gpr(telm, source);
1621         gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
1622         break;
1623     case OPC_CFCMSA:
1624         gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
1625         gen_store_gpr(telm, dest);
1626         break;
1627     case OPC_MOVE_V:
1628         gen_helper_msa_move_v(cpu_env, tdt, tsr);
1629         break;
1630     default:
1631         MIPS_INVAL("MSA instruction");
1632         gen_reserved_instruction(ctx);
1633         break;
1634     }
1635 
1636     tcg_temp_free(telm);
1637     tcg_temp_free_i32(tdt);
1638     tcg_temp_free_i32(tsr);
1639 }
1640 
1641 static void gen_msa_elm_df(DisasContext *ctx, uint32_t df, uint32_t n)
1642 {
1643 #define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
1644     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
1645     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
1646 
1647     TCGv_i32 tws = tcg_const_i32(ws);
1648     TCGv_i32 twd = tcg_const_i32(wd);
1649     TCGv_i32 tn  = tcg_const_i32(n);
1650     TCGv_i32 tdf = tcg_constant_i32(df);
1651 
1652     switch (MASK_MSA_ELM(ctx->opcode)) {
1653     case OPC_SLDI_df:
1654         gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
1655         break;
1656     case OPC_SPLATI_df:
1657         gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
1658         break;
1659     case OPC_INSVE_df:
1660         gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
1661         break;
1662     case OPC_COPY_S_df:
1663     case OPC_COPY_U_df:
1664     case OPC_INSERT_df:
1665 #if !defined(TARGET_MIPS64)
1666         /* Double format valid only for MIPS64 */
1667         if (df == DF_DOUBLE) {
1668             gen_reserved_instruction(ctx);
1669             break;
1670         }
1671         if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) &&
1672               (df == DF_WORD)) {
1673             gen_reserved_instruction(ctx);
1674             break;
1675         }
1676 #endif
1677         switch (MASK_MSA_ELM(ctx->opcode)) {
1678         case OPC_COPY_S_df:
1679             if (likely(wd != 0)) {
1680                 switch (df) {
1681                 case DF_BYTE:
1682                     gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn);
1683                     break;
1684                 case DF_HALF:
1685                     gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn);
1686                     break;
1687                 case DF_WORD:
1688                     gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn);
1689                     break;
1690 #if defined(TARGET_MIPS64)
1691                 case DF_DOUBLE:
1692                     gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn);
1693                     break;
1694 #endif
1695                 default:
1696                     assert(0);
1697                 }
1698             }
1699             break;
1700         case OPC_COPY_U_df:
1701             if (likely(wd != 0)) {
1702                 switch (df) {
1703                 case DF_BYTE:
1704                     gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn);
1705                     break;
1706                 case DF_HALF:
1707                     gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn);
1708                     break;
1709 #if defined(TARGET_MIPS64)
1710                 case DF_WORD:
1711                     gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn);
1712                     break;
1713 #endif
1714                 default:
1715                     assert(0);
1716                 }
1717             }
1718             break;
1719         case OPC_INSERT_df:
1720             switch (df) {
1721             case DF_BYTE:
1722                 gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
1723                 break;
1724             case DF_HALF:
1725                 gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
1726                 break;
1727             case DF_WORD:
1728                 gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
1729                 break;
1730 #if defined(TARGET_MIPS64)
1731             case DF_DOUBLE:
1732                 gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
1733                 break;
1734 #endif
1735             default:
1736                 assert(0);
1737             }
1738             break;
1739         }
1740         break;
1741     default:
1742         MIPS_INVAL("MSA instruction");
1743         gen_reserved_instruction(ctx);
1744     }
1745     tcg_temp_free_i32(twd);
1746     tcg_temp_free_i32(tws);
1747     tcg_temp_free_i32(tn);
1748 }
1749 
1750 static void gen_msa_elm(DisasContext *ctx)
1751 {
1752     uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
1753     uint32_t df = 0, n = 0;
1754 
1755     if ((dfn & 0x30) == 0x00) {
1756         n = dfn & 0x0f;
1757         df = DF_BYTE;
1758     } else if ((dfn & 0x38) == 0x20) {
1759         n = dfn & 0x07;
1760         df = DF_HALF;
1761     } else if ((dfn & 0x3c) == 0x30) {
1762         n = dfn & 0x03;
1763         df = DF_WORD;
1764     } else if ((dfn & 0x3e) == 0x38) {
1765         n = dfn & 0x01;
1766         df = DF_DOUBLE;
1767     } else if (dfn == 0x3E) {
1768         /* CTCMSA, CFCMSA, MOVE.V */
1769         gen_msa_elm_3e(ctx);
1770         return;
1771     } else {
1772         gen_reserved_instruction(ctx);
1773         return;
1774     }
1775 
1776     gen_msa_elm_df(ctx, df, n);
1777 }
1778 
1779 static void gen_msa_3rf(DisasContext *ctx)
1780 {
1781 #define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
1782     uint8_t df = (ctx->opcode >> 21) & 0x1;
1783     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
1784     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
1785     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
1786 
1787     TCGv_i32 twd = tcg_const_i32(wd);
1788     TCGv_i32 tws = tcg_const_i32(ws);
1789     TCGv_i32 twt = tcg_const_i32(wt);
1790     TCGv_i32 tdf;
1791 
1792     /* adjust df value for floating-point instruction */
1793     switch (MASK_MSA_3RF(ctx->opcode)) {
1794     case OPC_MUL_Q_df:
1795     case OPC_MADD_Q_df:
1796     case OPC_MSUB_Q_df:
1797     case OPC_MULR_Q_df:
1798     case OPC_MADDR_Q_df:
1799     case OPC_MSUBR_Q_df:
1800         tdf = tcg_constant_i32(df + 1);
1801         break;
1802     default:
1803         tdf = tcg_constant_i32(df + 2);
1804         break;
1805     }
1806 
1807     switch (MASK_MSA_3RF(ctx->opcode)) {
1808     case OPC_FCAF_df:
1809         gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
1810         break;
1811     case OPC_FADD_df:
1812         gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
1813         break;
1814     case OPC_FCUN_df:
1815         gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
1816         break;
1817     case OPC_FSUB_df:
1818         gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
1819         break;
1820     case OPC_FCOR_df:
1821         gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
1822         break;
1823     case OPC_FCEQ_df:
1824         gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
1825         break;
1826     case OPC_FMUL_df:
1827         gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
1828         break;
1829     case OPC_FCUNE_df:
1830         gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
1831         break;
1832     case OPC_FCUEQ_df:
1833         gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
1834         break;
1835     case OPC_FDIV_df:
1836         gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
1837         break;
1838     case OPC_FCNE_df:
1839         gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
1840         break;
1841     case OPC_FCLT_df:
1842         gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
1843         break;
1844     case OPC_FMADD_df:
1845         gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
1846         break;
1847     case OPC_MUL_Q_df:
1848         gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
1849         break;
1850     case OPC_FCULT_df:
1851         gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
1852         break;
1853     case OPC_FMSUB_df:
1854         gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
1855         break;
1856     case OPC_MADD_Q_df:
1857         gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
1858         break;
1859     case OPC_FCLE_df:
1860         gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
1861         break;
1862     case OPC_MSUB_Q_df:
1863         gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
1864         break;
1865     case OPC_FCULE_df:
1866         gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
1867         break;
1868     case OPC_FEXP2_df:
1869         gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
1870         break;
1871     case OPC_FSAF_df:
1872         gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
1873         break;
1874     case OPC_FEXDO_df:
1875         gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
1876         break;
1877     case OPC_FSUN_df:
1878         gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
1879         break;
1880     case OPC_FSOR_df:
1881         gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
1882         break;
1883     case OPC_FSEQ_df:
1884         gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
1885         break;
1886     case OPC_FTQ_df:
1887         gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
1888         break;
1889     case OPC_FSUNE_df:
1890         gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
1891         break;
1892     case OPC_FSUEQ_df:
1893         gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
1894         break;
1895     case OPC_FSNE_df:
1896         gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
1897         break;
1898     case OPC_FSLT_df:
1899         gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
1900         break;
1901     case OPC_FMIN_df:
1902         gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
1903         break;
1904     case OPC_MULR_Q_df:
1905         gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
1906         break;
1907     case OPC_FSULT_df:
1908         gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
1909         break;
1910     case OPC_FMIN_A_df:
1911         gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
1912         break;
1913     case OPC_MADDR_Q_df:
1914         gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
1915         break;
1916     case OPC_FSLE_df:
1917         gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
1918         break;
1919     case OPC_FMAX_df:
1920         gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
1921         break;
1922     case OPC_MSUBR_Q_df:
1923         gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
1924         break;
1925     case OPC_FSULE_df:
1926         gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
1927         break;
1928     case OPC_FMAX_A_df:
1929         gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
1930         break;
1931     default:
1932         MIPS_INVAL("MSA instruction");
1933         gen_reserved_instruction(ctx);
1934         break;
1935     }
1936 
1937     tcg_temp_free_i32(twd);
1938     tcg_temp_free_i32(tws);
1939     tcg_temp_free_i32(twt);
1940 }
1941 
1942 static void gen_msa_2r(DisasContext *ctx)
1943 {
1944 #define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
1945                             (op & (0x7 << 18)))
1946     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
1947     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
1948     uint8_t df = (ctx->opcode >> 16) & 0x3;
1949     TCGv_i32 twd = tcg_const_i32(wd);
1950     TCGv_i32 tws = tcg_const_i32(ws);
1951 
1952     switch (MASK_MSA_2R(ctx->opcode)) {
1953     case OPC_FILL_df:
1954 #if !defined(TARGET_MIPS64)
1955         /* Double format valid only for MIPS64 */
1956         if (df == DF_DOUBLE) {
1957             gen_reserved_instruction(ctx);
1958             break;
1959         }
1960 #endif
1961         gen_helper_msa_fill_df(cpu_env, tcg_constant_i32(df),
1962                                twd, tws); /* trs */
1963         break;
1964     case OPC_NLOC_df:
1965         switch (df) {
1966         case DF_BYTE:
1967             gen_helper_msa_nloc_b(cpu_env, twd, tws);
1968             break;
1969         case DF_HALF:
1970             gen_helper_msa_nloc_h(cpu_env, twd, tws);
1971             break;
1972         case DF_WORD:
1973             gen_helper_msa_nloc_w(cpu_env, twd, tws);
1974             break;
1975         case DF_DOUBLE:
1976             gen_helper_msa_nloc_d(cpu_env, twd, tws);
1977             break;
1978         }
1979         break;
1980     case OPC_NLZC_df:
1981         switch (df) {
1982         case DF_BYTE:
1983             gen_helper_msa_nlzc_b(cpu_env, twd, tws);
1984             break;
1985         case DF_HALF:
1986             gen_helper_msa_nlzc_h(cpu_env, twd, tws);
1987             break;
1988         case DF_WORD:
1989             gen_helper_msa_nlzc_w(cpu_env, twd, tws);
1990             break;
1991         case DF_DOUBLE:
1992             gen_helper_msa_nlzc_d(cpu_env, twd, tws);
1993             break;
1994         }
1995         break;
1996     case OPC_PCNT_df:
1997         switch (df) {
1998         case DF_BYTE:
1999             gen_helper_msa_pcnt_b(cpu_env, twd, tws);
2000             break;
2001         case DF_HALF:
2002             gen_helper_msa_pcnt_h(cpu_env, twd, tws);
2003             break;
2004         case DF_WORD:
2005             gen_helper_msa_pcnt_w(cpu_env, twd, tws);
2006             break;
2007         case DF_DOUBLE:
2008             gen_helper_msa_pcnt_d(cpu_env, twd, tws);
2009             break;
2010         }
2011         break;
2012     default:
2013         MIPS_INVAL("MSA instruction");
2014         gen_reserved_instruction(ctx);
2015         break;
2016     }
2017 
2018     tcg_temp_free_i32(twd);
2019     tcg_temp_free_i32(tws);
2020 }
2021 
2022 static void gen_msa_2rf(DisasContext *ctx)
2023 {
2024 #define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
2025                             (op & (0xf << 17)))
2026     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
2027     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
2028     uint8_t df = (ctx->opcode >> 16) & 0x1;
2029     TCGv_i32 twd = tcg_const_i32(wd);
2030     TCGv_i32 tws = tcg_const_i32(ws);
2031     /* adjust df value for floating-point instruction */
2032     TCGv_i32 tdf = tcg_constant_i32(df + 2);
2033 
2034     switch (MASK_MSA_2RF(ctx->opcode)) {
2035     case OPC_FCLASS_df:
2036         gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
2037         break;
2038     case OPC_FTRUNC_S_df:
2039         gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
2040         break;
2041     case OPC_FTRUNC_U_df:
2042         gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
2043         break;
2044     case OPC_FSQRT_df:
2045         gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
2046         break;
2047     case OPC_FRSQRT_df:
2048         gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
2049         break;
2050     case OPC_FRCP_df:
2051         gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
2052         break;
2053     case OPC_FRINT_df:
2054         gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
2055         break;
2056     case OPC_FLOG2_df:
2057         gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
2058         break;
2059     case OPC_FEXUPL_df:
2060         gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
2061         break;
2062     case OPC_FEXUPR_df:
2063         gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
2064         break;
2065     case OPC_FFQL_df:
2066         gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
2067         break;
2068     case OPC_FFQR_df:
2069         gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
2070         break;
2071     case OPC_FTINT_S_df:
2072         gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
2073         break;
2074     case OPC_FTINT_U_df:
2075         gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
2076         break;
2077     case OPC_FFINT_S_df:
2078         gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
2079         break;
2080     case OPC_FFINT_U_df:
2081         gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
2082         break;
2083     }
2084 
2085     tcg_temp_free_i32(twd);
2086     tcg_temp_free_i32(tws);
2087 }
2088 
2089 static void gen_msa_vec_v(DisasContext *ctx)
2090 {
2091 #define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
2092     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
2093     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
2094     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
2095     TCGv_i32 twd = tcg_const_i32(wd);
2096     TCGv_i32 tws = tcg_const_i32(ws);
2097     TCGv_i32 twt = tcg_const_i32(wt);
2098 
2099     switch (MASK_MSA_VEC(ctx->opcode)) {
2100     case OPC_AND_V:
2101         gen_helper_msa_and_v(cpu_env, twd, tws, twt);
2102         break;
2103     case OPC_OR_V:
2104         gen_helper_msa_or_v(cpu_env, twd, tws, twt);
2105         break;
2106     case OPC_NOR_V:
2107         gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
2108         break;
2109     case OPC_XOR_V:
2110         gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
2111         break;
2112     case OPC_BMNZ_V:
2113         gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
2114         break;
2115     case OPC_BMZ_V:
2116         gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
2117         break;
2118     case OPC_BSEL_V:
2119         gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
2120         break;
2121     default:
2122         MIPS_INVAL("MSA instruction");
2123         gen_reserved_instruction(ctx);
2124         break;
2125     }
2126 
2127     tcg_temp_free_i32(twd);
2128     tcg_temp_free_i32(tws);
2129     tcg_temp_free_i32(twt);
2130 }
2131 
2132 static void gen_msa_vec(DisasContext *ctx)
2133 {
2134     switch (MASK_MSA_VEC(ctx->opcode)) {
2135     case OPC_AND_V:
2136     case OPC_OR_V:
2137     case OPC_NOR_V:
2138     case OPC_XOR_V:
2139     case OPC_BMNZ_V:
2140     case OPC_BMZ_V:
2141     case OPC_BSEL_V:
2142         gen_msa_vec_v(ctx);
2143         break;
2144     case OPC_MSA_2R:
2145         gen_msa_2r(ctx);
2146         break;
2147     case OPC_MSA_2RF:
2148         gen_msa_2rf(ctx);
2149         break;
2150     default:
2151         MIPS_INVAL("MSA instruction");
2152         gen_reserved_instruction(ctx);
2153         break;
2154     }
2155 }
2156 
2157 static bool trans_MSA(DisasContext *ctx, arg_MSA *a)
2158 {
2159     uint32_t opcode = ctx->opcode;
2160 
2161     check_msa_access(ctx);
2162 
2163     switch (MASK_MSA_MINOR(opcode)) {
2164     case OPC_MSA_I8_00:
2165     case OPC_MSA_I8_01:
2166     case OPC_MSA_I8_02:
2167         gen_msa_i8(ctx);
2168         break;
2169     case OPC_MSA_I5_06:
2170     case OPC_MSA_I5_07:
2171         gen_msa_i5(ctx);
2172         break;
2173     case OPC_MSA_BIT_09:
2174     case OPC_MSA_BIT_0A:
2175         gen_msa_bit(ctx);
2176         break;
2177     case OPC_MSA_3R_0D:
2178     case OPC_MSA_3R_0E:
2179     case OPC_MSA_3R_0F:
2180     case OPC_MSA_3R_10:
2181     case OPC_MSA_3R_11:
2182     case OPC_MSA_3R_12:
2183     case OPC_MSA_3R_13:
2184     case OPC_MSA_3R_14:
2185     case OPC_MSA_3R_15:
2186         gen_msa_3r(ctx);
2187         break;
2188     case OPC_MSA_ELM:
2189         gen_msa_elm(ctx);
2190         break;
2191     case OPC_MSA_3RF_1A:
2192     case OPC_MSA_3RF_1B:
2193     case OPC_MSA_3RF_1C:
2194         gen_msa_3rf(ctx);
2195         break;
2196     case OPC_MSA_VEC:
2197         gen_msa_vec(ctx);
2198         break;
2199     case OPC_LD_B:
2200     case OPC_LD_H:
2201     case OPC_LD_W:
2202     case OPC_LD_D:
2203     case OPC_ST_B:
2204     case OPC_ST_H:
2205     case OPC_ST_W:
2206     case OPC_ST_D:
2207         {
2208             int32_t s10 = sextract32(ctx->opcode, 16, 10);
2209             uint8_t rs = (ctx->opcode >> 11) & 0x1f;
2210             uint8_t wd = (ctx->opcode >> 6) & 0x1f;
2211             uint8_t df = (ctx->opcode >> 0) & 0x3;
2212 
2213             TCGv_i32 twd = tcg_const_i32(wd);
2214             TCGv taddr = tcg_temp_new();
2215             gen_base_offset_addr(ctx, taddr, rs, s10 << df);
2216 
2217             switch (MASK_MSA_MINOR(opcode)) {
2218             case OPC_LD_B:
2219                 gen_helper_msa_ld_b(cpu_env, twd, taddr);
2220                 break;
2221             case OPC_LD_H:
2222                 gen_helper_msa_ld_h(cpu_env, twd, taddr);
2223                 break;
2224             case OPC_LD_W:
2225                 gen_helper_msa_ld_w(cpu_env, twd, taddr);
2226                 break;
2227             case OPC_LD_D:
2228                 gen_helper_msa_ld_d(cpu_env, twd, taddr);
2229                 break;
2230             case OPC_ST_B:
2231                 gen_helper_msa_st_b(cpu_env, twd, taddr);
2232                 break;
2233             case OPC_ST_H:
2234                 gen_helper_msa_st_h(cpu_env, twd, taddr);
2235                 break;
2236             case OPC_ST_W:
2237                 gen_helper_msa_st_w(cpu_env, twd, taddr);
2238                 break;
2239             case OPC_ST_D:
2240                 gen_helper_msa_st_d(cpu_env, twd, taddr);
2241                 break;
2242             }
2243 
2244             tcg_temp_free_i32(twd);
2245             tcg_temp_free(taddr);
2246         }
2247         break;
2248     default:
2249         MIPS_INVAL("MSA instruction");
2250         gen_reserved_instruction(ctx);
2251         break;
2252     }
2253 
2254     return true;
2255 }
2256 
2257 static bool trans_LSA(DisasContext *ctx, arg_r *a)
2258 {
2259     return gen_lsa(ctx, a->rd, a->rt, a->rs, a->sa);
2260 }
2261 
2262 static bool trans_DLSA(DisasContext *ctx, arg_r *a)
2263 {
2264     if (TARGET_LONG_BITS != 64) {
2265         return false;
2266     }
2267     return gen_dlsa(ctx, a->rd, a->rt, a->rs, a->sa);
2268 }
2269