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