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