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