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