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