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