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