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