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