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