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