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