xref: /openbmc/qemu/target/mips/tcg/msa_translate.c (revision 30b6852c)
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     uint8_t df = (ctx->opcode >> 21) & 0x3;
477     int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
478     uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
479     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
480     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
481 
482     TCGv_i32 tdf = tcg_const_i32(df);
483     TCGv_i32 twd = tcg_const_i32(wd);
484     TCGv_i32 tws = tcg_const_i32(ws);
485     TCGv_i32 timm = tcg_temp_new_i32();
486     tcg_gen_movi_i32(timm, u5);
487 
488     switch (MASK_MSA_I5(ctx->opcode)) {
489     case OPC_ADDVI_df:
490         gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
491         break;
492     case OPC_SUBVI_df:
493         gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
494         break;
495     case OPC_MAXI_S_df:
496         tcg_gen_movi_i32(timm, s5);
497         gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
498         break;
499     case OPC_MAXI_U_df:
500         gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
501         break;
502     case OPC_MINI_S_df:
503         tcg_gen_movi_i32(timm, s5);
504         gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
505         break;
506     case OPC_MINI_U_df:
507         gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
508         break;
509     case OPC_CEQI_df:
510         tcg_gen_movi_i32(timm, s5);
511         gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
512         break;
513     case OPC_CLTI_S_df:
514         tcg_gen_movi_i32(timm, s5);
515         gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
516         break;
517     case OPC_CLTI_U_df:
518         gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
519         break;
520     case OPC_CLEI_S_df:
521         tcg_gen_movi_i32(timm, s5);
522         gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
523         break;
524     case OPC_CLEI_U_df:
525         gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
526         break;
527     case OPC_LDI_df:
528         {
529             int32_t s10 = sextract32(ctx->opcode, 11, 10);
530             tcg_gen_movi_i32(timm, s10);
531             gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
532         }
533         break;
534     default:
535         MIPS_INVAL("MSA instruction");
536         gen_reserved_instruction(ctx);
537         break;
538     }
539 
540     tcg_temp_free_i32(tdf);
541     tcg_temp_free_i32(twd);
542     tcg_temp_free_i32(tws);
543     tcg_temp_free_i32(timm);
544 }
545 
546 static void gen_msa_bit(DisasContext *ctx)
547 {
548 #define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
549     uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
550     uint32_t df = 0, m = 0;
551     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
552     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
553 
554     TCGv_i32 tdf;
555     TCGv_i32 tm;
556     TCGv_i32 twd;
557     TCGv_i32 tws;
558 
559     if ((dfm & 0x40) == 0x00) {
560         m = dfm & 0x3f;
561         df = DF_DOUBLE;
562     } else if ((dfm & 0x60) == 0x40) {
563         m = dfm & 0x1f;
564         df = DF_WORD;
565     } else if ((dfm & 0x70) == 0x60) {
566         m = dfm & 0x0f;
567         df = DF_HALF;
568     } else if ((dfm & 0x78) == 0x70) {
569         m = dfm & 0x7;
570         df = DF_BYTE;
571     } else {
572         gen_reserved_instruction(ctx);
573         return;
574     }
575 
576     tdf = tcg_const_i32(df);
577     tm  = tcg_const_i32(m);
578     twd = tcg_const_i32(wd);
579     tws = tcg_const_i32(ws);
580 
581     switch (MASK_MSA_BIT(ctx->opcode)) {
582     case OPC_SLLI_df:
583         gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
584         break;
585     case OPC_SRAI_df:
586         gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
587         break;
588     case OPC_SRLI_df:
589         gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
590         break;
591     case OPC_BCLRI_df:
592         gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
593         break;
594     case OPC_BSETI_df:
595         gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
596         break;
597     case OPC_BNEGI_df:
598         gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
599         break;
600     case OPC_BINSLI_df:
601         gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
602         break;
603     case OPC_BINSRI_df:
604         gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
605         break;
606     case OPC_SAT_S_df:
607         gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
608         break;
609     case OPC_SAT_U_df:
610         gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
611         break;
612     case OPC_SRARI_df:
613         gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
614         break;
615     case OPC_SRLRI_df:
616         gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
617         break;
618     default:
619         MIPS_INVAL("MSA instruction");
620         gen_reserved_instruction(ctx);
621         break;
622     }
623 
624     tcg_temp_free_i32(tdf);
625     tcg_temp_free_i32(tm);
626     tcg_temp_free_i32(twd);
627     tcg_temp_free_i32(tws);
628 }
629 
630 static void gen_msa_3r(DisasContext *ctx)
631 {
632 #define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
633     uint8_t df = (ctx->opcode >> 21) & 0x3;
634     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
635     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
636     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
637 
638     TCGv_i32 tdf = tcg_const_i32(df);
639     TCGv_i32 twd = tcg_const_i32(wd);
640     TCGv_i32 tws = tcg_const_i32(ws);
641     TCGv_i32 twt = tcg_const_i32(wt);
642 
643     switch (MASK_MSA_3R(ctx->opcode)) {
644     case OPC_BINSL_df:
645         switch (df) {
646         case DF_BYTE:
647             gen_helper_msa_binsl_b(cpu_env, twd, tws, twt);
648             break;
649         case DF_HALF:
650             gen_helper_msa_binsl_h(cpu_env, twd, tws, twt);
651             break;
652         case DF_WORD:
653             gen_helper_msa_binsl_w(cpu_env, twd, tws, twt);
654             break;
655         case DF_DOUBLE:
656             gen_helper_msa_binsl_d(cpu_env, twd, tws, twt);
657             break;
658         }
659         break;
660     case OPC_BINSR_df:
661         switch (df) {
662         case DF_BYTE:
663             gen_helper_msa_binsr_b(cpu_env, twd, tws, twt);
664             break;
665         case DF_HALF:
666             gen_helper_msa_binsr_h(cpu_env, twd, tws, twt);
667             break;
668         case DF_WORD:
669             gen_helper_msa_binsr_w(cpu_env, twd, tws, twt);
670             break;
671         case DF_DOUBLE:
672             gen_helper_msa_binsr_d(cpu_env, twd, tws, twt);
673             break;
674         }
675         break;
676     case OPC_BCLR_df:
677         switch (df) {
678         case DF_BYTE:
679             gen_helper_msa_bclr_b(cpu_env, twd, tws, twt);
680             break;
681         case DF_HALF:
682             gen_helper_msa_bclr_h(cpu_env, twd, tws, twt);
683             break;
684         case DF_WORD:
685             gen_helper_msa_bclr_w(cpu_env, twd, tws, twt);
686             break;
687         case DF_DOUBLE:
688             gen_helper_msa_bclr_d(cpu_env, twd, tws, twt);
689             break;
690         }
691         break;
692     case OPC_BNEG_df:
693         switch (df) {
694         case DF_BYTE:
695             gen_helper_msa_bneg_b(cpu_env, twd, tws, twt);
696             break;
697         case DF_HALF:
698             gen_helper_msa_bneg_h(cpu_env, twd, tws, twt);
699             break;
700         case DF_WORD:
701             gen_helper_msa_bneg_w(cpu_env, twd, tws, twt);
702             break;
703         case DF_DOUBLE:
704             gen_helper_msa_bneg_d(cpu_env, twd, tws, twt);
705             break;
706         }
707         break;
708     case OPC_BSET_df:
709         switch (df) {
710         case DF_BYTE:
711             gen_helper_msa_bset_b(cpu_env, twd, tws, twt);
712             break;
713         case DF_HALF:
714             gen_helper_msa_bset_h(cpu_env, twd, tws, twt);
715             break;
716         case DF_WORD:
717             gen_helper_msa_bset_w(cpu_env, twd, tws, twt);
718             break;
719         case DF_DOUBLE:
720             gen_helper_msa_bset_d(cpu_env, twd, tws, twt);
721             break;
722         }
723         break;
724     case OPC_ADD_A_df:
725         switch (df) {
726         case DF_BYTE:
727             gen_helper_msa_add_a_b(cpu_env, twd, tws, twt);
728             break;
729         case DF_HALF:
730             gen_helper_msa_add_a_h(cpu_env, twd, tws, twt);
731             break;
732         case DF_WORD:
733             gen_helper_msa_add_a_w(cpu_env, twd, tws, twt);
734             break;
735         case DF_DOUBLE:
736             gen_helper_msa_add_a_d(cpu_env, twd, tws, twt);
737             break;
738         }
739         break;
740     case OPC_ADDS_A_df:
741         switch (df) {
742         case DF_BYTE:
743             gen_helper_msa_adds_a_b(cpu_env, twd, tws, twt);
744             break;
745         case DF_HALF:
746             gen_helper_msa_adds_a_h(cpu_env, twd, tws, twt);
747             break;
748         case DF_WORD:
749             gen_helper_msa_adds_a_w(cpu_env, twd, tws, twt);
750             break;
751         case DF_DOUBLE:
752             gen_helper_msa_adds_a_d(cpu_env, twd, tws, twt);
753             break;
754         }
755         break;
756     case OPC_ADDS_S_df:
757         switch (df) {
758         case DF_BYTE:
759             gen_helper_msa_adds_s_b(cpu_env, twd, tws, twt);
760             break;
761         case DF_HALF:
762             gen_helper_msa_adds_s_h(cpu_env, twd, tws, twt);
763             break;
764         case DF_WORD:
765             gen_helper_msa_adds_s_w(cpu_env, twd, tws, twt);
766             break;
767         case DF_DOUBLE:
768             gen_helper_msa_adds_s_d(cpu_env, twd, tws, twt);
769             break;
770         }
771         break;
772     case OPC_ADDS_U_df:
773         switch (df) {
774         case DF_BYTE:
775             gen_helper_msa_adds_u_b(cpu_env, twd, tws, twt);
776             break;
777         case DF_HALF:
778             gen_helper_msa_adds_u_h(cpu_env, twd, tws, twt);
779             break;
780         case DF_WORD:
781             gen_helper_msa_adds_u_w(cpu_env, twd, tws, twt);
782             break;
783         case DF_DOUBLE:
784             gen_helper_msa_adds_u_d(cpu_env, twd, tws, twt);
785             break;
786         }
787         break;
788     case OPC_ADDV_df:
789         switch (df) {
790         case DF_BYTE:
791             gen_helper_msa_addv_b(cpu_env, twd, tws, twt);
792             break;
793         case DF_HALF:
794             gen_helper_msa_addv_h(cpu_env, twd, tws, twt);
795             break;
796         case DF_WORD:
797             gen_helper_msa_addv_w(cpu_env, twd, tws, twt);
798             break;
799         case DF_DOUBLE:
800             gen_helper_msa_addv_d(cpu_env, twd, tws, twt);
801             break;
802         }
803         break;
804     case OPC_AVE_S_df:
805         switch (df) {
806         case DF_BYTE:
807             gen_helper_msa_ave_s_b(cpu_env, twd, tws, twt);
808             break;
809         case DF_HALF:
810             gen_helper_msa_ave_s_h(cpu_env, twd, tws, twt);
811             break;
812         case DF_WORD:
813             gen_helper_msa_ave_s_w(cpu_env, twd, tws, twt);
814             break;
815         case DF_DOUBLE:
816             gen_helper_msa_ave_s_d(cpu_env, twd, tws, twt);
817             break;
818         }
819         break;
820     case OPC_AVE_U_df:
821         switch (df) {
822         case DF_BYTE:
823             gen_helper_msa_ave_u_b(cpu_env, twd, tws, twt);
824             break;
825         case DF_HALF:
826             gen_helper_msa_ave_u_h(cpu_env, twd, tws, twt);
827             break;
828         case DF_WORD:
829             gen_helper_msa_ave_u_w(cpu_env, twd, tws, twt);
830             break;
831         case DF_DOUBLE:
832             gen_helper_msa_ave_u_d(cpu_env, twd, tws, twt);
833             break;
834         }
835         break;
836     case OPC_AVER_S_df:
837         switch (df) {
838         case DF_BYTE:
839             gen_helper_msa_aver_s_b(cpu_env, twd, tws, twt);
840             break;
841         case DF_HALF:
842             gen_helper_msa_aver_s_h(cpu_env, twd, tws, twt);
843             break;
844         case DF_WORD:
845             gen_helper_msa_aver_s_w(cpu_env, twd, tws, twt);
846             break;
847         case DF_DOUBLE:
848             gen_helper_msa_aver_s_d(cpu_env, twd, tws, twt);
849             break;
850         }
851         break;
852     case OPC_AVER_U_df:
853         switch (df) {
854         case DF_BYTE:
855             gen_helper_msa_aver_u_b(cpu_env, twd, tws, twt);
856             break;
857         case DF_HALF:
858             gen_helper_msa_aver_u_h(cpu_env, twd, tws, twt);
859             break;
860         case DF_WORD:
861             gen_helper_msa_aver_u_w(cpu_env, twd, tws, twt);
862             break;
863         case DF_DOUBLE:
864             gen_helper_msa_aver_u_d(cpu_env, twd, tws, twt);
865             break;
866         }
867         break;
868     case OPC_CEQ_df:
869         switch (df) {
870         case DF_BYTE:
871             gen_helper_msa_ceq_b(cpu_env, twd, tws, twt);
872             break;
873         case DF_HALF:
874             gen_helper_msa_ceq_h(cpu_env, twd, tws, twt);
875             break;
876         case DF_WORD:
877             gen_helper_msa_ceq_w(cpu_env, twd, tws, twt);
878             break;
879         case DF_DOUBLE:
880             gen_helper_msa_ceq_d(cpu_env, twd, tws, twt);
881             break;
882         }
883         break;
884     case OPC_CLE_S_df:
885         switch (df) {
886         case DF_BYTE:
887             gen_helper_msa_cle_s_b(cpu_env, twd, tws, twt);
888             break;
889         case DF_HALF:
890             gen_helper_msa_cle_s_h(cpu_env, twd, tws, twt);
891             break;
892         case DF_WORD:
893             gen_helper_msa_cle_s_w(cpu_env, twd, tws, twt);
894             break;
895         case DF_DOUBLE:
896             gen_helper_msa_cle_s_d(cpu_env, twd, tws, twt);
897             break;
898         }
899         break;
900     case OPC_CLE_U_df:
901         switch (df) {
902         case DF_BYTE:
903             gen_helper_msa_cle_u_b(cpu_env, twd, tws, twt);
904             break;
905         case DF_HALF:
906             gen_helper_msa_cle_u_h(cpu_env, twd, tws, twt);
907             break;
908         case DF_WORD:
909             gen_helper_msa_cle_u_w(cpu_env, twd, tws, twt);
910             break;
911         case DF_DOUBLE:
912             gen_helper_msa_cle_u_d(cpu_env, twd, tws, twt);
913             break;
914         }
915         break;
916     case OPC_CLT_S_df:
917         switch (df) {
918         case DF_BYTE:
919             gen_helper_msa_clt_s_b(cpu_env, twd, tws, twt);
920             break;
921         case DF_HALF:
922             gen_helper_msa_clt_s_h(cpu_env, twd, tws, twt);
923             break;
924         case DF_WORD:
925             gen_helper_msa_clt_s_w(cpu_env, twd, tws, twt);
926             break;
927         case DF_DOUBLE:
928             gen_helper_msa_clt_s_d(cpu_env, twd, tws, twt);
929             break;
930         }
931         break;
932     case OPC_CLT_U_df:
933         switch (df) {
934         case DF_BYTE:
935             gen_helper_msa_clt_u_b(cpu_env, twd, tws, twt);
936             break;
937         case DF_HALF:
938             gen_helper_msa_clt_u_h(cpu_env, twd, tws, twt);
939             break;
940         case DF_WORD:
941             gen_helper_msa_clt_u_w(cpu_env, twd, tws, twt);
942             break;
943         case DF_DOUBLE:
944             gen_helper_msa_clt_u_d(cpu_env, twd, tws, twt);
945             break;
946         }
947         break;
948     case OPC_DIV_S_df:
949         switch (df) {
950         case DF_BYTE:
951             gen_helper_msa_div_s_b(cpu_env, twd, tws, twt);
952             break;
953         case DF_HALF:
954             gen_helper_msa_div_s_h(cpu_env, twd, tws, twt);
955             break;
956         case DF_WORD:
957             gen_helper_msa_div_s_w(cpu_env, twd, tws, twt);
958             break;
959         case DF_DOUBLE:
960             gen_helper_msa_div_s_d(cpu_env, twd, tws, twt);
961             break;
962         }
963         break;
964     case OPC_DIV_U_df:
965         switch (df) {
966         case DF_BYTE:
967             gen_helper_msa_div_u_b(cpu_env, twd, tws, twt);
968             break;
969         case DF_HALF:
970             gen_helper_msa_div_u_h(cpu_env, twd, tws, twt);
971             break;
972         case DF_WORD:
973             gen_helper_msa_div_u_w(cpu_env, twd, tws, twt);
974             break;
975         case DF_DOUBLE:
976             gen_helper_msa_div_u_d(cpu_env, twd, tws, twt);
977             break;
978         }
979         break;
980     case OPC_MAX_A_df:
981         switch (df) {
982         case DF_BYTE:
983             gen_helper_msa_max_a_b(cpu_env, twd, tws, twt);
984             break;
985         case DF_HALF:
986             gen_helper_msa_max_a_h(cpu_env, twd, tws, twt);
987             break;
988         case DF_WORD:
989             gen_helper_msa_max_a_w(cpu_env, twd, tws, twt);
990             break;
991         case DF_DOUBLE:
992             gen_helper_msa_max_a_d(cpu_env, twd, tws, twt);
993             break;
994         }
995         break;
996     case OPC_MAX_S_df:
997         switch (df) {
998         case DF_BYTE:
999             gen_helper_msa_max_s_b(cpu_env, twd, tws, twt);
1000             break;
1001         case DF_HALF:
1002             gen_helper_msa_max_s_h(cpu_env, twd, tws, twt);
1003             break;
1004         case DF_WORD:
1005             gen_helper_msa_max_s_w(cpu_env, twd, tws, twt);
1006             break;
1007         case DF_DOUBLE:
1008             gen_helper_msa_max_s_d(cpu_env, twd, tws, twt);
1009             break;
1010         }
1011         break;
1012     case OPC_MAX_U_df:
1013         switch (df) {
1014         case DF_BYTE:
1015             gen_helper_msa_max_u_b(cpu_env, twd, tws, twt);
1016             break;
1017         case DF_HALF:
1018             gen_helper_msa_max_u_h(cpu_env, twd, tws, twt);
1019             break;
1020         case DF_WORD:
1021             gen_helper_msa_max_u_w(cpu_env, twd, tws, twt);
1022             break;
1023         case DF_DOUBLE:
1024             gen_helper_msa_max_u_d(cpu_env, twd, tws, twt);
1025             break;
1026         }
1027         break;
1028     case OPC_MIN_A_df:
1029         switch (df) {
1030         case DF_BYTE:
1031             gen_helper_msa_min_a_b(cpu_env, twd, tws, twt);
1032             break;
1033         case DF_HALF:
1034             gen_helper_msa_min_a_h(cpu_env, twd, tws, twt);
1035             break;
1036         case DF_WORD:
1037             gen_helper_msa_min_a_w(cpu_env, twd, tws, twt);
1038             break;
1039         case DF_DOUBLE:
1040             gen_helper_msa_min_a_d(cpu_env, twd, tws, twt);
1041             break;
1042         }
1043         break;
1044     case OPC_MIN_S_df:
1045         switch (df) {
1046         case DF_BYTE:
1047             gen_helper_msa_min_s_b(cpu_env, twd, tws, twt);
1048             break;
1049         case DF_HALF:
1050             gen_helper_msa_min_s_h(cpu_env, twd, tws, twt);
1051             break;
1052         case DF_WORD:
1053             gen_helper_msa_min_s_w(cpu_env, twd, tws, twt);
1054             break;
1055         case DF_DOUBLE:
1056             gen_helper_msa_min_s_d(cpu_env, twd, tws, twt);
1057             break;
1058         }
1059         break;
1060     case OPC_MIN_U_df:
1061         switch (df) {
1062         case DF_BYTE:
1063             gen_helper_msa_min_u_b(cpu_env, twd, tws, twt);
1064             break;
1065         case DF_HALF:
1066             gen_helper_msa_min_u_h(cpu_env, twd, tws, twt);
1067             break;
1068         case DF_WORD:
1069             gen_helper_msa_min_u_w(cpu_env, twd, tws, twt);
1070             break;
1071         case DF_DOUBLE:
1072             gen_helper_msa_min_u_d(cpu_env, twd, tws, twt);
1073             break;
1074         }
1075         break;
1076     case OPC_MOD_S_df:
1077         switch (df) {
1078         case DF_BYTE:
1079             gen_helper_msa_mod_s_b(cpu_env, twd, tws, twt);
1080             break;
1081         case DF_HALF:
1082             gen_helper_msa_mod_s_h(cpu_env, twd, tws, twt);
1083             break;
1084         case DF_WORD:
1085             gen_helper_msa_mod_s_w(cpu_env, twd, tws, twt);
1086             break;
1087         case DF_DOUBLE:
1088             gen_helper_msa_mod_s_d(cpu_env, twd, tws, twt);
1089             break;
1090         }
1091         break;
1092     case OPC_MOD_U_df:
1093         switch (df) {
1094         case DF_BYTE:
1095             gen_helper_msa_mod_u_b(cpu_env, twd, tws, twt);
1096             break;
1097         case DF_HALF:
1098             gen_helper_msa_mod_u_h(cpu_env, twd, tws, twt);
1099             break;
1100         case DF_WORD:
1101             gen_helper_msa_mod_u_w(cpu_env, twd, tws, twt);
1102             break;
1103         case DF_DOUBLE:
1104             gen_helper_msa_mod_u_d(cpu_env, twd, tws, twt);
1105             break;
1106         }
1107         break;
1108     case OPC_MADDV_df:
1109         switch (df) {
1110         case DF_BYTE:
1111             gen_helper_msa_maddv_b(cpu_env, twd, tws, twt);
1112             break;
1113         case DF_HALF:
1114             gen_helper_msa_maddv_h(cpu_env, twd, tws, twt);
1115             break;
1116         case DF_WORD:
1117             gen_helper_msa_maddv_w(cpu_env, twd, tws, twt);
1118             break;
1119         case DF_DOUBLE:
1120             gen_helper_msa_maddv_d(cpu_env, twd, tws, twt);
1121             break;
1122         }
1123         break;
1124     case OPC_MSUBV_df:
1125         switch (df) {
1126         case DF_BYTE:
1127             gen_helper_msa_msubv_b(cpu_env, twd, tws, twt);
1128             break;
1129         case DF_HALF:
1130             gen_helper_msa_msubv_h(cpu_env, twd, tws, twt);
1131             break;
1132         case DF_WORD:
1133             gen_helper_msa_msubv_w(cpu_env, twd, tws, twt);
1134             break;
1135         case DF_DOUBLE:
1136             gen_helper_msa_msubv_d(cpu_env, twd, tws, twt);
1137             break;
1138         }
1139         break;
1140     case OPC_ASUB_S_df:
1141         switch (df) {
1142         case DF_BYTE:
1143             gen_helper_msa_asub_s_b(cpu_env, twd, tws, twt);
1144             break;
1145         case DF_HALF:
1146             gen_helper_msa_asub_s_h(cpu_env, twd, tws, twt);
1147             break;
1148         case DF_WORD:
1149             gen_helper_msa_asub_s_w(cpu_env, twd, tws, twt);
1150             break;
1151         case DF_DOUBLE:
1152             gen_helper_msa_asub_s_d(cpu_env, twd, tws, twt);
1153             break;
1154         }
1155         break;
1156     case OPC_ASUB_U_df:
1157         switch (df) {
1158         case DF_BYTE:
1159             gen_helper_msa_asub_u_b(cpu_env, twd, tws, twt);
1160             break;
1161         case DF_HALF:
1162             gen_helper_msa_asub_u_h(cpu_env, twd, tws, twt);
1163             break;
1164         case DF_WORD:
1165             gen_helper_msa_asub_u_w(cpu_env, twd, tws, twt);
1166             break;
1167         case DF_DOUBLE:
1168             gen_helper_msa_asub_u_d(cpu_env, twd, tws, twt);
1169             break;
1170         }
1171         break;
1172     case OPC_ILVEV_df:
1173         switch (df) {
1174         case DF_BYTE:
1175             gen_helper_msa_ilvev_b(cpu_env, twd, tws, twt);
1176             break;
1177         case DF_HALF:
1178             gen_helper_msa_ilvev_h(cpu_env, twd, tws, twt);
1179             break;
1180         case DF_WORD:
1181             gen_helper_msa_ilvev_w(cpu_env, twd, tws, twt);
1182             break;
1183         case DF_DOUBLE:
1184             gen_helper_msa_ilvev_d(cpu_env, twd, tws, twt);
1185             break;
1186         }
1187         break;
1188     case OPC_ILVOD_df:
1189         switch (df) {
1190         case DF_BYTE:
1191             gen_helper_msa_ilvod_b(cpu_env, twd, tws, twt);
1192             break;
1193         case DF_HALF:
1194             gen_helper_msa_ilvod_h(cpu_env, twd, tws, twt);
1195             break;
1196         case DF_WORD:
1197             gen_helper_msa_ilvod_w(cpu_env, twd, tws, twt);
1198             break;
1199         case DF_DOUBLE:
1200             gen_helper_msa_ilvod_d(cpu_env, twd, tws, twt);
1201             break;
1202         }
1203         break;
1204     case OPC_ILVL_df:
1205         switch (df) {
1206         case DF_BYTE:
1207             gen_helper_msa_ilvl_b(cpu_env, twd, tws, twt);
1208             break;
1209         case DF_HALF:
1210             gen_helper_msa_ilvl_h(cpu_env, twd, tws, twt);
1211             break;
1212         case DF_WORD:
1213             gen_helper_msa_ilvl_w(cpu_env, twd, tws, twt);
1214             break;
1215         case DF_DOUBLE:
1216             gen_helper_msa_ilvl_d(cpu_env, twd, tws, twt);
1217             break;
1218         }
1219         break;
1220     case OPC_ILVR_df:
1221         switch (df) {
1222         case DF_BYTE:
1223             gen_helper_msa_ilvr_b(cpu_env, twd, tws, twt);
1224             break;
1225         case DF_HALF:
1226             gen_helper_msa_ilvr_h(cpu_env, twd, tws, twt);
1227             break;
1228         case DF_WORD:
1229             gen_helper_msa_ilvr_w(cpu_env, twd, tws, twt);
1230             break;
1231         case DF_DOUBLE:
1232             gen_helper_msa_ilvr_d(cpu_env, twd, tws, twt);
1233             break;
1234         }
1235         break;
1236     case OPC_PCKEV_df:
1237         switch (df) {
1238         case DF_BYTE:
1239             gen_helper_msa_pckev_b(cpu_env, twd, tws, twt);
1240             break;
1241         case DF_HALF:
1242             gen_helper_msa_pckev_h(cpu_env, twd, tws, twt);
1243             break;
1244         case DF_WORD:
1245             gen_helper_msa_pckev_w(cpu_env, twd, tws, twt);
1246             break;
1247         case DF_DOUBLE:
1248             gen_helper_msa_pckev_d(cpu_env, twd, tws, twt);
1249             break;
1250         }
1251         break;
1252     case OPC_PCKOD_df:
1253         switch (df) {
1254         case DF_BYTE:
1255             gen_helper_msa_pckod_b(cpu_env, twd, tws, twt);
1256             break;
1257         case DF_HALF:
1258             gen_helper_msa_pckod_h(cpu_env, twd, tws, twt);
1259             break;
1260         case DF_WORD:
1261             gen_helper_msa_pckod_w(cpu_env, twd, tws, twt);
1262             break;
1263         case DF_DOUBLE:
1264             gen_helper_msa_pckod_d(cpu_env, twd, tws, twt);
1265             break;
1266         }
1267         break;
1268     case OPC_SLL_df:
1269         switch (df) {
1270         case DF_BYTE:
1271             gen_helper_msa_sll_b(cpu_env, twd, tws, twt);
1272             break;
1273         case DF_HALF:
1274             gen_helper_msa_sll_h(cpu_env, twd, tws, twt);
1275             break;
1276         case DF_WORD:
1277             gen_helper_msa_sll_w(cpu_env, twd, tws, twt);
1278             break;
1279         case DF_DOUBLE:
1280             gen_helper_msa_sll_d(cpu_env, twd, tws, twt);
1281             break;
1282         }
1283         break;
1284     case OPC_SRA_df:
1285         switch (df) {
1286         case DF_BYTE:
1287             gen_helper_msa_sra_b(cpu_env, twd, tws, twt);
1288             break;
1289         case DF_HALF:
1290             gen_helper_msa_sra_h(cpu_env, twd, tws, twt);
1291             break;
1292         case DF_WORD:
1293             gen_helper_msa_sra_w(cpu_env, twd, tws, twt);
1294             break;
1295         case DF_DOUBLE:
1296             gen_helper_msa_sra_d(cpu_env, twd, tws, twt);
1297             break;
1298         }
1299         break;
1300     case OPC_SRAR_df:
1301         switch (df) {
1302         case DF_BYTE:
1303             gen_helper_msa_srar_b(cpu_env, twd, tws, twt);
1304             break;
1305         case DF_HALF:
1306             gen_helper_msa_srar_h(cpu_env, twd, tws, twt);
1307             break;
1308         case DF_WORD:
1309             gen_helper_msa_srar_w(cpu_env, twd, tws, twt);
1310             break;
1311         case DF_DOUBLE:
1312             gen_helper_msa_srar_d(cpu_env, twd, tws, twt);
1313             break;
1314         }
1315         break;
1316     case OPC_SRL_df:
1317         switch (df) {
1318         case DF_BYTE:
1319             gen_helper_msa_srl_b(cpu_env, twd, tws, twt);
1320             break;
1321         case DF_HALF:
1322             gen_helper_msa_srl_h(cpu_env, twd, tws, twt);
1323             break;
1324         case DF_WORD:
1325             gen_helper_msa_srl_w(cpu_env, twd, tws, twt);
1326             break;
1327         case DF_DOUBLE:
1328             gen_helper_msa_srl_d(cpu_env, twd, tws, twt);
1329             break;
1330         }
1331         break;
1332     case OPC_SRLR_df:
1333         switch (df) {
1334         case DF_BYTE:
1335             gen_helper_msa_srlr_b(cpu_env, twd, tws, twt);
1336             break;
1337         case DF_HALF:
1338             gen_helper_msa_srlr_h(cpu_env, twd, tws, twt);
1339             break;
1340         case DF_WORD:
1341             gen_helper_msa_srlr_w(cpu_env, twd, tws, twt);
1342             break;
1343         case DF_DOUBLE:
1344             gen_helper_msa_srlr_d(cpu_env, twd, tws, twt);
1345             break;
1346         }
1347         break;
1348     case OPC_SUBS_S_df:
1349         switch (df) {
1350         case DF_BYTE:
1351             gen_helper_msa_subs_s_b(cpu_env, twd, tws, twt);
1352             break;
1353         case DF_HALF:
1354             gen_helper_msa_subs_s_h(cpu_env, twd, tws, twt);
1355             break;
1356         case DF_WORD:
1357             gen_helper_msa_subs_s_w(cpu_env, twd, tws, twt);
1358             break;
1359         case DF_DOUBLE:
1360             gen_helper_msa_subs_s_d(cpu_env, twd, tws, twt);
1361             break;
1362         }
1363         break;
1364     case OPC_MULV_df:
1365         switch (df) {
1366         case DF_BYTE:
1367             gen_helper_msa_mulv_b(cpu_env, twd, tws, twt);
1368             break;
1369         case DF_HALF:
1370             gen_helper_msa_mulv_h(cpu_env, twd, tws, twt);
1371             break;
1372         case DF_WORD:
1373             gen_helper_msa_mulv_w(cpu_env, twd, tws, twt);
1374             break;
1375         case DF_DOUBLE:
1376             gen_helper_msa_mulv_d(cpu_env, twd, tws, twt);
1377             break;
1378         }
1379         break;
1380     case OPC_SLD_df:
1381         gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
1382         break;
1383     case OPC_VSHF_df:
1384         gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
1385         break;
1386     case OPC_SUBV_df:
1387         switch (df) {
1388         case DF_BYTE:
1389             gen_helper_msa_subv_b(cpu_env, twd, tws, twt);
1390             break;
1391         case DF_HALF:
1392             gen_helper_msa_subv_h(cpu_env, twd, tws, twt);
1393             break;
1394         case DF_WORD:
1395             gen_helper_msa_subv_w(cpu_env, twd, tws, twt);
1396             break;
1397         case DF_DOUBLE:
1398             gen_helper_msa_subv_d(cpu_env, twd, tws, twt);
1399             break;
1400         }
1401         break;
1402     case OPC_SUBS_U_df:
1403         switch (df) {
1404         case DF_BYTE:
1405             gen_helper_msa_subs_u_b(cpu_env, twd, tws, twt);
1406             break;
1407         case DF_HALF:
1408             gen_helper_msa_subs_u_h(cpu_env, twd, tws, twt);
1409             break;
1410         case DF_WORD:
1411             gen_helper_msa_subs_u_w(cpu_env, twd, tws, twt);
1412             break;
1413         case DF_DOUBLE:
1414             gen_helper_msa_subs_u_d(cpu_env, twd, tws, twt);
1415             break;
1416         }
1417         break;
1418     case OPC_SPLAT_df:
1419         gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
1420         break;
1421     case OPC_SUBSUS_U_df:
1422         switch (df) {
1423         case DF_BYTE:
1424             gen_helper_msa_subsus_u_b(cpu_env, twd, tws, twt);
1425             break;
1426         case DF_HALF:
1427             gen_helper_msa_subsus_u_h(cpu_env, twd, tws, twt);
1428             break;
1429         case DF_WORD:
1430             gen_helper_msa_subsus_u_w(cpu_env, twd, tws, twt);
1431             break;
1432         case DF_DOUBLE:
1433             gen_helper_msa_subsus_u_d(cpu_env, twd, tws, twt);
1434             break;
1435         }
1436         break;
1437     case OPC_SUBSUU_S_df:
1438         switch (df) {
1439         case DF_BYTE:
1440             gen_helper_msa_subsuu_s_b(cpu_env, twd, tws, twt);
1441             break;
1442         case DF_HALF:
1443             gen_helper_msa_subsuu_s_h(cpu_env, twd, tws, twt);
1444             break;
1445         case DF_WORD:
1446             gen_helper_msa_subsuu_s_w(cpu_env, twd, tws, twt);
1447             break;
1448         case DF_DOUBLE:
1449             gen_helper_msa_subsuu_s_d(cpu_env, twd, tws, twt);
1450             break;
1451         }
1452         break;
1453 
1454     case OPC_DOTP_S_df:
1455     case OPC_DOTP_U_df:
1456     case OPC_DPADD_S_df:
1457     case OPC_DPADD_U_df:
1458     case OPC_DPSUB_S_df:
1459     case OPC_HADD_S_df:
1460     case OPC_DPSUB_U_df:
1461     case OPC_HADD_U_df:
1462     case OPC_HSUB_S_df:
1463     case OPC_HSUB_U_df:
1464         if (df == DF_BYTE) {
1465             gen_reserved_instruction(ctx);
1466             break;
1467         }
1468         switch (MASK_MSA_3R(ctx->opcode)) {
1469         case OPC_HADD_S_df:
1470             switch (df) {
1471             case DF_HALF:
1472                 gen_helper_msa_hadd_s_h(cpu_env, twd, tws, twt);
1473                 break;
1474             case DF_WORD:
1475                 gen_helper_msa_hadd_s_w(cpu_env, twd, tws, twt);
1476                 break;
1477             case DF_DOUBLE:
1478                 gen_helper_msa_hadd_s_d(cpu_env, twd, tws, twt);
1479                 break;
1480             }
1481             break;
1482         case OPC_HADD_U_df:
1483             switch (df) {
1484             case DF_HALF:
1485                 gen_helper_msa_hadd_u_h(cpu_env, twd, tws, twt);
1486                 break;
1487             case DF_WORD:
1488                 gen_helper_msa_hadd_u_w(cpu_env, twd, tws, twt);
1489                 break;
1490             case DF_DOUBLE:
1491                 gen_helper_msa_hadd_u_d(cpu_env, twd, tws, twt);
1492                 break;
1493             }
1494             break;
1495         case OPC_HSUB_S_df:
1496             switch (df) {
1497             case DF_HALF:
1498                 gen_helper_msa_hsub_s_h(cpu_env, twd, tws, twt);
1499                 break;
1500             case DF_WORD:
1501                 gen_helper_msa_hsub_s_w(cpu_env, twd, tws, twt);
1502                 break;
1503             case DF_DOUBLE:
1504                 gen_helper_msa_hsub_s_d(cpu_env, twd, tws, twt);
1505                 break;
1506             }
1507             break;
1508         case OPC_HSUB_U_df:
1509             switch (df) {
1510             case DF_HALF:
1511                 gen_helper_msa_hsub_u_h(cpu_env, twd, tws, twt);
1512                 break;
1513             case DF_WORD:
1514                 gen_helper_msa_hsub_u_w(cpu_env, twd, tws, twt);
1515                 break;
1516             case DF_DOUBLE:
1517                 gen_helper_msa_hsub_u_d(cpu_env, twd, tws, twt);
1518                 break;
1519             }
1520             break;
1521         case OPC_DOTP_S_df:
1522             switch (df) {
1523             case DF_HALF:
1524                 gen_helper_msa_dotp_s_h(cpu_env, twd, tws, twt);
1525                 break;
1526             case DF_WORD:
1527                 gen_helper_msa_dotp_s_w(cpu_env, twd, tws, twt);
1528                 break;
1529             case DF_DOUBLE:
1530                 gen_helper_msa_dotp_s_d(cpu_env, twd, tws, twt);
1531                 break;
1532             }
1533             break;
1534         case OPC_DOTP_U_df:
1535             switch (df) {
1536             case DF_HALF:
1537                 gen_helper_msa_dotp_u_h(cpu_env, twd, tws, twt);
1538                 break;
1539             case DF_WORD:
1540                 gen_helper_msa_dotp_u_w(cpu_env, twd, tws, twt);
1541                 break;
1542             case DF_DOUBLE:
1543                 gen_helper_msa_dotp_u_d(cpu_env, twd, tws, twt);
1544                 break;
1545             }
1546             break;
1547         case OPC_DPADD_S_df:
1548             switch (df) {
1549             case DF_HALF:
1550                 gen_helper_msa_dpadd_s_h(cpu_env, twd, tws, twt);
1551                 break;
1552             case DF_WORD:
1553                 gen_helper_msa_dpadd_s_w(cpu_env, twd, tws, twt);
1554                 break;
1555             case DF_DOUBLE:
1556                 gen_helper_msa_dpadd_s_d(cpu_env, twd, tws, twt);
1557                 break;
1558             }
1559             break;
1560         case OPC_DPADD_U_df:
1561             switch (df) {
1562             case DF_HALF:
1563                 gen_helper_msa_dpadd_u_h(cpu_env, twd, tws, twt);
1564                 break;
1565             case DF_WORD:
1566                 gen_helper_msa_dpadd_u_w(cpu_env, twd, tws, twt);
1567                 break;
1568             case DF_DOUBLE:
1569                 gen_helper_msa_dpadd_u_d(cpu_env, twd, tws, twt);
1570                 break;
1571             }
1572             break;
1573         case OPC_DPSUB_S_df:
1574             switch (df) {
1575             case DF_HALF:
1576                 gen_helper_msa_dpsub_s_h(cpu_env, twd, tws, twt);
1577                 break;
1578             case DF_WORD:
1579                 gen_helper_msa_dpsub_s_w(cpu_env, twd, tws, twt);
1580                 break;
1581             case DF_DOUBLE:
1582                 gen_helper_msa_dpsub_s_d(cpu_env, twd, tws, twt);
1583                 break;
1584             }
1585             break;
1586         case OPC_DPSUB_U_df:
1587             switch (df) {
1588             case DF_HALF:
1589                 gen_helper_msa_dpsub_u_h(cpu_env, twd, tws, twt);
1590                 break;
1591             case DF_WORD:
1592                 gen_helper_msa_dpsub_u_w(cpu_env, twd, tws, twt);
1593                 break;
1594             case DF_DOUBLE:
1595                 gen_helper_msa_dpsub_u_d(cpu_env, twd, tws, twt);
1596                 break;
1597             }
1598             break;
1599         }
1600         break;
1601     default:
1602         MIPS_INVAL("MSA instruction");
1603         gen_reserved_instruction(ctx);
1604         break;
1605     }
1606     tcg_temp_free_i32(twd);
1607     tcg_temp_free_i32(tws);
1608     tcg_temp_free_i32(twt);
1609     tcg_temp_free_i32(tdf);
1610 }
1611 
1612 static void gen_msa_elm_3e(DisasContext *ctx)
1613 {
1614 #define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
1615     uint8_t source = (ctx->opcode >> 11) & 0x1f;
1616     uint8_t dest = (ctx->opcode >> 6) & 0x1f;
1617     TCGv telm = tcg_temp_new();
1618     TCGv_i32 tsr = tcg_const_i32(source);
1619     TCGv_i32 tdt = tcg_const_i32(dest);
1620 
1621     switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
1622     case OPC_CTCMSA:
1623         gen_load_gpr(telm, source);
1624         gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
1625         break;
1626     case OPC_CFCMSA:
1627         gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
1628         gen_store_gpr(telm, dest);
1629         break;
1630     case OPC_MOVE_V:
1631         gen_helper_msa_move_v(cpu_env, tdt, tsr);
1632         break;
1633     default:
1634         MIPS_INVAL("MSA instruction");
1635         gen_reserved_instruction(ctx);
1636         break;
1637     }
1638 
1639     tcg_temp_free(telm);
1640     tcg_temp_free_i32(tdt);
1641     tcg_temp_free_i32(tsr);
1642 }
1643 
1644 static void gen_msa_elm_df(DisasContext *ctx, uint32_t df, uint32_t n)
1645 {
1646 #define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
1647     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
1648     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
1649 
1650     TCGv_i32 tws = tcg_const_i32(ws);
1651     TCGv_i32 twd = tcg_const_i32(wd);
1652     TCGv_i32 tn  = tcg_const_i32(n);
1653     TCGv_i32 tdf = tcg_const_i32(df);
1654 
1655     switch (MASK_MSA_ELM(ctx->opcode)) {
1656     case OPC_SLDI_df:
1657         gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
1658         break;
1659     case OPC_SPLATI_df:
1660         gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
1661         break;
1662     case OPC_INSVE_df:
1663         gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
1664         break;
1665     case OPC_COPY_S_df:
1666     case OPC_COPY_U_df:
1667     case OPC_INSERT_df:
1668 #if !defined(TARGET_MIPS64)
1669         /* Double format valid only for MIPS64 */
1670         if (df == DF_DOUBLE) {
1671             gen_reserved_instruction(ctx);
1672             break;
1673         }
1674         if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) &&
1675               (df == DF_WORD)) {
1676             gen_reserved_instruction(ctx);
1677             break;
1678         }
1679 #endif
1680         switch (MASK_MSA_ELM(ctx->opcode)) {
1681         case OPC_COPY_S_df:
1682             if (likely(wd != 0)) {
1683                 switch (df) {
1684                 case DF_BYTE:
1685                     gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn);
1686                     break;
1687                 case DF_HALF:
1688                     gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn);
1689                     break;
1690                 case DF_WORD:
1691                     gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn);
1692                     break;
1693 #if defined(TARGET_MIPS64)
1694                 case DF_DOUBLE:
1695                     gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn);
1696                     break;
1697 #endif
1698                 default:
1699                     assert(0);
1700                 }
1701             }
1702             break;
1703         case OPC_COPY_U_df:
1704             if (likely(wd != 0)) {
1705                 switch (df) {
1706                 case DF_BYTE:
1707                     gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn);
1708                     break;
1709                 case DF_HALF:
1710                     gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn);
1711                     break;
1712 #if defined(TARGET_MIPS64)
1713                 case DF_WORD:
1714                     gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn);
1715                     break;
1716 #endif
1717                 default:
1718                     assert(0);
1719                 }
1720             }
1721             break;
1722         case OPC_INSERT_df:
1723             switch (df) {
1724             case DF_BYTE:
1725                 gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
1726                 break;
1727             case DF_HALF:
1728                 gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
1729                 break;
1730             case DF_WORD:
1731                 gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
1732                 break;
1733 #if defined(TARGET_MIPS64)
1734             case DF_DOUBLE:
1735                 gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
1736                 break;
1737 #endif
1738             default:
1739                 assert(0);
1740             }
1741             break;
1742         }
1743         break;
1744     default:
1745         MIPS_INVAL("MSA instruction");
1746         gen_reserved_instruction(ctx);
1747     }
1748     tcg_temp_free_i32(twd);
1749     tcg_temp_free_i32(tws);
1750     tcg_temp_free_i32(tn);
1751     tcg_temp_free_i32(tdf);
1752 }
1753 
1754 static void gen_msa_elm(DisasContext *ctx)
1755 {
1756     uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
1757     uint32_t df = 0, n = 0;
1758 
1759     if ((dfn & 0x30) == 0x00) {
1760         n = dfn & 0x0f;
1761         df = DF_BYTE;
1762     } else if ((dfn & 0x38) == 0x20) {
1763         n = dfn & 0x07;
1764         df = DF_HALF;
1765     } else if ((dfn & 0x3c) == 0x30) {
1766         n = dfn & 0x03;
1767         df = DF_WORD;
1768     } else if ((dfn & 0x3e) == 0x38) {
1769         n = dfn & 0x01;
1770         df = DF_DOUBLE;
1771     } else if (dfn == 0x3E) {
1772         /* CTCMSA, CFCMSA, MOVE.V */
1773         gen_msa_elm_3e(ctx);
1774         return;
1775     } else {
1776         gen_reserved_instruction(ctx);
1777         return;
1778     }
1779 
1780     gen_msa_elm_df(ctx, df, n);
1781 }
1782 
1783 static void gen_msa_3rf(DisasContext *ctx)
1784 {
1785 #define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
1786     uint8_t df = (ctx->opcode >> 21) & 0x1;
1787     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
1788     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
1789     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
1790 
1791     TCGv_i32 twd = tcg_const_i32(wd);
1792     TCGv_i32 tws = tcg_const_i32(ws);
1793     TCGv_i32 twt = tcg_const_i32(wt);
1794     TCGv_i32 tdf = tcg_temp_new_i32();
1795 
1796     /* adjust df value for floating-point instruction */
1797     tcg_gen_movi_i32(tdf, df + 2);
1798 
1799     switch (MASK_MSA_3RF(ctx->opcode)) {
1800     case OPC_FCAF_df:
1801         gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
1802         break;
1803     case OPC_FADD_df:
1804         gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
1805         break;
1806     case OPC_FCUN_df:
1807         gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
1808         break;
1809     case OPC_FSUB_df:
1810         gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
1811         break;
1812     case OPC_FCOR_df:
1813         gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
1814         break;
1815     case OPC_FCEQ_df:
1816         gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
1817         break;
1818     case OPC_FMUL_df:
1819         gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
1820         break;
1821     case OPC_FCUNE_df:
1822         gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
1823         break;
1824     case OPC_FCUEQ_df:
1825         gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
1826         break;
1827     case OPC_FDIV_df:
1828         gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
1829         break;
1830     case OPC_FCNE_df:
1831         gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
1832         break;
1833     case OPC_FCLT_df:
1834         gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
1835         break;
1836     case OPC_FMADD_df:
1837         gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
1838         break;
1839     case OPC_MUL_Q_df:
1840         tcg_gen_movi_i32(tdf, df + 1);
1841         gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
1842         break;
1843     case OPC_FCULT_df:
1844         gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
1845         break;
1846     case OPC_FMSUB_df:
1847         gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
1848         break;
1849     case OPC_MADD_Q_df:
1850         tcg_gen_movi_i32(tdf, df + 1);
1851         gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
1852         break;
1853     case OPC_FCLE_df:
1854         gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
1855         break;
1856     case OPC_MSUB_Q_df:
1857         tcg_gen_movi_i32(tdf, df + 1);
1858         gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
1859         break;
1860     case OPC_FCULE_df:
1861         gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
1862         break;
1863     case OPC_FEXP2_df:
1864         gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
1865         break;
1866     case OPC_FSAF_df:
1867         gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
1868         break;
1869     case OPC_FEXDO_df:
1870         gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
1871         break;
1872     case OPC_FSUN_df:
1873         gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
1874         break;
1875     case OPC_FSOR_df:
1876         gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
1877         break;
1878     case OPC_FSEQ_df:
1879         gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
1880         break;
1881     case OPC_FTQ_df:
1882         gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
1883         break;
1884     case OPC_FSUNE_df:
1885         gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
1886         break;
1887     case OPC_FSUEQ_df:
1888         gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
1889         break;
1890     case OPC_FSNE_df:
1891         gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
1892         break;
1893     case OPC_FSLT_df:
1894         gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
1895         break;
1896     case OPC_FMIN_df:
1897         gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
1898         break;
1899     case OPC_MULR_Q_df:
1900         tcg_gen_movi_i32(tdf, df + 1);
1901         gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
1902         break;
1903     case OPC_FSULT_df:
1904         gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
1905         break;
1906     case OPC_FMIN_A_df:
1907         gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
1908         break;
1909     case OPC_MADDR_Q_df:
1910         tcg_gen_movi_i32(tdf, df + 1);
1911         gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
1912         break;
1913     case OPC_FSLE_df:
1914         gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
1915         break;
1916     case OPC_FMAX_df:
1917         gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
1918         break;
1919     case OPC_MSUBR_Q_df:
1920         tcg_gen_movi_i32(tdf, df + 1);
1921         gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
1922         break;
1923     case OPC_FSULE_df:
1924         gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
1925         break;
1926     case OPC_FMAX_A_df:
1927         gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
1928         break;
1929     default:
1930         MIPS_INVAL("MSA instruction");
1931         gen_reserved_instruction(ctx);
1932         break;
1933     }
1934 
1935     tcg_temp_free_i32(twd);
1936     tcg_temp_free_i32(tws);
1937     tcg_temp_free_i32(twt);
1938     tcg_temp_free_i32(tdf);
1939 }
1940 
1941 static void gen_msa_2r(DisasContext *ctx)
1942 {
1943 #define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
1944                             (op & (0x7 << 18)))
1945     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
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     TCGv_i32 twt = tcg_const_i32(wt);
1952     TCGv_i32 tdf = tcg_const_i32(df);
1953 
1954     switch (MASK_MSA_2R(ctx->opcode)) {
1955     case OPC_FILL_df:
1956 #if !defined(TARGET_MIPS64)
1957         /* Double format valid only for MIPS64 */
1958         if (df == DF_DOUBLE) {
1959             gen_reserved_instruction(ctx);
1960             break;
1961         }
1962 #endif
1963         gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
1964         break;
1965     case OPC_NLOC_df:
1966         switch (df) {
1967         case DF_BYTE:
1968             gen_helper_msa_nloc_b(cpu_env, twd, tws);
1969             break;
1970         case DF_HALF:
1971             gen_helper_msa_nloc_h(cpu_env, twd, tws);
1972             break;
1973         case DF_WORD:
1974             gen_helper_msa_nloc_w(cpu_env, twd, tws);
1975             break;
1976         case DF_DOUBLE:
1977             gen_helper_msa_nloc_d(cpu_env, twd, tws);
1978             break;
1979         }
1980         break;
1981     case OPC_NLZC_df:
1982         switch (df) {
1983         case DF_BYTE:
1984             gen_helper_msa_nlzc_b(cpu_env, twd, tws);
1985             break;
1986         case DF_HALF:
1987             gen_helper_msa_nlzc_h(cpu_env, twd, tws);
1988             break;
1989         case DF_WORD:
1990             gen_helper_msa_nlzc_w(cpu_env, twd, tws);
1991             break;
1992         case DF_DOUBLE:
1993             gen_helper_msa_nlzc_d(cpu_env, twd, tws);
1994             break;
1995         }
1996         break;
1997     case OPC_PCNT_df:
1998         switch (df) {
1999         case DF_BYTE:
2000             gen_helper_msa_pcnt_b(cpu_env, twd, tws);
2001             break;
2002         case DF_HALF:
2003             gen_helper_msa_pcnt_h(cpu_env, twd, tws);
2004             break;
2005         case DF_WORD:
2006             gen_helper_msa_pcnt_w(cpu_env, twd, tws);
2007             break;
2008         case DF_DOUBLE:
2009             gen_helper_msa_pcnt_d(cpu_env, twd, tws);
2010             break;
2011         }
2012         break;
2013     default:
2014         MIPS_INVAL("MSA instruction");
2015         gen_reserved_instruction(ctx);
2016         break;
2017     }
2018 
2019     tcg_temp_free_i32(twd);
2020     tcg_temp_free_i32(tws);
2021     tcg_temp_free_i32(twt);
2022     tcg_temp_free_i32(tdf);
2023 }
2024 
2025 static void gen_msa_2rf(DisasContext *ctx)
2026 {
2027 #define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
2028                             (op & (0xf << 17)))
2029     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
2030     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
2031     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
2032     uint8_t df = (ctx->opcode >> 16) & 0x1;
2033     TCGv_i32 twd = tcg_const_i32(wd);
2034     TCGv_i32 tws = tcg_const_i32(ws);
2035     TCGv_i32 twt = tcg_const_i32(wt);
2036     /* adjust df value for floating-point instruction */
2037     TCGv_i32 tdf = tcg_const_i32(df + 2);
2038 
2039     switch (MASK_MSA_2RF(ctx->opcode)) {
2040     case OPC_FCLASS_df:
2041         gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
2042         break;
2043     case OPC_FTRUNC_S_df:
2044         gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
2045         break;
2046     case OPC_FTRUNC_U_df:
2047         gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
2048         break;
2049     case OPC_FSQRT_df:
2050         gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
2051         break;
2052     case OPC_FRSQRT_df:
2053         gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
2054         break;
2055     case OPC_FRCP_df:
2056         gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
2057         break;
2058     case OPC_FRINT_df:
2059         gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
2060         break;
2061     case OPC_FLOG2_df:
2062         gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
2063         break;
2064     case OPC_FEXUPL_df:
2065         gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
2066         break;
2067     case OPC_FEXUPR_df:
2068         gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
2069         break;
2070     case OPC_FFQL_df:
2071         gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
2072         break;
2073     case OPC_FFQR_df:
2074         gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
2075         break;
2076     case OPC_FTINT_S_df:
2077         gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
2078         break;
2079     case OPC_FTINT_U_df:
2080         gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
2081         break;
2082     case OPC_FFINT_S_df:
2083         gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
2084         break;
2085     case OPC_FFINT_U_df:
2086         gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
2087         break;
2088     }
2089 
2090     tcg_temp_free_i32(twd);
2091     tcg_temp_free_i32(tws);
2092     tcg_temp_free_i32(twt);
2093     tcg_temp_free_i32(tdf);
2094 }
2095 
2096 static void gen_msa_vec_v(DisasContext *ctx)
2097 {
2098 #define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
2099     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
2100     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
2101     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
2102     TCGv_i32 twd = tcg_const_i32(wd);
2103     TCGv_i32 tws = tcg_const_i32(ws);
2104     TCGv_i32 twt = tcg_const_i32(wt);
2105 
2106     switch (MASK_MSA_VEC(ctx->opcode)) {
2107     case OPC_AND_V:
2108         gen_helper_msa_and_v(cpu_env, twd, tws, twt);
2109         break;
2110     case OPC_OR_V:
2111         gen_helper_msa_or_v(cpu_env, twd, tws, twt);
2112         break;
2113     case OPC_NOR_V:
2114         gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
2115         break;
2116     case OPC_XOR_V:
2117         gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
2118         break;
2119     case OPC_BMNZ_V:
2120         gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
2121         break;
2122     case OPC_BMZ_V:
2123         gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
2124         break;
2125     case OPC_BSEL_V:
2126         gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
2127         break;
2128     default:
2129         MIPS_INVAL("MSA instruction");
2130         gen_reserved_instruction(ctx);
2131         break;
2132     }
2133 
2134     tcg_temp_free_i32(twd);
2135     tcg_temp_free_i32(tws);
2136     tcg_temp_free_i32(twt);
2137 }
2138 
2139 static void gen_msa_vec(DisasContext *ctx)
2140 {
2141     switch (MASK_MSA_VEC(ctx->opcode)) {
2142     case OPC_AND_V:
2143     case OPC_OR_V:
2144     case OPC_NOR_V:
2145     case OPC_XOR_V:
2146     case OPC_BMNZ_V:
2147     case OPC_BMZ_V:
2148     case OPC_BSEL_V:
2149         gen_msa_vec_v(ctx);
2150         break;
2151     case OPC_MSA_2R:
2152         gen_msa_2r(ctx);
2153         break;
2154     case OPC_MSA_2RF:
2155         gen_msa_2rf(ctx);
2156         break;
2157     default:
2158         MIPS_INVAL("MSA instruction");
2159         gen_reserved_instruction(ctx);
2160         break;
2161     }
2162 }
2163 
2164 static bool trans_MSA(DisasContext *ctx, arg_MSA *a)
2165 {
2166     uint32_t opcode = ctx->opcode;
2167 
2168     check_msa_access(ctx);
2169 
2170     switch (MASK_MSA_MINOR(opcode)) {
2171     case OPC_MSA_I8_00:
2172     case OPC_MSA_I8_01:
2173     case OPC_MSA_I8_02:
2174         gen_msa_i8(ctx);
2175         break;
2176     case OPC_MSA_I5_06:
2177     case OPC_MSA_I5_07:
2178         gen_msa_i5(ctx);
2179         break;
2180     case OPC_MSA_BIT_09:
2181     case OPC_MSA_BIT_0A:
2182         gen_msa_bit(ctx);
2183         break;
2184     case OPC_MSA_3R_0D:
2185     case OPC_MSA_3R_0E:
2186     case OPC_MSA_3R_0F:
2187     case OPC_MSA_3R_10:
2188     case OPC_MSA_3R_11:
2189     case OPC_MSA_3R_12:
2190     case OPC_MSA_3R_13:
2191     case OPC_MSA_3R_14:
2192     case OPC_MSA_3R_15:
2193         gen_msa_3r(ctx);
2194         break;
2195     case OPC_MSA_ELM:
2196         gen_msa_elm(ctx);
2197         break;
2198     case OPC_MSA_3RF_1A:
2199     case OPC_MSA_3RF_1B:
2200     case OPC_MSA_3RF_1C:
2201         gen_msa_3rf(ctx);
2202         break;
2203     case OPC_MSA_VEC:
2204         gen_msa_vec(ctx);
2205         break;
2206     case OPC_LD_B:
2207     case OPC_LD_H:
2208     case OPC_LD_W:
2209     case OPC_LD_D:
2210     case OPC_ST_B:
2211     case OPC_ST_H:
2212     case OPC_ST_W:
2213     case OPC_ST_D:
2214         {
2215             int32_t s10 = sextract32(ctx->opcode, 16, 10);
2216             uint8_t rs = (ctx->opcode >> 11) & 0x1f;
2217             uint8_t wd = (ctx->opcode >> 6) & 0x1f;
2218             uint8_t df = (ctx->opcode >> 0) & 0x3;
2219 
2220             TCGv_i32 twd = tcg_const_i32(wd);
2221             TCGv taddr = tcg_temp_new();
2222             gen_base_offset_addr(ctx, taddr, rs, s10 << df);
2223 
2224             switch (MASK_MSA_MINOR(opcode)) {
2225             case OPC_LD_B:
2226                 gen_helper_msa_ld_b(cpu_env, twd, taddr);
2227                 break;
2228             case OPC_LD_H:
2229                 gen_helper_msa_ld_h(cpu_env, twd, taddr);
2230                 break;
2231             case OPC_LD_W:
2232                 gen_helper_msa_ld_w(cpu_env, twd, taddr);
2233                 break;
2234             case OPC_LD_D:
2235                 gen_helper_msa_ld_d(cpu_env, twd, taddr);
2236                 break;
2237             case OPC_ST_B:
2238                 gen_helper_msa_st_b(cpu_env, twd, taddr);
2239                 break;
2240             case OPC_ST_H:
2241                 gen_helper_msa_st_h(cpu_env, twd, taddr);
2242                 break;
2243             case OPC_ST_W:
2244                 gen_helper_msa_st_w(cpu_env, twd, taddr);
2245                 break;
2246             case OPC_ST_D:
2247                 gen_helper_msa_st_d(cpu_env, twd, taddr);
2248                 break;
2249             }
2250 
2251             tcg_temp_free_i32(twd);
2252             tcg_temp_free(taddr);
2253         }
2254         break;
2255     default:
2256         MIPS_INVAL("MSA instruction");
2257         gen_reserved_instruction(ctx);
2258         break;
2259     }
2260 
2261     return true;
2262 }
2263 
2264 static bool trans_LSA(DisasContext *ctx, arg_r *a)
2265 {
2266     return gen_lsa(ctx, a->rd, a->rt, a->rs, a->sa);
2267 }
2268 
2269 static bool trans_DLSA(DisasContext *ctx, arg_r *a)
2270 {
2271     if (TARGET_LONG_BITS != 64) {
2272         return false;
2273     }
2274     return gen_dlsa(ctx, a->rd, a->rt, a->rs, a->sa);
2275 }
2276