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