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