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