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