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