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