1 /* 2 * MIPS emulation for QEMU - main 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 * This library is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU Lesser General Public 13 * License as published by the Free Software Foundation; either 14 * version 2.1 of the License, or (at your option) any later version. 15 * 16 * This library is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "translate.h" 27 #include "internal.h" 28 #include "exec/helper-proto.h" 29 #include "exec/translation-block.h" 30 #include "exec/target_page.h" 31 #include "semihosting/semihost.h" 32 #include "trace.h" 33 #include "fpu_helper.h" 34 35 #define HELPER_H "helper.h" 36 #include "exec/helper-info.c.inc" 37 #undef HELPER_H 38 39 40 /* 41 * Many system-only helpers are not reachable for user-only. 42 * Define stub generators here, so that we need not either sprinkle 43 * ifdefs through the translator, nor provide the helper function. 44 */ 45 #define STUB_HELPER(NAME, ...) \ 46 static inline void gen_helper_##NAME(__VA_ARGS__) \ 47 { g_assert_not_reached(); } 48 49 #ifdef CONFIG_USER_ONLY 50 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg) 51 #endif 52 53 enum { 54 /* indirect opcode tables */ 55 OPC_SPECIAL = (0x00 << 26), 56 OPC_REGIMM = (0x01 << 26), 57 OPC_CP0 = (0x10 << 26), 58 OPC_CP2 = (0x12 << 26), 59 OPC_CP3 = (0x13 << 26), 60 OPC_SPECIAL2 = (0x1C << 26), 61 OPC_SPECIAL3 = (0x1F << 26), 62 /* arithmetic with immediate */ 63 OPC_ADDI = (0x08 << 26), 64 OPC_ADDIU = (0x09 << 26), 65 OPC_SLTI = (0x0A << 26), 66 OPC_SLTIU = (0x0B << 26), 67 /* logic with immediate */ 68 OPC_ANDI = (0x0C << 26), 69 OPC_ORI = (0x0D << 26), 70 OPC_XORI = (0x0E << 26), 71 OPC_LUI = (0x0F << 26), 72 /* arithmetic with immediate */ 73 OPC_DADDI = (0x18 << 26), 74 OPC_DADDIU = (0x19 << 26), 75 /* Jump and branches */ 76 OPC_J = (0x02 << 26), 77 OPC_JAL = (0x03 << 26), 78 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */ 79 OPC_BEQL = (0x14 << 26), 80 OPC_BNE = (0x05 << 26), 81 OPC_BNEL = (0x15 << 26), 82 OPC_BLEZ = (0x06 << 26), 83 OPC_BLEZL = (0x16 << 26), 84 OPC_BGTZ = (0x07 << 26), 85 OPC_BGTZL = (0x17 << 26), 86 OPC_JALX = (0x1D << 26), 87 OPC_DAUI = (0x1D << 26), 88 /* Load and stores */ 89 OPC_LDL = (0x1A << 26), 90 OPC_LDR = (0x1B << 26), 91 OPC_LB = (0x20 << 26), 92 OPC_LH = (0x21 << 26), 93 OPC_LWL = (0x22 << 26), 94 OPC_LW = (0x23 << 26), 95 OPC_LWPC = OPC_LW | 0x5, 96 OPC_LBU = (0x24 << 26), 97 OPC_LHU = (0x25 << 26), 98 OPC_LWR = (0x26 << 26), 99 OPC_LWU = (0x27 << 26), 100 OPC_SB = (0x28 << 26), 101 OPC_SH = (0x29 << 26), 102 OPC_SWL = (0x2A << 26), 103 OPC_SW = (0x2B << 26), 104 OPC_SDL = (0x2C << 26), 105 OPC_SDR = (0x2D << 26), 106 OPC_SWR = (0x2E << 26), 107 OPC_LL = (0x30 << 26), 108 OPC_LLD = (0x34 << 26), 109 OPC_LD = (0x37 << 26), 110 OPC_LDPC = OPC_LD | 0x5, 111 OPC_SC = (0x38 << 26), 112 OPC_SCD = (0x3C << 26), 113 OPC_SD = (0x3F << 26), 114 /* Floating point load/store */ 115 OPC_LWC1 = (0x31 << 26), 116 OPC_LWC2 = (0x32 << 26), 117 OPC_LDC1 = (0x35 << 26), 118 OPC_LDC2 = (0x36 << 26), 119 OPC_SWC1 = (0x39 << 26), 120 OPC_SWC2 = (0x3A << 26), 121 OPC_SDC1 = (0x3D << 26), 122 OPC_SDC2 = (0x3E << 26), 123 /* Compact Branches */ 124 OPC_BLEZALC = (0x06 << 26), 125 OPC_BGEZALC = (0x06 << 26), 126 OPC_BGEUC = (0x06 << 26), 127 OPC_BGTZALC = (0x07 << 26), 128 OPC_BLTZALC = (0x07 << 26), 129 OPC_BLTUC = (0x07 << 26), 130 OPC_BOVC = (0x08 << 26), 131 OPC_BEQZALC = (0x08 << 26), 132 OPC_BEQC = (0x08 << 26), 133 OPC_BLEZC = (0x16 << 26), 134 OPC_BGEZC = (0x16 << 26), 135 OPC_BGEC = (0x16 << 26), 136 OPC_BGTZC = (0x17 << 26), 137 OPC_BLTZC = (0x17 << 26), 138 OPC_BLTC = (0x17 << 26), 139 OPC_BNVC = (0x18 << 26), 140 OPC_BNEZALC = (0x18 << 26), 141 OPC_BNEC = (0x18 << 26), 142 OPC_BC = (0x32 << 26), 143 OPC_BEQZC = (0x36 << 26), 144 OPC_JIC = (0x36 << 26), 145 OPC_BALC = (0x3A << 26), 146 OPC_BNEZC = (0x3E << 26), 147 OPC_JIALC = (0x3E << 26), 148 /* MDMX ASE specific */ 149 OPC_MDMX = (0x1E << 26), 150 /* Cache and prefetch */ 151 OPC_CACHE = (0x2F << 26), 152 OPC_PREF = (0x33 << 26), 153 /* PC-relative address computation / loads */ 154 OPC_PCREL = (0x3B << 26), 155 }; 156 157 /* PC-relative address computation / loads */ 158 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19))) 159 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16))) 160 enum { 161 /* Instructions determined by bits 19 and 20 */ 162 OPC_ADDIUPC = OPC_PCREL | (0 << 19), 163 R6_OPC_LWPC = OPC_PCREL | (1 << 19), 164 OPC_LWUPC = OPC_PCREL | (2 << 19), 165 166 /* Instructions determined by bits 16 ... 20 */ 167 OPC_AUIPC = OPC_PCREL | (0x1e << 16), 168 OPC_ALUIPC = OPC_PCREL | (0x1f << 16), 169 170 /* Other */ 171 R6_OPC_LDPC = OPC_PCREL | (6 << 18), 172 }; 173 174 /* MIPS special opcodes */ 175 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 176 177 enum { 178 /* Shifts */ 179 OPC_SLL = 0x00 | OPC_SPECIAL, 180 /* NOP is SLL r0, r0, 0 */ 181 /* SSNOP is SLL r0, r0, 1 */ 182 /* EHB is SLL r0, r0, 3 */ 183 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */ 184 OPC_ROTR = OPC_SRL | (1 << 21), 185 OPC_SRA = 0x03 | OPC_SPECIAL, 186 OPC_SLLV = 0x04 | OPC_SPECIAL, 187 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */ 188 OPC_ROTRV = OPC_SRLV | (1 << 6), 189 OPC_SRAV = 0x07 | OPC_SPECIAL, 190 OPC_DSLLV = 0x14 | OPC_SPECIAL, 191 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */ 192 OPC_DROTRV = OPC_DSRLV | (1 << 6), 193 OPC_DSRAV = 0x17 | OPC_SPECIAL, 194 OPC_DSLL = 0x38 | OPC_SPECIAL, 195 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */ 196 OPC_DROTR = OPC_DSRL | (1 << 21), 197 OPC_DSRA = 0x3B | OPC_SPECIAL, 198 OPC_DSLL32 = 0x3C | OPC_SPECIAL, 199 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */ 200 OPC_DROTR32 = OPC_DSRL32 | (1 << 21), 201 OPC_DSRA32 = 0x3F | OPC_SPECIAL, 202 /* Multiplication / division */ 203 OPC_MULT = 0x18 | OPC_SPECIAL, 204 OPC_MULTU = 0x19 | OPC_SPECIAL, 205 OPC_DIV = 0x1A | OPC_SPECIAL, 206 OPC_DIVU = 0x1B | OPC_SPECIAL, 207 OPC_DMULT = 0x1C | OPC_SPECIAL, 208 OPC_DMULTU = 0x1D | OPC_SPECIAL, 209 OPC_DDIV = 0x1E | OPC_SPECIAL, 210 OPC_DDIVU = 0x1F | OPC_SPECIAL, 211 212 /* 2 registers arithmetic / logic */ 213 OPC_ADD = 0x20 | OPC_SPECIAL, 214 OPC_ADDU = 0x21 | OPC_SPECIAL, 215 OPC_SUB = 0x22 | OPC_SPECIAL, 216 OPC_SUBU = 0x23 | OPC_SPECIAL, 217 OPC_AND = 0x24 | OPC_SPECIAL, 218 OPC_OR = 0x25 | OPC_SPECIAL, 219 OPC_XOR = 0x26 | OPC_SPECIAL, 220 OPC_NOR = 0x27 | OPC_SPECIAL, 221 OPC_SLT = 0x2A | OPC_SPECIAL, 222 OPC_SLTU = 0x2B | OPC_SPECIAL, 223 OPC_DADD = 0x2C | OPC_SPECIAL, 224 OPC_DADDU = 0x2D | OPC_SPECIAL, 225 OPC_DSUB = 0x2E | OPC_SPECIAL, 226 OPC_DSUBU = 0x2F | OPC_SPECIAL, 227 /* Jumps */ 228 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ 229 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ 230 /* Traps */ 231 OPC_TGE = 0x30 | OPC_SPECIAL, 232 OPC_TGEU = 0x31 | OPC_SPECIAL, 233 OPC_TLT = 0x32 | OPC_SPECIAL, 234 OPC_TLTU = 0x33 | OPC_SPECIAL, 235 OPC_TEQ = 0x34 | OPC_SPECIAL, 236 OPC_TNE = 0x36 | OPC_SPECIAL, 237 /* HI / LO registers load & stores */ 238 OPC_MFHI = 0x10 | OPC_SPECIAL, 239 OPC_MTHI = 0x11 | OPC_SPECIAL, 240 OPC_MFLO = 0x12 | OPC_SPECIAL, 241 OPC_MTLO = 0x13 | OPC_SPECIAL, 242 /* Conditional moves */ 243 OPC_MOVZ = 0x0A | OPC_SPECIAL, 244 OPC_MOVN = 0x0B | OPC_SPECIAL, 245 246 OPC_SELEQZ = 0x35 | OPC_SPECIAL, 247 OPC_SELNEZ = 0x37 | OPC_SPECIAL, 248 249 OPC_MOVCI = 0x01 | OPC_SPECIAL, 250 251 /* Special */ 252 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */ 253 OPC_SYSCALL = 0x0C | OPC_SPECIAL, 254 OPC_BREAK = 0x0D | OPC_SPECIAL, 255 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */ 256 OPC_SYNC = 0x0F | OPC_SPECIAL, 257 258 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, 259 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, 260 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, 261 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, 262 }; 263 264 /* 265 * R6 Multiply and Divide instructions have the same opcode 266 * and function field as legacy OPC_MULT[U]/OPC_DIV[U] 267 */ 268 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff))) 269 270 enum { 271 R6_OPC_MUL = OPC_MULT | (2 << 6), 272 R6_OPC_MUH = OPC_MULT | (3 << 6), 273 R6_OPC_MULU = OPC_MULTU | (2 << 6), 274 R6_OPC_MUHU = OPC_MULTU | (3 << 6), 275 R6_OPC_DIV = OPC_DIV | (2 << 6), 276 R6_OPC_MOD = OPC_DIV | (3 << 6), 277 R6_OPC_DIVU = OPC_DIVU | (2 << 6), 278 R6_OPC_MODU = OPC_DIVU | (3 << 6), 279 280 R6_OPC_DMUL = OPC_DMULT | (2 << 6), 281 R6_OPC_DMUH = OPC_DMULT | (3 << 6), 282 R6_OPC_DMULU = OPC_DMULTU | (2 << 6), 283 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6), 284 R6_OPC_DDIV = OPC_DDIV | (2 << 6), 285 R6_OPC_DMOD = OPC_DDIV | (3 << 6), 286 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6), 287 R6_OPC_DMODU = OPC_DDIVU | (3 << 6), 288 289 R6_OPC_CLZ = 0x10 | OPC_SPECIAL, 290 R6_OPC_CLO = 0x11 | OPC_SPECIAL, 291 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL, 292 R6_OPC_DCLO = 0x13 | OPC_SPECIAL, 293 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL, 294 }; 295 296 /* REGIMM (rt field) opcodes */ 297 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16))) 298 299 enum { 300 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM, 301 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM, 302 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM, 303 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM, 304 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM, 305 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM, 306 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM, 307 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM, 308 OPC_TGEI = (0x08 << 16) | OPC_REGIMM, 309 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM, 310 OPC_TLTI = (0x0A << 16) | OPC_REGIMM, 311 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM, 312 OPC_TEQI = (0x0C << 16) | OPC_REGIMM, 313 OPC_TNEI = (0x0E << 16) | OPC_REGIMM, 314 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM, 315 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM, 316 317 OPC_DAHI = (0x06 << 16) | OPC_REGIMM, 318 OPC_DATI = (0x1e << 16) | OPC_REGIMM, 319 }; 320 321 /* Special2 opcodes */ 322 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 323 324 enum { 325 /* Multiply & xxx operations */ 326 OPC_MADD = 0x00 | OPC_SPECIAL2, 327 OPC_MADDU = 0x01 | OPC_SPECIAL2, 328 OPC_MUL = 0x02 | OPC_SPECIAL2, 329 OPC_MSUB = 0x04 | OPC_SPECIAL2, 330 OPC_MSUBU = 0x05 | OPC_SPECIAL2, 331 /* Misc */ 332 OPC_CLZ = 0x20 | OPC_SPECIAL2, 333 OPC_CLO = 0x21 | OPC_SPECIAL2, 334 OPC_DCLZ = 0x24 | OPC_SPECIAL2, 335 OPC_DCLO = 0x25 | OPC_SPECIAL2, 336 /* Special */ 337 OPC_SDBBP = 0x3F | OPC_SPECIAL2, 338 }; 339 340 /* Special3 opcodes */ 341 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 342 343 enum { 344 OPC_EXT = 0x00 | OPC_SPECIAL3, 345 OPC_DEXTM = 0x01 | OPC_SPECIAL3, 346 OPC_DEXTU = 0x02 | OPC_SPECIAL3, 347 OPC_DEXT = 0x03 | OPC_SPECIAL3, 348 OPC_INS = 0x04 | OPC_SPECIAL3, 349 OPC_DINSM = 0x05 | OPC_SPECIAL3, 350 OPC_DINSU = 0x06 | OPC_SPECIAL3, 351 OPC_DINS = 0x07 | OPC_SPECIAL3, 352 OPC_FORK = 0x08 | OPC_SPECIAL3, 353 OPC_YIELD = 0x09 | OPC_SPECIAL3, 354 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 355 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 356 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 357 OPC_GINV = 0x3D | OPC_SPECIAL3, 358 359 /* MIPS DSP Load */ 360 OPC_LX_DSP = 0x0A | OPC_SPECIAL3, 361 /* MIPS DSP Arithmetic */ 362 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3, 363 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3, 364 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3, 365 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3, 366 OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, 367 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3, 368 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3, 369 /* MIPS DSP GPR-Based Shift Sub-class */ 370 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3, 371 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3, 372 /* MIPS DSP Multiply Sub-class insns */ 373 OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, 374 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3, 375 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3, 376 /* DSP Bit/Manipulation Sub-class */ 377 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, 378 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3, 379 /* MIPS DSP Append Sub-class */ 380 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3, 381 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3, 382 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 383 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, 384 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, 385 386 /* EVA */ 387 OPC_LWLE = 0x19 | OPC_SPECIAL3, 388 OPC_LWRE = 0x1A | OPC_SPECIAL3, 389 OPC_CACHEE = 0x1B | OPC_SPECIAL3, 390 OPC_SBE = 0x1C | OPC_SPECIAL3, 391 OPC_SHE = 0x1D | OPC_SPECIAL3, 392 OPC_SCE = 0x1E | OPC_SPECIAL3, 393 OPC_SWE = 0x1F | OPC_SPECIAL3, 394 OPC_SWLE = 0x21 | OPC_SPECIAL3, 395 OPC_SWRE = 0x22 | OPC_SPECIAL3, 396 OPC_PREFE = 0x23 | OPC_SPECIAL3, 397 OPC_LBUE = 0x28 | OPC_SPECIAL3, 398 OPC_LHUE = 0x29 | OPC_SPECIAL3, 399 OPC_LBE = 0x2C | OPC_SPECIAL3, 400 OPC_LHE = 0x2D | OPC_SPECIAL3, 401 OPC_LLE = 0x2E | OPC_SPECIAL3, 402 OPC_LWE = 0x2F | OPC_SPECIAL3, 403 404 /* R6 */ 405 R6_OPC_PREF = 0x35 | OPC_SPECIAL3, 406 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, 407 R6_OPC_LL = 0x36 | OPC_SPECIAL3, 408 R6_OPC_SC = 0x26 | OPC_SPECIAL3, 409 R6_OPC_LLD = 0x37 | OPC_SPECIAL3, 410 R6_OPC_SCD = 0x27 | OPC_SPECIAL3, 411 }; 412 413 /* Loongson EXT load/store quad word opcodes */ 414 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020)) 415 enum { 416 OPC_GSLQ = 0x0020 | OPC_LWC2, 417 OPC_GSLQC1 = 0x8020 | OPC_LWC2, 418 OPC_GSSHFL = OPC_LWC2, 419 OPC_GSSQ = 0x0020 | OPC_SWC2, 420 OPC_GSSQC1 = 0x8020 | OPC_SWC2, 421 OPC_GSSHFS = OPC_SWC2, 422 }; 423 424 /* Loongson EXT shifted load/store opcodes */ 425 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f)) 426 enum { 427 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL, 428 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL, 429 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL, 430 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL, 431 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS, 432 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS, 433 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS, 434 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS, 435 }; 436 437 /* Loongson EXT LDC2/SDC2 opcodes */ 438 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7)) 439 440 enum { 441 OPC_GSLBX = 0x0 | OPC_LDC2, 442 OPC_GSLHX = 0x1 | OPC_LDC2, 443 OPC_GSLWX = 0x2 | OPC_LDC2, 444 OPC_GSLDX = 0x3 | OPC_LDC2, 445 OPC_GSLWXC1 = 0x6 | OPC_LDC2, 446 OPC_GSLDXC1 = 0x7 | OPC_LDC2, 447 OPC_GSSBX = 0x0 | OPC_SDC2, 448 OPC_GSSHX = 0x1 | OPC_SDC2, 449 OPC_GSSWX = 0x2 | OPC_SDC2, 450 OPC_GSSDX = 0x3 | OPC_SDC2, 451 OPC_GSSWXC1 = 0x6 | OPC_SDC2, 452 OPC_GSSDXC1 = 0x7 | OPC_SDC2, 453 }; 454 455 /* BSHFL opcodes */ 456 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 457 458 enum { 459 OPC_WSBH = (0x02 << 6) | OPC_BSHFL, 460 OPC_SEB = (0x10 << 6) | OPC_BSHFL, 461 OPC_SEH = (0x18 << 6) | OPC_BSHFL, 462 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */ 463 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL, 464 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL, 465 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL, 466 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */ 467 }; 468 469 /* DBSHFL opcodes */ 470 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 471 472 enum { 473 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, 474 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, 475 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */ 476 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL, 477 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL, 478 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL, 479 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL, 480 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL, 481 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL, 482 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL, 483 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */ 484 }; 485 486 /* MIPS DSP REGIMM opcodes */ 487 enum { 488 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM, 489 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM, 490 }; 491 492 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 493 /* MIPS DSP Load */ 494 enum { 495 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP, 496 OPC_LHX = (0x04 << 6) | OPC_LX_DSP, 497 OPC_LWX = (0x00 << 6) | OPC_LX_DSP, 498 OPC_LDX = (0x08 << 6) | OPC_LX_DSP, 499 }; 500 501 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 502 enum { 503 /* MIPS DSP Arithmetic Sub-class */ 504 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP, 505 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP, 506 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP, 507 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP, 508 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP, 509 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP, 510 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP, 511 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP, 512 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP, 513 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP, 514 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP, 515 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP, 516 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP, 517 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP, 518 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP, 519 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP, 520 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP, 521 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP, 522 /* MIPS DSP Multiply Sub-class insns */ 523 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP, 524 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP, 525 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP, 526 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP, 527 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP, 528 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP, 529 }; 530 531 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 532 enum { 533 /* MIPS DSP Arithmetic Sub-class */ 534 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP, 535 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP, 536 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP, 537 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP, 538 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP, 539 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP, 540 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP, 541 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP, 542 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP, 543 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP, 544 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP, 545 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP, 546 /* MIPS DSP Multiply Sub-class insns */ 547 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP, 548 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP, 549 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP, 550 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP, 551 }; 552 553 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 554 enum { 555 /* MIPS DSP Arithmetic Sub-class */ 556 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP, 557 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP, 558 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP, 559 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP, 560 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP, 561 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP, 562 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP, 563 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP, 564 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP, 565 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP, 566 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP, 567 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP, 568 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP, 569 /* DSP Bit/Manipulation Sub-class */ 570 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP, 571 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP, 572 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP, 573 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP, 574 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP, 575 }; 576 577 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 578 enum { 579 /* MIPS DSP Arithmetic Sub-class */ 580 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP, 581 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP, 582 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP, 583 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP, 584 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP, 585 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP, 586 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP, 587 /* DSP Compare-Pick Sub-class */ 588 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP, 589 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP, 590 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP, 591 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP, 592 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP, 593 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP, 594 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP, 595 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP, 596 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP, 597 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP, 598 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP, 599 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP, 600 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, 601 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, 602 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, 603 }; 604 605 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 606 enum { 607 /* MIPS DSP GPR-Based Shift Sub-class */ 608 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP, 609 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP, 610 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP, 611 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP, 612 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP, 613 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP, 614 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP, 615 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP, 616 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP, 617 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP, 618 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP, 619 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP, 620 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP, 621 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP, 622 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP, 623 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP, 624 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP, 625 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP, 626 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP, 627 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP, 628 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP, 629 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP, 630 }; 631 632 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 633 enum { 634 /* MIPS DSP Multiply Sub-class insns */ 635 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP, 636 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP, 637 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP, 638 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP, 639 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP, 640 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP, 641 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP, 642 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP, 643 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP, 644 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP, 645 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP, 646 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP, 647 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP, 648 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP, 649 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP, 650 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP, 651 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP, 652 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP, 653 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP, 654 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP, 655 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP, 656 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP, 657 }; 658 659 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 660 enum { 661 /* DSP Bit/Manipulation Sub-class */ 662 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP, 663 }; 664 665 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 666 enum { 667 /* MIPS DSP Append Sub-class */ 668 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP, 669 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP, 670 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP, 671 }; 672 673 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 674 enum { 675 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 676 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP, 677 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP, 678 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP, 679 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP, 680 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP, 681 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP, 682 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP, 683 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP, 684 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP, 685 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP, 686 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP, 687 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP, 688 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP, 689 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP, 690 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP, 691 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP, 692 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP, 693 }; 694 695 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 696 enum { 697 /* MIPS DSP Arithmetic Sub-class */ 698 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP, 699 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP, 700 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP, 701 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP, 702 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP, 703 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP, 704 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP, 705 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP, 706 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP, 707 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP, 708 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP, 709 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP, 710 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP, 711 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP, 712 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP, 713 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP, 714 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP, 715 /* DSP Bit/Manipulation Sub-class */ 716 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP, 717 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP, 718 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP, 719 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP, 720 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP, 721 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP, 722 }; 723 724 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 725 enum { 726 /* MIPS DSP Multiply Sub-class insns */ 727 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP, 728 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP, 729 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP, 730 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP, 731 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP, 732 /* MIPS DSP Arithmetic Sub-class */ 733 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP, 734 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP, 735 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP, 736 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP, 737 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP, 738 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP, 739 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP, 740 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP, 741 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP, 742 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP, 743 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP, 744 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP, 745 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP, 746 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP, 747 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP, 748 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP, 749 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP, 750 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP, 751 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP, 752 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP, 753 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP, 754 }; 755 756 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 757 enum { 758 /* DSP Compare-Pick Sub-class */ 759 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP, 760 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP, 761 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP, 762 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP, 763 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP, 764 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP, 765 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP, 766 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP, 767 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP, 768 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP, 769 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP, 770 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP, 771 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP, 772 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP, 773 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP, 774 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP, 775 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP, 776 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP, 777 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP, 778 /* MIPS DSP Arithmetic Sub-class */ 779 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP, 780 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP, 781 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP, 782 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP, 783 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP, 784 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP, 785 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP, 786 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP, 787 }; 788 789 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 790 enum { 791 /* DSP Append Sub-class */ 792 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP, 793 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP, 794 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP, 795 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP, 796 }; 797 798 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 799 enum { 800 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 801 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP, 802 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP, 803 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP, 804 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP, 805 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP, 806 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP, 807 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP, 808 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP, 809 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP, 810 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP, 811 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP, 812 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP, 813 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP, 814 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP, 815 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP, 816 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP, 817 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP, 818 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP, 819 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP, 820 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP, 821 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP, 822 }; 823 824 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 825 enum { 826 /* DSP Bit/Manipulation Sub-class */ 827 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP, 828 }; 829 830 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 831 enum { 832 /* MIPS DSP Multiply Sub-class insns */ 833 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP, 834 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP, 835 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP, 836 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP, 837 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP, 838 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP, 839 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP, 840 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP, 841 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP, 842 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP, 843 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP, 844 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP, 845 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP, 846 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP, 847 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP, 848 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP, 849 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP, 850 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP, 851 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP, 852 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP, 853 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP, 854 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP, 855 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP, 856 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP, 857 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP, 858 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP, 859 }; 860 861 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 862 enum { 863 /* MIPS DSP GPR-Based Shift Sub-class */ 864 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP, 865 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP, 866 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP, 867 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP, 868 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP, 869 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP, 870 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP, 871 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP, 872 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP, 873 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP, 874 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP, 875 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP, 876 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP, 877 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP, 878 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP, 879 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP, 880 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP, 881 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP, 882 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP, 883 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP, 884 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP, 885 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP, 886 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP, 887 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP, 888 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP, 889 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP, 890 }; 891 892 /* Coprocessor 0 (rs field) */ 893 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 894 895 enum { 896 OPC_MFC0 = (0x00 << 21) | OPC_CP0, 897 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 898 OPC_MFHC0 = (0x02 << 21) | OPC_CP0, 899 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 900 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 901 OPC_MTHC0 = (0x06 << 21) | OPC_CP0, 902 OPC_MFTR = (0x08 << 21) | OPC_CP0, 903 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 904 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 905 OPC_MTTR = (0x0C << 21) | OPC_CP0, 906 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 907 OPC_C0 = (0x10 << 21) | OPC_CP0, 908 OPC_C0_1 = (0x11 << 21) | OPC_CP0, 909 OPC_C0_2 = (0x12 << 21) | OPC_CP0, 910 OPC_C0_3 = (0x13 << 21) | OPC_CP0, 911 OPC_C0_4 = (0x14 << 21) | OPC_CP0, 912 OPC_C0_5 = (0x15 << 21) | OPC_CP0, 913 OPC_C0_6 = (0x16 << 21) | OPC_CP0, 914 OPC_C0_7 = (0x17 << 21) | OPC_CP0, 915 OPC_C0_8 = (0x18 << 21) | OPC_CP0, 916 OPC_C0_9 = (0x19 << 21) | OPC_CP0, 917 OPC_C0_A = (0x1A << 21) | OPC_CP0, 918 OPC_C0_B = (0x1B << 21) | OPC_CP0, 919 OPC_C0_C = (0x1C << 21) | OPC_CP0, 920 OPC_C0_D = (0x1D << 21) | OPC_CP0, 921 OPC_C0_E = (0x1E << 21) | OPC_CP0, 922 OPC_C0_F = (0x1F << 21) | OPC_CP0, 923 }; 924 925 /* MFMC0 opcodes */ 926 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF)) 927 928 enum { 929 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 930 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 931 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0, 932 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0, 933 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 934 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 935 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0, 936 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0, 937 }; 938 939 /* Coprocessor 0 (with rs == C0) */ 940 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F)) 941 942 enum { 943 OPC_TLBR = 0x01 | OPC_C0, 944 OPC_TLBWI = 0x02 | OPC_C0, 945 OPC_TLBINV = 0x03 | OPC_C0, 946 OPC_TLBINVF = 0x04 | OPC_C0, 947 OPC_TLBWR = 0x06 | OPC_C0, 948 OPC_TLBP = 0x08 | OPC_C0, 949 OPC_RFE = 0x10 | OPC_C0, 950 OPC_ERET = 0x18 | OPC_C0, 951 OPC_DERET = 0x1F | OPC_C0, 952 OPC_WAIT = 0x20 | OPC_C0, 953 }; 954 955 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 956 957 enum { 958 OPC_MFC2 = (0x00 << 21) | OPC_CP2, 959 OPC_DMFC2 = (0x01 << 21) | OPC_CP2, 960 OPC_CFC2 = (0x02 << 21) | OPC_CP2, 961 OPC_MFHC2 = (0x03 << 21) | OPC_CP2, 962 OPC_MTC2 = (0x04 << 21) | OPC_CP2, 963 OPC_DMTC2 = (0x05 << 21) | OPC_CP2, 964 OPC_CTC2 = (0x06 << 21) | OPC_CP2, 965 OPC_MTHC2 = (0x07 << 21) | OPC_CP2, 966 OPC_BC2 = (0x08 << 21) | OPC_CP2, 967 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2, 968 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2, 969 }; 970 971 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F)) 972 973 enum { 974 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2, 975 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2, 976 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2, 977 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2, 978 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2, 979 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2, 980 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2, 981 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2, 982 983 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2, 984 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2, 985 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2, 986 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2, 987 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2, 988 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2, 989 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2, 990 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2, 991 992 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2, 993 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2, 994 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2, 995 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2, 996 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2, 997 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2, 998 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2, 999 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2, 1000 1001 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2, 1002 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2, 1003 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2, 1004 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2, 1005 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2, 1006 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2, 1007 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2, 1008 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2, 1009 1010 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2, 1011 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2, 1012 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2, 1013 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2, 1014 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2, 1015 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2, 1016 1017 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2, 1018 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2, 1019 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2, 1020 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2, 1021 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2, 1022 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2, 1023 1024 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2, 1025 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2, 1026 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2, 1027 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2, 1028 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2, 1029 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2, 1030 1031 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2, 1032 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2, 1033 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2, 1034 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2, 1035 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2, 1036 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2, 1037 1038 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2, 1039 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2, 1040 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2, 1041 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2, 1042 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2, 1043 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2, 1044 1045 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2, 1046 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2, 1047 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2, 1048 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2, 1049 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2, 1050 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2, 1051 1052 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2, 1053 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2, 1054 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2, 1055 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2, 1056 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2, 1057 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2, 1058 1059 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2, 1060 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2, 1061 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2, 1062 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2, 1063 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2, 1064 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2, 1065 }; 1066 1067 1068 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 1069 1070 enum { 1071 OPC_LWXC1 = 0x00 | OPC_CP3, 1072 OPC_LDXC1 = 0x01 | OPC_CP3, 1073 OPC_LUXC1 = 0x05 | OPC_CP3, 1074 OPC_SWXC1 = 0x08 | OPC_CP3, 1075 OPC_SDXC1 = 0x09 | OPC_CP3, 1076 OPC_SUXC1 = 0x0D | OPC_CP3, 1077 OPC_PREFX = 0x0F | OPC_CP3, 1078 OPC_ALNV_PS = 0x1E | OPC_CP3, 1079 OPC_MADD_S = 0x20 | OPC_CP3, 1080 OPC_MADD_D = 0x21 | OPC_CP3, 1081 OPC_MADD_PS = 0x26 | OPC_CP3, 1082 OPC_MSUB_S = 0x28 | OPC_CP3, 1083 OPC_MSUB_D = 0x29 | OPC_CP3, 1084 OPC_MSUB_PS = 0x2E | OPC_CP3, 1085 OPC_NMADD_S = 0x30 | OPC_CP3, 1086 OPC_NMADD_D = 0x31 | OPC_CP3, 1087 OPC_NMADD_PS = 0x36 | OPC_CP3, 1088 OPC_NMSUB_S = 0x38 | OPC_CP3, 1089 OPC_NMSUB_D = 0x39 | OPC_CP3, 1090 OPC_NMSUB_PS = 0x3E | OPC_CP3, 1091 }; 1092 1093 /* 1094 * MMI (MultiMedia Instruction) encodings 1095 * ====================================== 1096 * 1097 * MMI instructions encoding table keys: 1098 * 1099 * * This code is reserved for future use. An attempt to execute it 1100 * causes a Reserved Instruction exception. 1101 * % This code indicates an instruction class. The instruction word 1102 * must be further decoded by examining additional tables that show 1103 * the values for other instruction fields. 1104 * # This code is reserved for the unsupported instructions DMULT, 1105 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt 1106 * to execute it causes a Reserved Instruction exception. 1107 * 1108 * MMI instructions encoded by opcode field (MMI, LQ, SQ): 1109 * 1110 * 31 26 0 1111 * +--------+----------------------------------------+ 1112 * | opcode | | 1113 * +--------+----------------------------------------+ 1114 * 1115 * opcode bits 28..26 1116 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1117 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1118 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1119 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ 1120 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI 1121 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL 1122 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ 1123 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU 1124 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE 1125 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD 1126 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD 1127 */ 1128 1129 enum { 1130 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */ 1131 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */ 1132 }; 1133 1134 /* 1135 * MMI instructions with opcode field = MMI: 1136 * 1137 * 31 26 5 0 1138 * +--------+-------------------------------+--------+ 1139 * | MMI | |function| 1140 * +--------+-------------------------------+--------+ 1141 * 1142 * function bits 2..0 1143 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1144 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1145 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1146 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * 1147 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * 1148 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * 1149 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * 1150 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * 1151 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * 1152 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH 1153 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW 1154 */ 1155 1156 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) 1157 enum { 1158 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */ 1159 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */ 1160 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */ 1161 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */ 1162 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */ 1163 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */ 1164 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI, 1165 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI, 1166 }; 1167 1168 /* global register indices */ 1169 TCGv cpu_gpr[32], cpu_PC; 1170 /* 1171 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[]) 1172 * and the upper halves in cpu_gpr_hi[]. 1173 */ 1174 TCGv_i64 cpu_gpr_hi[32]; 1175 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; 1176 static TCGv cpu_dspctrl, btarget; 1177 TCGv bcond; 1178 static TCGv cpu_lladdr, cpu_llval; 1179 static TCGv_i32 hflags; 1180 TCGv_i32 fpu_fcr0, fpu_fcr31; 1181 TCGv_i64 fpu_f64[32]; 1182 1183 static const char regnames_HI[][4] = { 1184 "HI0", "HI1", "HI2", "HI3", 1185 }; 1186 1187 static const char regnames_LO[][4] = { 1188 "LO0", "LO1", "LO2", "LO3", 1189 }; 1190 1191 /* General purpose registers moves. */ 1192 void gen_load_gpr(TCGv t, int reg) 1193 { 1194 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr)); 1195 if (reg == 0) { 1196 tcg_gen_movi_tl(t, 0); 1197 } else { 1198 tcg_gen_mov_tl(t, cpu_gpr[reg]); 1199 } 1200 } 1201 1202 void gen_store_gpr(TCGv t, int reg) 1203 { 1204 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr)); 1205 if (reg != 0) { 1206 tcg_gen_mov_tl(cpu_gpr[reg], t); 1207 } 1208 } 1209 1210 #if defined(TARGET_MIPS64) 1211 void gen_load_gpr_hi(TCGv_i64 t, int reg) 1212 { 1213 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi)); 1214 if (reg == 0) { 1215 tcg_gen_movi_i64(t, 0); 1216 } else { 1217 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]); 1218 } 1219 } 1220 1221 void gen_store_gpr_hi(TCGv_i64 t, int reg) 1222 { 1223 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi)); 1224 if (reg != 0) { 1225 tcg_gen_mov_i64(cpu_gpr_hi[reg], t); 1226 } 1227 } 1228 #endif /* TARGET_MIPS64 */ 1229 1230 /* Moves to/from shadow registers. */ 1231 static inline void gen_load_srsgpr(int from, int to) 1232 { 1233 TCGv t0 = tcg_temp_new(); 1234 1235 if (from == 0) { 1236 tcg_gen_movi_tl(t0, 0); 1237 } else { 1238 TCGv_i32 t2 = tcg_temp_new_i32(); 1239 TCGv_ptr addr = tcg_temp_new_ptr(); 1240 1241 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1242 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1243 tcg_gen_andi_i32(t2, t2, 0xf); 1244 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1245 tcg_gen_ext_i32_ptr(addr, t2); 1246 tcg_gen_add_ptr(addr, tcg_env, addr); 1247 1248 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 1249 } 1250 gen_store_gpr(t0, to); 1251 } 1252 1253 static inline void gen_store_srsgpr(int from, int to) 1254 { 1255 if (to != 0) { 1256 TCGv t0 = tcg_temp_new(); 1257 TCGv_i32 t2 = tcg_temp_new_i32(); 1258 TCGv_ptr addr = tcg_temp_new_ptr(); 1259 1260 gen_load_gpr(t0, from); 1261 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1262 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1263 tcg_gen_andi_i32(t2, t2, 0xf); 1264 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1265 tcg_gen_ext_i32_ptr(addr, t2); 1266 tcg_gen_add_ptr(addr, tcg_env, addr); 1267 1268 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 1269 } 1270 } 1271 1272 /* Tests */ 1273 static inline void gen_save_pc(target_ulong pc) 1274 { 1275 tcg_gen_movi_tl(cpu_PC, pc); 1276 } 1277 1278 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) 1279 { 1280 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 1281 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { 1282 gen_save_pc(ctx->base.pc_next); 1283 ctx->saved_pc = ctx->base.pc_next; 1284 } 1285 if (ctx->hflags != ctx->saved_hflags) { 1286 tcg_gen_movi_i32(hflags, ctx->hflags); 1287 ctx->saved_hflags = ctx->hflags; 1288 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1289 case MIPS_HFLAG_BR: 1290 break; 1291 case MIPS_HFLAG_BC: 1292 case MIPS_HFLAG_BL: 1293 case MIPS_HFLAG_B: 1294 tcg_gen_movi_tl(btarget, ctx->btarget); 1295 break; 1296 } 1297 } 1298 } 1299 1300 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) 1301 { 1302 ctx->saved_hflags = ctx->hflags; 1303 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1304 case MIPS_HFLAG_BR: 1305 break; 1306 case MIPS_HFLAG_BC: 1307 case MIPS_HFLAG_BL: 1308 case MIPS_HFLAG_B: 1309 ctx->btarget = env->btarget; 1310 break; 1311 } 1312 } 1313 1314 void generate_exception_err(DisasContext *ctx, int excp, int err) 1315 { 1316 save_cpu_state(ctx, 1); 1317 gen_helper_raise_exception_err(tcg_env, tcg_constant_i32(excp), 1318 tcg_constant_i32(err)); 1319 ctx->base.is_jmp = DISAS_NORETURN; 1320 } 1321 1322 void generate_exception(DisasContext *ctx, int excp) 1323 { 1324 gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp)); 1325 } 1326 1327 void generate_exception_end(DisasContext *ctx, int excp) 1328 { 1329 generate_exception_err(ctx, excp, 0); 1330 } 1331 1332 void generate_exception_break(DisasContext *ctx, int code) 1333 { 1334 #ifdef CONFIG_USER_ONLY 1335 /* Pass the break code along to cpu_loop. */ 1336 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 1337 offsetof(CPUMIPSState, error_code)); 1338 #endif 1339 generate_exception_end(ctx, EXCP_BREAK); 1340 } 1341 1342 void gen_reserved_instruction(DisasContext *ctx) 1343 { 1344 generate_exception_end(ctx, EXCP_RI); 1345 } 1346 1347 /* Floating point register moves. */ 1348 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1349 { 1350 if (ctx->hflags & MIPS_HFLAG_FRE) { 1351 generate_exception(ctx, EXCP_RI); 1352 } 1353 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); 1354 } 1355 1356 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1357 { 1358 TCGv_i64 t64; 1359 if (ctx->hflags & MIPS_HFLAG_FRE) { 1360 generate_exception(ctx, EXCP_RI); 1361 } 1362 t64 = tcg_temp_new_i64(); 1363 tcg_gen_extu_i32_i64(t64, t); 1364 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); 1365 } 1366 1367 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1368 { 1369 if (ctx->hflags & MIPS_HFLAG_F64) { 1370 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); 1371 } else { 1372 gen_load_fpr32(ctx, t, reg | 1); 1373 } 1374 } 1375 1376 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1377 { 1378 if (ctx->hflags & MIPS_HFLAG_F64) { 1379 TCGv_i64 t64 = tcg_temp_new_i64(); 1380 tcg_gen_extu_i32_i64(t64, t); 1381 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); 1382 } else { 1383 gen_store_fpr32(ctx, t, reg | 1); 1384 } 1385 } 1386 1387 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1388 { 1389 if (ctx->hflags & MIPS_HFLAG_F64) { 1390 tcg_gen_mov_i64(t, fpu_f64[reg]); 1391 } else { 1392 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]); 1393 } 1394 } 1395 1396 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1397 { 1398 if (ctx->hflags & MIPS_HFLAG_F64) { 1399 tcg_gen_mov_i64(fpu_f64[reg], t); 1400 } else { 1401 TCGv_i64 t0; 1402 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32); 1403 t0 = tcg_temp_new_i64(); 1404 tcg_gen_shri_i64(t0, t, 32); 1405 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32); 1406 } 1407 } 1408 1409 int get_fp_bit(int cc) 1410 { 1411 if (cc) { 1412 return 24 + cc; 1413 } else { 1414 return 23; 1415 } 1416 } 1417 1418 /* Addresses computation */ 1419 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 1420 { 1421 tcg_gen_add_tl(ret, arg0, arg1); 1422 1423 #if defined(TARGET_MIPS64) 1424 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1425 tcg_gen_ext32s_i64(ret, ret); 1426 } 1427 #endif 1428 } 1429 1430 void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, target_long ofs) 1431 { 1432 tcg_gen_addi_tl(ret, base, ofs); 1433 1434 #if defined(TARGET_MIPS64) 1435 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1436 tcg_gen_ext32s_i64(ret, ret); 1437 } 1438 #endif 1439 } 1440 1441 /* Addresses computation (translation time) */ 1442 static target_long addr_add(DisasContext *ctx, target_long base, 1443 target_long offset) 1444 { 1445 target_long sum = base + offset; 1446 1447 #if defined(TARGET_MIPS64) 1448 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1449 sum = (int32_t)sum; 1450 } 1451 #endif 1452 return sum; 1453 } 1454 1455 /* Sign-extract the low 32-bits to a target_long. */ 1456 void gen_move_low32(TCGv ret, TCGv_i64 arg) 1457 { 1458 #if defined(TARGET_MIPS64) 1459 tcg_gen_ext32s_i64(ret, arg); 1460 #else 1461 tcg_gen_extrl_i64_i32(ret, arg); 1462 #endif 1463 } 1464 1465 /* Sign-extract the high 32-bits to a target_long. */ 1466 void gen_move_high32(TCGv ret, TCGv_i64 arg) 1467 { 1468 #if defined(TARGET_MIPS64) 1469 tcg_gen_sari_i64(ret, arg, 32); 1470 #else 1471 tcg_gen_extrh_i64_i32(ret, arg); 1472 #endif 1473 } 1474 1475 bool check_cp0_enabled(DisasContext *ctx) 1476 { 1477 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1478 generate_exception_end(ctx, EXCP_CpU); 1479 return false; 1480 } 1481 return true; 1482 } 1483 1484 void check_cp1_enabled(DisasContext *ctx) 1485 { 1486 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) { 1487 generate_exception_err(ctx, EXCP_CpU, 1); 1488 } 1489 } 1490 1491 /* 1492 * Verify that the processor is running with COP1X instructions enabled. 1493 * This is associated with the nabla symbol in the MIPS32 and MIPS64 1494 * opcode tables. 1495 */ 1496 void check_cop1x(DisasContext *ctx) 1497 { 1498 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { 1499 gen_reserved_instruction(ctx); 1500 } 1501 } 1502 1503 /* 1504 * Verify that the processor is running with 64-bit floating-point 1505 * operations enabled. 1506 */ 1507 void check_cp1_64bitmode(DisasContext *ctx) 1508 { 1509 if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) { 1510 gen_reserved_instruction(ctx); 1511 } 1512 } 1513 1514 /* 1515 * Verify if floating point register is valid; an operation is not defined 1516 * if bit 0 of any register specification is set and the FR bit in the 1517 * Status register equals zero, since the register numbers specify an 1518 * even-odd pair of adjacent coprocessor general registers. When the FR bit 1519 * in the Status register equals one, both even and odd register numbers 1520 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 1521 * 1522 * Multiple 64 bit wide registers can be checked by calling 1523 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 1524 */ 1525 void check_cp1_registers(DisasContext *ctx, int regs) 1526 { 1527 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { 1528 gen_reserved_instruction(ctx); 1529 } 1530 } 1531 1532 /* 1533 * Verify that the processor is running with DSP instructions enabled. 1534 * This is enabled by CP0 Status register MX(24) bit. 1535 */ 1536 static inline void check_dsp(DisasContext *ctx) 1537 { 1538 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { 1539 if (ctx->insn_flags & ASE_DSP) { 1540 generate_exception_end(ctx, EXCP_DSPDIS); 1541 } else { 1542 gen_reserved_instruction(ctx); 1543 } 1544 } 1545 } 1546 1547 static inline void check_dsp_r2(DisasContext *ctx) 1548 { 1549 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { 1550 if (ctx->insn_flags & ASE_DSP) { 1551 generate_exception_end(ctx, EXCP_DSPDIS); 1552 } else { 1553 gen_reserved_instruction(ctx); 1554 } 1555 } 1556 } 1557 1558 static inline void check_dsp_r3(DisasContext *ctx) 1559 { 1560 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { 1561 if (ctx->insn_flags & ASE_DSP) { 1562 generate_exception_end(ctx, EXCP_DSPDIS); 1563 } else { 1564 gen_reserved_instruction(ctx); 1565 } 1566 } 1567 } 1568 1569 /* 1570 * This code generates a "reserved instruction" exception if the 1571 * CPU does not support the instruction set corresponding to flags. 1572 */ 1573 void check_insn(DisasContext *ctx, uint64_t flags) 1574 { 1575 if (unlikely(!(ctx->insn_flags & flags))) { 1576 gen_reserved_instruction(ctx); 1577 } 1578 } 1579 1580 /* 1581 * This code generates a "reserved instruction" exception if the 1582 * CPU has corresponding flag set which indicates that the instruction 1583 * has been removed. 1584 */ 1585 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) 1586 { 1587 if (unlikely(ctx->insn_flags & flags)) { 1588 gen_reserved_instruction(ctx); 1589 } 1590 } 1591 1592 /* 1593 * The Linux kernel traps certain reserved instruction exceptions to 1594 * emulate the corresponding instructions. QEMU is the kernel in user 1595 * mode, so those traps are emulated by accepting the instructions. 1596 * 1597 * A reserved instruction exception is generated for flagged CPUs if 1598 * QEMU runs in system mode. 1599 */ 1600 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) 1601 { 1602 #ifndef CONFIG_USER_ONLY 1603 check_insn_opc_removed(ctx, flags); 1604 #endif 1605 } 1606 1607 /* 1608 * This code generates a "reserved instruction" exception if the 1609 * CPU does not support 64-bit paired-single (PS) floating point data type. 1610 */ 1611 static inline void check_ps(DisasContext *ctx) 1612 { 1613 if (unlikely(!ctx->ps)) { 1614 generate_exception(ctx, EXCP_RI); 1615 } 1616 check_cp1_64bitmode(ctx); 1617 } 1618 1619 bool decode_64bit_enabled(DisasContext *ctx) 1620 { 1621 return ctx->hflags & MIPS_HFLAG_64; 1622 } 1623 1624 /* 1625 * This code generates a "reserved instruction" exception if cpu is not 1626 * 64-bit or 64-bit instructions are not enabled. 1627 */ 1628 void check_mips_64(DisasContext *ctx) 1629 { 1630 if (unlikely((TARGET_LONG_BITS != 64) || !decode_64bit_enabled(ctx))) { 1631 gen_reserved_instruction(ctx); 1632 } 1633 } 1634 1635 #ifndef CONFIG_USER_ONLY 1636 static inline void check_mvh(DisasContext *ctx) 1637 { 1638 if (unlikely(!ctx->mvh)) { 1639 generate_exception(ctx, EXCP_RI); 1640 } 1641 } 1642 #endif 1643 1644 /* 1645 * This code generates a "reserved instruction" exception if the 1646 * Config5 XNP bit is set. 1647 */ 1648 static inline void check_xnp(DisasContext *ctx) 1649 { 1650 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) { 1651 gen_reserved_instruction(ctx); 1652 } 1653 } 1654 1655 #ifndef CONFIG_USER_ONLY 1656 /* 1657 * This code generates a "reserved instruction" exception if the 1658 * Config3 PW bit is NOT set. 1659 */ 1660 static inline void check_pw(DisasContext *ctx) 1661 { 1662 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) { 1663 gen_reserved_instruction(ctx); 1664 } 1665 } 1666 #endif 1667 1668 /* 1669 * This code generates a "reserved instruction" exception if the 1670 * Config3 MT bit is NOT set. 1671 */ 1672 static inline void check_mt(DisasContext *ctx) 1673 { 1674 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1675 gen_reserved_instruction(ctx); 1676 } 1677 } 1678 1679 #ifndef CONFIG_USER_ONLY 1680 /* 1681 * This code generates a "coprocessor unusable" exception if CP0 is not 1682 * available, and, if that is not the case, generates a "reserved instruction" 1683 * exception if the Config5 MT bit is NOT set. This is needed for availability 1684 * control of some of MT ASE instructions. 1685 */ 1686 static inline void check_cp0_mt(DisasContext *ctx) 1687 { 1688 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1689 generate_exception_end(ctx, EXCP_CpU); 1690 } else { 1691 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1692 gen_reserved_instruction(ctx); 1693 } 1694 } 1695 } 1696 #endif 1697 1698 /* 1699 * This code generates a "reserved instruction" exception if the 1700 * Config5 NMS bit is set. 1701 */ 1702 static inline void check_nms(DisasContext *ctx) 1703 { 1704 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) { 1705 gen_reserved_instruction(ctx); 1706 } 1707 } 1708 1709 /* 1710 * This code generates a "reserved instruction" exception if the 1711 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, 1712 * Config2 TL, and Config5 L2C are unset. 1713 */ 1714 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) 1715 { 1716 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) && 1717 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) && 1718 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) && 1719 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && 1720 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && 1721 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) { 1722 gen_reserved_instruction(ctx); 1723 } 1724 } 1725 1726 /* 1727 * This code generates a "reserved instruction" exception if the 1728 * Config5 EVA bit is NOT set. 1729 */ 1730 static inline void check_eva(DisasContext *ctx) 1731 { 1732 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) { 1733 gen_reserved_instruction(ctx); 1734 } 1735 } 1736 1737 1738 /* 1739 * Define small wrappers for gen_load_fpr* so that we have a uniform 1740 * calling interface for 32 and 64-bit FPRs. No sense in changing 1741 * all callers for gen_load_fpr32 when we need the CTX parameter for 1742 * this one use. 1743 */ 1744 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) 1745 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) 1746 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \ 1747 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ 1748 int ft, int fs, int cc) \ 1749 { \ 1750 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ 1751 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ 1752 switch (ifmt) { \ 1753 case FMT_PS: \ 1754 check_ps(ctx); \ 1755 break; \ 1756 case FMT_D: \ 1757 if (abs) { \ 1758 check_cop1x(ctx); \ 1759 } \ 1760 check_cp1_registers(ctx, fs | ft); \ 1761 break; \ 1762 case FMT_S: \ 1763 if (abs) { \ 1764 check_cop1x(ctx); \ 1765 } \ 1766 break; \ 1767 } \ 1768 gen_ldcmp_fpr##bits(ctx, fp0, fs); \ 1769 gen_ldcmp_fpr##bits(ctx, fp1, ft); \ 1770 switch (n) { \ 1771 case 0: \ 1772 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \ 1773 break; \ 1774 case 1: \ 1775 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \ 1776 break; \ 1777 case 2: \ 1778 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \ 1779 break; \ 1780 case 3: \ 1781 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \ 1782 break; \ 1783 case 4: \ 1784 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \ 1785 break; \ 1786 case 5: \ 1787 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \ 1788 break; \ 1789 case 6: \ 1790 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \ 1791 break; \ 1792 case 7: \ 1793 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \ 1794 break; \ 1795 case 8: \ 1796 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \ 1797 break; \ 1798 case 9: \ 1799 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \ 1800 break; \ 1801 case 10: \ 1802 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \ 1803 break; \ 1804 case 11: \ 1805 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \ 1806 break; \ 1807 case 12: \ 1808 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \ 1809 break; \ 1810 case 13: \ 1811 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \ 1812 break; \ 1813 case 14: \ 1814 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \ 1815 break; \ 1816 case 15: \ 1817 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \ 1818 break; \ 1819 default: \ 1820 abort(); \ 1821 } \ 1822 } 1823 1824 FOP_CONDS(, 0, d, FMT_D, 64) 1825 FOP_CONDS(abs, 1, d, FMT_D, 64) 1826 FOP_CONDS(, 0, s, FMT_S, 32) 1827 FOP_CONDS(abs, 1, s, FMT_S, 32) 1828 FOP_CONDS(, 0, ps, FMT_PS, 64) 1829 FOP_CONDS(abs, 1, ps, FMT_PS, 64) 1830 #undef FOP_CONDS 1831 1832 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \ 1833 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \ 1834 int ft, int fs, int fd) \ 1835 { \ 1836 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ 1837 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ 1838 if (ifmt == FMT_D) { \ 1839 check_cp1_registers(ctx, fs | ft | fd); \ 1840 } \ 1841 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ 1842 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ 1843 switch (n) { \ 1844 case 0: \ 1845 gen_helper_r6_cmp_ ## fmt ## _af(fp0, tcg_env, fp0, fp1); \ 1846 break; \ 1847 case 1: \ 1848 gen_helper_r6_cmp_ ## fmt ## _un(fp0, tcg_env, fp0, fp1); \ 1849 break; \ 1850 case 2: \ 1851 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, tcg_env, fp0, fp1); \ 1852 break; \ 1853 case 3: \ 1854 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, tcg_env, fp0, fp1); \ 1855 break; \ 1856 case 4: \ 1857 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, tcg_env, fp0, fp1); \ 1858 break; \ 1859 case 5: \ 1860 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, tcg_env, fp0, fp1); \ 1861 break; \ 1862 case 6: \ 1863 gen_helper_r6_cmp_ ## fmt ## _le(fp0, tcg_env, fp0, fp1); \ 1864 break; \ 1865 case 7: \ 1866 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, tcg_env, fp0, fp1); \ 1867 break; \ 1868 case 8: \ 1869 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, tcg_env, fp0, fp1); \ 1870 break; \ 1871 case 9: \ 1872 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, tcg_env, fp0, fp1); \ 1873 break; \ 1874 case 10: \ 1875 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, tcg_env, fp0, fp1); \ 1876 break; \ 1877 case 11: \ 1878 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, tcg_env, fp0, fp1); \ 1879 break; \ 1880 case 12: \ 1881 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, tcg_env, fp0, fp1); \ 1882 break; \ 1883 case 13: \ 1884 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, tcg_env, fp0, fp1); \ 1885 break; \ 1886 case 14: \ 1887 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, tcg_env, fp0, fp1); \ 1888 break; \ 1889 case 15: \ 1890 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, tcg_env, fp0, fp1); \ 1891 break; \ 1892 case 17: \ 1893 gen_helper_r6_cmp_ ## fmt ## _or(fp0, tcg_env, fp0, fp1); \ 1894 break; \ 1895 case 18: \ 1896 gen_helper_r6_cmp_ ## fmt ## _une(fp0, tcg_env, fp0, fp1); \ 1897 break; \ 1898 case 19: \ 1899 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, tcg_env, fp0, fp1); \ 1900 break; \ 1901 case 25: \ 1902 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, tcg_env, fp0, fp1); \ 1903 break; \ 1904 case 26: \ 1905 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, tcg_env, fp0, fp1); \ 1906 break; \ 1907 case 27: \ 1908 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, tcg_env, fp0, fp1); \ 1909 break; \ 1910 default: \ 1911 abort(); \ 1912 } \ 1913 STORE; \ 1914 } 1915 1916 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) 1917 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd)) 1918 #undef FOP_CONDNS 1919 #undef gen_ldcmp_fpr32 1920 #undef gen_ldcmp_fpr64 1921 1922 /* load/store instructions. */ 1923 #ifdef CONFIG_USER_ONLY 1924 #define OP_LD_ATOMIC(insn, memop) \ 1925 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1926 DisasContext *ctx) \ 1927 { \ 1928 TCGv t0 = tcg_temp_new(); \ 1929 tcg_gen_mov_tl(t0, arg1); \ 1930 tcg_gen_qemu_ld_tl(ret, arg1, ctx->mem_idx, memop); \ 1931 tcg_gen_st_tl(t0, tcg_env, offsetof(CPUMIPSState, lladdr)); \ 1932 tcg_gen_st_tl(ret, tcg_env, offsetof(CPUMIPSState, llval)); \ 1933 } 1934 #else 1935 #define OP_LD_ATOMIC(insn, ignored_memop) \ 1936 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1937 DisasContext *ctx) \ 1938 { \ 1939 gen_helper_##insn(ret, tcg_env, arg1, tcg_constant_i32(mem_idx)); \ 1940 } 1941 #endif 1942 OP_LD_ATOMIC(ll, mo_endian(ctx) | MO_SL); 1943 #if defined(TARGET_MIPS64) 1944 OP_LD_ATOMIC(lld, mo_endian(ctx) | MO_UQ); 1945 #endif 1946 #undef OP_LD_ATOMIC 1947 1948 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset) 1949 { 1950 if (base == 0) { 1951 tcg_gen_movi_tl(addr, offset); 1952 } else if (offset == 0) { 1953 gen_load_gpr(addr, base); 1954 } else { 1955 tcg_gen_movi_tl(addr, offset); 1956 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); 1957 } 1958 } 1959 1960 void gen_base_index_addr(DisasContext *ctx, TCGv addr, int base, int index) 1961 { 1962 if (base == 0) { 1963 gen_load_gpr(addr, index); 1964 } else if (index == 0) { 1965 gen_load_gpr(addr, base); 1966 } else { 1967 gen_op_addr_add(ctx, addr, cpu_gpr[base], cpu_gpr[index]); 1968 } 1969 } 1970 1971 static target_ulong pc_relative_pc(DisasContext *ctx) 1972 { 1973 target_ulong pc = ctx->base.pc_next; 1974 1975 if (ctx->hflags & MIPS_HFLAG_BMASK) { 1976 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4; 1977 1978 pc -= branch_bytes; 1979 } 1980 1981 pc &= ~(target_ulong)3; 1982 return pc; 1983 } 1984 1985 /* LWL or LDL, depending on MemOp. */ 1986 static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr, 1987 int mem_idx, MemOp mop) 1988 { 1989 int sizem1 = memop_size(mop) - 1; 1990 TCGv t0 = tcg_temp_new(); 1991 TCGv t1 = tcg_temp_new(); 1992 1993 /* 1994 * Do a byte access to possibly trigger a page 1995 * fault with the unaligned address. 1996 */ 1997 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); 1998 tcg_gen_andi_tl(t1, addr, sizem1); 1999 if (!disas_is_bigendian(ctx)) { 2000 tcg_gen_xori_tl(t1, t1, sizem1); 2001 } 2002 tcg_gen_shli_tl(t1, t1, 3); 2003 tcg_gen_andi_tl(t0, addr, ~sizem1); 2004 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); 2005 tcg_gen_shl_tl(t0, t0, t1); 2006 tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1); 2007 tcg_gen_andc_tl(t1, reg, t1); 2008 tcg_gen_or_tl(reg, t0, t1); 2009 } 2010 2011 /* LWR or LDR, depending on MemOp. */ 2012 static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr, 2013 int mem_idx, MemOp mop) 2014 { 2015 int size = memop_size(mop); 2016 int sizem1 = size - 1; 2017 TCGv t0 = tcg_temp_new(); 2018 TCGv t1 = tcg_temp_new(); 2019 2020 /* 2021 * Do a byte access to possibly trigger a page 2022 * fault with the unaligned address. 2023 */ 2024 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); 2025 tcg_gen_andi_tl(t1, addr, sizem1); 2026 if (disas_is_bigendian(ctx)) { 2027 tcg_gen_xori_tl(t1, t1, sizem1); 2028 } 2029 tcg_gen_shli_tl(t1, t1, 3); 2030 tcg_gen_andi_tl(t0, addr, ~sizem1); 2031 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); 2032 tcg_gen_shr_tl(t0, t0, t1); 2033 tcg_gen_xori_tl(t1, t1, size * 8 - 1); 2034 tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1); 2035 tcg_gen_and_tl(t1, reg, t1); 2036 tcg_gen_or_tl(reg, t0, t1); 2037 } 2038 2039 void gen_lx(DisasContext *ctx, int rd, int base, int index, MemOp mop) 2040 { 2041 TCGv t0 = tcg_temp_new(); 2042 2043 gen_base_index_addr(ctx, t0, base, index); 2044 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | mop); 2045 gen_store_gpr(t0, rd); 2046 } 2047 2048 /* Load */ 2049 static void gen_ld(DisasContext *ctx, uint32_t opc, 2050 int rt, int base, int offset) 2051 { 2052 TCGv t0, t1; 2053 int mem_idx = ctx->mem_idx; 2054 2055 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F | 2056 INSN_LOONGSON3A)) { 2057 /* 2058 * Loongson CPU uses a load to zero register for prefetch. 2059 * We emulate it as a NOP. On other CPU we must perform the 2060 * actual memory access. 2061 */ 2062 return; 2063 } 2064 2065 t0 = tcg_temp_new(); 2066 gen_base_offset_addr(ctx, t0, base, offset); 2067 2068 switch (opc) { 2069 #if defined(TARGET_MIPS64) 2070 case OPC_LWU: 2071 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UL | 2072 ctx->default_tcg_memop_mask); 2073 gen_store_gpr(t0, rt); 2074 break; 2075 case OPC_LD: 2076 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ | 2077 ctx->default_tcg_memop_mask); 2078 gen_store_gpr(t0, rt); 2079 break; 2080 case OPC_LLD: 2081 case R6_OPC_LLD: 2082 op_ld_lld(t0, t0, mem_idx, ctx); 2083 gen_store_gpr(t0, rt); 2084 break; 2085 case OPC_LDL: 2086 t1 = tcg_temp_new(); 2087 gen_load_gpr(t1, rt); 2088 gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2089 gen_store_gpr(t1, rt); 2090 break; 2091 case OPC_LDR: 2092 t1 = tcg_temp_new(); 2093 gen_load_gpr(t1, rt); 2094 gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2095 gen_store_gpr(t1, rt); 2096 break; 2097 case OPC_LDPC: 2098 t1 = tcg_constant_tl(pc_relative_pc(ctx)); 2099 gen_op_addr_add(ctx, t0, t0, t1); 2100 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2101 gen_store_gpr(t0, rt); 2102 break; 2103 #endif 2104 case OPC_LWPC: 2105 t1 = tcg_constant_tl(pc_relative_pc(ctx)); 2106 gen_op_addr_add(ctx, t0, t0, t1); 2107 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL); 2108 gen_store_gpr(t0, rt); 2109 break; 2110 case OPC_LWE: 2111 mem_idx = MIPS_HFLAG_UM; 2112 /* fall through */ 2113 case OPC_LW: 2114 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL | 2115 ctx->default_tcg_memop_mask); 2116 gen_store_gpr(t0, rt); 2117 break; 2118 case OPC_LHE: 2119 mem_idx = MIPS_HFLAG_UM; 2120 /* fall through */ 2121 case OPC_LH: 2122 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SW | 2123 ctx->default_tcg_memop_mask); 2124 gen_store_gpr(t0, rt); 2125 break; 2126 case OPC_LHUE: 2127 mem_idx = MIPS_HFLAG_UM; 2128 /* fall through */ 2129 case OPC_LHU: 2130 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UW | 2131 ctx->default_tcg_memop_mask); 2132 gen_store_gpr(t0, rt); 2133 break; 2134 case OPC_LBE: 2135 mem_idx = MIPS_HFLAG_UM; 2136 /* fall through */ 2137 case OPC_LB: 2138 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); 2139 gen_store_gpr(t0, rt); 2140 break; 2141 case OPC_LBUE: 2142 mem_idx = MIPS_HFLAG_UM; 2143 /* fall through */ 2144 case OPC_LBU: 2145 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); 2146 gen_store_gpr(t0, rt); 2147 break; 2148 case OPC_LWLE: 2149 mem_idx = MIPS_HFLAG_UM; 2150 /* fall through */ 2151 case OPC_LWL: 2152 t1 = tcg_temp_new(); 2153 gen_load_gpr(t1, rt); 2154 gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL); 2155 tcg_gen_ext32s_tl(t1, t1); 2156 gen_store_gpr(t1, rt); 2157 break; 2158 case OPC_LWRE: 2159 mem_idx = MIPS_HFLAG_UM; 2160 /* fall through */ 2161 case OPC_LWR: 2162 t1 = tcg_temp_new(); 2163 gen_load_gpr(t1, rt); 2164 gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL); 2165 tcg_gen_ext32s_tl(t1, t1); 2166 gen_store_gpr(t1, rt); 2167 break; 2168 case OPC_LLE: 2169 mem_idx = MIPS_HFLAG_UM; 2170 /* fall through */ 2171 case OPC_LL: 2172 case R6_OPC_LL: 2173 op_ld_ll(t0, t0, mem_idx, ctx); 2174 gen_store_gpr(t0, rt); 2175 break; 2176 } 2177 } 2178 2179 /* Store */ 2180 static void gen_st(DisasContext *ctx, uint32_t opc, int rt, 2181 int base, int offset) 2182 { 2183 TCGv t0 = tcg_temp_new(); 2184 TCGv t1 = tcg_temp_new(); 2185 int mem_idx = ctx->mem_idx; 2186 2187 gen_base_offset_addr(ctx, t0, base, offset); 2188 gen_load_gpr(t1, rt); 2189 switch (opc) { 2190 #if defined(TARGET_MIPS64) 2191 case OPC_SD: 2192 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UQ | 2193 ctx->default_tcg_memop_mask); 2194 break; 2195 case OPC_SDL: 2196 gen_helper_0e2i(sdl, t1, t0, mem_idx); 2197 break; 2198 case OPC_SDR: 2199 gen_helper_0e2i(sdr, t1, t0, mem_idx); 2200 break; 2201 #endif 2202 case OPC_SWE: 2203 mem_idx = MIPS_HFLAG_UM; 2204 /* fall through */ 2205 case OPC_SW: 2206 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UL | 2207 ctx->default_tcg_memop_mask); 2208 break; 2209 case OPC_SHE: 2210 mem_idx = MIPS_HFLAG_UM; 2211 /* fall through */ 2212 case OPC_SH: 2213 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UW | 2214 ctx->default_tcg_memop_mask); 2215 break; 2216 case OPC_SBE: 2217 mem_idx = MIPS_HFLAG_UM; 2218 /* fall through */ 2219 case OPC_SB: 2220 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); 2221 break; 2222 case OPC_SWLE: 2223 mem_idx = MIPS_HFLAG_UM; 2224 /* fall through */ 2225 case OPC_SWL: 2226 gen_helper_0e2i(swl, t1, t0, mem_idx); 2227 break; 2228 case OPC_SWRE: 2229 mem_idx = MIPS_HFLAG_UM; 2230 /* fall through */ 2231 case OPC_SWR: 2232 gen_helper_0e2i(swr, t1, t0, mem_idx); 2233 break; 2234 } 2235 } 2236 2237 2238 /* Store conditional */ 2239 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, 2240 MemOp tcg_mo, bool eva) 2241 { 2242 TCGv addr, t0, val; 2243 TCGLabel *l1 = gen_new_label(); 2244 TCGLabel *done = gen_new_label(); 2245 2246 t0 = tcg_temp_new(); 2247 addr = tcg_temp_new(); 2248 /* compare the address against that of the preceding LL */ 2249 gen_base_offset_addr(ctx, addr, base, offset); 2250 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); 2251 gen_store_gpr(tcg_constant_tl(0), rt); 2252 tcg_gen_br(done); 2253 2254 gen_set_label(l1); 2255 /* generate cmpxchg */ 2256 val = tcg_temp_new(); 2257 gen_load_gpr(val, rt); 2258 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, 2259 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo); 2260 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); 2261 gen_store_gpr(t0, rt); 2262 2263 gen_set_label(done); 2264 } 2265 2266 /* Load and store */ 2267 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, 2268 TCGv t0) 2269 { 2270 /* 2271 * Don't do NOP if destination is zero: we must perform the actual 2272 * memory access. 2273 */ 2274 switch (opc) { 2275 case OPC_LWC1: 2276 { 2277 TCGv_i32 fp0 = tcg_temp_new_i32(); 2278 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 2279 ctx->default_tcg_memop_mask); 2280 gen_store_fpr32(ctx, fp0, ft); 2281 } 2282 break; 2283 case OPC_SWC1: 2284 { 2285 TCGv_i32 fp0 = tcg_temp_new_i32(); 2286 gen_load_fpr32(ctx, fp0, ft); 2287 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 2288 ctx->default_tcg_memop_mask); 2289 } 2290 break; 2291 case OPC_LDC1: 2292 { 2293 TCGv_i64 fp0 = tcg_temp_new_i64(); 2294 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 2295 ctx->default_tcg_memop_mask); 2296 gen_store_fpr64(ctx, fp0, ft); 2297 } 2298 break; 2299 case OPC_SDC1: 2300 { 2301 TCGv_i64 fp0 = tcg_temp_new_i64(); 2302 gen_load_fpr64(ctx, fp0, ft); 2303 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 2304 ctx->default_tcg_memop_mask); 2305 } 2306 break; 2307 default: 2308 MIPS_INVAL("flt_ldst"); 2309 gen_reserved_instruction(ctx); 2310 break; 2311 } 2312 } 2313 2314 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, 2315 int rs, int16_t imm) 2316 { 2317 TCGv t0 = tcg_temp_new(); 2318 2319 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2320 check_cp1_enabled(ctx); 2321 switch (op) { 2322 case OPC_LDC1: 2323 case OPC_SDC1: 2324 check_insn(ctx, ISA_MIPS2); 2325 /* Fallthrough */ 2326 default: 2327 gen_base_offset_addr(ctx, t0, rs, imm); 2328 gen_flt_ldst(ctx, op, rt, t0); 2329 } 2330 } else { 2331 generate_exception_err(ctx, EXCP_CpU, 1); 2332 } 2333 } 2334 2335 /* Arithmetic with immediate operand */ 2336 static void gen_arith_imm(DisasContext *ctx, uint32_t opc, 2337 int rt, int rs, int imm) 2338 { 2339 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2340 2341 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 2342 /* 2343 * If no destination, treat it as a NOP. 2344 * For addi, we must generate the overflow exception when needed. 2345 */ 2346 return; 2347 } 2348 switch (opc) { 2349 case OPC_ADDI: 2350 { 2351 TCGv t0 = tcg_temp_new(); 2352 TCGv t1 = tcg_temp_new(); 2353 TCGv t2 = tcg_temp_new(); 2354 TCGLabel *l1 = gen_new_label(); 2355 2356 gen_load_gpr(t1, rs); 2357 tcg_gen_addi_tl(t0, t1, uimm); 2358 tcg_gen_ext32s_tl(t0, t0); 2359 2360 tcg_gen_xori_tl(t1, t1, ~uimm); 2361 tcg_gen_xori_tl(t2, t0, uimm); 2362 tcg_gen_and_tl(t1, t1, t2); 2363 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2364 /* operands of same sign, result different sign */ 2365 generate_exception(ctx, EXCP_OVERFLOW); 2366 gen_set_label(l1); 2367 tcg_gen_ext32s_tl(t0, t0); 2368 gen_store_gpr(t0, rt); 2369 } 2370 break; 2371 case OPC_ADDIU: 2372 if (rs != 0) { 2373 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2374 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2375 } else { 2376 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2377 } 2378 break; 2379 #if defined(TARGET_MIPS64) 2380 case OPC_DADDI: 2381 { 2382 TCGv t0 = tcg_temp_new(); 2383 TCGv t1 = tcg_temp_new(); 2384 TCGv t2 = tcg_temp_new(); 2385 TCGLabel *l1 = gen_new_label(); 2386 2387 gen_load_gpr(t1, rs); 2388 tcg_gen_addi_tl(t0, t1, uimm); 2389 2390 tcg_gen_xori_tl(t1, t1, ~uimm); 2391 tcg_gen_xori_tl(t2, t0, uimm); 2392 tcg_gen_and_tl(t1, t1, t2); 2393 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2394 /* operands of same sign, result different sign */ 2395 generate_exception(ctx, EXCP_OVERFLOW); 2396 gen_set_label(l1); 2397 gen_store_gpr(t0, rt); 2398 } 2399 break; 2400 case OPC_DADDIU: 2401 if (rs != 0) { 2402 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2403 } else { 2404 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2405 } 2406 break; 2407 #endif 2408 } 2409 } 2410 2411 /* Logic with immediate operand */ 2412 static void gen_logic_imm(DisasContext *ctx, uint32_t opc, 2413 int rt, int rs, int16_t imm) 2414 { 2415 target_ulong uimm; 2416 2417 if (rt == 0) { 2418 /* If no destination, treat it as a NOP. */ 2419 return; 2420 } 2421 uimm = (uint16_t)imm; 2422 switch (opc) { 2423 case OPC_ANDI: 2424 if (likely(rs != 0)) { 2425 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2426 } else { 2427 tcg_gen_movi_tl(cpu_gpr[rt], 0); 2428 } 2429 break; 2430 case OPC_ORI: 2431 if (rs != 0) { 2432 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2433 } else { 2434 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2435 } 2436 break; 2437 case OPC_XORI: 2438 if (likely(rs != 0)) { 2439 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2440 } else { 2441 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2442 } 2443 break; 2444 case OPC_LUI: 2445 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) { 2446 /* OPC_AUI */ 2447 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16); 2448 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2449 } else { 2450 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 2451 } 2452 break; 2453 2454 default: 2455 break; 2456 } 2457 } 2458 2459 /* Set on less than with immediate operand */ 2460 static void gen_slt_imm(DisasContext *ctx, uint32_t opc, 2461 int rt, int rs, int16_t imm) 2462 { 2463 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2464 TCGv t0; 2465 2466 if (rt == 0) { 2467 /* If no destination, treat it as a NOP. */ 2468 return; 2469 } 2470 t0 = tcg_temp_new(); 2471 gen_load_gpr(t0, rs); 2472 switch (opc) { 2473 case OPC_SLTI: 2474 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); 2475 break; 2476 case OPC_SLTIU: 2477 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); 2478 break; 2479 } 2480 } 2481 2482 /* Shifts with immediate operand */ 2483 static void gen_shift_imm(DisasContext *ctx, uint32_t opc, 2484 int rt, int rs, int16_t imm) 2485 { 2486 target_ulong uimm = ((uint16_t)imm) & 0x1f; 2487 TCGv t0; 2488 2489 if (rt == 0) { 2490 /* If no destination, treat it as a NOP. */ 2491 return; 2492 } 2493 2494 t0 = tcg_temp_new(); 2495 gen_load_gpr(t0, rs); 2496 switch (opc) { 2497 case OPC_SLL: 2498 tcg_gen_shli_tl(t0, t0, uimm); 2499 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2500 break; 2501 case OPC_SRA: 2502 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2503 break; 2504 case OPC_SRL: 2505 if (uimm != 0) { 2506 tcg_gen_ext32u_tl(t0, t0); 2507 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2508 } else { 2509 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2510 } 2511 break; 2512 case OPC_ROTR: 2513 if (uimm != 0) { 2514 TCGv_i32 t1 = tcg_temp_new_i32(); 2515 2516 tcg_gen_trunc_tl_i32(t1, t0); 2517 tcg_gen_rotri_i32(t1, t1, uimm); 2518 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 2519 } else { 2520 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2521 } 2522 break; 2523 #if defined(TARGET_MIPS64) 2524 case OPC_DSLL: 2525 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 2526 break; 2527 case OPC_DSRA: 2528 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2529 break; 2530 case OPC_DSRL: 2531 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2532 break; 2533 case OPC_DROTR: 2534 if (uimm != 0) { 2535 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 2536 } else { 2537 tcg_gen_mov_tl(cpu_gpr[rt], t0); 2538 } 2539 break; 2540 case OPC_DSLL32: 2541 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 2542 break; 2543 case OPC_DSRA32: 2544 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 2545 break; 2546 case OPC_DSRL32: 2547 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 2548 break; 2549 case OPC_DROTR32: 2550 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 2551 break; 2552 #endif 2553 } 2554 } 2555 2556 /* Arithmetic */ 2557 static void gen_arith(DisasContext *ctx, uint32_t opc, 2558 int rd, int rs, int rt) 2559 { 2560 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 2561 && opc != OPC_DADD && opc != OPC_DSUB) { 2562 /* 2563 * If no destination, treat it as a NOP. 2564 * For add & sub, we must generate the overflow exception when needed. 2565 */ 2566 return; 2567 } 2568 2569 switch (opc) { 2570 case OPC_ADD: 2571 { 2572 TCGv t0 = tcg_temp_new(); 2573 TCGv t1 = tcg_temp_new(); 2574 TCGv t2 = tcg_temp_new(); 2575 TCGLabel *l1 = gen_new_label(); 2576 2577 gen_load_gpr(t1, rs); 2578 gen_load_gpr(t2, rt); 2579 tcg_gen_add_tl(t0, t1, t2); 2580 tcg_gen_ext32s_tl(t0, t0); 2581 tcg_gen_xor_tl(t1, t1, t2); 2582 tcg_gen_xor_tl(t2, t0, t2); 2583 tcg_gen_andc_tl(t1, t2, t1); 2584 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2585 /* operands of same sign, result different sign */ 2586 generate_exception(ctx, EXCP_OVERFLOW); 2587 gen_set_label(l1); 2588 gen_store_gpr(t0, rd); 2589 } 2590 break; 2591 case OPC_ADDU: 2592 if (rs != 0 && rt != 0) { 2593 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2594 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2595 } else if (rs == 0 && rt != 0) { 2596 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2597 } else if (rs != 0 && rt == 0) { 2598 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2599 } else { 2600 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2601 } 2602 break; 2603 case OPC_SUB: 2604 { 2605 TCGv t0 = tcg_temp_new(); 2606 TCGv t1 = tcg_temp_new(); 2607 TCGv t2 = tcg_temp_new(); 2608 TCGLabel *l1 = gen_new_label(); 2609 2610 gen_load_gpr(t1, rs); 2611 gen_load_gpr(t2, rt); 2612 tcg_gen_sub_tl(t0, t1, t2); 2613 tcg_gen_ext32s_tl(t0, t0); 2614 tcg_gen_xor_tl(t2, t1, t2); 2615 tcg_gen_xor_tl(t1, t0, t1); 2616 tcg_gen_and_tl(t1, t1, t2); 2617 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2618 /* 2619 * operands of different sign, first operand and the result 2620 * of different sign 2621 */ 2622 generate_exception(ctx, EXCP_OVERFLOW); 2623 gen_set_label(l1); 2624 gen_store_gpr(t0, rd); 2625 } 2626 break; 2627 case OPC_SUBU: 2628 if (rs != 0 && rt != 0) { 2629 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2630 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2631 } else if (rs == 0 && rt != 0) { 2632 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2633 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2634 } else if (rs != 0 && rt == 0) { 2635 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2636 } else { 2637 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2638 } 2639 break; 2640 #if defined(TARGET_MIPS64) 2641 case OPC_DADD: 2642 { 2643 TCGv t0 = tcg_temp_new(); 2644 TCGv t1 = tcg_temp_new(); 2645 TCGv t2 = tcg_temp_new(); 2646 TCGLabel *l1 = gen_new_label(); 2647 2648 gen_load_gpr(t1, rs); 2649 gen_load_gpr(t2, rt); 2650 tcg_gen_add_tl(t0, t1, t2); 2651 tcg_gen_xor_tl(t1, t1, t2); 2652 tcg_gen_xor_tl(t2, t0, t2); 2653 tcg_gen_andc_tl(t1, t2, t1); 2654 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2655 /* operands of same sign, result different sign */ 2656 generate_exception(ctx, EXCP_OVERFLOW); 2657 gen_set_label(l1); 2658 gen_store_gpr(t0, rd); 2659 } 2660 break; 2661 case OPC_DADDU: 2662 if (rs != 0 && rt != 0) { 2663 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2664 } else if (rs == 0 && rt != 0) { 2665 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2666 } else if (rs != 0 && rt == 0) { 2667 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2668 } else { 2669 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2670 } 2671 break; 2672 case OPC_DSUB: 2673 { 2674 TCGv t0 = tcg_temp_new(); 2675 TCGv t1 = tcg_temp_new(); 2676 TCGv t2 = tcg_temp_new(); 2677 TCGLabel *l1 = gen_new_label(); 2678 2679 gen_load_gpr(t1, rs); 2680 gen_load_gpr(t2, rt); 2681 tcg_gen_sub_tl(t0, t1, t2); 2682 tcg_gen_xor_tl(t2, t1, t2); 2683 tcg_gen_xor_tl(t1, t0, t1); 2684 tcg_gen_and_tl(t1, t1, t2); 2685 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2686 /* 2687 * Operands of different sign, first operand and result different 2688 * sign. 2689 */ 2690 generate_exception(ctx, EXCP_OVERFLOW); 2691 gen_set_label(l1); 2692 gen_store_gpr(t0, rd); 2693 } 2694 break; 2695 case OPC_DSUBU: 2696 if (rs != 0 && rt != 0) { 2697 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2698 } else if (rs == 0 && rt != 0) { 2699 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2700 } else if (rs != 0 && rt == 0) { 2701 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2702 } else { 2703 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2704 } 2705 break; 2706 #endif 2707 case OPC_MUL: 2708 if (likely(rs != 0 && rt != 0)) { 2709 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2710 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2711 } else { 2712 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2713 } 2714 break; 2715 } 2716 } 2717 2718 /* Conditional move */ 2719 static void gen_cond_move(DisasContext *ctx, uint32_t opc, 2720 int rd, int rs, int rt) 2721 { 2722 TCGv t0, t1, t2; 2723 2724 if (rd == 0) { 2725 /* If no destination, treat it as a NOP. */ 2726 return; 2727 } 2728 2729 t0 = tcg_temp_new(); 2730 gen_load_gpr(t0, rt); 2731 t1 = tcg_constant_tl(0); 2732 t2 = tcg_temp_new(); 2733 gen_load_gpr(t2, rs); 2734 switch (opc) { 2735 case OPC_MOVN: 2736 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2737 break; 2738 case OPC_MOVZ: 2739 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2740 break; 2741 case OPC_SELNEZ: 2742 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); 2743 break; 2744 case OPC_SELEQZ: 2745 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); 2746 break; 2747 } 2748 } 2749 2750 /* Logic */ 2751 static void gen_logic(DisasContext *ctx, uint32_t opc, 2752 int rd, int rs, int rt) 2753 { 2754 if (rd == 0) { 2755 /* If no destination, treat it as a NOP. */ 2756 return; 2757 } 2758 2759 switch (opc) { 2760 case OPC_AND: 2761 if (likely(rs != 0 && rt != 0)) { 2762 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2763 } else { 2764 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2765 } 2766 break; 2767 case OPC_NOR: 2768 if (rs != 0 && rt != 0) { 2769 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2770 } else if (rs == 0 && rt != 0) { 2771 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 2772 } else if (rs != 0 && rt == 0) { 2773 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 2774 } else { 2775 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 2776 } 2777 break; 2778 case OPC_OR: 2779 if (likely(rs != 0 && rt != 0)) { 2780 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2781 } else if (rs == 0 && rt != 0) { 2782 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2783 } else if (rs != 0 && rt == 0) { 2784 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2785 } else { 2786 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2787 } 2788 break; 2789 case OPC_XOR: 2790 if (likely(rs != 0 && rt != 0)) { 2791 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2792 } else if (rs == 0 && rt != 0) { 2793 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2794 } else if (rs != 0 && rt == 0) { 2795 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2796 } else { 2797 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2798 } 2799 break; 2800 } 2801 } 2802 2803 /* Set on lower than */ 2804 static void gen_slt(DisasContext *ctx, uint32_t opc, 2805 int rd, int rs, int rt) 2806 { 2807 TCGv t0, t1; 2808 2809 if (rd == 0) { 2810 /* If no destination, treat it as a NOP. */ 2811 return; 2812 } 2813 2814 t0 = tcg_temp_new(); 2815 t1 = tcg_temp_new(); 2816 gen_load_gpr(t0, rs); 2817 gen_load_gpr(t1, rt); 2818 switch (opc) { 2819 case OPC_SLT: 2820 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); 2821 break; 2822 case OPC_SLTU: 2823 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); 2824 break; 2825 } 2826 } 2827 2828 /* Shifts */ 2829 static void gen_shift(DisasContext *ctx, uint32_t opc, 2830 int rd, int rs, int rt) 2831 { 2832 TCGv t0, t1; 2833 2834 if (rd == 0) { 2835 /* 2836 * If no destination, treat it as a NOP. 2837 * For add & sub, we must generate the overflow exception when needed. 2838 */ 2839 return; 2840 } 2841 2842 t0 = tcg_temp_new(); 2843 t1 = tcg_temp_new(); 2844 gen_load_gpr(t0, rs); 2845 gen_load_gpr(t1, rt); 2846 switch (opc) { 2847 case OPC_SLLV: 2848 tcg_gen_andi_tl(t0, t0, 0x1f); 2849 tcg_gen_shl_tl(t0, t1, t0); 2850 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2851 break; 2852 case OPC_SRAV: 2853 tcg_gen_andi_tl(t0, t0, 0x1f); 2854 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2855 break; 2856 case OPC_SRLV: 2857 tcg_gen_ext32u_tl(t1, t1); 2858 tcg_gen_andi_tl(t0, t0, 0x1f); 2859 tcg_gen_shr_tl(t0, t1, t0); 2860 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2861 break; 2862 case OPC_ROTRV: 2863 { 2864 TCGv_i32 t2 = tcg_temp_new_i32(); 2865 TCGv_i32 t3 = tcg_temp_new_i32(); 2866 2867 tcg_gen_trunc_tl_i32(t2, t0); 2868 tcg_gen_trunc_tl_i32(t3, t1); 2869 tcg_gen_andi_i32(t2, t2, 0x1f); 2870 tcg_gen_rotr_i32(t2, t3, t2); 2871 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 2872 } 2873 break; 2874 #if defined(TARGET_MIPS64) 2875 case OPC_DSLLV: 2876 tcg_gen_andi_tl(t0, t0, 0x3f); 2877 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 2878 break; 2879 case OPC_DSRAV: 2880 tcg_gen_andi_tl(t0, t0, 0x3f); 2881 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2882 break; 2883 case OPC_DSRLV: 2884 tcg_gen_andi_tl(t0, t0, 0x3f); 2885 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 2886 break; 2887 case OPC_DROTRV: 2888 tcg_gen_andi_tl(t0, t0, 0x3f); 2889 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 2890 break; 2891 #endif 2892 } 2893 } 2894 2895 /* Arithmetic on HI/LO registers */ 2896 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) 2897 { 2898 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 2899 /* Treat as NOP. */ 2900 return; 2901 } 2902 2903 if (acc != 0) { 2904 check_dsp(ctx); 2905 } 2906 2907 switch (opc) { 2908 case OPC_MFHI: 2909 #if defined(TARGET_MIPS64) 2910 if (acc != 0) { 2911 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); 2912 } else 2913 #endif 2914 { 2915 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); 2916 } 2917 break; 2918 case OPC_MFLO: 2919 #if defined(TARGET_MIPS64) 2920 if (acc != 0) { 2921 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); 2922 } else 2923 #endif 2924 { 2925 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); 2926 } 2927 break; 2928 case OPC_MTHI: 2929 if (reg != 0) { 2930 #if defined(TARGET_MIPS64) 2931 if (acc != 0) { 2932 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); 2933 } else 2934 #endif 2935 { 2936 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); 2937 } 2938 } else { 2939 tcg_gen_movi_tl(cpu_HI[acc], 0); 2940 } 2941 break; 2942 case OPC_MTLO: 2943 if (reg != 0) { 2944 #if defined(TARGET_MIPS64) 2945 if (acc != 0) { 2946 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); 2947 } else 2948 #endif 2949 { 2950 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); 2951 } 2952 } else { 2953 tcg_gen_movi_tl(cpu_LO[acc], 0); 2954 } 2955 break; 2956 } 2957 } 2958 2959 static inline void gen_r6_ld(target_long addr, int reg, int memidx, 2960 MemOp memop) 2961 { 2962 TCGv t0 = tcg_temp_new(); 2963 tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop); 2964 gen_store_gpr(t0, reg); 2965 } 2966 2967 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, 2968 int rs) 2969 { 2970 target_long offset; 2971 target_long addr; 2972 2973 switch (MASK_OPC_PCREL_TOP2BITS(opc)) { 2974 case OPC_ADDIUPC: 2975 if (rs != 0) { 2976 offset = sextract32(ctx->opcode << 2, 0, 21); 2977 addr = addr_add(ctx, pc, offset); 2978 tcg_gen_movi_tl(cpu_gpr[rs], addr); 2979 } 2980 break; 2981 case R6_OPC_LWPC: 2982 offset = sextract32(ctx->opcode << 2, 0, 21); 2983 addr = addr_add(ctx, pc, offset); 2984 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_SL); 2985 break; 2986 #if defined(TARGET_MIPS64) 2987 case OPC_LWUPC: 2988 check_mips_64(ctx); 2989 offset = sextract32(ctx->opcode << 2, 0, 21); 2990 addr = addr_add(ctx, pc, offset); 2991 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UL); 2992 break; 2993 #endif 2994 default: 2995 switch (MASK_OPC_PCREL_TOP5BITS(opc)) { 2996 case OPC_AUIPC: 2997 if (rs != 0) { 2998 offset = sextract32(ctx->opcode, 0, 16) << 16; 2999 addr = addr_add(ctx, pc, offset); 3000 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3001 } 3002 break; 3003 case OPC_ALUIPC: 3004 if (rs != 0) { 3005 offset = sextract32(ctx->opcode, 0, 16) << 16; 3006 addr = ~0xFFFF & addr_add(ctx, pc, offset); 3007 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3008 } 3009 break; 3010 #if defined(TARGET_MIPS64) 3011 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */ 3012 case R6_OPC_LDPC + (1 << 16): 3013 case R6_OPC_LDPC + (2 << 16): 3014 case R6_OPC_LDPC + (3 << 16): 3015 check_mips_64(ctx); 3016 offset = sextract32(ctx->opcode << 3, 0, 21); 3017 addr = addr_add(ctx, (pc & ~0x7), offset); 3018 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 3019 break; 3020 #endif 3021 default: 3022 MIPS_INVAL("OPC_PCREL"); 3023 gen_reserved_instruction(ctx); 3024 break; 3025 } 3026 break; 3027 } 3028 } 3029 3030 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) 3031 { 3032 TCGv t0, t1; 3033 3034 if (rd == 0) { 3035 /* Treat as NOP. */ 3036 return; 3037 } 3038 3039 t0 = tcg_temp_new(); 3040 t1 = tcg_temp_new(); 3041 3042 gen_load_gpr(t0, rs); 3043 gen_load_gpr(t1, rt); 3044 3045 switch (opc) { 3046 case R6_OPC_DIV: 3047 { 3048 TCGv t2 = tcg_temp_new(); 3049 TCGv t3 = tcg_temp_new(); 3050 tcg_gen_ext32s_tl(t0, t0); 3051 tcg_gen_ext32s_tl(t1, t1); 3052 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3053 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3054 tcg_gen_and_tl(t2, t2, t3); 3055 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3056 tcg_gen_or_tl(t2, t2, t3); 3057 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3058 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3059 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3060 } 3061 break; 3062 case R6_OPC_MOD: 3063 { 3064 TCGv t2 = tcg_temp_new(); 3065 TCGv t3 = tcg_temp_new(); 3066 tcg_gen_ext32s_tl(t0, t0); 3067 tcg_gen_ext32s_tl(t1, t1); 3068 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3069 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3070 tcg_gen_and_tl(t2, t2, t3); 3071 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3072 tcg_gen_or_tl(t2, t2, t3); 3073 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3074 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3075 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3076 } 3077 break; 3078 case R6_OPC_DIVU: 3079 { 3080 tcg_gen_ext32u_tl(t0, t0); 3081 tcg_gen_ext32u_tl(t1, t1); 3082 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3083 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3084 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3085 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3086 } 3087 break; 3088 case R6_OPC_MODU: 3089 { 3090 tcg_gen_ext32u_tl(t0, t0); 3091 tcg_gen_ext32u_tl(t1, t1); 3092 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3093 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3094 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3095 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3096 } 3097 break; 3098 case R6_OPC_MUL: 3099 { 3100 TCGv_i32 t2 = tcg_temp_new_i32(); 3101 TCGv_i32 t3 = tcg_temp_new_i32(); 3102 tcg_gen_trunc_tl_i32(t2, t0); 3103 tcg_gen_trunc_tl_i32(t3, t1); 3104 tcg_gen_mul_i32(t2, t2, t3); 3105 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3106 } 3107 break; 3108 case R6_OPC_MUH: 3109 { 3110 TCGv_i32 t2 = tcg_temp_new_i32(); 3111 TCGv_i32 t3 = tcg_temp_new_i32(); 3112 tcg_gen_trunc_tl_i32(t2, t0); 3113 tcg_gen_trunc_tl_i32(t3, t1); 3114 tcg_gen_muls2_i32(t2, t3, t2, t3); 3115 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3116 } 3117 break; 3118 case R6_OPC_MULU: 3119 { 3120 TCGv_i32 t2 = tcg_temp_new_i32(); 3121 TCGv_i32 t3 = tcg_temp_new_i32(); 3122 tcg_gen_trunc_tl_i32(t2, t0); 3123 tcg_gen_trunc_tl_i32(t3, t1); 3124 tcg_gen_mul_i32(t2, t2, t3); 3125 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3126 } 3127 break; 3128 case R6_OPC_MUHU: 3129 { 3130 TCGv_i32 t2 = tcg_temp_new_i32(); 3131 TCGv_i32 t3 = tcg_temp_new_i32(); 3132 tcg_gen_trunc_tl_i32(t2, t0); 3133 tcg_gen_trunc_tl_i32(t3, t1); 3134 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3135 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3136 } 3137 break; 3138 #if defined(TARGET_MIPS64) 3139 case R6_OPC_DDIV: 3140 { 3141 TCGv t2 = tcg_temp_new(); 3142 TCGv t3 = tcg_temp_new(); 3143 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3144 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3145 tcg_gen_and_tl(t2, t2, t3); 3146 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3147 tcg_gen_or_tl(t2, t2, t3); 3148 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3149 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3150 } 3151 break; 3152 case R6_OPC_DMOD: 3153 { 3154 TCGv t2 = tcg_temp_new(); 3155 TCGv t3 = tcg_temp_new(); 3156 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3157 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3158 tcg_gen_and_tl(t2, t2, t3); 3159 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3160 tcg_gen_or_tl(t2, t2, t3); 3161 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3162 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3163 } 3164 break; 3165 case R6_OPC_DDIVU: 3166 { 3167 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3168 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3169 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); 3170 } 3171 break; 3172 case R6_OPC_DMODU: 3173 { 3174 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3175 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3176 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); 3177 } 3178 break; 3179 case R6_OPC_DMUL: 3180 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3181 break; 3182 case R6_OPC_DMUH: 3183 { 3184 TCGv t2 = tcg_temp_new(); 3185 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); 3186 } 3187 break; 3188 case R6_OPC_DMULU: 3189 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3190 break; 3191 case R6_OPC_DMUHU: 3192 { 3193 TCGv t2 = tcg_temp_new(); 3194 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); 3195 } 3196 break; 3197 #endif 3198 default: 3199 MIPS_INVAL("r6 mul/div"); 3200 gen_reserved_instruction(ctx); 3201 break; 3202 } 3203 } 3204 3205 #if defined(TARGET_MIPS64) 3206 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) 3207 { 3208 TCGv t0, t1; 3209 3210 t0 = tcg_temp_new(); 3211 t1 = tcg_temp_new(); 3212 3213 gen_load_gpr(t0, rs); 3214 gen_load_gpr(t1, rt); 3215 3216 switch (opc) { 3217 case MMI_OPC_DIV1: 3218 { 3219 TCGv t2 = tcg_temp_new(); 3220 TCGv t3 = tcg_temp_new(); 3221 tcg_gen_ext32s_tl(t0, t0); 3222 tcg_gen_ext32s_tl(t1, t1); 3223 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3224 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3225 tcg_gen_and_tl(t2, t2, t3); 3226 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3227 tcg_gen_or_tl(t2, t2, t3); 3228 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3229 tcg_gen_div_tl(cpu_LO[1], t0, t1); 3230 tcg_gen_rem_tl(cpu_HI[1], t0, t1); 3231 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3232 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3233 } 3234 break; 3235 case MMI_OPC_DIVU1: 3236 { 3237 TCGv t2 = tcg_constant_tl(0); 3238 TCGv t3 = tcg_constant_tl(1); 3239 tcg_gen_ext32u_tl(t0, t0); 3240 tcg_gen_ext32u_tl(t1, t1); 3241 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3242 tcg_gen_divu_tl(cpu_LO[1], t0, t1); 3243 tcg_gen_remu_tl(cpu_HI[1], t0, t1); 3244 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3245 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3246 } 3247 break; 3248 default: 3249 MIPS_INVAL("div1 TX79"); 3250 gen_reserved_instruction(ctx); 3251 break; 3252 } 3253 } 3254 #endif 3255 3256 static void gen_muldiv(DisasContext *ctx, uint32_t opc, 3257 int acc, int rs, int rt) 3258 { 3259 TCGv t0, t1; 3260 3261 t0 = tcg_temp_new(); 3262 t1 = tcg_temp_new(); 3263 3264 gen_load_gpr(t0, rs); 3265 gen_load_gpr(t1, rt); 3266 3267 if (acc != 0) { 3268 check_dsp(ctx); 3269 } 3270 3271 switch (opc) { 3272 case OPC_DIV: 3273 { 3274 TCGv t2 = tcg_temp_new(); 3275 TCGv t3 = tcg_temp_new(); 3276 tcg_gen_ext32s_tl(t0, t0); 3277 tcg_gen_ext32s_tl(t1, t1); 3278 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3279 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3280 tcg_gen_and_tl(t2, t2, t3); 3281 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3282 tcg_gen_or_tl(t2, t2, t3); 3283 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3284 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3285 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3286 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3287 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3288 } 3289 break; 3290 case OPC_DIVU: 3291 { 3292 TCGv t2 = tcg_constant_tl(0); 3293 TCGv t3 = tcg_constant_tl(1); 3294 tcg_gen_ext32u_tl(t0, t0); 3295 tcg_gen_ext32u_tl(t1, t1); 3296 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3297 tcg_gen_divu_tl(cpu_LO[acc], t0, t1); 3298 tcg_gen_remu_tl(cpu_HI[acc], t0, t1); 3299 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3300 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3301 } 3302 break; 3303 case OPC_MULT: 3304 { 3305 TCGv_i32 t2 = tcg_temp_new_i32(); 3306 TCGv_i32 t3 = tcg_temp_new_i32(); 3307 tcg_gen_trunc_tl_i32(t2, t0); 3308 tcg_gen_trunc_tl_i32(t3, t1); 3309 tcg_gen_muls2_i32(t2, t3, t2, t3); 3310 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3311 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3312 } 3313 break; 3314 case OPC_MULTU: 3315 { 3316 TCGv_i32 t2 = tcg_temp_new_i32(); 3317 TCGv_i32 t3 = tcg_temp_new_i32(); 3318 tcg_gen_trunc_tl_i32(t2, t0); 3319 tcg_gen_trunc_tl_i32(t3, t1); 3320 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3321 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3322 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3323 } 3324 break; 3325 #if defined(TARGET_MIPS64) 3326 case OPC_DDIV: 3327 { 3328 TCGv t2 = tcg_temp_new(); 3329 TCGv t3 = tcg_temp_new(); 3330 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3331 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3332 tcg_gen_and_tl(t2, t2, t3); 3333 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3334 tcg_gen_or_tl(t2, t2, t3); 3335 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3336 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3337 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3338 } 3339 break; 3340 case OPC_DDIVU: 3341 { 3342 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3343 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3344 tcg_gen_divu_i64(cpu_LO[acc], t0, t1); 3345 tcg_gen_remu_i64(cpu_HI[acc], t0, t1); 3346 } 3347 break; 3348 case OPC_DMULT: 3349 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3350 break; 3351 case OPC_DMULTU: 3352 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3353 break; 3354 #endif 3355 case OPC_MADD: 3356 { 3357 TCGv_i64 t2 = tcg_temp_new_i64(); 3358 TCGv_i64 t3 = tcg_temp_new_i64(); 3359 3360 tcg_gen_ext_tl_i64(t2, t0); 3361 tcg_gen_ext_tl_i64(t3, t1); 3362 tcg_gen_mul_i64(t2, t2, t3); 3363 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3364 tcg_gen_add_i64(t2, t2, t3); 3365 gen_move_low32(cpu_LO[acc], t2); 3366 gen_move_high32(cpu_HI[acc], t2); 3367 } 3368 break; 3369 case OPC_MADDU: 3370 { 3371 TCGv_i64 t2 = tcg_temp_new_i64(); 3372 TCGv_i64 t3 = tcg_temp_new_i64(); 3373 3374 tcg_gen_ext32u_tl(t0, t0); 3375 tcg_gen_ext32u_tl(t1, t1); 3376 tcg_gen_extu_tl_i64(t2, t0); 3377 tcg_gen_extu_tl_i64(t3, t1); 3378 tcg_gen_mul_i64(t2, t2, t3); 3379 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3380 tcg_gen_add_i64(t2, t2, t3); 3381 gen_move_low32(cpu_LO[acc], t2); 3382 gen_move_high32(cpu_HI[acc], t2); 3383 } 3384 break; 3385 case OPC_MSUB: 3386 { 3387 TCGv_i64 t2 = tcg_temp_new_i64(); 3388 TCGv_i64 t3 = tcg_temp_new_i64(); 3389 3390 tcg_gen_ext_tl_i64(t2, t0); 3391 tcg_gen_ext_tl_i64(t3, t1); 3392 tcg_gen_mul_i64(t2, t2, t3); 3393 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3394 tcg_gen_sub_i64(t2, t3, t2); 3395 gen_move_low32(cpu_LO[acc], t2); 3396 gen_move_high32(cpu_HI[acc], t2); 3397 } 3398 break; 3399 case OPC_MSUBU: 3400 { 3401 TCGv_i64 t2 = tcg_temp_new_i64(); 3402 TCGv_i64 t3 = tcg_temp_new_i64(); 3403 3404 tcg_gen_ext32u_tl(t0, t0); 3405 tcg_gen_ext32u_tl(t1, t1); 3406 tcg_gen_extu_tl_i64(t2, t0); 3407 tcg_gen_extu_tl_i64(t3, t1); 3408 tcg_gen_mul_i64(t2, t2, t3); 3409 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3410 tcg_gen_sub_i64(t2, t3, t2); 3411 gen_move_low32(cpu_LO[acc], t2); 3412 gen_move_high32(cpu_HI[acc], t2); 3413 } 3414 break; 3415 default: 3416 MIPS_INVAL("mul/div"); 3417 gen_reserved_instruction(ctx); 3418 break; 3419 } 3420 } 3421 3422 /* 3423 * These MULT[U] and MADD[U] instructions implemented in for example 3424 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core 3425 * architectures are special three-operand variants with the syntax 3426 * 3427 * MULT[U][1] rd, rs, rt 3428 * 3429 * such that 3430 * 3431 * (rd, LO, HI) <- rs * rt 3432 * 3433 * and 3434 * 3435 * MADD[U][1] rd, rs, rt 3436 * 3437 * such that 3438 * 3439 * (rd, LO, HI) <- (LO, HI) + rs * rt 3440 * 3441 * where the low-order 32-bits of the result is placed into both the 3442 * GPR rd and the special register LO. The high-order 32-bits of the 3443 * result is placed into the special register HI. 3444 * 3445 * If the GPR rd is omitted in assembly language, it is taken to be 0, 3446 * which is the zero register that always reads as 0. 3447 */ 3448 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, 3449 int rd, int rs, int rt) 3450 { 3451 TCGv t0 = tcg_temp_new(); 3452 TCGv t1 = tcg_temp_new(); 3453 int acc = 0; 3454 3455 gen_load_gpr(t0, rs); 3456 gen_load_gpr(t1, rt); 3457 3458 switch (opc) { 3459 case MMI_OPC_MULT1: 3460 acc = 1; 3461 /* Fall through */ 3462 case OPC_MULT: 3463 { 3464 TCGv_i32 t2 = tcg_temp_new_i32(); 3465 TCGv_i32 t3 = tcg_temp_new_i32(); 3466 tcg_gen_trunc_tl_i32(t2, t0); 3467 tcg_gen_trunc_tl_i32(t3, t1); 3468 tcg_gen_muls2_i32(t2, t3, t2, t3); 3469 if (rd) { 3470 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3471 } 3472 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3473 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3474 } 3475 break; 3476 case MMI_OPC_MULTU1: 3477 acc = 1; 3478 /* Fall through */ 3479 case OPC_MULTU: 3480 { 3481 TCGv_i32 t2 = tcg_temp_new_i32(); 3482 TCGv_i32 t3 = tcg_temp_new_i32(); 3483 tcg_gen_trunc_tl_i32(t2, t0); 3484 tcg_gen_trunc_tl_i32(t3, t1); 3485 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3486 if (rd) { 3487 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3488 } 3489 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3490 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3491 } 3492 break; 3493 case MMI_OPC_MADD1: 3494 acc = 1; 3495 /* Fall through */ 3496 case MMI_OPC_MADD: 3497 { 3498 TCGv_i64 t2 = tcg_temp_new_i64(); 3499 TCGv_i64 t3 = tcg_temp_new_i64(); 3500 3501 tcg_gen_ext_tl_i64(t2, t0); 3502 tcg_gen_ext_tl_i64(t3, t1); 3503 tcg_gen_mul_i64(t2, t2, t3); 3504 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3505 tcg_gen_add_i64(t2, t2, t3); 3506 gen_move_low32(cpu_LO[acc], t2); 3507 gen_move_high32(cpu_HI[acc], t2); 3508 if (rd) { 3509 gen_move_low32(cpu_gpr[rd], t2); 3510 } 3511 } 3512 break; 3513 case MMI_OPC_MADDU1: 3514 acc = 1; 3515 /* Fall through */ 3516 case MMI_OPC_MADDU: 3517 { 3518 TCGv_i64 t2 = tcg_temp_new_i64(); 3519 TCGv_i64 t3 = tcg_temp_new_i64(); 3520 3521 tcg_gen_ext32u_tl(t0, t0); 3522 tcg_gen_ext32u_tl(t1, t1); 3523 tcg_gen_extu_tl_i64(t2, t0); 3524 tcg_gen_extu_tl_i64(t3, t1); 3525 tcg_gen_mul_i64(t2, t2, t3); 3526 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3527 tcg_gen_add_i64(t2, t2, t3); 3528 gen_move_low32(cpu_LO[acc], t2); 3529 gen_move_high32(cpu_HI[acc], t2); 3530 if (rd) { 3531 gen_move_low32(cpu_gpr[rd], t2); 3532 } 3533 } 3534 break; 3535 default: 3536 MIPS_INVAL("mul/madd TXx9"); 3537 gen_reserved_instruction(ctx); 3538 break; 3539 } 3540 } 3541 3542 static void gen_cl(DisasContext *ctx, uint32_t opc, 3543 int rd, int rs) 3544 { 3545 TCGv t0; 3546 3547 if (rd == 0) { 3548 /* Treat as NOP. */ 3549 return; 3550 } 3551 t0 = cpu_gpr[rd]; 3552 gen_load_gpr(t0, rs); 3553 3554 switch (opc) { 3555 case OPC_CLO: 3556 case R6_OPC_CLO: 3557 #if defined(TARGET_MIPS64) 3558 case OPC_DCLO: 3559 case R6_OPC_DCLO: 3560 #endif 3561 tcg_gen_not_tl(t0, t0); 3562 break; 3563 } 3564 3565 switch (opc) { 3566 case OPC_CLO: 3567 case R6_OPC_CLO: 3568 case OPC_CLZ: 3569 case R6_OPC_CLZ: 3570 tcg_gen_ext32u_tl(t0, t0); 3571 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); 3572 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); 3573 break; 3574 #if defined(TARGET_MIPS64) 3575 case OPC_DCLO: 3576 case R6_OPC_DCLO: 3577 case OPC_DCLZ: 3578 case R6_OPC_DCLZ: 3579 tcg_gen_clzi_i64(t0, t0, 64); 3580 break; 3581 #endif 3582 } 3583 } 3584 3585 /* Loongson multimedia instructions */ 3586 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) 3587 { 3588 uint32_t opc, shift_max; 3589 TCGv_i64 t0, t1; 3590 TCGCond cond; 3591 3592 opc = MASK_LMMI(ctx->opcode); 3593 check_cp1_enabled(ctx); 3594 3595 t0 = tcg_temp_new_i64(); 3596 t1 = tcg_temp_new_i64(); 3597 gen_load_fpr64(ctx, t0, rs); 3598 gen_load_fpr64(ctx, t1, rt); 3599 3600 switch (opc) { 3601 case OPC_PADDSH: 3602 gen_helper_paddsh(t0, t0, t1); 3603 break; 3604 case OPC_PADDUSH: 3605 gen_helper_paddush(t0, t0, t1); 3606 break; 3607 case OPC_PADDH: 3608 gen_helper_paddh(t0, t0, t1); 3609 break; 3610 case OPC_PADDW: 3611 gen_helper_paddw(t0, t0, t1); 3612 break; 3613 case OPC_PADDSB: 3614 gen_helper_paddsb(t0, t0, t1); 3615 break; 3616 case OPC_PADDUSB: 3617 gen_helper_paddusb(t0, t0, t1); 3618 break; 3619 case OPC_PADDB: 3620 gen_helper_paddb(t0, t0, t1); 3621 break; 3622 3623 case OPC_PSUBSH: 3624 gen_helper_psubsh(t0, t0, t1); 3625 break; 3626 case OPC_PSUBUSH: 3627 gen_helper_psubush(t0, t0, t1); 3628 break; 3629 case OPC_PSUBH: 3630 gen_helper_psubh(t0, t0, t1); 3631 break; 3632 case OPC_PSUBW: 3633 gen_helper_psubw(t0, t0, t1); 3634 break; 3635 case OPC_PSUBSB: 3636 gen_helper_psubsb(t0, t0, t1); 3637 break; 3638 case OPC_PSUBUSB: 3639 gen_helper_psubusb(t0, t0, t1); 3640 break; 3641 case OPC_PSUBB: 3642 gen_helper_psubb(t0, t0, t1); 3643 break; 3644 3645 case OPC_PSHUFH: 3646 gen_helper_pshufh(t0, t0, t1); 3647 break; 3648 case OPC_PACKSSWH: 3649 gen_helper_packsswh(t0, t0, t1); 3650 break; 3651 case OPC_PACKSSHB: 3652 gen_helper_packsshb(t0, t0, t1); 3653 break; 3654 case OPC_PACKUSHB: 3655 gen_helper_packushb(t0, t0, t1); 3656 break; 3657 3658 case OPC_PUNPCKLHW: 3659 gen_helper_punpcklhw(t0, t0, t1); 3660 break; 3661 case OPC_PUNPCKHHW: 3662 gen_helper_punpckhhw(t0, t0, t1); 3663 break; 3664 case OPC_PUNPCKLBH: 3665 gen_helper_punpcklbh(t0, t0, t1); 3666 break; 3667 case OPC_PUNPCKHBH: 3668 gen_helper_punpckhbh(t0, t0, t1); 3669 break; 3670 case OPC_PUNPCKLWD: 3671 gen_helper_punpcklwd(t0, t0, t1); 3672 break; 3673 case OPC_PUNPCKHWD: 3674 gen_helper_punpckhwd(t0, t0, t1); 3675 break; 3676 3677 case OPC_PAVGH: 3678 gen_helper_pavgh(t0, t0, t1); 3679 break; 3680 case OPC_PAVGB: 3681 gen_helper_pavgb(t0, t0, t1); 3682 break; 3683 case OPC_PMAXSH: 3684 gen_helper_pmaxsh(t0, t0, t1); 3685 break; 3686 case OPC_PMINSH: 3687 gen_helper_pminsh(t0, t0, t1); 3688 break; 3689 case OPC_PMAXUB: 3690 gen_helper_pmaxub(t0, t0, t1); 3691 break; 3692 case OPC_PMINUB: 3693 gen_helper_pminub(t0, t0, t1); 3694 break; 3695 3696 case OPC_PCMPEQW: 3697 gen_helper_pcmpeqw(t0, t0, t1); 3698 break; 3699 case OPC_PCMPGTW: 3700 gen_helper_pcmpgtw(t0, t0, t1); 3701 break; 3702 case OPC_PCMPEQH: 3703 gen_helper_pcmpeqh(t0, t0, t1); 3704 break; 3705 case OPC_PCMPGTH: 3706 gen_helper_pcmpgth(t0, t0, t1); 3707 break; 3708 case OPC_PCMPEQB: 3709 gen_helper_pcmpeqb(t0, t0, t1); 3710 break; 3711 case OPC_PCMPGTB: 3712 gen_helper_pcmpgtb(t0, t0, t1); 3713 break; 3714 3715 case OPC_PSLLW: 3716 gen_helper_psllw(t0, t0, t1); 3717 break; 3718 case OPC_PSLLH: 3719 gen_helper_psllh(t0, t0, t1); 3720 break; 3721 case OPC_PSRLW: 3722 gen_helper_psrlw(t0, t0, t1); 3723 break; 3724 case OPC_PSRLH: 3725 gen_helper_psrlh(t0, t0, t1); 3726 break; 3727 case OPC_PSRAW: 3728 gen_helper_psraw(t0, t0, t1); 3729 break; 3730 case OPC_PSRAH: 3731 gen_helper_psrah(t0, t0, t1); 3732 break; 3733 3734 case OPC_PMULLH: 3735 gen_helper_pmullh(t0, t0, t1); 3736 break; 3737 case OPC_PMULHH: 3738 gen_helper_pmulhh(t0, t0, t1); 3739 break; 3740 case OPC_PMULHUH: 3741 gen_helper_pmulhuh(t0, t0, t1); 3742 break; 3743 case OPC_PMADDHW: 3744 gen_helper_pmaddhw(t0, t0, t1); 3745 break; 3746 3747 case OPC_PASUBUB: 3748 gen_helper_pasubub(t0, t0, t1); 3749 break; 3750 case OPC_BIADD: 3751 gen_helper_biadd(t0, t0); 3752 break; 3753 case OPC_PMOVMSKB: 3754 gen_helper_pmovmskb(t0, t0); 3755 break; 3756 3757 case OPC_PADDD: 3758 tcg_gen_add_i64(t0, t0, t1); 3759 break; 3760 case OPC_PSUBD: 3761 tcg_gen_sub_i64(t0, t0, t1); 3762 break; 3763 case OPC_XOR_CP2: 3764 tcg_gen_xor_i64(t0, t0, t1); 3765 break; 3766 case OPC_NOR_CP2: 3767 tcg_gen_nor_i64(t0, t0, t1); 3768 break; 3769 case OPC_AND_CP2: 3770 tcg_gen_and_i64(t0, t0, t1); 3771 break; 3772 case OPC_OR_CP2: 3773 tcg_gen_or_i64(t0, t0, t1); 3774 break; 3775 3776 case OPC_PANDN: 3777 tcg_gen_andc_i64(t0, t1, t0); 3778 break; 3779 3780 case OPC_PINSRH_0: 3781 tcg_gen_deposit_i64(t0, t0, t1, 0, 16); 3782 break; 3783 case OPC_PINSRH_1: 3784 tcg_gen_deposit_i64(t0, t0, t1, 16, 16); 3785 break; 3786 case OPC_PINSRH_2: 3787 tcg_gen_deposit_i64(t0, t0, t1, 32, 16); 3788 break; 3789 case OPC_PINSRH_3: 3790 tcg_gen_deposit_i64(t0, t0, t1, 48, 16); 3791 break; 3792 3793 case OPC_PEXTRH: 3794 tcg_gen_andi_i64(t1, t1, 3); 3795 tcg_gen_shli_i64(t1, t1, 4); 3796 tcg_gen_shr_i64(t0, t0, t1); 3797 tcg_gen_ext16u_i64(t0, t0); 3798 break; 3799 3800 case OPC_ADDU_CP2: 3801 tcg_gen_add_i64(t0, t0, t1); 3802 tcg_gen_ext32s_i64(t0, t0); 3803 break; 3804 case OPC_SUBU_CP2: 3805 tcg_gen_sub_i64(t0, t0, t1); 3806 tcg_gen_ext32s_i64(t0, t0); 3807 break; 3808 3809 case OPC_SLL_CP2: 3810 shift_max = 32; 3811 goto do_shift; 3812 case OPC_SRL_CP2: 3813 shift_max = 32; 3814 goto do_shift; 3815 case OPC_SRA_CP2: 3816 shift_max = 32; 3817 goto do_shift; 3818 case OPC_DSLL_CP2: 3819 shift_max = 64; 3820 goto do_shift; 3821 case OPC_DSRL_CP2: 3822 shift_max = 64; 3823 goto do_shift; 3824 case OPC_DSRA_CP2: 3825 shift_max = 64; 3826 goto do_shift; 3827 do_shift: 3828 /* Make sure shift count isn't TCG undefined behaviour. */ 3829 tcg_gen_andi_i64(t1, t1, shift_max - 1); 3830 3831 switch (opc) { 3832 case OPC_SLL_CP2: 3833 case OPC_DSLL_CP2: 3834 tcg_gen_shl_i64(t0, t0, t1); 3835 break; 3836 case OPC_SRA_CP2: 3837 case OPC_DSRA_CP2: 3838 /* 3839 * Since SRA is UndefinedResult without sign-extended inputs, 3840 * we can treat SRA and DSRA the same. 3841 */ 3842 tcg_gen_sar_i64(t0, t0, t1); 3843 break; 3844 case OPC_SRL_CP2: 3845 /* We want to shift in zeros for SRL; zero-extend first. */ 3846 tcg_gen_ext32u_i64(t0, t0); 3847 /* FALLTHRU */ 3848 case OPC_DSRL_CP2: 3849 tcg_gen_shr_i64(t0, t0, t1); 3850 break; 3851 } 3852 3853 if (shift_max == 32) { 3854 tcg_gen_ext32s_i64(t0, t0); 3855 } 3856 3857 /* Shifts larger than MAX produce zero. */ 3858 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); 3859 tcg_gen_neg_i64(t1, t1); 3860 tcg_gen_and_i64(t0, t0, t1); 3861 break; 3862 3863 case OPC_ADD_CP2: 3864 case OPC_DADD_CP2: 3865 { 3866 TCGv_i64 t2 = tcg_temp_new_i64(); 3867 TCGLabel *lab = gen_new_label(); 3868 3869 tcg_gen_mov_i64(t2, t0); 3870 tcg_gen_add_i64(t0, t1, t2); 3871 if (opc == OPC_ADD_CP2) { 3872 tcg_gen_ext32s_i64(t0, t0); 3873 } 3874 tcg_gen_xor_i64(t1, t1, t2); 3875 tcg_gen_xor_i64(t2, t2, t0); 3876 tcg_gen_andc_i64(t1, t2, t1); 3877 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 3878 generate_exception(ctx, EXCP_OVERFLOW); 3879 gen_set_label(lab); 3880 break; 3881 } 3882 3883 case OPC_SUB_CP2: 3884 case OPC_DSUB_CP2: 3885 { 3886 TCGv_i64 t2 = tcg_temp_new_i64(); 3887 TCGLabel *lab = gen_new_label(); 3888 3889 tcg_gen_mov_i64(t2, t0); 3890 tcg_gen_sub_i64(t0, t1, t2); 3891 if (opc == OPC_SUB_CP2) { 3892 tcg_gen_ext32s_i64(t0, t0); 3893 } 3894 tcg_gen_xor_i64(t1, t1, t2); 3895 tcg_gen_xor_i64(t2, t2, t0); 3896 tcg_gen_and_i64(t1, t1, t2); 3897 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 3898 generate_exception(ctx, EXCP_OVERFLOW); 3899 gen_set_label(lab); 3900 break; 3901 } 3902 3903 case OPC_PMULUW: 3904 tcg_gen_ext32u_i64(t0, t0); 3905 tcg_gen_ext32u_i64(t1, t1); 3906 tcg_gen_mul_i64(t0, t0, t1); 3907 break; 3908 3909 case OPC_SEQU_CP2: 3910 case OPC_SEQ_CP2: 3911 cond = TCG_COND_EQ; 3912 goto do_cc_cond; 3913 break; 3914 case OPC_SLTU_CP2: 3915 cond = TCG_COND_LTU; 3916 goto do_cc_cond; 3917 break; 3918 case OPC_SLT_CP2: 3919 cond = TCG_COND_LT; 3920 goto do_cc_cond; 3921 break; 3922 case OPC_SLEU_CP2: 3923 cond = TCG_COND_LEU; 3924 goto do_cc_cond; 3925 break; 3926 case OPC_SLE_CP2: 3927 cond = TCG_COND_LE; 3928 do_cc_cond: 3929 { 3930 int cc = (ctx->opcode >> 8) & 0x7; 3931 TCGv_i64 t64 = tcg_temp_new_i64(); 3932 TCGv_i32 t32 = tcg_temp_new_i32(); 3933 3934 tcg_gen_setcond_i64(cond, t64, t0, t1); 3935 tcg_gen_extrl_i64_i32(t32, t64); 3936 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, 3937 get_fp_bit(cc), 1); 3938 } 3939 return; 3940 default: 3941 MIPS_INVAL("loongson_cp2"); 3942 gen_reserved_instruction(ctx); 3943 return; 3944 } 3945 3946 gen_store_fpr64(ctx, t0, rd); 3947 } 3948 3949 static void gen_loongson_lswc2(DisasContext *ctx, int rt, 3950 int rs, int rd) 3951 { 3952 TCGv t0, t1; 3953 TCGv_i32 fp0; 3954 #if defined(TARGET_MIPS64) 3955 int lsq_rt1 = ctx->opcode & 0x1f; 3956 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4; 3957 #endif 3958 int shf_offset = sextract32(ctx->opcode, 6, 8); 3959 3960 t0 = tcg_temp_new(); 3961 3962 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { 3963 #if defined(TARGET_MIPS64) 3964 case OPC_GSLQ: 3965 t1 = tcg_temp_new(); 3966 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3967 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3968 ctx->default_tcg_memop_mask); 3969 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 3970 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3971 ctx->default_tcg_memop_mask); 3972 gen_store_gpr(t1, rt); 3973 gen_store_gpr(t0, lsq_rt1); 3974 break; 3975 case OPC_GSLQC1: 3976 check_cp1_enabled(ctx); 3977 t1 = tcg_temp_new(); 3978 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3979 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3980 ctx->default_tcg_memop_mask); 3981 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 3982 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3983 ctx->default_tcg_memop_mask); 3984 gen_store_fpr64(ctx, t1, rt); 3985 gen_store_fpr64(ctx, t0, lsq_rt1); 3986 break; 3987 case OPC_GSSQ: 3988 t1 = tcg_temp_new(); 3989 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3990 gen_load_gpr(t1, rt); 3991 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3992 ctx->default_tcg_memop_mask); 3993 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 3994 gen_load_gpr(t1, lsq_rt1); 3995 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3996 ctx->default_tcg_memop_mask); 3997 break; 3998 case OPC_GSSQC1: 3999 check_cp1_enabled(ctx); 4000 t1 = tcg_temp_new(); 4001 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4002 gen_load_fpr64(ctx, t1, rt); 4003 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4004 ctx->default_tcg_memop_mask); 4005 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4006 gen_load_fpr64(ctx, t1, lsq_rt1); 4007 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4008 ctx->default_tcg_memop_mask); 4009 break; 4010 #endif 4011 case OPC_GSSHFL: 4012 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4013 case OPC_GSLWLC1: 4014 check_cp1_enabled(ctx); 4015 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4016 fp0 = tcg_temp_new_i32(); 4017 gen_load_fpr32(ctx, fp0, rt); 4018 t1 = tcg_temp_new(); 4019 tcg_gen_ext_i32_tl(t1, fp0); 4020 gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 4021 tcg_gen_trunc_tl_i32(fp0, t1); 4022 gen_store_fpr32(ctx, fp0, rt); 4023 break; 4024 case OPC_GSLWRC1: 4025 check_cp1_enabled(ctx); 4026 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4027 fp0 = tcg_temp_new_i32(); 4028 gen_load_fpr32(ctx, fp0, rt); 4029 t1 = tcg_temp_new(); 4030 tcg_gen_ext_i32_tl(t1, fp0); 4031 gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 4032 tcg_gen_trunc_tl_i32(fp0, t1); 4033 gen_store_fpr32(ctx, fp0, rt); 4034 break; 4035 #if defined(TARGET_MIPS64) 4036 case OPC_GSLDLC1: 4037 check_cp1_enabled(ctx); 4038 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4039 t1 = tcg_temp_new(); 4040 gen_load_fpr64(ctx, t1, rt); 4041 gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 4042 gen_store_fpr64(ctx, t1, rt); 4043 break; 4044 case OPC_GSLDRC1: 4045 check_cp1_enabled(ctx); 4046 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4047 t1 = tcg_temp_new(); 4048 gen_load_fpr64(ctx, t1, rt); 4049 gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 4050 gen_store_fpr64(ctx, t1, rt); 4051 break; 4052 #endif 4053 default: 4054 MIPS_INVAL("loongson_gsshfl"); 4055 gen_reserved_instruction(ctx); 4056 break; 4057 } 4058 break; 4059 case OPC_GSSHFS: 4060 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4061 case OPC_GSSWLC1: 4062 check_cp1_enabled(ctx); 4063 t1 = tcg_temp_new(); 4064 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4065 fp0 = tcg_temp_new_i32(); 4066 gen_load_fpr32(ctx, fp0, rt); 4067 tcg_gen_ext_i32_tl(t1, fp0); 4068 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); 4069 break; 4070 case OPC_GSSWRC1: 4071 check_cp1_enabled(ctx); 4072 t1 = tcg_temp_new(); 4073 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4074 fp0 = tcg_temp_new_i32(); 4075 gen_load_fpr32(ctx, fp0, rt); 4076 tcg_gen_ext_i32_tl(t1, fp0); 4077 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); 4078 break; 4079 #if defined(TARGET_MIPS64) 4080 case OPC_GSSDLC1: 4081 check_cp1_enabled(ctx); 4082 t1 = tcg_temp_new(); 4083 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4084 gen_load_fpr64(ctx, t1, rt); 4085 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); 4086 break; 4087 case OPC_GSSDRC1: 4088 check_cp1_enabled(ctx); 4089 t1 = tcg_temp_new(); 4090 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4091 gen_load_fpr64(ctx, t1, rt); 4092 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); 4093 break; 4094 #endif 4095 default: 4096 MIPS_INVAL("loongson_gsshfs"); 4097 gen_reserved_instruction(ctx); 4098 break; 4099 } 4100 break; 4101 default: 4102 MIPS_INVAL("loongson_gslsq"); 4103 gen_reserved_instruction(ctx); 4104 break; 4105 } 4106 } 4107 4108 /* Loongson EXT LDC2/SDC2 */ 4109 static void gen_loongson_lsdc2(DisasContext *ctx, int rt, 4110 int rs, int rd) 4111 { 4112 int offset = sextract32(ctx->opcode, 3, 8); 4113 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode); 4114 TCGv t0, t1; 4115 TCGv_i32 fp0; 4116 4117 /* Pre-conditions */ 4118 switch (opc) { 4119 case OPC_GSLBX: 4120 case OPC_GSLHX: 4121 case OPC_GSLWX: 4122 case OPC_GSLDX: 4123 /* prefetch, implement as NOP */ 4124 if (rt == 0) { 4125 return; 4126 } 4127 break; 4128 case OPC_GSSBX: 4129 case OPC_GSSHX: 4130 case OPC_GSSWX: 4131 case OPC_GSSDX: 4132 break; 4133 case OPC_GSLWXC1: 4134 #if defined(TARGET_MIPS64) 4135 case OPC_GSLDXC1: 4136 #endif 4137 check_cp1_enabled(ctx); 4138 /* prefetch, implement as NOP */ 4139 if (rt == 0) { 4140 return; 4141 } 4142 break; 4143 case OPC_GSSWXC1: 4144 #if defined(TARGET_MIPS64) 4145 case OPC_GSSDXC1: 4146 #endif 4147 check_cp1_enabled(ctx); 4148 break; 4149 default: 4150 MIPS_INVAL("loongson_lsdc2"); 4151 gen_reserved_instruction(ctx); 4152 return; 4153 break; 4154 } 4155 4156 t0 = tcg_temp_new(); 4157 4158 gen_base_offset_addr(ctx, t0, rs, offset); 4159 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4160 4161 switch (opc) { 4162 case OPC_GSLBX: 4163 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); 4164 gen_store_gpr(t0, rt); 4165 break; 4166 case OPC_GSLHX: 4167 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW | 4168 ctx->default_tcg_memop_mask); 4169 gen_store_gpr(t0, rt); 4170 break; 4171 case OPC_GSLWX: 4172 gen_base_offset_addr(ctx, t0, rs, offset); 4173 if (rd) { 4174 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4175 } 4176 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 4177 ctx->default_tcg_memop_mask); 4178 gen_store_gpr(t0, rt); 4179 break; 4180 #if defined(TARGET_MIPS64) 4181 case OPC_GSLDX: 4182 gen_base_offset_addr(ctx, t0, rs, offset); 4183 if (rd) { 4184 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4185 } 4186 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4187 ctx->default_tcg_memop_mask); 4188 gen_store_gpr(t0, rt); 4189 break; 4190 #endif 4191 case OPC_GSLWXC1: 4192 gen_base_offset_addr(ctx, t0, rs, offset); 4193 if (rd) { 4194 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4195 } 4196 fp0 = tcg_temp_new_i32(); 4197 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 4198 ctx->default_tcg_memop_mask); 4199 gen_store_fpr32(ctx, fp0, rt); 4200 break; 4201 #if defined(TARGET_MIPS64) 4202 case OPC_GSLDXC1: 4203 gen_base_offset_addr(ctx, t0, rs, offset); 4204 if (rd) { 4205 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4206 } 4207 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4208 ctx->default_tcg_memop_mask); 4209 gen_store_fpr64(ctx, t0, rt); 4210 break; 4211 #endif 4212 case OPC_GSSBX: 4213 t1 = tcg_temp_new(); 4214 gen_load_gpr(t1, rt); 4215 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); 4216 break; 4217 case OPC_GSSHX: 4218 t1 = tcg_temp_new(); 4219 gen_load_gpr(t1, rt); 4220 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UW | 4221 ctx->default_tcg_memop_mask); 4222 break; 4223 case OPC_GSSWX: 4224 t1 = tcg_temp_new(); 4225 gen_load_gpr(t1, rt); 4226 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 4227 ctx->default_tcg_memop_mask); 4228 break; 4229 #if defined(TARGET_MIPS64) 4230 case OPC_GSSDX: 4231 t1 = tcg_temp_new(); 4232 gen_load_gpr(t1, rt); 4233 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4234 ctx->default_tcg_memop_mask); 4235 break; 4236 #endif 4237 case OPC_GSSWXC1: 4238 fp0 = tcg_temp_new_i32(); 4239 gen_load_fpr32(ctx, fp0, rt); 4240 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 4241 ctx->default_tcg_memop_mask); 4242 break; 4243 #if defined(TARGET_MIPS64) 4244 case OPC_GSSDXC1: 4245 t1 = tcg_temp_new(); 4246 gen_load_fpr64(ctx, t1, rt); 4247 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4248 ctx->default_tcg_memop_mask); 4249 break; 4250 #endif 4251 default: 4252 break; 4253 } 4254 } 4255 4256 /* Traps */ 4257 static void gen_trap(DisasContext *ctx, uint32_t opc, 4258 int rs, int rt, int16_t imm, int code) 4259 { 4260 int cond; 4261 TCGv t0 = tcg_temp_new(); 4262 TCGv t1 = tcg_temp_new(); 4263 4264 cond = 0; 4265 /* Load needed operands */ 4266 switch (opc) { 4267 case OPC_TEQ: 4268 case OPC_TGE: 4269 case OPC_TGEU: 4270 case OPC_TLT: 4271 case OPC_TLTU: 4272 case OPC_TNE: 4273 /* Compare two registers */ 4274 if (rs != rt) { 4275 gen_load_gpr(t0, rs); 4276 gen_load_gpr(t1, rt); 4277 cond = 1; 4278 } 4279 break; 4280 case OPC_TEQI: 4281 case OPC_TGEI: 4282 case OPC_TGEIU: 4283 case OPC_TLTI: 4284 case OPC_TLTIU: 4285 case OPC_TNEI: 4286 /* Compare register to immediate */ 4287 if (rs != 0 || imm != 0) { 4288 gen_load_gpr(t0, rs); 4289 tcg_gen_movi_tl(t1, (int32_t)imm); 4290 cond = 1; 4291 } 4292 break; 4293 } 4294 if (cond == 0) { 4295 switch (opc) { 4296 case OPC_TEQ: /* rs == rs */ 4297 case OPC_TEQI: /* r0 == 0 */ 4298 case OPC_TGE: /* rs >= rs */ 4299 case OPC_TGEI: /* r0 >= 0 */ 4300 case OPC_TGEU: /* rs >= rs unsigned */ 4301 case OPC_TGEIU: /* r0 >= 0 unsigned */ 4302 /* Always trap */ 4303 #ifdef CONFIG_USER_ONLY 4304 /* Pass the break code along to cpu_loop. */ 4305 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 4306 offsetof(CPUMIPSState, error_code)); 4307 #endif 4308 generate_exception_end(ctx, EXCP_TRAP); 4309 break; 4310 case OPC_TLT: /* rs < rs */ 4311 case OPC_TLTI: /* r0 < 0 */ 4312 case OPC_TLTU: /* rs < rs unsigned */ 4313 case OPC_TLTIU: /* r0 < 0 unsigned */ 4314 case OPC_TNE: /* rs != rs */ 4315 case OPC_TNEI: /* r0 != 0 */ 4316 /* Never trap: treat as NOP. */ 4317 break; 4318 } 4319 } else { 4320 TCGLabel *l1 = gen_new_label(); 4321 4322 switch (opc) { 4323 case OPC_TEQ: 4324 case OPC_TEQI: 4325 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 4326 break; 4327 case OPC_TGE: 4328 case OPC_TGEI: 4329 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 4330 break; 4331 case OPC_TGEU: 4332 case OPC_TGEIU: 4333 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 4334 break; 4335 case OPC_TLT: 4336 case OPC_TLTI: 4337 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 4338 break; 4339 case OPC_TLTU: 4340 case OPC_TLTIU: 4341 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 4342 break; 4343 case OPC_TNE: 4344 case OPC_TNEI: 4345 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 4346 break; 4347 } 4348 #ifdef CONFIG_USER_ONLY 4349 /* Pass the break code along to cpu_loop. */ 4350 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 4351 offsetof(CPUMIPSState, error_code)); 4352 #endif 4353 /* Like save_cpu_state, only don't update saved values. */ 4354 if (ctx->base.pc_next != ctx->saved_pc) { 4355 gen_save_pc(ctx->base.pc_next); 4356 } 4357 if (ctx->hflags != ctx->saved_hflags) { 4358 tcg_gen_movi_i32(hflags, ctx->hflags); 4359 } 4360 generate_exception(ctx, EXCP_TRAP); 4361 gen_set_label(l1); 4362 } 4363 } 4364 4365 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 4366 { 4367 if (translator_use_goto_tb(&ctx->base, dest)) { 4368 tcg_gen_goto_tb(n); 4369 gen_save_pc(dest); 4370 tcg_gen_exit_tb(ctx->base.tb, n); 4371 } else { 4372 gen_save_pc(dest); 4373 tcg_gen_lookup_and_goto_ptr(); 4374 } 4375 } 4376 4377 /* Branches (before delay slot) */ 4378 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, 4379 int insn_bytes, 4380 int rs, int rt, int32_t offset, 4381 int delayslot_size) 4382 { 4383 target_ulong btgt = -1; 4384 int blink = 0; 4385 int bcond_compute = 0; 4386 TCGv t0 = tcg_temp_new(); 4387 TCGv t1 = tcg_temp_new(); 4388 4389 if (ctx->hflags & MIPS_HFLAG_BMASK) { 4390 #ifdef MIPS_DEBUG_DISAS 4391 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 4392 VADDR_PRIx "\n", ctx->base.pc_next); 4393 #endif 4394 gen_reserved_instruction(ctx); 4395 goto out; 4396 } 4397 4398 /* Load needed operands */ 4399 switch (opc) { 4400 case OPC_BEQ: 4401 case OPC_BEQL: 4402 case OPC_BNE: 4403 case OPC_BNEL: 4404 /* Compare two registers */ 4405 if (rs != rt) { 4406 gen_load_gpr(t0, rs); 4407 gen_load_gpr(t1, rt); 4408 bcond_compute = 1; 4409 } 4410 btgt = ctx->base.pc_next + insn_bytes + offset; 4411 break; 4412 case OPC_BGEZ: 4413 case OPC_BGEZAL: 4414 case OPC_BGEZALL: 4415 case OPC_BGEZL: 4416 case OPC_BGTZ: 4417 case OPC_BGTZL: 4418 case OPC_BLEZ: 4419 case OPC_BLEZL: 4420 case OPC_BLTZ: 4421 case OPC_BLTZAL: 4422 case OPC_BLTZALL: 4423 case OPC_BLTZL: 4424 /* Compare to zero */ 4425 if (rs != 0) { 4426 gen_load_gpr(t0, rs); 4427 bcond_compute = 1; 4428 } 4429 btgt = ctx->base.pc_next + insn_bytes + offset; 4430 break; 4431 case OPC_BPOSGE32: 4432 #if defined(TARGET_MIPS64) 4433 case OPC_BPOSGE64: 4434 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F); 4435 #else 4436 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 4437 #endif 4438 bcond_compute = 1; 4439 btgt = ctx->base.pc_next + insn_bytes + offset; 4440 break; 4441 case OPC_J: 4442 case OPC_JAL: 4443 { 4444 /* Jump to immediate */ 4445 int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000 4446 : 0xF0000000; 4447 btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask) 4448 | (uint32_t)offset; 4449 break; 4450 } 4451 case OPC_JALX: 4452 /* Jump to immediate */ 4453 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) | 4454 (uint32_t)offset; 4455 break; 4456 case OPC_JR: 4457 case OPC_JALR: 4458 /* Jump to register */ 4459 if (offset != 0 && offset != 16) { 4460 /* 4461 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 4462 * others are reserved. 4463 */ 4464 MIPS_INVAL("jump hint"); 4465 gen_reserved_instruction(ctx); 4466 goto out; 4467 } 4468 gen_load_gpr(btarget, rs); 4469 break; 4470 default: 4471 MIPS_INVAL("branch/jump"); 4472 gen_reserved_instruction(ctx); 4473 goto out; 4474 } 4475 if (bcond_compute == 0) { 4476 /* No condition to be computed */ 4477 switch (opc) { 4478 case OPC_BEQ: /* rx == rx */ 4479 case OPC_BEQL: /* rx == rx likely */ 4480 case OPC_BGEZ: /* 0 >= 0 */ 4481 case OPC_BGEZL: /* 0 >= 0 likely */ 4482 case OPC_BLEZ: /* 0 <= 0 */ 4483 case OPC_BLEZL: /* 0 <= 0 likely */ 4484 /* Always take */ 4485 ctx->hflags |= MIPS_HFLAG_B; 4486 break; 4487 case OPC_BGEZAL: /* 0 >= 0 */ 4488 case OPC_BGEZALL: /* 0 >= 0 likely */ 4489 /* Always take and link */ 4490 blink = 31; 4491 ctx->hflags |= MIPS_HFLAG_B; 4492 break; 4493 case OPC_BNE: /* rx != rx */ 4494 case OPC_BGTZ: /* 0 > 0 */ 4495 case OPC_BLTZ: /* 0 < 0 */ 4496 /* Treat as NOP. */ 4497 goto out; 4498 case OPC_BLTZAL: /* 0 < 0 */ 4499 /* 4500 * Handle as an unconditional branch to get correct delay 4501 * slot checking. 4502 */ 4503 blink = 31; 4504 btgt = ctx->base.pc_next + insn_bytes + delayslot_size; 4505 ctx->hflags |= MIPS_HFLAG_B; 4506 break; 4507 case OPC_BLTZALL: /* 0 < 0 likely */ 4508 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 4509 /* Skip the instruction in the delay slot */ 4510 ctx->base.pc_next += 4; 4511 goto out; 4512 case OPC_BNEL: /* rx != rx likely */ 4513 case OPC_BGTZL: /* 0 > 0 likely */ 4514 case OPC_BLTZL: /* 0 < 0 likely */ 4515 /* Skip the instruction in the delay slot */ 4516 ctx->base.pc_next += 4; 4517 goto out; 4518 case OPC_J: 4519 ctx->hflags |= MIPS_HFLAG_B; 4520 break; 4521 case OPC_JALX: 4522 ctx->hflags |= MIPS_HFLAG_BX; 4523 /* Fallthrough */ 4524 case OPC_JAL: 4525 blink = 31; 4526 ctx->hflags |= MIPS_HFLAG_B; 4527 break; 4528 case OPC_JR: 4529 ctx->hflags |= MIPS_HFLAG_BR; 4530 break; 4531 case OPC_JALR: 4532 blink = rt; 4533 ctx->hflags |= MIPS_HFLAG_BR; 4534 break; 4535 default: 4536 MIPS_INVAL("branch/jump"); 4537 gen_reserved_instruction(ctx); 4538 goto out; 4539 } 4540 } else { 4541 switch (opc) { 4542 case OPC_BEQ: 4543 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 4544 goto not_likely; 4545 case OPC_BEQL: 4546 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 4547 goto likely; 4548 case OPC_BNE: 4549 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 4550 goto not_likely; 4551 case OPC_BNEL: 4552 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 4553 goto likely; 4554 case OPC_BGEZ: 4555 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4556 goto not_likely; 4557 case OPC_BGEZL: 4558 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4559 goto likely; 4560 case OPC_BGEZAL: 4561 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4562 blink = 31; 4563 goto not_likely; 4564 case OPC_BGEZALL: 4565 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4566 blink = 31; 4567 goto likely; 4568 case OPC_BGTZ: 4569 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 4570 goto not_likely; 4571 case OPC_BGTZL: 4572 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 4573 goto likely; 4574 case OPC_BLEZ: 4575 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 4576 goto not_likely; 4577 case OPC_BLEZL: 4578 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 4579 goto likely; 4580 case OPC_BLTZ: 4581 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4582 goto not_likely; 4583 case OPC_BLTZL: 4584 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4585 goto likely; 4586 case OPC_BPOSGE32: 4587 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 4588 goto not_likely; 4589 #if defined(TARGET_MIPS64) 4590 case OPC_BPOSGE64: 4591 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64); 4592 goto not_likely; 4593 #endif 4594 case OPC_BLTZAL: 4595 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4596 blink = 31; 4597 not_likely: 4598 ctx->hflags |= MIPS_HFLAG_BC; 4599 break; 4600 case OPC_BLTZALL: 4601 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4602 blink = 31; 4603 likely: 4604 ctx->hflags |= MIPS_HFLAG_BL; 4605 break; 4606 default: 4607 MIPS_INVAL("conditional branch/jump"); 4608 gen_reserved_instruction(ctx); 4609 goto out; 4610 } 4611 } 4612 4613 ctx->btarget = btgt; 4614 4615 switch (delayslot_size) { 4616 case 2: 4617 ctx->hflags |= MIPS_HFLAG_BDS16; 4618 break; 4619 case 4: 4620 ctx->hflags |= MIPS_HFLAG_BDS32; 4621 break; 4622 } 4623 4624 if (blink > 0) { 4625 int post_delay = insn_bytes + delayslot_size; 4626 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); 4627 4628 tcg_gen_movi_tl(cpu_gpr[blink], 4629 ctx->base.pc_next + post_delay + lowbit); 4630 } 4631 4632 out: 4633 if (insn_bytes == 2) { 4634 ctx->hflags |= MIPS_HFLAG_B16; 4635 } 4636 } 4637 4638 4639 /* special3 bitfield operations */ 4640 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, 4641 int rs, int lsb, int msb) 4642 { 4643 TCGv t0 = tcg_temp_new(); 4644 TCGv t1 = tcg_temp_new(); 4645 4646 gen_load_gpr(t1, rs); 4647 switch (opc) { 4648 case OPC_EXT: 4649 if (lsb + msb > 31) { 4650 goto fail; 4651 } 4652 if (msb != 31) { 4653 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 4654 } else { 4655 /* 4656 * The two checks together imply that lsb == 0, 4657 * so this is a simple sign-extension. 4658 */ 4659 tcg_gen_ext32s_tl(t0, t1); 4660 } 4661 break; 4662 #if defined(TARGET_MIPS64) 4663 case OPC_DEXTU: 4664 lsb += 32; 4665 goto do_dext; 4666 case OPC_DEXTM: 4667 msb += 32; 4668 goto do_dext; 4669 case OPC_DEXT: 4670 do_dext: 4671 if (lsb + msb > 63) { 4672 goto fail; 4673 } 4674 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 4675 break; 4676 #endif 4677 case OPC_INS: 4678 if (lsb > msb) { 4679 goto fail; 4680 } 4681 gen_load_gpr(t0, rt); 4682 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 4683 tcg_gen_ext32s_tl(t0, t0); 4684 break; 4685 #if defined(TARGET_MIPS64) 4686 case OPC_DINSU: 4687 lsb += 32; 4688 /* FALLTHRU */ 4689 case OPC_DINSM: 4690 msb += 32; 4691 /* FALLTHRU */ 4692 case OPC_DINS: 4693 if (lsb > msb) { 4694 goto fail; 4695 } 4696 gen_load_gpr(t0, rt); 4697 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 4698 break; 4699 #endif 4700 default: 4701 fail: 4702 MIPS_INVAL("bitops"); 4703 gen_reserved_instruction(ctx); 4704 return; 4705 } 4706 gen_store_gpr(t0, rt); 4707 } 4708 4709 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) 4710 { 4711 TCGv t0; 4712 4713 if (rd == 0) { 4714 /* If no destination, treat it as a NOP. */ 4715 return; 4716 } 4717 4718 t0 = tcg_temp_new(); 4719 gen_load_gpr(t0, rt); 4720 switch (op2) { 4721 case OPC_WSBH: 4722 { 4723 TCGv t1 = tcg_temp_new(); 4724 TCGv t2 = tcg_constant_tl(0x00FF00FF); 4725 4726 tcg_gen_shri_tl(t1, t0, 8); 4727 tcg_gen_and_tl(t1, t1, t2); 4728 tcg_gen_and_tl(t0, t0, t2); 4729 tcg_gen_shli_tl(t0, t0, 8); 4730 tcg_gen_or_tl(t0, t0, t1); 4731 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 4732 } 4733 break; 4734 case OPC_SEB: 4735 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 4736 break; 4737 case OPC_SEH: 4738 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 4739 break; 4740 #if defined(TARGET_MIPS64) 4741 case OPC_DSBH: 4742 { 4743 TCGv t1 = tcg_temp_new(); 4744 TCGv t2 = tcg_constant_tl(0x00FF00FF00FF00FFULL); 4745 4746 tcg_gen_shri_tl(t1, t0, 8); 4747 tcg_gen_and_tl(t1, t1, t2); 4748 tcg_gen_and_tl(t0, t0, t2); 4749 tcg_gen_shli_tl(t0, t0, 8); 4750 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 4751 } 4752 break; 4753 case OPC_DSHD: 4754 { 4755 TCGv t1 = tcg_temp_new(); 4756 TCGv t2 = tcg_constant_tl(0x0000FFFF0000FFFFULL); 4757 4758 tcg_gen_shri_tl(t1, t0, 16); 4759 tcg_gen_and_tl(t1, t1, t2); 4760 tcg_gen_and_tl(t0, t0, t2); 4761 tcg_gen_shli_tl(t0, t0, 16); 4762 tcg_gen_or_tl(t0, t0, t1); 4763 tcg_gen_shri_tl(t1, t0, 32); 4764 tcg_gen_shli_tl(t0, t0, 32); 4765 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 4766 } 4767 break; 4768 #endif 4769 default: 4770 MIPS_INVAL("bsfhl"); 4771 gen_reserved_instruction(ctx); 4772 return; 4773 } 4774 } 4775 4776 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, 4777 int rt, int bits) 4778 { 4779 TCGv t0; 4780 if (rd == 0) { 4781 /* Treat as NOP. */ 4782 return; 4783 } 4784 t0 = tcg_temp_new(); 4785 if (bits == 0 || bits == wordsz) { 4786 if (bits == 0) { 4787 gen_load_gpr(t0, rt); 4788 } else { 4789 gen_load_gpr(t0, rs); 4790 } 4791 switch (wordsz) { 4792 case 32: 4793 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 4794 break; 4795 #if defined(TARGET_MIPS64) 4796 case 64: 4797 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4798 break; 4799 #endif 4800 } 4801 } else { 4802 TCGv t1 = tcg_temp_new(); 4803 gen_load_gpr(t0, rt); 4804 gen_load_gpr(t1, rs); 4805 switch (wordsz) { 4806 case 32: 4807 { 4808 TCGv_i64 t2 = tcg_temp_new_i64(); 4809 tcg_gen_concat_tl_i64(t2, t1, t0); 4810 tcg_gen_shri_i64(t2, t2, 32 - bits); 4811 gen_move_low32(cpu_gpr[rd], t2); 4812 } 4813 break; 4814 #if defined(TARGET_MIPS64) 4815 case 64: 4816 tcg_gen_shli_tl(t0, t0, bits); 4817 tcg_gen_shri_tl(t1, t1, 64 - bits); 4818 tcg_gen_or_tl(cpu_gpr[rd], t1, t0); 4819 break; 4820 #endif 4821 } 4822 } 4823 } 4824 4825 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp) 4826 { 4827 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); 4828 } 4829 4830 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) 4831 { 4832 TCGv t0; 4833 if (rd == 0) { 4834 /* Treat as NOP. */ 4835 return; 4836 } 4837 t0 = tcg_temp_new(); 4838 gen_load_gpr(t0, rt); 4839 switch (opc) { 4840 case OPC_BITSWAP: 4841 gen_helper_bitswap(cpu_gpr[rd], t0); 4842 break; 4843 #if defined(TARGET_MIPS64) 4844 case OPC_DBITSWAP: 4845 gen_helper_dbitswap(cpu_gpr[rd], t0); 4846 break; 4847 #endif 4848 } 4849 } 4850 4851 #ifndef CONFIG_USER_ONLY 4852 /* CP0 (MMU and control) */ 4853 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off) 4854 { 4855 TCGv_i64 t0 = tcg_temp_new_i64(); 4856 TCGv_i64 t1 = tcg_temp_new_i64(); 4857 4858 tcg_gen_ext_tl_i64(t0, arg); 4859 tcg_gen_ld_i64(t1, tcg_env, off); 4860 #if defined(TARGET_MIPS64) 4861 tcg_gen_deposit_i64(t1, t1, t0, 30, 32); 4862 #else 4863 tcg_gen_concat32_i64(t1, t1, t0); 4864 #endif 4865 tcg_gen_st_i64(t1, tcg_env, off); 4866 } 4867 4868 static inline void gen_mthc0_store64(TCGv arg, target_ulong off) 4869 { 4870 TCGv_i64 t0 = tcg_temp_new_i64(); 4871 TCGv_i64 t1 = tcg_temp_new_i64(); 4872 4873 tcg_gen_ext_tl_i64(t0, arg); 4874 tcg_gen_ld_i64(t1, tcg_env, off); 4875 tcg_gen_concat32_i64(t1, t1, t0); 4876 tcg_gen_st_i64(t1, tcg_env, off); 4877 } 4878 4879 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off) 4880 { 4881 TCGv_i64 t0 = tcg_temp_new_i64(); 4882 4883 tcg_gen_ld_i64(t0, tcg_env, off); 4884 #if defined(TARGET_MIPS64) 4885 tcg_gen_shri_i64(t0, t0, 30); 4886 #else 4887 tcg_gen_shri_i64(t0, t0, 32); 4888 #endif 4889 gen_move_low32(arg, t0); 4890 } 4891 4892 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift) 4893 { 4894 TCGv_i64 t0 = tcg_temp_new_i64(); 4895 4896 tcg_gen_ld_i64(t0, tcg_env, off); 4897 tcg_gen_shri_i64(t0, t0, 32 + shift); 4898 gen_move_low32(arg, t0); 4899 } 4900 4901 static inline void gen_mfc0_load32(TCGv arg, target_ulong off) 4902 { 4903 TCGv_i32 t0 = tcg_temp_new_i32(); 4904 4905 tcg_gen_ld_i32(t0, tcg_env, off); 4906 tcg_gen_ext_i32_tl(arg, t0); 4907 } 4908 4909 static inline void gen_mfc0_load64(TCGv arg, target_ulong off) 4910 { 4911 tcg_gen_ld_tl(arg, tcg_env, off); 4912 tcg_gen_ext32s_tl(arg, arg); 4913 } 4914 4915 static inline void gen_mtc0_store32(TCGv arg, target_ulong off) 4916 { 4917 TCGv_i32 t0 = tcg_temp_new_i32(); 4918 4919 tcg_gen_trunc_tl_i32(t0, arg); 4920 tcg_gen_st_i32(t0, tcg_env, off); 4921 } 4922 4923 #define CP0_CHECK(c) \ 4924 do { \ 4925 if (!(c)) { \ 4926 goto cp0_unimplemented; \ 4927 } \ 4928 } while (0) 4929 4930 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) 4931 { 4932 const char *register_name = "invalid"; 4933 4934 switch (reg) { 4935 case CP0_REGISTER_02: 4936 switch (sel) { 4937 case 0: 4938 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 4939 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 4940 register_name = "EntryLo0"; 4941 break; 4942 default: 4943 goto cp0_unimplemented; 4944 } 4945 break; 4946 case CP0_REGISTER_03: 4947 switch (sel) { 4948 case CP0_REG03__ENTRYLO1: 4949 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 4950 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 4951 register_name = "EntryLo1"; 4952 break; 4953 default: 4954 goto cp0_unimplemented; 4955 } 4956 break; 4957 case CP0_REGISTER_17: 4958 switch (sel) { 4959 case CP0_REG17__LLADDR: 4960 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr), 4961 ctx->CP0_LLAddr_shift); 4962 register_name = "LLAddr"; 4963 break; 4964 case CP0_REG17__MAAR: 4965 CP0_CHECK(ctx->mrp); 4966 gen_helper_mfhc0_maar(arg, tcg_env); 4967 register_name = "MAAR"; 4968 break; 4969 default: 4970 goto cp0_unimplemented; 4971 } 4972 break; 4973 case CP0_REGISTER_19: 4974 switch (sel) { 4975 case CP0_REG19__WATCHHI0: 4976 case CP0_REG19__WATCHHI1: 4977 case CP0_REG19__WATCHHI2: 4978 case CP0_REG19__WATCHHI3: 4979 case CP0_REG19__WATCHHI4: 4980 case CP0_REG19__WATCHHI5: 4981 case CP0_REG19__WATCHHI6: 4982 case CP0_REG19__WATCHHI7: 4983 /* upper 32 bits are only available when Config5MI != 0 */ 4984 CP0_CHECK(ctx->mi); 4985 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0); 4986 register_name = "WatchHi"; 4987 break; 4988 default: 4989 goto cp0_unimplemented; 4990 } 4991 break; 4992 case CP0_REGISTER_28: 4993 switch (sel) { 4994 case 0: 4995 case 2: 4996 case 4: 4997 case 6: 4998 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0); 4999 register_name = "TagLo"; 5000 break; 5001 default: 5002 goto cp0_unimplemented; 5003 } 5004 break; 5005 default: 5006 goto cp0_unimplemented; 5007 } 5008 trace_mips_translate_c0("mfhc0", register_name, reg, sel); 5009 return; 5010 5011 cp0_unimplemented: 5012 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", 5013 register_name, reg, sel); 5014 tcg_gen_movi_tl(arg, 0); 5015 } 5016 5017 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5018 { 5019 const char *register_name = "invalid"; 5020 uint64_t mask = ctx->PAMask >> 36; 5021 5022 switch (reg) { 5023 case CP0_REGISTER_02: 5024 switch (sel) { 5025 case 0: 5026 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5027 tcg_gen_andi_tl(arg, arg, mask); 5028 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5029 register_name = "EntryLo0"; 5030 break; 5031 default: 5032 goto cp0_unimplemented; 5033 } 5034 break; 5035 case CP0_REGISTER_03: 5036 switch (sel) { 5037 case CP0_REG03__ENTRYLO1: 5038 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5039 tcg_gen_andi_tl(arg, arg, mask); 5040 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5041 register_name = "EntryLo1"; 5042 break; 5043 default: 5044 goto cp0_unimplemented; 5045 } 5046 break; 5047 case CP0_REGISTER_17: 5048 switch (sel) { 5049 case CP0_REG17__LLADDR: 5050 /* 5051 * LLAddr is read-only (the only exception is bit 0 if LLB is 5052 * supported); the CP0_LLAddr_rw_bitmask does not seem to be 5053 * relevant for modern MIPS cores supporting MTHC0, therefore 5054 * treating MTHC0 to LLAddr as NOP. 5055 */ 5056 register_name = "LLAddr"; 5057 break; 5058 case CP0_REG17__MAAR: 5059 CP0_CHECK(ctx->mrp); 5060 gen_helper_mthc0_maar(tcg_env, arg); 5061 register_name = "MAAR"; 5062 break; 5063 default: 5064 goto cp0_unimplemented; 5065 } 5066 break; 5067 case CP0_REGISTER_19: 5068 switch (sel) { 5069 case CP0_REG19__WATCHHI0: 5070 case CP0_REG19__WATCHHI1: 5071 case CP0_REG19__WATCHHI2: 5072 case CP0_REG19__WATCHHI3: 5073 case CP0_REG19__WATCHHI4: 5074 case CP0_REG19__WATCHHI5: 5075 case CP0_REG19__WATCHHI6: 5076 case CP0_REG19__WATCHHI7: 5077 /* upper 32 bits are only available when Config5MI != 0 */ 5078 CP0_CHECK(ctx->mi); 5079 gen_helper_0e1i(mthc0_watchhi, arg, sel); 5080 register_name = "WatchHi"; 5081 break; 5082 default: 5083 goto cp0_unimplemented; 5084 } 5085 break; 5086 case CP0_REGISTER_28: 5087 switch (sel) { 5088 case 0: 5089 case 2: 5090 case 4: 5091 case 6: 5092 tcg_gen_andi_tl(arg, arg, mask); 5093 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo)); 5094 register_name = "TagLo"; 5095 break; 5096 default: 5097 goto cp0_unimplemented; 5098 } 5099 break; 5100 default: 5101 goto cp0_unimplemented; 5102 } 5103 trace_mips_translate_c0("mthc0", register_name, reg, sel); 5104 return; 5105 5106 cp0_unimplemented: 5107 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", 5108 register_name, reg, sel); 5109 } 5110 5111 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg) 5112 { 5113 if (ctx->insn_flags & ISA_MIPS_R6) { 5114 tcg_gen_movi_tl(arg, 0); 5115 } else { 5116 tcg_gen_movi_tl(arg, ~0); 5117 } 5118 } 5119 5120 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5121 { 5122 const char *register_name = "invalid"; 5123 5124 if (sel != 0) { 5125 check_insn(ctx, ISA_MIPS_R1); 5126 } 5127 5128 switch (reg) { 5129 case CP0_REGISTER_00: 5130 switch (sel) { 5131 case CP0_REG00__INDEX: 5132 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 5133 register_name = "Index"; 5134 break; 5135 case CP0_REG00__MVPCONTROL: 5136 CP0_CHECK(disas_mt_available(ctx)); 5137 gen_helper_mfc0_mvpcontrol(arg, tcg_env); 5138 register_name = "MVPControl"; 5139 break; 5140 case CP0_REG00__MVPCONF0: 5141 CP0_CHECK(disas_mt_available(ctx)); 5142 gen_helper_mfc0_mvpconf0(arg, tcg_env); 5143 register_name = "MVPConf0"; 5144 break; 5145 case CP0_REG00__MVPCONF1: 5146 CP0_CHECK(disas_mt_available(ctx)); 5147 gen_helper_mfc0_mvpconf1(arg, tcg_env); 5148 register_name = "MVPConf1"; 5149 break; 5150 case CP0_REG00__VPCONTROL: 5151 CP0_CHECK(ctx->vp); 5152 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 5153 register_name = "VPControl"; 5154 break; 5155 default: 5156 goto cp0_unimplemented; 5157 } 5158 break; 5159 case CP0_REGISTER_01: 5160 switch (sel) { 5161 case CP0_REG01__RANDOM: 5162 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5163 gen_helper_mfc0_random(arg, tcg_env); 5164 register_name = "Random"; 5165 break; 5166 case CP0_REG01__VPECONTROL: 5167 CP0_CHECK(disas_mt_available(ctx)); 5168 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 5169 register_name = "VPEControl"; 5170 break; 5171 case CP0_REG01__VPECONF0: 5172 CP0_CHECK(disas_mt_available(ctx)); 5173 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 5174 register_name = "VPEConf0"; 5175 break; 5176 case CP0_REG01__VPECONF1: 5177 CP0_CHECK(disas_mt_available(ctx)); 5178 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 5179 register_name = "VPEConf1"; 5180 break; 5181 case CP0_REG01__YQMASK: 5182 CP0_CHECK(disas_mt_available(ctx)); 5183 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 5184 register_name = "YQMask"; 5185 break; 5186 case CP0_REG01__VPESCHEDULE: 5187 CP0_CHECK(disas_mt_available(ctx)); 5188 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 5189 register_name = "VPESchedule"; 5190 break; 5191 case CP0_REG01__VPESCHEFBACK: 5192 CP0_CHECK(disas_mt_available(ctx)); 5193 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5194 register_name = "VPEScheFBack"; 5195 break; 5196 case CP0_REG01__VPEOPT: 5197 CP0_CHECK(disas_mt_available(ctx)); 5198 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 5199 register_name = "VPEOpt"; 5200 break; 5201 default: 5202 goto cp0_unimplemented; 5203 } 5204 break; 5205 case CP0_REGISTER_02: 5206 switch (sel) { 5207 case CP0_REG02__ENTRYLO0: 5208 { 5209 TCGv_i64 tmp = tcg_temp_new_i64(); 5210 tcg_gen_ld_i64(tmp, tcg_env, 5211 offsetof(CPUMIPSState, CP0_EntryLo0)); 5212 #if defined(TARGET_MIPS64) 5213 if (ctx->rxi) { 5214 /* Move RI/XI fields to bits 31:30 */ 5215 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5216 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5217 } 5218 #endif 5219 gen_move_low32(arg, tmp); 5220 } 5221 register_name = "EntryLo0"; 5222 break; 5223 case CP0_REG02__TCSTATUS: 5224 CP0_CHECK(disas_mt_available(ctx)); 5225 gen_helper_mfc0_tcstatus(arg, tcg_env); 5226 register_name = "TCStatus"; 5227 break; 5228 case CP0_REG02__TCBIND: 5229 CP0_CHECK(disas_mt_available(ctx)); 5230 gen_helper_mfc0_tcbind(arg, tcg_env); 5231 register_name = "TCBind"; 5232 break; 5233 case CP0_REG02__TCRESTART: 5234 CP0_CHECK(disas_mt_available(ctx)); 5235 gen_helper_mfc0_tcrestart(arg, tcg_env); 5236 register_name = "TCRestart"; 5237 break; 5238 case CP0_REG02__TCHALT: 5239 CP0_CHECK(disas_mt_available(ctx)); 5240 gen_helper_mfc0_tchalt(arg, tcg_env); 5241 register_name = "TCHalt"; 5242 break; 5243 case CP0_REG02__TCCONTEXT: 5244 CP0_CHECK(disas_mt_available(ctx)); 5245 gen_helper_mfc0_tccontext(arg, tcg_env); 5246 register_name = "TCContext"; 5247 break; 5248 case CP0_REG02__TCSCHEDULE: 5249 CP0_CHECK(disas_mt_available(ctx)); 5250 gen_helper_mfc0_tcschedule(arg, tcg_env); 5251 register_name = "TCSchedule"; 5252 break; 5253 case CP0_REG02__TCSCHEFBACK: 5254 CP0_CHECK(disas_mt_available(ctx)); 5255 gen_helper_mfc0_tcschefback(arg, tcg_env); 5256 register_name = "TCScheFBack"; 5257 break; 5258 default: 5259 goto cp0_unimplemented; 5260 } 5261 break; 5262 case CP0_REGISTER_03: 5263 switch (sel) { 5264 case CP0_REG03__ENTRYLO1: 5265 { 5266 TCGv_i64 tmp = tcg_temp_new_i64(); 5267 tcg_gen_ld_i64(tmp, tcg_env, 5268 offsetof(CPUMIPSState, CP0_EntryLo1)); 5269 #if defined(TARGET_MIPS64) 5270 if (ctx->rxi) { 5271 /* Move RI/XI fields to bits 31:30 */ 5272 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5273 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5274 } 5275 #endif 5276 gen_move_low32(arg, tmp); 5277 } 5278 register_name = "EntryLo1"; 5279 break; 5280 case CP0_REG03__GLOBALNUM: 5281 CP0_CHECK(ctx->vp); 5282 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 5283 register_name = "GlobalNumber"; 5284 break; 5285 default: 5286 goto cp0_unimplemented; 5287 } 5288 break; 5289 case CP0_REGISTER_04: 5290 switch (sel) { 5291 case CP0_REG04__CONTEXT: 5292 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context)); 5293 tcg_gen_ext32s_tl(arg, arg); 5294 register_name = "Context"; 5295 break; 5296 case CP0_REG04__CONTEXTCONFIG: 5297 /* SmartMIPS ASE */ 5298 /* gen_helper_mfc0_contextconfig(arg); */ 5299 register_name = "ContextConfig"; 5300 goto cp0_unimplemented; 5301 case CP0_REG04__USERLOCAL: 5302 CP0_CHECK(ctx->ulri); 5303 tcg_gen_ld_tl(arg, tcg_env, 5304 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 5305 tcg_gen_ext32s_tl(arg, arg); 5306 register_name = "UserLocal"; 5307 break; 5308 case CP0_REG04__MMID: 5309 CP0_CHECK(ctx->mi); 5310 gen_helper_mtc0_memorymapid(tcg_env, arg); 5311 register_name = "MMID"; 5312 break; 5313 default: 5314 goto cp0_unimplemented; 5315 } 5316 break; 5317 case CP0_REGISTER_05: 5318 switch (sel) { 5319 case CP0_REG05__PAGEMASK: 5320 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 5321 register_name = "PageMask"; 5322 break; 5323 case CP0_REG05__PAGEGRAIN: 5324 check_insn(ctx, ISA_MIPS_R2); 5325 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 5326 register_name = "PageGrain"; 5327 break; 5328 case CP0_REG05__SEGCTL0: 5329 CP0_CHECK(ctx->sc); 5330 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 5331 tcg_gen_ext32s_tl(arg, arg); 5332 register_name = "SegCtl0"; 5333 break; 5334 case CP0_REG05__SEGCTL1: 5335 CP0_CHECK(ctx->sc); 5336 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 5337 tcg_gen_ext32s_tl(arg, arg); 5338 register_name = "SegCtl1"; 5339 break; 5340 case CP0_REG05__SEGCTL2: 5341 CP0_CHECK(ctx->sc); 5342 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 5343 tcg_gen_ext32s_tl(arg, arg); 5344 register_name = "SegCtl2"; 5345 break; 5346 case CP0_REG05__PWBASE: 5347 check_pw(ctx); 5348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 5349 register_name = "PWBase"; 5350 break; 5351 case CP0_REG05__PWFIELD: 5352 check_pw(ctx); 5353 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField)); 5354 register_name = "PWField"; 5355 break; 5356 case CP0_REG05__PWSIZE: 5357 check_pw(ctx); 5358 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize)); 5359 register_name = "PWSize"; 5360 break; 5361 default: 5362 goto cp0_unimplemented; 5363 } 5364 break; 5365 case CP0_REGISTER_06: 5366 switch (sel) { 5367 case CP0_REG06__WIRED: 5368 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 5369 register_name = "Wired"; 5370 break; 5371 case CP0_REG06__SRSCONF0: 5372 check_insn(ctx, ISA_MIPS_R2); 5373 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 5374 register_name = "SRSConf0"; 5375 break; 5376 case CP0_REG06__SRSCONF1: 5377 check_insn(ctx, ISA_MIPS_R2); 5378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 5379 register_name = "SRSConf1"; 5380 break; 5381 case CP0_REG06__SRSCONF2: 5382 check_insn(ctx, ISA_MIPS_R2); 5383 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 5384 register_name = "SRSConf2"; 5385 break; 5386 case CP0_REG06__SRSCONF3: 5387 check_insn(ctx, ISA_MIPS_R2); 5388 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 5389 register_name = "SRSConf3"; 5390 break; 5391 case CP0_REG06__SRSCONF4: 5392 check_insn(ctx, ISA_MIPS_R2); 5393 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 5394 register_name = "SRSConf4"; 5395 break; 5396 case CP0_REG06__PWCTL: 5397 check_pw(ctx); 5398 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 5399 register_name = "PWCtl"; 5400 break; 5401 default: 5402 goto cp0_unimplemented; 5403 } 5404 break; 5405 case CP0_REGISTER_07: 5406 switch (sel) { 5407 case CP0_REG07__HWRENA: 5408 check_insn(ctx, ISA_MIPS_R2); 5409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 5410 register_name = "HWREna"; 5411 break; 5412 default: 5413 goto cp0_unimplemented; 5414 } 5415 break; 5416 case CP0_REGISTER_08: 5417 switch (sel) { 5418 case CP0_REG08__BADVADDR: 5419 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 5420 tcg_gen_ext32s_tl(arg, arg); 5421 register_name = "BadVAddr"; 5422 break; 5423 case CP0_REG08__BADINSTR: 5424 CP0_CHECK(ctx->bi); 5425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 5426 register_name = "BadInstr"; 5427 break; 5428 case CP0_REG08__BADINSTRP: 5429 CP0_CHECK(ctx->bp); 5430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 5431 register_name = "BadInstrP"; 5432 break; 5433 case CP0_REG08__BADINSTRX: 5434 CP0_CHECK(ctx->bi); 5435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 5436 tcg_gen_andi_tl(arg, arg, ~0xffff); 5437 register_name = "BadInstrX"; 5438 break; 5439 default: 5440 goto cp0_unimplemented; 5441 } 5442 break; 5443 case CP0_REGISTER_09: 5444 switch (sel) { 5445 case CP0_REG09__COUNT: 5446 /* Mark as an IO operation because we read the time. */ 5447 translator_io_start(&ctx->base); 5448 5449 gen_helper_mfc0_count(arg, tcg_env); 5450 /* 5451 * Break the TB to be able to take timer interrupts immediately 5452 * after reading count. DISAS_STOP isn't sufficient, we need to 5453 * ensure we break completely out of translated code. 5454 */ 5455 gen_save_pc(ctx->base.pc_next + 4); 5456 ctx->base.is_jmp = DISAS_EXIT; 5457 register_name = "Count"; 5458 break; 5459 default: 5460 goto cp0_unimplemented; 5461 } 5462 break; 5463 case CP0_REGISTER_10: 5464 switch (sel) { 5465 case CP0_REG10__ENTRYHI: 5466 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi)); 5467 tcg_gen_ext32s_tl(arg, arg); 5468 register_name = "EntryHi"; 5469 break; 5470 default: 5471 goto cp0_unimplemented; 5472 } 5473 break; 5474 case CP0_REGISTER_11: 5475 switch (sel) { 5476 case CP0_REG11__COMPARE: 5477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 5478 register_name = "Compare"; 5479 break; 5480 /* 6,7 are implementation dependent */ 5481 default: 5482 goto cp0_unimplemented; 5483 } 5484 break; 5485 case CP0_REGISTER_12: 5486 switch (sel) { 5487 case CP0_REG12__STATUS: 5488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 5489 register_name = "Status"; 5490 break; 5491 case CP0_REG12__INTCTL: 5492 check_insn(ctx, ISA_MIPS_R2); 5493 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 5494 register_name = "IntCtl"; 5495 break; 5496 case CP0_REG12__SRSCTL: 5497 check_insn(ctx, ISA_MIPS_R2); 5498 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 5499 register_name = "SRSCtl"; 5500 break; 5501 case CP0_REG12__SRSMAP: 5502 check_insn(ctx, ISA_MIPS_R2); 5503 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 5504 register_name = "SRSMap"; 5505 break; 5506 default: 5507 goto cp0_unimplemented; 5508 } 5509 break; 5510 case CP0_REGISTER_13: 5511 switch (sel) { 5512 case CP0_REG13__CAUSE: 5513 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 5514 register_name = "Cause"; 5515 break; 5516 default: 5517 goto cp0_unimplemented; 5518 } 5519 break; 5520 case CP0_REGISTER_14: 5521 switch (sel) { 5522 case CP0_REG14__EPC: 5523 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 5524 tcg_gen_ext32s_tl(arg, arg); 5525 register_name = "EPC"; 5526 break; 5527 default: 5528 goto cp0_unimplemented; 5529 } 5530 break; 5531 case CP0_REGISTER_15: 5532 switch (sel) { 5533 case CP0_REG15__PRID: 5534 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 5535 register_name = "PRid"; 5536 break; 5537 case CP0_REG15__EBASE: 5538 check_insn(ctx, ISA_MIPS_R2); 5539 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase)); 5540 tcg_gen_ext32s_tl(arg, arg); 5541 register_name = "EBase"; 5542 break; 5543 case CP0_REG15__CMGCRBASE: 5544 check_insn(ctx, ISA_MIPS_R2); 5545 CP0_CHECK(ctx->cmgcr); 5546 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 5547 tcg_gen_ext32s_tl(arg, arg); 5548 register_name = "CMGCRBase"; 5549 break; 5550 default: 5551 goto cp0_unimplemented; 5552 } 5553 break; 5554 case CP0_REGISTER_16: 5555 switch (sel) { 5556 case CP0_REG16__CONFIG: 5557 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 5558 register_name = "Config"; 5559 break; 5560 case CP0_REG16__CONFIG1: 5561 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 5562 register_name = "Config1"; 5563 break; 5564 case CP0_REG16__CONFIG2: 5565 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 5566 register_name = "Config2"; 5567 break; 5568 case CP0_REG16__CONFIG3: 5569 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 5570 register_name = "Config3"; 5571 break; 5572 case CP0_REG16__CONFIG4: 5573 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 5574 register_name = "Config4"; 5575 break; 5576 case CP0_REG16__CONFIG5: 5577 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 5578 register_name = "Config5"; 5579 break; 5580 /* 6,7 are implementation dependent */ 5581 case CP0_REG16__CONFIG6: 5582 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 5583 register_name = "Config6"; 5584 break; 5585 case CP0_REG16__CONFIG7: 5586 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 5587 register_name = "Config7"; 5588 break; 5589 default: 5590 goto cp0_unimplemented; 5591 } 5592 break; 5593 case CP0_REGISTER_17: 5594 switch (sel) { 5595 case CP0_REG17__LLADDR: 5596 gen_helper_mfc0_lladdr(arg, tcg_env); 5597 register_name = "LLAddr"; 5598 break; 5599 case CP0_REG17__MAAR: 5600 CP0_CHECK(ctx->mrp); 5601 gen_helper_mfc0_maar(arg, tcg_env); 5602 register_name = "MAAR"; 5603 break; 5604 case CP0_REG17__MAARI: 5605 CP0_CHECK(ctx->mrp); 5606 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 5607 register_name = "MAARI"; 5608 break; 5609 default: 5610 goto cp0_unimplemented; 5611 } 5612 break; 5613 case CP0_REGISTER_18: 5614 switch (sel) { 5615 case CP0_REG18__WATCHLO0: 5616 case CP0_REG18__WATCHLO1: 5617 case CP0_REG18__WATCHLO2: 5618 case CP0_REG18__WATCHLO3: 5619 case CP0_REG18__WATCHLO4: 5620 case CP0_REG18__WATCHLO5: 5621 case CP0_REG18__WATCHLO6: 5622 case CP0_REG18__WATCHLO7: 5623 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 5624 gen_helper_1e0i(mfc0_watchlo, arg, sel); 5625 register_name = "WatchLo"; 5626 break; 5627 default: 5628 goto cp0_unimplemented; 5629 } 5630 break; 5631 case CP0_REGISTER_19: 5632 switch (sel) { 5633 case CP0_REG19__WATCHHI0: 5634 case CP0_REG19__WATCHHI1: 5635 case CP0_REG19__WATCHHI2: 5636 case CP0_REG19__WATCHHI3: 5637 case CP0_REG19__WATCHHI4: 5638 case CP0_REG19__WATCHHI5: 5639 case CP0_REG19__WATCHHI6: 5640 case CP0_REG19__WATCHHI7: 5641 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 5642 gen_helper_1e0i(mfc0_watchhi, arg, sel); 5643 register_name = "WatchHi"; 5644 break; 5645 default: 5646 goto cp0_unimplemented; 5647 } 5648 break; 5649 case CP0_REGISTER_20: 5650 switch (sel) { 5651 case CP0_REG20__XCONTEXT: 5652 #if defined(TARGET_MIPS64) 5653 check_insn(ctx, ISA_MIPS3); 5654 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext)); 5655 tcg_gen_ext32s_tl(arg, arg); 5656 register_name = "XContext"; 5657 break; 5658 #endif 5659 default: 5660 goto cp0_unimplemented; 5661 } 5662 break; 5663 case CP0_REGISTER_21: 5664 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 5665 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5666 switch (sel) { 5667 case 0: 5668 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 5669 register_name = "Framemask"; 5670 break; 5671 default: 5672 goto cp0_unimplemented; 5673 } 5674 break; 5675 case CP0_REGISTER_22: 5676 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 5677 register_name = "'Diagnostic"; /* implementation dependent */ 5678 break; 5679 case CP0_REGISTER_23: 5680 switch (sel) { 5681 case CP0_REG23__DEBUG: 5682 gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */ 5683 register_name = "Debug"; 5684 break; 5685 case CP0_REG23__TRACECONTROL: 5686 /* PDtrace support */ 5687 /* gen_helper_mfc0_tracecontrol(arg); */ 5688 register_name = "TraceControl"; 5689 goto cp0_unimplemented; 5690 case CP0_REG23__TRACECONTROL2: 5691 /* PDtrace support */ 5692 /* gen_helper_mfc0_tracecontrol2(arg); */ 5693 register_name = "TraceControl2"; 5694 goto cp0_unimplemented; 5695 case CP0_REG23__USERTRACEDATA1: 5696 /* PDtrace support */ 5697 /* gen_helper_mfc0_usertracedata1(arg);*/ 5698 register_name = "UserTraceData1"; 5699 goto cp0_unimplemented; 5700 case CP0_REG23__TRACEIBPC: 5701 /* PDtrace support */ 5702 /* gen_helper_mfc0_traceibpc(arg); */ 5703 register_name = "TraceIBPC"; 5704 goto cp0_unimplemented; 5705 case CP0_REG23__TRACEDBPC: 5706 /* PDtrace support */ 5707 /* gen_helper_mfc0_tracedbpc(arg); */ 5708 register_name = "TraceDBPC"; 5709 goto cp0_unimplemented; 5710 default: 5711 goto cp0_unimplemented; 5712 } 5713 break; 5714 case CP0_REGISTER_24: 5715 switch (sel) { 5716 case CP0_REG24__DEPC: 5717 /* EJTAG support */ 5718 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 5719 tcg_gen_ext32s_tl(arg, arg); 5720 register_name = "DEPC"; 5721 break; 5722 default: 5723 goto cp0_unimplemented; 5724 } 5725 break; 5726 case CP0_REGISTER_25: 5727 switch (sel) { 5728 case CP0_REG25__PERFCTL0: 5729 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 5730 register_name = "Performance0"; 5731 break; 5732 case CP0_REG25__PERFCNT0: 5733 /* gen_helper_mfc0_performance1(arg); */ 5734 register_name = "Performance1"; 5735 goto cp0_unimplemented; 5736 case CP0_REG25__PERFCTL1: 5737 /* gen_helper_mfc0_performance2(arg); */ 5738 register_name = "Performance2"; 5739 goto cp0_unimplemented; 5740 case CP0_REG25__PERFCNT1: 5741 /* gen_helper_mfc0_performance3(arg); */ 5742 register_name = "Performance3"; 5743 goto cp0_unimplemented; 5744 case CP0_REG25__PERFCTL2: 5745 /* gen_helper_mfc0_performance4(arg); */ 5746 register_name = "Performance4"; 5747 goto cp0_unimplemented; 5748 case CP0_REG25__PERFCNT2: 5749 /* gen_helper_mfc0_performance5(arg); */ 5750 register_name = "Performance5"; 5751 goto cp0_unimplemented; 5752 case CP0_REG25__PERFCTL3: 5753 /* gen_helper_mfc0_performance6(arg); */ 5754 register_name = "Performance6"; 5755 goto cp0_unimplemented; 5756 case CP0_REG25__PERFCNT3: 5757 /* gen_helper_mfc0_performance7(arg); */ 5758 register_name = "Performance7"; 5759 goto cp0_unimplemented; 5760 default: 5761 goto cp0_unimplemented; 5762 } 5763 break; 5764 case CP0_REGISTER_26: 5765 switch (sel) { 5766 case CP0_REG26__ERRCTL: 5767 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 5768 register_name = "ErrCtl"; 5769 break; 5770 default: 5771 goto cp0_unimplemented; 5772 } 5773 break; 5774 case CP0_REGISTER_27: 5775 switch (sel) { 5776 case CP0_REG27__CACHERR: 5777 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 5778 register_name = "CacheErr"; 5779 break; 5780 default: 5781 goto cp0_unimplemented; 5782 } 5783 break; 5784 case CP0_REGISTER_28: 5785 switch (sel) { 5786 case CP0_REG28__TAGLO: 5787 case CP0_REG28__TAGLO1: 5788 case CP0_REG28__TAGLO2: 5789 case CP0_REG28__TAGLO3: 5790 { 5791 TCGv_i64 tmp = tcg_temp_new_i64(); 5792 tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPUMIPSState, CP0_TagLo)); 5793 gen_move_low32(arg, tmp); 5794 } 5795 register_name = "TagLo"; 5796 break; 5797 case CP0_REG28__DATALO: 5798 case CP0_REG28__DATALO1: 5799 case CP0_REG28__DATALO2: 5800 case CP0_REG28__DATALO3: 5801 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 5802 register_name = "DataLo"; 5803 break; 5804 default: 5805 goto cp0_unimplemented; 5806 } 5807 break; 5808 case CP0_REGISTER_29: 5809 switch (sel) { 5810 case CP0_REG29__TAGHI: 5811 case CP0_REG29__TAGHI1: 5812 case CP0_REG29__TAGHI2: 5813 case CP0_REG29__TAGHI3: 5814 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 5815 register_name = "TagHi"; 5816 break; 5817 case CP0_REG29__DATAHI: 5818 case CP0_REG29__DATAHI1: 5819 case CP0_REG29__DATAHI2: 5820 case CP0_REG29__DATAHI3: 5821 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 5822 register_name = "DataHi"; 5823 break; 5824 default: 5825 goto cp0_unimplemented; 5826 } 5827 break; 5828 case CP0_REGISTER_30: 5829 switch (sel) { 5830 case CP0_REG30__ERROREPC: 5831 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 5832 tcg_gen_ext32s_tl(arg, arg); 5833 register_name = "ErrorEPC"; 5834 break; 5835 default: 5836 goto cp0_unimplemented; 5837 } 5838 break; 5839 case CP0_REGISTER_31: 5840 switch (sel) { 5841 case CP0_REG31__DESAVE: 5842 /* EJTAG support */ 5843 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 5844 register_name = "DESAVE"; 5845 break; 5846 case CP0_REG31__KSCRATCH1: 5847 case CP0_REG31__KSCRATCH2: 5848 case CP0_REG31__KSCRATCH3: 5849 case CP0_REG31__KSCRATCH4: 5850 case CP0_REG31__KSCRATCH5: 5851 case CP0_REG31__KSCRATCH6: 5852 CP0_CHECK(ctx->kscrexist & (1 << sel)); 5853 tcg_gen_ld_tl(arg, tcg_env, 5854 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 5855 tcg_gen_ext32s_tl(arg, arg); 5856 register_name = "KScratch"; 5857 break; 5858 default: 5859 goto cp0_unimplemented; 5860 } 5861 break; 5862 default: 5863 goto cp0_unimplemented; 5864 } 5865 trace_mips_translate_c0("mfc0", register_name, reg, sel); 5866 return; 5867 5868 cp0_unimplemented: 5869 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", 5870 register_name, reg, sel); 5871 gen_mfc0_unimplemented(ctx, arg); 5872 } 5873 5874 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5875 { 5876 const char *register_name = "invalid"; 5877 bool icount; 5878 5879 if (sel != 0) { 5880 check_insn(ctx, ISA_MIPS_R1); 5881 } 5882 5883 icount = translator_io_start(&ctx->base); 5884 5885 switch (reg) { 5886 case CP0_REGISTER_00: 5887 switch (sel) { 5888 case CP0_REG00__INDEX: 5889 gen_helper_mtc0_index(tcg_env, arg); 5890 register_name = "Index"; 5891 break; 5892 case CP0_REG00__MVPCONTROL: 5893 CP0_CHECK(disas_mt_available(ctx)); 5894 gen_helper_mtc0_mvpcontrol(tcg_env, arg); 5895 register_name = "MVPControl"; 5896 break; 5897 case CP0_REG00__MVPCONF0: 5898 CP0_CHECK(disas_mt_available(ctx)); 5899 /* ignored */ 5900 register_name = "MVPConf0"; 5901 break; 5902 case CP0_REG00__MVPCONF1: 5903 CP0_CHECK(disas_mt_available(ctx)); 5904 /* ignored */ 5905 register_name = "MVPConf1"; 5906 break; 5907 case CP0_REG00__VPCONTROL: 5908 CP0_CHECK(ctx->vp); 5909 /* ignored */ 5910 register_name = "VPControl"; 5911 break; 5912 default: 5913 goto cp0_unimplemented; 5914 } 5915 break; 5916 case CP0_REGISTER_01: 5917 switch (sel) { 5918 case CP0_REG01__RANDOM: 5919 /* ignored */ 5920 register_name = "Random"; 5921 break; 5922 case CP0_REG01__VPECONTROL: 5923 CP0_CHECK(disas_mt_available(ctx)); 5924 gen_helper_mtc0_vpecontrol(tcg_env, arg); 5925 register_name = "VPEControl"; 5926 break; 5927 case CP0_REG01__VPECONF0: 5928 CP0_CHECK(disas_mt_available(ctx)); 5929 gen_helper_mtc0_vpeconf0(tcg_env, arg); 5930 register_name = "VPEConf0"; 5931 break; 5932 case CP0_REG01__VPECONF1: 5933 CP0_CHECK(disas_mt_available(ctx)); 5934 gen_helper_mtc0_vpeconf1(tcg_env, arg); 5935 register_name = "VPEConf1"; 5936 break; 5937 case CP0_REG01__YQMASK: 5938 CP0_CHECK(disas_mt_available(ctx)); 5939 gen_helper_mtc0_yqmask(tcg_env, arg); 5940 register_name = "YQMask"; 5941 break; 5942 case CP0_REG01__VPESCHEDULE: 5943 CP0_CHECK(disas_mt_available(ctx)); 5944 tcg_gen_st_tl(arg, tcg_env, 5945 offsetof(CPUMIPSState, CP0_VPESchedule)); 5946 register_name = "VPESchedule"; 5947 break; 5948 case CP0_REG01__VPESCHEFBACK: 5949 CP0_CHECK(disas_mt_available(ctx)); 5950 tcg_gen_st_tl(arg, tcg_env, 5951 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5952 register_name = "VPEScheFBack"; 5953 break; 5954 case CP0_REG01__VPEOPT: 5955 CP0_CHECK(disas_mt_available(ctx)); 5956 gen_helper_mtc0_vpeopt(tcg_env, arg); 5957 register_name = "VPEOpt"; 5958 break; 5959 default: 5960 goto cp0_unimplemented; 5961 } 5962 break; 5963 case CP0_REGISTER_02: 5964 switch (sel) { 5965 case CP0_REG02__ENTRYLO0: 5966 gen_helper_mtc0_entrylo0(tcg_env, arg); 5967 register_name = "EntryLo0"; 5968 break; 5969 case CP0_REG02__TCSTATUS: 5970 CP0_CHECK(disas_mt_available(ctx)); 5971 gen_helper_mtc0_tcstatus(tcg_env, arg); 5972 register_name = "TCStatus"; 5973 break; 5974 case CP0_REG02__TCBIND: 5975 CP0_CHECK(disas_mt_available(ctx)); 5976 gen_helper_mtc0_tcbind(tcg_env, arg); 5977 register_name = "TCBind"; 5978 break; 5979 case CP0_REG02__TCRESTART: 5980 CP0_CHECK(disas_mt_available(ctx)); 5981 gen_helper_mtc0_tcrestart(tcg_env, arg); 5982 register_name = "TCRestart"; 5983 break; 5984 case CP0_REG02__TCHALT: 5985 CP0_CHECK(disas_mt_available(ctx)); 5986 gen_helper_mtc0_tchalt(tcg_env, arg); 5987 register_name = "TCHalt"; 5988 break; 5989 case CP0_REG02__TCCONTEXT: 5990 CP0_CHECK(disas_mt_available(ctx)); 5991 gen_helper_mtc0_tccontext(tcg_env, arg); 5992 register_name = "TCContext"; 5993 break; 5994 case CP0_REG02__TCSCHEDULE: 5995 CP0_CHECK(disas_mt_available(ctx)); 5996 gen_helper_mtc0_tcschedule(tcg_env, arg); 5997 register_name = "TCSchedule"; 5998 break; 5999 case CP0_REG02__TCSCHEFBACK: 6000 CP0_CHECK(disas_mt_available(ctx)); 6001 gen_helper_mtc0_tcschefback(tcg_env, arg); 6002 register_name = "TCScheFBack"; 6003 break; 6004 default: 6005 goto cp0_unimplemented; 6006 } 6007 break; 6008 case CP0_REGISTER_03: 6009 switch (sel) { 6010 case CP0_REG03__ENTRYLO1: 6011 gen_helper_mtc0_entrylo1(tcg_env, arg); 6012 register_name = "EntryLo1"; 6013 break; 6014 case CP0_REG03__GLOBALNUM: 6015 CP0_CHECK(ctx->vp); 6016 /* ignored */ 6017 register_name = "GlobalNumber"; 6018 break; 6019 default: 6020 goto cp0_unimplemented; 6021 } 6022 break; 6023 case CP0_REGISTER_04: 6024 switch (sel) { 6025 case CP0_REG04__CONTEXT: 6026 gen_helper_mtc0_context(tcg_env, arg); 6027 register_name = "Context"; 6028 break; 6029 case CP0_REG04__CONTEXTCONFIG: 6030 /* SmartMIPS ASE */ 6031 /* gen_helper_mtc0_contextconfig(arg); */ 6032 register_name = "ContextConfig"; 6033 goto cp0_unimplemented; 6034 case CP0_REG04__USERLOCAL: 6035 CP0_CHECK(ctx->ulri); 6036 tcg_gen_st_tl(arg, tcg_env, 6037 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6038 register_name = "UserLocal"; 6039 break; 6040 case CP0_REG04__MMID: 6041 CP0_CHECK(ctx->mi); 6042 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 6043 register_name = "MMID"; 6044 break; 6045 default: 6046 goto cp0_unimplemented; 6047 } 6048 break; 6049 case CP0_REGISTER_05: 6050 switch (sel) { 6051 case CP0_REG05__PAGEMASK: 6052 gen_helper_mtc0_pagemask(tcg_env, arg); 6053 register_name = "PageMask"; 6054 break; 6055 case CP0_REG05__PAGEGRAIN: 6056 check_insn(ctx, ISA_MIPS_R2); 6057 gen_helper_mtc0_pagegrain(tcg_env, arg); 6058 register_name = "PageGrain"; 6059 ctx->base.is_jmp = DISAS_STOP; 6060 break; 6061 case CP0_REG05__SEGCTL0: 6062 CP0_CHECK(ctx->sc); 6063 gen_helper_mtc0_segctl0(tcg_env, arg); 6064 register_name = "SegCtl0"; 6065 break; 6066 case CP0_REG05__SEGCTL1: 6067 CP0_CHECK(ctx->sc); 6068 gen_helper_mtc0_segctl1(tcg_env, arg); 6069 register_name = "SegCtl1"; 6070 break; 6071 case CP0_REG05__SEGCTL2: 6072 CP0_CHECK(ctx->sc); 6073 gen_helper_mtc0_segctl2(tcg_env, arg); 6074 register_name = "SegCtl2"; 6075 break; 6076 case CP0_REG05__PWBASE: 6077 check_pw(ctx); 6078 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 6079 register_name = "PWBase"; 6080 break; 6081 case CP0_REG05__PWFIELD: 6082 check_pw(ctx); 6083 gen_helper_mtc0_pwfield(tcg_env, arg); 6084 register_name = "PWField"; 6085 break; 6086 case CP0_REG05__PWSIZE: 6087 check_pw(ctx); 6088 gen_helper_mtc0_pwsize(tcg_env, arg); 6089 register_name = "PWSize"; 6090 break; 6091 default: 6092 goto cp0_unimplemented; 6093 } 6094 break; 6095 case CP0_REGISTER_06: 6096 switch (sel) { 6097 case CP0_REG06__WIRED: 6098 gen_helper_mtc0_wired(tcg_env, arg); 6099 register_name = "Wired"; 6100 break; 6101 case CP0_REG06__SRSCONF0: 6102 check_insn(ctx, ISA_MIPS_R2); 6103 gen_helper_mtc0_srsconf0(tcg_env, arg); 6104 register_name = "SRSConf0"; 6105 break; 6106 case CP0_REG06__SRSCONF1: 6107 check_insn(ctx, ISA_MIPS_R2); 6108 gen_helper_mtc0_srsconf1(tcg_env, arg); 6109 register_name = "SRSConf1"; 6110 break; 6111 case CP0_REG06__SRSCONF2: 6112 check_insn(ctx, ISA_MIPS_R2); 6113 gen_helper_mtc0_srsconf2(tcg_env, arg); 6114 register_name = "SRSConf2"; 6115 break; 6116 case CP0_REG06__SRSCONF3: 6117 check_insn(ctx, ISA_MIPS_R2); 6118 gen_helper_mtc0_srsconf3(tcg_env, arg); 6119 register_name = "SRSConf3"; 6120 break; 6121 case CP0_REG06__SRSCONF4: 6122 check_insn(ctx, ISA_MIPS_R2); 6123 gen_helper_mtc0_srsconf4(tcg_env, arg); 6124 register_name = "SRSConf4"; 6125 break; 6126 case CP0_REG06__PWCTL: 6127 check_pw(ctx); 6128 gen_helper_mtc0_pwctl(tcg_env, arg); 6129 register_name = "PWCtl"; 6130 break; 6131 default: 6132 goto cp0_unimplemented; 6133 } 6134 break; 6135 case CP0_REGISTER_07: 6136 switch (sel) { 6137 case CP0_REG07__HWRENA: 6138 check_insn(ctx, ISA_MIPS_R2); 6139 gen_helper_mtc0_hwrena(tcg_env, arg); 6140 ctx->base.is_jmp = DISAS_STOP; 6141 register_name = "HWREna"; 6142 break; 6143 default: 6144 goto cp0_unimplemented; 6145 } 6146 break; 6147 case CP0_REGISTER_08: 6148 switch (sel) { 6149 case CP0_REG08__BADVADDR: 6150 /* ignored */ 6151 register_name = "BadVAddr"; 6152 break; 6153 case CP0_REG08__BADINSTR: 6154 /* ignored */ 6155 register_name = "BadInstr"; 6156 break; 6157 case CP0_REG08__BADINSTRP: 6158 /* ignored */ 6159 register_name = "BadInstrP"; 6160 break; 6161 case CP0_REG08__BADINSTRX: 6162 /* ignored */ 6163 register_name = "BadInstrX"; 6164 break; 6165 default: 6166 goto cp0_unimplemented; 6167 } 6168 break; 6169 case CP0_REGISTER_09: 6170 switch (sel) { 6171 case CP0_REG09__COUNT: 6172 gen_helper_mtc0_count(tcg_env, arg); 6173 register_name = "Count"; 6174 break; 6175 default: 6176 goto cp0_unimplemented; 6177 } 6178 break; 6179 case CP0_REGISTER_10: 6180 switch (sel) { 6181 case CP0_REG10__ENTRYHI: 6182 gen_helper_mtc0_entryhi(tcg_env, arg); 6183 register_name = "EntryHi"; 6184 break; 6185 default: 6186 goto cp0_unimplemented; 6187 } 6188 break; 6189 case CP0_REGISTER_11: 6190 switch (sel) { 6191 case CP0_REG11__COMPARE: 6192 gen_helper_mtc0_compare(tcg_env, arg); 6193 register_name = "Compare"; 6194 break; 6195 /* 6,7 are implementation dependent */ 6196 default: 6197 goto cp0_unimplemented; 6198 } 6199 break; 6200 case CP0_REGISTER_12: 6201 switch (sel) { 6202 case CP0_REG12__STATUS: 6203 save_cpu_state(ctx, 1); 6204 gen_helper_mtc0_status(tcg_env, arg); 6205 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6206 gen_save_pc(ctx->base.pc_next + 4); 6207 ctx->base.is_jmp = DISAS_EXIT; 6208 register_name = "Status"; 6209 break; 6210 case CP0_REG12__INTCTL: 6211 check_insn(ctx, ISA_MIPS_R2); 6212 gen_helper_mtc0_intctl(tcg_env, arg); 6213 /* Stop translation as we may have switched the execution mode */ 6214 ctx->base.is_jmp = DISAS_STOP; 6215 register_name = "IntCtl"; 6216 break; 6217 case CP0_REG12__SRSCTL: 6218 check_insn(ctx, ISA_MIPS_R2); 6219 gen_helper_mtc0_srsctl(tcg_env, arg); 6220 /* Stop translation as we may have switched the execution mode */ 6221 ctx->base.is_jmp = DISAS_STOP; 6222 register_name = "SRSCtl"; 6223 break; 6224 case CP0_REG12__SRSMAP: 6225 check_insn(ctx, ISA_MIPS_R2); 6226 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6227 /* Stop translation as we may have switched the execution mode */ 6228 ctx->base.is_jmp = DISAS_STOP; 6229 register_name = "SRSMap"; 6230 break; 6231 default: 6232 goto cp0_unimplemented; 6233 } 6234 break; 6235 case CP0_REGISTER_13: 6236 switch (sel) { 6237 case CP0_REG13__CAUSE: 6238 save_cpu_state(ctx, 1); 6239 gen_helper_mtc0_cause(tcg_env, arg); 6240 /* 6241 * Stop translation as we may have triggered an interrupt. 6242 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6243 * translated code to check for pending interrupts. 6244 */ 6245 gen_save_pc(ctx->base.pc_next + 4); 6246 ctx->base.is_jmp = DISAS_EXIT; 6247 register_name = "Cause"; 6248 break; 6249 default: 6250 goto cp0_unimplemented; 6251 } 6252 break; 6253 case CP0_REGISTER_14: 6254 switch (sel) { 6255 case CP0_REG14__EPC: 6256 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 6257 register_name = "EPC"; 6258 break; 6259 default: 6260 goto cp0_unimplemented; 6261 } 6262 break; 6263 case CP0_REGISTER_15: 6264 switch (sel) { 6265 case CP0_REG15__PRID: 6266 /* ignored */ 6267 register_name = "PRid"; 6268 break; 6269 case CP0_REG15__EBASE: 6270 check_insn(ctx, ISA_MIPS_R2); 6271 gen_helper_mtc0_ebase(tcg_env, arg); 6272 register_name = "EBase"; 6273 break; 6274 default: 6275 goto cp0_unimplemented; 6276 } 6277 break; 6278 case CP0_REGISTER_16: 6279 switch (sel) { 6280 case CP0_REG16__CONFIG: 6281 gen_helper_mtc0_config0(tcg_env, arg); 6282 register_name = "Config"; 6283 /* Stop translation as we may have switched the execution mode */ 6284 ctx->base.is_jmp = DISAS_STOP; 6285 break; 6286 case CP0_REG16__CONFIG1: 6287 /* ignored, read only */ 6288 register_name = "Config1"; 6289 break; 6290 case CP0_REG16__CONFIG2: 6291 gen_helper_mtc0_config2(tcg_env, arg); 6292 register_name = "Config2"; 6293 /* Stop translation as we may have switched the execution mode */ 6294 ctx->base.is_jmp = DISAS_STOP; 6295 break; 6296 case CP0_REG16__CONFIG3: 6297 gen_helper_mtc0_config3(tcg_env, arg); 6298 register_name = "Config3"; 6299 /* Stop translation as we may have switched the execution mode */ 6300 ctx->base.is_jmp = DISAS_STOP; 6301 break; 6302 case CP0_REG16__CONFIG4: 6303 gen_helper_mtc0_config4(tcg_env, arg); 6304 register_name = "Config4"; 6305 ctx->base.is_jmp = DISAS_STOP; 6306 break; 6307 case CP0_REG16__CONFIG5: 6308 gen_helper_mtc0_config5(tcg_env, arg); 6309 register_name = "Config5"; 6310 /* Stop translation as we may have switched the execution mode */ 6311 ctx->base.is_jmp = DISAS_STOP; 6312 break; 6313 /* 6,7 are implementation dependent */ 6314 case CP0_REG16__CONFIG6: 6315 /* ignored */ 6316 register_name = "Config6"; 6317 break; 6318 case CP0_REG16__CONFIG7: 6319 /* ignored */ 6320 register_name = "Config7"; 6321 break; 6322 default: 6323 register_name = "Invalid config selector"; 6324 goto cp0_unimplemented; 6325 } 6326 break; 6327 case CP0_REGISTER_17: 6328 switch (sel) { 6329 case CP0_REG17__LLADDR: 6330 gen_helper_mtc0_lladdr(tcg_env, arg); 6331 register_name = "LLAddr"; 6332 break; 6333 case CP0_REG17__MAAR: 6334 CP0_CHECK(ctx->mrp); 6335 gen_helper_mtc0_maar(tcg_env, arg); 6336 register_name = "MAAR"; 6337 break; 6338 case CP0_REG17__MAARI: 6339 CP0_CHECK(ctx->mrp); 6340 gen_helper_mtc0_maari(tcg_env, arg); 6341 register_name = "MAARI"; 6342 break; 6343 default: 6344 goto cp0_unimplemented; 6345 } 6346 break; 6347 case CP0_REGISTER_18: 6348 switch (sel) { 6349 case CP0_REG18__WATCHLO0: 6350 case CP0_REG18__WATCHLO1: 6351 case CP0_REG18__WATCHLO2: 6352 case CP0_REG18__WATCHLO3: 6353 case CP0_REG18__WATCHLO4: 6354 case CP0_REG18__WATCHLO5: 6355 case CP0_REG18__WATCHLO6: 6356 case CP0_REG18__WATCHLO7: 6357 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6358 gen_helper_0e1i(mtc0_watchlo, arg, sel); 6359 register_name = "WatchLo"; 6360 break; 6361 default: 6362 goto cp0_unimplemented; 6363 } 6364 break; 6365 case CP0_REGISTER_19: 6366 switch (sel) { 6367 case CP0_REG19__WATCHHI0: 6368 case CP0_REG19__WATCHHI1: 6369 case CP0_REG19__WATCHHI2: 6370 case CP0_REG19__WATCHHI3: 6371 case CP0_REG19__WATCHHI4: 6372 case CP0_REG19__WATCHHI5: 6373 case CP0_REG19__WATCHHI6: 6374 case CP0_REG19__WATCHHI7: 6375 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6376 gen_helper_0e1i(mtc0_watchhi, arg, sel); 6377 register_name = "WatchHi"; 6378 break; 6379 default: 6380 goto cp0_unimplemented; 6381 } 6382 break; 6383 case CP0_REGISTER_20: 6384 switch (sel) { 6385 case CP0_REG20__XCONTEXT: 6386 #if defined(TARGET_MIPS64) 6387 check_insn(ctx, ISA_MIPS3); 6388 gen_helper_mtc0_xcontext(tcg_env, arg); 6389 register_name = "XContext"; 6390 break; 6391 #endif 6392 default: 6393 goto cp0_unimplemented; 6394 } 6395 break; 6396 case CP0_REGISTER_21: 6397 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6398 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6399 switch (sel) { 6400 case 0: 6401 gen_helper_mtc0_framemask(tcg_env, arg); 6402 register_name = "Framemask"; 6403 break; 6404 default: 6405 goto cp0_unimplemented; 6406 } 6407 break; 6408 case CP0_REGISTER_22: 6409 /* ignored */ 6410 register_name = "Diagnostic"; /* implementation dependent */ 6411 break; 6412 case CP0_REGISTER_23: 6413 switch (sel) { 6414 case CP0_REG23__DEBUG: 6415 gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */ 6416 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6417 gen_save_pc(ctx->base.pc_next + 4); 6418 ctx->base.is_jmp = DISAS_EXIT; 6419 register_name = "Debug"; 6420 break; 6421 case CP0_REG23__TRACECONTROL: 6422 /* PDtrace support */ 6423 /* gen_helper_mtc0_tracecontrol(tcg_env, arg); */ 6424 register_name = "TraceControl"; 6425 /* Stop translation as we may have switched the execution mode */ 6426 ctx->base.is_jmp = DISAS_STOP; 6427 goto cp0_unimplemented; 6428 case CP0_REG23__TRACECONTROL2: 6429 /* PDtrace support */ 6430 /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */ 6431 register_name = "TraceControl2"; 6432 /* Stop translation as we may have switched the execution mode */ 6433 ctx->base.is_jmp = DISAS_STOP; 6434 goto cp0_unimplemented; 6435 case CP0_REG23__USERTRACEDATA1: 6436 /* Stop translation as we may have switched the execution mode */ 6437 ctx->base.is_jmp = DISAS_STOP; 6438 /* PDtrace support */ 6439 /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/ 6440 register_name = "UserTraceData"; 6441 /* Stop translation as we may have switched the execution mode */ 6442 ctx->base.is_jmp = DISAS_STOP; 6443 goto cp0_unimplemented; 6444 case CP0_REG23__TRACEIBPC: 6445 /* PDtrace support */ 6446 /* gen_helper_mtc0_traceibpc(tcg_env, arg); */ 6447 /* Stop translation as we may have switched the execution mode */ 6448 ctx->base.is_jmp = DISAS_STOP; 6449 register_name = "TraceIBPC"; 6450 goto cp0_unimplemented; 6451 case CP0_REG23__TRACEDBPC: 6452 /* PDtrace support */ 6453 /* gen_helper_mtc0_tracedbpc(tcg_env, arg); */ 6454 /* Stop translation as we may have switched the execution mode */ 6455 ctx->base.is_jmp = DISAS_STOP; 6456 register_name = "TraceDBPC"; 6457 goto cp0_unimplemented; 6458 default: 6459 goto cp0_unimplemented; 6460 } 6461 break; 6462 case CP0_REGISTER_24: 6463 switch (sel) { 6464 case CP0_REG24__DEPC: 6465 /* EJTAG support */ 6466 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 6467 register_name = "DEPC"; 6468 break; 6469 default: 6470 goto cp0_unimplemented; 6471 } 6472 break; 6473 case CP0_REGISTER_25: 6474 switch (sel) { 6475 case CP0_REG25__PERFCTL0: 6476 gen_helper_mtc0_performance0(tcg_env, arg); 6477 register_name = "Performance0"; 6478 break; 6479 case CP0_REG25__PERFCNT0: 6480 /* gen_helper_mtc0_performance1(arg); */ 6481 register_name = "Performance1"; 6482 goto cp0_unimplemented; 6483 case CP0_REG25__PERFCTL1: 6484 /* gen_helper_mtc0_performance2(arg); */ 6485 register_name = "Performance2"; 6486 goto cp0_unimplemented; 6487 case CP0_REG25__PERFCNT1: 6488 /* gen_helper_mtc0_performance3(arg); */ 6489 register_name = "Performance3"; 6490 goto cp0_unimplemented; 6491 case CP0_REG25__PERFCTL2: 6492 /* gen_helper_mtc0_performance4(arg); */ 6493 register_name = "Performance4"; 6494 goto cp0_unimplemented; 6495 case CP0_REG25__PERFCNT2: 6496 /* gen_helper_mtc0_performance5(arg); */ 6497 register_name = "Performance5"; 6498 goto cp0_unimplemented; 6499 case CP0_REG25__PERFCTL3: 6500 /* gen_helper_mtc0_performance6(arg); */ 6501 register_name = "Performance6"; 6502 goto cp0_unimplemented; 6503 case CP0_REG25__PERFCNT3: 6504 /* gen_helper_mtc0_performance7(arg); */ 6505 register_name = "Performance7"; 6506 goto cp0_unimplemented; 6507 default: 6508 goto cp0_unimplemented; 6509 } 6510 break; 6511 case CP0_REGISTER_26: 6512 switch (sel) { 6513 case CP0_REG26__ERRCTL: 6514 gen_helper_mtc0_errctl(tcg_env, arg); 6515 ctx->base.is_jmp = DISAS_STOP; 6516 register_name = "ErrCtl"; 6517 break; 6518 default: 6519 goto cp0_unimplemented; 6520 } 6521 break; 6522 case CP0_REGISTER_27: 6523 switch (sel) { 6524 case CP0_REG27__CACHERR: 6525 /* ignored */ 6526 register_name = "CacheErr"; 6527 break; 6528 default: 6529 goto cp0_unimplemented; 6530 } 6531 break; 6532 case CP0_REGISTER_28: 6533 switch (sel) { 6534 case CP0_REG28__TAGLO: 6535 case CP0_REG28__TAGLO1: 6536 case CP0_REG28__TAGLO2: 6537 case CP0_REG28__TAGLO3: 6538 gen_helper_mtc0_taglo(tcg_env, arg); 6539 register_name = "TagLo"; 6540 break; 6541 case CP0_REG28__DATALO: 6542 case CP0_REG28__DATALO1: 6543 case CP0_REG28__DATALO2: 6544 case CP0_REG28__DATALO3: 6545 gen_helper_mtc0_datalo(tcg_env, arg); 6546 register_name = "DataLo"; 6547 break; 6548 default: 6549 goto cp0_unimplemented; 6550 } 6551 break; 6552 case CP0_REGISTER_29: 6553 switch (sel) { 6554 case CP0_REG29__TAGHI: 6555 case CP0_REG29__TAGHI1: 6556 case CP0_REG29__TAGHI2: 6557 case CP0_REG29__TAGHI3: 6558 gen_helper_mtc0_taghi(tcg_env, arg); 6559 register_name = "TagHi"; 6560 break; 6561 case CP0_REG29__DATAHI: 6562 case CP0_REG29__DATAHI1: 6563 case CP0_REG29__DATAHI2: 6564 case CP0_REG29__DATAHI3: 6565 gen_helper_mtc0_datahi(tcg_env, arg); 6566 register_name = "DataHi"; 6567 break; 6568 default: 6569 register_name = "invalid sel"; 6570 goto cp0_unimplemented; 6571 } 6572 break; 6573 case CP0_REGISTER_30: 6574 switch (sel) { 6575 case CP0_REG30__ERROREPC: 6576 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 6577 register_name = "ErrorEPC"; 6578 break; 6579 default: 6580 goto cp0_unimplemented; 6581 } 6582 break; 6583 case CP0_REGISTER_31: 6584 switch (sel) { 6585 case CP0_REG31__DESAVE: 6586 /* EJTAG support */ 6587 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 6588 register_name = "DESAVE"; 6589 break; 6590 case CP0_REG31__KSCRATCH1: 6591 case CP0_REG31__KSCRATCH2: 6592 case CP0_REG31__KSCRATCH3: 6593 case CP0_REG31__KSCRATCH4: 6594 case CP0_REG31__KSCRATCH5: 6595 case CP0_REG31__KSCRATCH6: 6596 CP0_CHECK(ctx->kscrexist & (1 << sel)); 6597 tcg_gen_st_tl(arg, tcg_env, 6598 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 6599 register_name = "KScratch"; 6600 break; 6601 default: 6602 goto cp0_unimplemented; 6603 } 6604 break; 6605 default: 6606 goto cp0_unimplemented; 6607 } 6608 trace_mips_translate_c0("mtc0", register_name, reg, sel); 6609 6610 /* For simplicity assume that all writes can cause interrupts. */ 6611 if (icount) { 6612 /* 6613 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6614 * translated code to check for pending interrupts. 6615 */ 6616 gen_save_pc(ctx->base.pc_next + 4); 6617 ctx->base.is_jmp = DISAS_EXIT; 6618 } 6619 return; 6620 6621 cp0_unimplemented: 6622 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", 6623 register_name, reg, sel); 6624 } 6625 6626 #if defined(TARGET_MIPS64) 6627 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 6628 { 6629 const char *register_name = "invalid"; 6630 6631 if (sel != 0) { 6632 check_insn(ctx, ISA_MIPS_R1); 6633 } 6634 6635 switch (reg) { 6636 case CP0_REGISTER_00: 6637 switch (sel) { 6638 case CP0_REG00__INDEX: 6639 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 6640 register_name = "Index"; 6641 break; 6642 case CP0_REG00__MVPCONTROL: 6643 CP0_CHECK(disas_mt_available(ctx)); 6644 gen_helper_mfc0_mvpcontrol(arg, tcg_env); 6645 register_name = "MVPControl"; 6646 break; 6647 case CP0_REG00__MVPCONF0: 6648 CP0_CHECK(disas_mt_available(ctx)); 6649 gen_helper_mfc0_mvpconf0(arg, tcg_env); 6650 register_name = "MVPConf0"; 6651 break; 6652 case CP0_REG00__MVPCONF1: 6653 CP0_CHECK(disas_mt_available(ctx)); 6654 gen_helper_mfc0_mvpconf1(arg, tcg_env); 6655 register_name = "MVPConf1"; 6656 break; 6657 case CP0_REG00__VPCONTROL: 6658 CP0_CHECK(ctx->vp); 6659 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 6660 register_name = "VPControl"; 6661 break; 6662 default: 6663 goto cp0_unimplemented; 6664 } 6665 break; 6666 case CP0_REGISTER_01: 6667 switch (sel) { 6668 case CP0_REG01__RANDOM: 6669 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6670 gen_helper_mfc0_random(arg, tcg_env); 6671 register_name = "Random"; 6672 break; 6673 case CP0_REG01__VPECONTROL: 6674 CP0_CHECK(disas_mt_available(ctx)); 6675 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 6676 register_name = "VPEControl"; 6677 break; 6678 case CP0_REG01__VPECONF0: 6679 CP0_CHECK(disas_mt_available(ctx)); 6680 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 6681 register_name = "VPEConf0"; 6682 break; 6683 case CP0_REG01__VPECONF1: 6684 CP0_CHECK(disas_mt_available(ctx)); 6685 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 6686 register_name = "VPEConf1"; 6687 break; 6688 case CP0_REG01__YQMASK: 6689 CP0_CHECK(disas_mt_available(ctx)); 6690 tcg_gen_ld_tl(arg, tcg_env, 6691 offsetof(CPUMIPSState, CP0_YQMask)); 6692 register_name = "YQMask"; 6693 break; 6694 case CP0_REG01__VPESCHEDULE: 6695 CP0_CHECK(disas_mt_available(ctx)); 6696 tcg_gen_ld_tl(arg, tcg_env, 6697 offsetof(CPUMIPSState, CP0_VPESchedule)); 6698 register_name = "VPESchedule"; 6699 break; 6700 case CP0_REG01__VPESCHEFBACK: 6701 CP0_CHECK(disas_mt_available(ctx)); 6702 tcg_gen_ld_tl(arg, tcg_env, 6703 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6704 register_name = "VPEScheFBack"; 6705 break; 6706 case CP0_REG01__VPEOPT: 6707 CP0_CHECK(disas_mt_available(ctx)); 6708 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 6709 register_name = "VPEOpt"; 6710 break; 6711 default: 6712 goto cp0_unimplemented; 6713 } 6714 break; 6715 case CP0_REGISTER_02: 6716 switch (sel) { 6717 case CP0_REG02__ENTRYLO0: 6718 tcg_gen_ld_tl(arg, tcg_env, 6719 offsetof(CPUMIPSState, CP0_EntryLo0)); 6720 register_name = "EntryLo0"; 6721 break; 6722 case CP0_REG02__TCSTATUS: 6723 CP0_CHECK(disas_mt_available(ctx)); 6724 gen_helper_mfc0_tcstatus(arg, tcg_env); 6725 register_name = "TCStatus"; 6726 break; 6727 case CP0_REG02__TCBIND: 6728 CP0_CHECK(disas_mt_available(ctx)); 6729 gen_helper_mfc0_tcbind(arg, tcg_env); 6730 register_name = "TCBind"; 6731 break; 6732 case CP0_REG02__TCRESTART: 6733 CP0_CHECK(disas_mt_available(ctx)); 6734 gen_helper_dmfc0_tcrestart(arg, tcg_env); 6735 register_name = "TCRestart"; 6736 break; 6737 case CP0_REG02__TCHALT: 6738 CP0_CHECK(disas_mt_available(ctx)); 6739 gen_helper_dmfc0_tchalt(arg, tcg_env); 6740 register_name = "TCHalt"; 6741 break; 6742 case CP0_REG02__TCCONTEXT: 6743 CP0_CHECK(disas_mt_available(ctx)); 6744 gen_helper_dmfc0_tccontext(arg, tcg_env); 6745 register_name = "TCContext"; 6746 break; 6747 case CP0_REG02__TCSCHEDULE: 6748 CP0_CHECK(disas_mt_available(ctx)); 6749 gen_helper_dmfc0_tcschedule(arg, tcg_env); 6750 register_name = "TCSchedule"; 6751 break; 6752 case CP0_REG02__TCSCHEFBACK: 6753 CP0_CHECK(disas_mt_available(ctx)); 6754 gen_helper_dmfc0_tcschefback(arg, tcg_env); 6755 register_name = "TCScheFBack"; 6756 break; 6757 default: 6758 goto cp0_unimplemented; 6759 } 6760 break; 6761 case CP0_REGISTER_03: 6762 switch (sel) { 6763 case CP0_REG03__ENTRYLO1: 6764 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 6765 register_name = "EntryLo1"; 6766 break; 6767 case CP0_REG03__GLOBALNUM: 6768 CP0_CHECK(ctx->vp); 6769 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 6770 register_name = "GlobalNumber"; 6771 break; 6772 default: 6773 goto cp0_unimplemented; 6774 } 6775 break; 6776 case CP0_REGISTER_04: 6777 switch (sel) { 6778 case CP0_REG04__CONTEXT: 6779 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context)); 6780 register_name = "Context"; 6781 break; 6782 case CP0_REG04__CONTEXTCONFIG: 6783 /* SmartMIPS ASE */ 6784 /* gen_helper_dmfc0_contextconfig(arg); */ 6785 register_name = "ContextConfig"; 6786 goto cp0_unimplemented; 6787 case CP0_REG04__USERLOCAL: 6788 CP0_CHECK(ctx->ulri); 6789 tcg_gen_ld_tl(arg, tcg_env, 6790 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6791 register_name = "UserLocal"; 6792 break; 6793 case CP0_REG04__MMID: 6794 CP0_CHECK(ctx->mi); 6795 gen_helper_mtc0_memorymapid(tcg_env, arg); 6796 register_name = "MMID"; 6797 break; 6798 default: 6799 goto cp0_unimplemented; 6800 } 6801 break; 6802 case CP0_REGISTER_05: 6803 switch (sel) { 6804 case CP0_REG05__PAGEMASK: 6805 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 6806 register_name = "PageMask"; 6807 break; 6808 case CP0_REG05__PAGEGRAIN: 6809 check_insn(ctx, ISA_MIPS_R2); 6810 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 6811 register_name = "PageGrain"; 6812 break; 6813 case CP0_REG05__SEGCTL0: 6814 CP0_CHECK(ctx->sc); 6815 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 6816 register_name = "SegCtl0"; 6817 break; 6818 case CP0_REG05__SEGCTL1: 6819 CP0_CHECK(ctx->sc); 6820 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 6821 register_name = "SegCtl1"; 6822 break; 6823 case CP0_REG05__SEGCTL2: 6824 CP0_CHECK(ctx->sc); 6825 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 6826 register_name = "SegCtl2"; 6827 break; 6828 case CP0_REG05__PWBASE: 6829 check_pw(ctx); 6830 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase)); 6831 register_name = "PWBase"; 6832 break; 6833 case CP0_REG05__PWFIELD: 6834 check_pw(ctx); 6835 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWField)); 6836 register_name = "PWField"; 6837 break; 6838 case CP0_REG05__PWSIZE: 6839 check_pw(ctx); 6840 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWSize)); 6841 register_name = "PWSize"; 6842 break; 6843 default: 6844 goto cp0_unimplemented; 6845 } 6846 break; 6847 case CP0_REGISTER_06: 6848 switch (sel) { 6849 case CP0_REG06__WIRED: 6850 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 6851 register_name = "Wired"; 6852 break; 6853 case CP0_REG06__SRSCONF0: 6854 check_insn(ctx, ISA_MIPS_R2); 6855 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 6856 register_name = "SRSConf0"; 6857 break; 6858 case CP0_REG06__SRSCONF1: 6859 check_insn(ctx, ISA_MIPS_R2); 6860 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 6861 register_name = "SRSConf1"; 6862 break; 6863 case CP0_REG06__SRSCONF2: 6864 check_insn(ctx, ISA_MIPS_R2); 6865 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 6866 register_name = "SRSConf2"; 6867 break; 6868 case CP0_REG06__SRSCONF3: 6869 check_insn(ctx, ISA_MIPS_R2); 6870 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 6871 register_name = "SRSConf3"; 6872 break; 6873 case CP0_REG06__SRSCONF4: 6874 check_insn(ctx, ISA_MIPS_R2); 6875 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 6876 register_name = "SRSConf4"; 6877 break; 6878 case CP0_REG06__PWCTL: 6879 check_pw(ctx); 6880 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 6881 register_name = "PWCtl"; 6882 break; 6883 default: 6884 goto cp0_unimplemented; 6885 } 6886 break; 6887 case CP0_REGISTER_07: 6888 switch (sel) { 6889 case CP0_REG07__HWRENA: 6890 check_insn(ctx, ISA_MIPS_R2); 6891 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 6892 register_name = "HWREna"; 6893 break; 6894 default: 6895 goto cp0_unimplemented; 6896 } 6897 break; 6898 case CP0_REGISTER_08: 6899 switch (sel) { 6900 case CP0_REG08__BADVADDR: 6901 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 6902 register_name = "BadVAddr"; 6903 break; 6904 case CP0_REG08__BADINSTR: 6905 CP0_CHECK(ctx->bi); 6906 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 6907 register_name = "BadInstr"; 6908 break; 6909 case CP0_REG08__BADINSTRP: 6910 CP0_CHECK(ctx->bp); 6911 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 6912 register_name = "BadInstrP"; 6913 break; 6914 case CP0_REG08__BADINSTRX: 6915 CP0_CHECK(ctx->bi); 6916 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 6917 tcg_gen_andi_tl(arg, arg, ~0xffff); 6918 register_name = "BadInstrX"; 6919 break; 6920 default: 6921 goto cp0_unimplemented; 6922 } 6923 break; 6924 case CP0_REGISTER_09: 6925 switch (sel) { 6926 case CP0_REG09__COUNT: 6927 /* Mark as an IO operation because we read the time. */ 6928 translator_io_start(&ctx->base); 6929 gen_helper_mfc0_count(arg, tcg_env); 6930 /* 6931 * Break the TB to be able to take timer interrupts immediately 6932 * after reading count. DISAS_STOP isn't sufficient, we need to 6933 * ensure we break completely out of translated code. 6934 */ 6935 gen_save_pc(ctx->base.pc_next + 4); 6936 ctx->base.is_jmp = DISAS_EXIT; 6937 register_name = "Count"; 6938 break; 6939 default: 6940 goto cp0_unimplemented; 6941 } 6942 break; 6943 case CP0_REGISTER_10: 6944 switch (sel) { 6945 case CP0_REG10__ENTRYHI: 6946 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi)); 6947 register_name = "EntryHi"; 6948 break; 6949 default: 6950 goto cp0_unimplemented; 6951 } 6952 break; 6953 case CP0_REGISTER_11: 6954 switch (sel) { 6955 case CP0_REG11__COMPARE: 6956 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 6957 register_name = "Compare"; 6958 break; 6959 /* 6,7 are implementation dependent */ 6960 default: 6961 goto cp0_unimplemented; 6962 } 6963 break; 6964 case CP0_REGISTER_12: 6965 switch (sel) { 6966 case CP0_REG12__STATUS: 6967 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 6968 register_name = "Status"; 6969 break; 6970 case CP0_REG12__INTCTL: 6971 check_insn(ctx, ISA_MIPS_R2); 6972 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 6973 register_name = "IntCtl"; 6974 break; 6975 case CP0_REG12__SRSCTL: 6976 check_insn(ctx, ISA_MIPS_R2); 6977 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 6978 register_name = "SRSCtl"; 6979 break; 6980 case CP0_REG12__SRSMAP: 6981 check_insn(ctx, ISA_MIPS_R2); 6982 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6983 register_name = "SRSMap"; 6984 break; 6985 default: 6986 goto cp0_unimplemented; 6987 } 6988 break; 6989 case CP0_REGISTER_13: 6990 switch (sel) { 6991 case CP0_REG13__CAUSE: 6992 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 6993 register_name = "Cause"; 6994 break; 6995 default: 6996 goto cp0_unimplemented; 6997 } 6998 break; 6999 case CP0_REGISTER_14: 7000 switch (sel) { 7001 case CP0_REG14__EPC: 7002 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 7003 register_name = "EPC"; 7004 break; 7005 default: 7006 goto cp0_unimplemented; 7007 } 7008 break; 7009 case CP0_REGISTER_15: 7010 switch (sel) { 7011 case CP0_REG15__PRID: 7012 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 7013 register_name = "PRid"; 7014 break; 7015 case CP0_REG15__EBASE: 7016 check_insn(ctx, ISA_MIPS_R2); 7017 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase)); 7018 register_name = "EBase"; 7019 break; 7020 case CP0_REG15__CMGCRBASE: 7021 check_insn(ctx, ISA_MIPS_R2); 7022 CP0_CHECK(ctx->cmgcr); 7023 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 7024 register_name = "CMGCRBase"; 7025 break; 7026 default: 7027 goto cp0_unimplemented; 7028 } 7029 break; 7030 case CP0_REGISTER_16: 7031 switch (sel) { 7032 case CP0_REG16__CONFIG: 7033 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 7034 register_name = "Config"; 7035 break; 7036 case CP0_REG16__CONFIG1: 7037 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 7038 register_name = "Config1"; 7039 break; 7040 case CP0_REG16__CONFIG2: 7041 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 7042 register_name = "Config2"; 7043 break; 7044 case CP0_REG16__CONFIG3: 7045 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 7046 register_name = "Config3"; 7047 break; 7048 case CP0_REG16__CONFIG4: 7049 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 7050 register_name = "Config4"; 7051 break; 7052 case CP0_REG16__CONFIG5: 7053 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 7054 register_name = "Config5"; 7055 break; 7056 /* 6,7 are implementation dependent */ 7057 case CP0_REG16__CONFIG6: 7058 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 7059 register_name = "Config6"; 7060 break; 7061 case CP0_REG16__CONFIG7: 7062 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 7063 register_name = "Config7"; 7064 break; 7065 default: 7066 goto cp0_unimplemented; 7067 } 7068 break; 7069 case CP0_REGISTER_17: 7070 switch (sel) { 7071 case CP0_REG17__LLADDR: 7072 gen_helper_dmfc0_lladdr(arg, tcg_env); 7073 register_name = "LLAddr"; 7074 break; 7075 case CP0_REG17__MAAR: 7076 CP0_CHECK(ctx->mrp); 7077 gen_helper_dmfc0_maar(arg, tcg_env); 7078 register_name = "MAAR"; 7079 break; 7080 case CP0_REG17__MAARI: 7081 CP0_CHECK(ctx->mrp); 7082 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 7083 register_name = "MAARI"; 7084 break; 7085 default: 7086 goto cp0_unimplemented; 7087 } 7088 break; 7089 case CP0_REGISTER_18: 7090 switch (sel) { 7091 case CP0_REG18__WATCHLO0: 7092 case CP0_REG18__WATCHLO1: 7093 case CP0_REG18__WATCHLO2: 7094 case CP0_REG18__WATCHLO3: 7095 case CP0_REG18__WATCHLO4: 7096 case CP0_REG18__WATCHLO5: 7097 case CP0_REG18__WATCHLO6: 7098 case CP0_REG18__WATCHLO7: 7099 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7100 gen_helper_1e0i(dmfc0_watchlo, arg, sel); 7101 register_name = "WatchLo"; 7102 break; 7103 default: 7104 goto cp0_unimplemented; 7105 } 7106 break; 7107 case CP0_REGISTER_19: 7108 switch (sel) { 7109 case CP0_REG19__WATCHHI0: 7110 case CP0_REG19__WATCHHI1: 7111 case CP0_REG19__WATCHHI2: 7112 case CP0_REG19__WATCHHI3: 7113 case CP0_REG19__WATCHHI4: 7114 case CP0_REG19__WATCHHI5: 7115 case CP0_REG19__WATCHHI6: 7116 case CP0_REG19__WATCHHI7: 7117 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7118 gen_helper_1e0i(dmfc0_watchhi, arg, sel); 7119 register_name = "WatchHi"; 7120 break; 7121 default: 7122 goto cp0_unimplemented; 7123 } 7124 break; 7125 case CP0_REGISTER_20: 7126 switch (sel) { 7127 case CP0_REG20__XCONTEXT: 7128 check_insn(ctx, ISA_MIPS3); 7129 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext)); 7130 register_name = "XContext"; 7131 break; 7132 default: 7133 goto cp0_unimplemented; 7134 } 7135 break; 7136 case CP0_REGISTER_21: 7137 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7138 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7139 switch (sel) { 7140 case 0: 7141 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 7142 register_name = "Framemask"; 7143 break; 7144 default: 7145 goto cp0_unimplemented; 7146 } 7147 break; 7148 case CP0_REGISTER_22: 7149 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7150 register_name = "'Diagnostic"; /* implementation dependent */ 7151 break; 7152 case CP0_REGISTER_23: 7153 switch (sel) { 7154 case CP0_REG23__DEBUG: 7155 gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */ 7156 register_name = "Debug"; 7157 break; 7158 case CP0_REG23__TRACECONTROL: 7159 /* PDtrace support */ 7160 /* gen_helper_dmfc0_tracecontrol(arg, tcg_env); */ 7161 register_name = "TraceControl"; 7162 goto cp0_unimplemented; 7163 case CP0_REG23__TRACECONTROL2: 7164 /* PDtrace support */ 7165 /* gen_helper_dmfc0_tracecontrol2(arg, tcg_env); */ 7166 register_name = "TraceControl2"; 7167 goto cp0_unimplemented; 7168 case CP0_REG23__USERTRACEDATA1: 7169 /* PDtrace support */ 7170 /* gen_helper_dmfc0_usertracedata1(arg, tcg_env);*/ 7171 register_name = "UserTraceData1"; 7172 goto cp0_unimplemented; 7173 case CP0_REG23__TRACEIBPC: 7174 /* PDtrace support */ 7175 /* gen_helper_dmfc0_traceibpc(arg, tcg_env); */ 7176 register_name = "TraceIBPC"; 7177 goto cp0_unimplemented; 7178 case CP0_REG23__TRACEDBPC: 7179 /* PDtrace support */ 7180 /* gen_helper_dmfc0_tracedbpc(arg, tcg_env); */ 7181 register_name = "TraceDBPC"; 7182 goto cp0_unimplemented; 7183 default: 7184 goto cp0_unimplemented; 7185 } 7186 break; 7187 case CP0_REGISTER_24: 7188 switch (sel) { 7189 case CP0_REG24__DEPC: 7190 /* EJTAG support */ 7191 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 7192 register_name = "DEPC"; 7193 break; 7194 default: 7195 goto cp0_unimplemented; 7196 } 7197 break; 7198 case CP0_REGISTER_25: 7199 switch (sel) { 7200 case CP0_REG25__PERFCTL0: 7201 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 7202 register_name = "Performance0"; 7203 break; 7204 case CP0_REG25__PERFCNT0: 7205 /* gen_helper_dmfc0_performance1(arg); */ 7206 register_name = "Performance1"; 7207 goto cp0_unimplemented; 7208 case CP0_REG25__PERFCTL1: 7209 /* gen_helper_dmfc0_performance2(arg); */ 7210 register_name = "Performance2"; 7211 goto cp0_unimplemented; 7212 case CP0_REG25__PERFCNT1: 7213 /* gen_helper_dmfc0_performance3(arg); */ 7214 register_name = "Performance3"; 7215 goto cp0_unimplemented; 7216 case CP0_REG25__PERFCTL2: 7217 /* gen_helper_dmfc0_performance4(arg); */ 7218 register_name = "Performance4"; 7219 goto cp0_unimplemented; 7220 case CP0_REG25__PERFCNT2: 7221 /* gen_helper_dmfc0_performance5(arg); */ 7222 register_name = "Performance5"; 7223 goto cp0_unimplemented; 7224 case CP0_REG25__PERFCTL3: 7225 /* gen_helper_dmfc0_performance6(arg); */ 7226 register_name = "Performance6"; 7227 goto cp0_unimplemented; 7228 case CP0_REG25__PERFCNT3: 7229 /* gen_helper_dmfc0_performance7(arg); */ 7230 register_name = "Performance7"; 7231 goto cp0_unimplemented; 7232 default: 7233 goto cp0_unimplemented; 7234 } 7235 break; 7236 case CP0_REGISTER_26: 7237 switch (sel) { 7238 case CP0_REG26__ERRCTL: 7239 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 7240 register_name = "ErrCtl"; 7241 break; 7242 default: 7243 goto cp0_unimplemented; 7244 } 7245 break; 7246 case CP0_REGISTER_27: 7247 switch (sel) { 7248 /* ignored */ 7249 case CP0_REG27__CACHERR: 7250 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7251 register_name = "CacheErr"; 7252 break; 7253 default: 7254 goto cp0_unimplemented; 7255 } 7256 break; 7257 case CP0_REGISTER_28: 7258 switch (sel) { 7259 case CP0_REG28__TAGLO: 7260 case CP0_REG28__TAGLO1: 7261 case CP0_REG28__TAGLO2: 7262 case CP0_REG28__TAGLO3: 7263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 7264 register_name = "TagLo"; 7265 break; 7266 case CP0_REG28__DATALO: 7267 case CP0_REG28__DATALO1: 7268 case CP0_REG28__DATALO2: 7269 case CP0_REG28__DATALO3: 7270 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 7271 register_name = "DataLo"; 7272 break; 7273 default: 7274 goto cp0_unimplemented; 7275 } 7276 break; 7277 case CP0_REGISTER_29: 7278 switch (sel) { 7279 case CP0_REG29__TAGHI: 7280 case CP0_REG29__TAGHI1: 7281 case CP0_REG29__TAGHI2: 7282 case CP0_REG29__TAGHI3: 7283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 7284 register_name = "TagHi"; 7285 break; 7286 case CP0_REG29__DATAHI: 7287 case CP0_REG29__DATAHI1: 7288 case CP0_REG29__DATAHI2: 7289 case CP0_REG29__DATAHI3: 7290 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 7291 register_name = "DataHi"; 7292 break; 7293 default: 7294 goto cp0_unimplemented; 7295 } 7296 break; 7297 case CP0_REGISTER_30: 7298 switch (sel) { 7299 case CP0_REG30__ERROREPC: 7300 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7301 register_name = "ErrorEPC"; 7302 break; 7303 default: 7304 goto cp0_unimplemented; 7305 } 7306 break; 7307 case CP0_REGISTER_31: 7308 switch (sel) { 7309 case CP0_REG31__DESAVE: 7310 /* EJTAG support */ 7311 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7312 register_name = "DESAVE"; 7313 break; 7314 case CP0_REG31__KSCRATCH1: 7315 case CP0_REG31__KSCRATCH2: 7316 case CP0_REG31__KSCRATCH3: 7317 case CP0_REG31__KSCRATCH4: 7318 case CP0_REG31__KSCRATCH5: 7319 case CP0_REG31__KSCRATCH6: 7320 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7321 tcg_gen_ld_tl(arg, tcg_env, 7322 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7323 register_name = "KScratch"; 7324 break; 7325 default: 7326 goto cp0_unimplemented; 7327 } 7328 break; 7329 default: 7330 goto cp0_unimplemented; 7331 } 7332 trace_mips_translate_c0("dmfc0", register_name, reg, sel); 7333 return; 7334 7335 cp0_unimplemented: 7336 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", 7337 register_name, reg, sel); 7338 gen_mfc0_unimplemented(ctx, arg); 7339 } 7340 7341 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7342 { 7343 const char *register_name = "invalid"; 7344 bool icount; 7345 7346 if (sel != 0) { 7347 check_insn(ctx, ISA_MIPS_R1); 7348 } 7349 7350 icount = translator_io_start(&ctx->base); 7351 7352 switch (reg) { 7353 case CP0_REGISTER_00: 7354 switch (sel) { 7355 case CP0_REG00__INDEX: 7356 gen_helper_mtc0_index(tcg_env, arg); 7357 register_name = "Index"; 7358 break; 7359 case CP0_REG00__MVPCONTROL: 7360 CP0_CHECK(disas_mt_available(ctx)); 7361 gen_helper_mtc0_mvpcontrol(tcg_env, arg); 7362 register_name = "MVPControl"; 7363 break; 7364 case CP0_REG00__MVPCONF0: 7365 CP0_CHECK(disas_mt_available(ctx)); 7366 /* ignored */ 7367 register_name = "MVPConf0"; 7368 break; 7369 case CP0_REG00__MVPCONF1: 7370 CP0_CHECK(disas_mt_available(ctx)); 7371 /* ignored */ 7372 register_name = "MVPConf1"; 7373 break; 7374 case CP0_REG00__VPCONTROL: 7375 CP0_CHECK(ctx->vp); 7376 /* ignored */ 7377 register_name = "VPControl"; 7378 break; 7379 default: 7380 goto cp0_unimplemented; 7381 } 7382 break; 7383 case CP0_REGISTER_01: 7384 switch (sel) { 7385 case CP0_REG01__RANDOM: 7386 /* ignored */ 7387 register_name = "Random"; 7388 break; 7389 case CP0_REG01__VPECONTROL: 7390 CP0_CHECK(disas_mt_available(ctx)); 7391 gen_helper_mtc0_vpecontrol(tcg_env, arg); 7392 register_name = "VPEControl"; 7393 break; 7394 case CP0_REG01__VPECONF0: 7395 CP0_CHECK(disas_mt_available(ctx)); 7396 gen_helper_mtc0_vpeconf0(tcg_env, arg); 7397 register_name = "VPEConf0"; 7398 break; 7399 case CP0_REG01__VPECONF1: 7400 CP0_CHECK(disas_mt_available(ctx)); 7401 gen_helper_mtc0_vpeconf1(tcg_env, arg); 7402 register_name = "VPEConf1"; 7403 break; 7404 case CP0_REG01__YQMASK: 7405 CP0_CHECK(disas_mt_available(ctx)); 7406 gen_helper_mtc0_yqmask(tcg_env, arg); 7407 register_name = "YQMask"; 7408 break; 7409 case CP0_REG01__VPESCHEDULE: 7410 CP0_CHECK(disas_mt_available(ctx)); 7411 tcg_gen_st_tl(arg, tcg_env, 7412 offsetof(CPUMIPSState, CP0_VPESchedule)); 7413 register_name = "VPESchedule"; 7414 break; 7415 case CP0_REG01__VPESCHEFBACK: 7416 CP0_CHECK(disas_mt_available(ctx)); 7417 tcg_gen_st_tl(arg, tcg_env, 7418 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7419 register_name = "VPEScheFBack"; 7420 break; 7421 case CP0_REG01__VPEOPT: 7422 CP0_CHECK(disas_mt_available(ctx)); 7423 gen_helper_mtc0_vpeopt(tcg_env, arg); 7424 register_name = "VPEOpt"; 7425 break; 7426 default: 7427 goto cp0_unimplemented; 7428 } 7429 break; 7430 case CP0_REGISTER_02: 7431 switch (sel) { 7432 case CP0_REG02__ENTRYLO0: 7433 gen_helper_dmtc0_entrylo0(tcg_env, arg); 7434 register_name = "EntryLo0"; 7435 break; 7436 case CP0_REG02__TCSTATUS: 7437 CP0_CHECK(disas_mt_available(ctx)); 7438 gen_helper_mtc0_tcstatus(tcg_env, arg); 7439 register_name = "TCStatus"; 7440 break; 7441 case CP0_REG02__TCBIND: 7442 CP0_CHECK(disas_mt_available(ctx)); 7443 gen_helper_mtc0_tcbind(tcg_env, arg); 7444 register_name = "TCBind"; 7445 break; 7446 case CP0_REG02__TCRESTART: 7447 CP0_CHECK(disas_mt_available(ctx)); 7448 gen_helper_mtc0_tcrestart(tcg_env, arg); 7449 register_name = "TCRestart"; 7450 break; 7451 case CP0_REG02__TCHALT: 7452 CP0_CHECK(disas_mt_available(ctx)); 7453 gen_helper_mtc0_tchalt(tcg_env, arg); 7454 register_name = "TCHalt"; 7455 break; 7456 case CP0_REG02__TCCONTEXT: 7457 CP0_CHECK(disas_mt_available(ctx)); 7458 gen_helper_mtc0_tccontext(tcg_env, arg); 7459 register_name = "TCContext"; 7460 break; 7461 case CP0_REG02__TCSCHEDULE: 7462 CP0_CHECK(disas_mt_available(ctx)); 7463 gen_helper_mtc0_tcschedule(tcg_env, arg); 7464 register_name = "TCSchedule"; 7465 break; 7466 case CP0_REG02__TCSCHEFBACK: 7467 CP0_CHECK(disas_mt_available(ctx)); 7468 gen_helper_mtc0_tcschefback(tcg_env, arg); 7469 register_name = "TCScheFBack"; 7470 break; 7471 default: 7472 goto cp0_unimplemented; 7473 } 7474 break; 7475 case CP0_REGISTER_03: 7476 switch (sel) { 7477 case CP0_REG03__ENTRYLO1: 7478 gen_helper_dmtc0_entrylo1(tcg_env, arg); 7479 register_name = "EntryLo1"; 7480 break; 7481 case CP0_REG03__GLOBALNUM: 7482 CP0_CHECK(ctx->vp); 7483 /* ignored */ 7484 register_name = "GlobalNumber"; 7485 break; 7486 default: 7487 goto cp0_unimplemented; 7488 } 7489 break; 7490 case CP0_REGISTER_04: 7491 switch (sel) { 7492 case CP0_REG04__CONTEXT: 7493 gen_helper_mtc0_context(tcg_env, arg); 7494 register_name = "Context"; 7495 break; 7496 case CP0_REG04__CONTEXTCONFIG: 7497 /* SmartMIPS ASE */ 7498 /* gen_helper_dmtc0_contextconfig(arg); */ 7499 register_name = "ContextConfig"; 7500 goto cp0_unimplemented; 7501 case CP0_REG04__USERLOCAL: 7502 CP0_CHECK(ctx->ulri); 7503 tcg_gen_st_tl(arg, tcg_env, 7504 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 7505 register_name = "UserLocal"; 7506 break; 7507 case CP0_REG04__MMID: 7508 CP0_CHECK(ctx->mi); 7509 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 7510 register_name = "MMID"; 7511 break; 7512 default: 7513 goto cp0_unimplemented; 7514 } 7515 break; 7516 case CP0_REGISTER_05: 7517 switch (sel) { 7518 case CP0_REG05__PAGEMASK: 7519 gen_helper_mtc0_pagemask(tcg_env, arg); 7520 register_name = "PageMask"; 7521 break; 7522 case CP0_REG05__PAGEGRAIN: 7523 check_insn(ctx, ISA_MIPS_R2); 7524 gen_helper_mtc0_pagegrain(tcg_env, arg); 7525 register_name = "PageGrain"; 7526 break; 7527 case CP0_REG05__SEGCTL0: 7528 CP0_CHECK(ctx->sc); 7529 gen_helper_mtc0_segctl0(tcg_env, arg); 7530 register_name = "SegCtl0"; 7531 break; 7532 case CP0_REG05__SEGCTL1: 7533 CP0_CHECK(ctx->sc); 7534 gen_helper_mtc0_segctl1(tcg_env, arg); 7535 register_name = "SegCtl1"; 7536 break; 7537 case CP0_REG05__SEGCTL2: 7538 CP0_CHECK(ctx->sc); 7539 gen_helper_mtc0_segctl2(tcg_env, arg); 7540 register_name = "SegCtl2"; 7541 break; 7542 case CP0_REG05__PWBASE: 7543 check_pw(ctx); 7544 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase)); 7545 register_name = "PWBase"; 7546 break; 7547 case CP0_REG05__PWFIELD: 7548 check_pw(ctx); 7549 gen_helper_mtc0_pwfield(tcg_env, arg); 7550 register_name = "PWField"; 7551 break; 7552 case CP0_REG05__PWSIZE: 7553 check_pw(ctx); 7554 gen_helper_mtc0_pwsize(tcg_env, arg); 7555 register_name = "PWSize"; 7556 break; 7557 default: 7558 goto cp0_unimplemented; 7559 } 7560 break; 7561 case CP0_REGISTER_06: 7562 switch (sel) { 7563 case CP0_REG06__WIRED: 7564 gen_helper_mtc0_wired(tcg_env, arg); 7565 register_name = "Wired"; 7566 break; 7567 case CP0_REG06__SRSCONF0: 7568 check_insn(ctx, ISA_MIPS_R2); 7569 gen_helper_mtc0_srsconf0(tcg_env, arg); 7570 register_name = "SRSConf0"; 7571 break; 7572 case CP0_REG06__SRSCONF1: 7573 check_insn(ctx, ISA_MIPS_R2); 7574 gen_helper_mtc0_srsconf1(tcg_env, arg); 7575 register_name = "SRSConf1"; 7576 break; 7577 case CP0_REG06__SRSCONF2: 7578 check_insn(ctx, ISA_MIPS_R2); 7579 gen_helper_mtc0_srsconf2(tcg_env, arg); 7580 register_name = "SRSConf2"; 7581 break; 7582 case CP0_REG06__SRSCONF3: 7583 check_insn(ctx, ISA_MIPS_R2); 7584 gen_helper_mtc0_srsconf3(tcg_env, arg); 7585 register_name = "SRSConf3"; 7586 break; 7587 case CP0_REG06__SRSCONF4: 7588 check_insn(ctx, ISA_MIPS_R2); 7589 gen_helper_mtc0_srsconf4(tcg_env, arg); 7590 register_name = "SRSConf4"; 7591 break; 7592 case CP0_REG06__PWCTL: 7593 check_pw(ctx); 7594 gen_helper_mtc0_pwctl(tcg_env, arg); 7595 register_name = "PWCtl"; 7596 break; 7597 default: 7598 goto cp0_unimplemented; 7599 } 7600 break; 7601 case CP0_REGISTER_07: 7602 switch (sel) { 7603 case CP0_REG07__HWRENA: 7604 check_insn(ctx, ISA_MIPS_R2); 7605 gen_helper_mtc0_hwrena(tcg_env, arg); 7606 ctx->base.is_jmp = DISAS_STOP; 7607 register_name = "HWREna"; 7608 break; 7609 default: 7610 goto cp0_unimplemented; 7611 } 7612 break; 7613 case CP0_REGISTER_08: 7614 switch (sel) { 7615 case CP0_REG08__BADVADDR: 7616 /* ignored */ 7617 register_name = "BadVAddr"; 7618 break; 7619 case CP0_REG08__BADINSTR: 7620 /* ignored */ 7621 register_name = "BadInstr"; 7622 break; 7623 case CP0_REG08__BADINSTRP: 7624 /* ignored */ 7625 register_name = "BadInstrP"; 7626 break; 7627 case CP0_REG08__BADINSTRX: 7628 /* ignored */ 7629 register_name = "BadInstrX"; 7630 break; 7631 default: 7632 goto cp0_unimplemented; 7633 } 7634 break; 7635 case CP0_REGISTER_09: 7636 switch (sel) { 7637 case CP0_REG09__COUNT: 7638 gen_helper_mtc0_count(tcg_env, arg); 7639 register_name = "Count"; 7640 break; 7641 default: 7642 goto cp0_unimplemented; 7643 } 7644 /* Stop translation as we may have switched the execution mode */ 7645 ctx->base.is_jmp = DISAS_STOP; 7646 break; 7647 case CP0_REGISTER_10: 7648 switch (sel) { 7649 case CP0_REG10__ENTRYHI: 7650 gen_helper_mtc0_entryhi(tcg_env, arg); 7651 register_name = "EntryHi"; 7652 break; 7653 default: 7654 goto cp0_unimplemented; 7655 } 7656 break; 7657 case CP0_REGISTER_11: 7658 switch (sel) { 7659 case CP0_REG11__COMPARE: 7660 gen_helper_mtc0_compare(tcg_env, arg); 7661 register_name = "Compare"; 7662 break; 7663 /* 6,7 are implementation dependent */ 7664 default: 7665 goto cp0_unimplemented; 7666 } 7667 /* Stop translation as we may have switched the execution mode */ 7668 ctx->base.is_jmp = DISAS_STOP; 7669 break; 7670 case CP0_REGISTER_12: 7671 switch (sel) { 7672 case CP0_REG12__STATUS: 7673 save_cpu_state(ctx, 1); 7674 gen_helper_mtc0_status(tcg_env, arg); 7675 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7676 gen_save_pc(ctx->base.pc_next + 4); 7677 ctx->base.is_jmp = DISAS_EXIT; 7678 register_name = "Status"; 7679 break; 7680 case CP0_REG12__INTCTL: 7681 check_insn(ctx, ISA_MIPS_R2); 7682 gen_helper_mtc0_intctl(tcg_env, arg); 7683 /* Stop translation as we may have switched the execution mode */ 7684 ctx->base.is_jmp = DISAS_STOP; 7685 register_name = "IntCtl"; 7686 break; 7687 case CP0_REG12__SRSCTL: 7688 check_insn(ctx, ISA_MIPS_R2); 7689 gen_helper_mtc0_srsctl(tcg_env, arg); 7690 /* Stop translation as we may have switched the execution mode */ 7691 ctx->base.is_jmp = DISAS_STOP; 7692 register_name = "SRSCtl"; 7693 break; 7694 case CP0_REG12__SRSMAP: 7695 check_insn(ctx, ISA_MIPS_R2); 7696 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7697 /* Stop translation as we may have switched the execution mode */ 7698 ctx->base.is_jmp = DISAS_STOP; 7699 register_name = "SRSMap"; 7700 break; 7701 default: 7702 goto cp0_unimplemented; 7703 } 7704 break; 7705 case CP0_REGISTER_13: 7706 switch (sel) { 7707 case CP0_REG13__CAUSE: 7708 save_cpu_state(ctx, 1); 7709 gen_helper_mtc0_cause(tcg_env, arg); 7710 /* 7711 * Stop translation as we may have triggered an interrupt. 7712 * DISAS_STOP isn't sufficient, we need to ensure we break out of 7713 * translated code to check for pending interrupts. 7714 */ 7715 gen_save_pc(ctx->base.pc_next + 4); 7716 ctx->base.is_jmp = DISAS_EXIT; 7717 register_name = "Cause"; 7718 break; 7719 default: 7720 goto cp0_unimplemented; 7721 } 7722 break; 7723 case CP0_REGISTER_14: 7724 switch (sel) { 7725 case CP0_REG14__EPC: 7726 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 7727 register_name = "EPC"; 7728 break; 7729 default: 7730 goto cp0_unimplemented; 7731 } 7732 break; 7733 case CP0_REGISTER_15: 7734 switch (sel) { 7735 case CP0_REG15__PRID: 7736 /* ignored */ 7737 register_name = "PRid"; 7738 break; 7739 case CP0_REG15__EBASE: 7740 check_insn(ctx, ISA_MIPS_R2); 7741 gen_helper_mtc0_ebase(tcg_env, arg); 7742 register_name = "EBase"; 7743 break; 7744 default: 7745 goto cp0_unimplemented; 7746 } 7747 break; 7748 case CP0_REGISTER_16: 7749 switch (sel) { 7750 case CP0_REG16__CONFIG: 7751 gen_helper_mtc0_config0(tcg_env, arg); 7752 register_name = "Config"; 7753 /* Stop translation as we may have switched the execution mode */ 7754 ctx->base.is_jmp = DISAS_STOP; 7755 break; 7756 case CP0_REG16__CONFIG1: 7757 /* ignored, read only */ 7758 register_name = "Config1"; 7759 break; 7760 case CP0_REG16__CONFIG2: 7761 gen_helper_mtc0_config2(tcg_env, arg); 7762 register_name = "Config2"; 7763 /* Stop translation as we may have switched the execution mode */ 7764 ctx->base.is_jmp = DISAS_STOP; 7765 break; 7766 case CP0_REG16__CONFIG3: 7767 gen_helper_mtc0_config3(tcg_env, arg); 7768 register_name = "Config3"; 7769 /* Stop translation as we may have switched the execution mode */ 7770 ctx->base.is_jmp = DISAS_STOP; 7771 break; 7772 case CP0_REG16__CONFIG4: 7773 /* currently ignored */ 7774 register_name = "Config4"; 7775 break; 7776 case CP0_REG16__CONFIG5: 7777 gen_helper_mtc0_config5(tcg_env, arg); 7778 register_name = "Config5"; 7779 /* Stop translation as we may have switched the execution mode */ 7780 ctx->base.is_jmp = DISAS_STOP; 7781 break; 7782 /* 6,7 are implementation dependent */ 7783 default: 7784 register_name = "Invalid config selector"; 7785 goto cp0_unimplemented; 7786 } 7787 break; 7788 case CP0_REGISTER_17: 7789 switch (sel) { 7790 case CP0_REG17__LLADDR: 7791 gen_helper_mtc0_lladdr(tcg_env, arg); 7792 register_name = "LLAddr"; 7793 break; 7794 case CP0_REG17__MAAR: 7795 CP0_CHECK(ctx->mrp); 7796 gen_helper_mtc0_maar(tcg_env, arg); 7797 register_name = "MAAR"; 7798 break; 7799 case CP0_REG17__MAARI: 7800 CP0_CHECK(ctx->mrp); 7801 gen_helper_mtc0_maari(tcg_env, arg); 7802 register_name = "MAARI"; 7803 break; 7804 default: 7805 goto cp0_unimplemented; 7806 } 7807 break; 7808 case CP0_REGISTER_18: 7809 switch (sel) { 7810 case CP0_REG18__WATCHLO0: 7811 case CP0_REG18__WATCHLO1: 7812 case CP0_REG18__WATCHLO2: 7813 case CP0_REG18__WATCHLO3: 7814 case CP0_REG18__WATCHLO4: 7815 case CP0_REG18__WATCHLO5: 7816 case CP0_REG18__WATCHLO6: 7817 case CP0_REG18__WATCHLO7: 7818 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7819 gen_helper_0e1i(mtc0_watchlo, arg, sel); 7820 register_name = "WatchLo"; 7821 break; 7822 default: 7823 goto cp0_unimplemented; 7824 } 7825 break; 7826 case CP0_REGISTER_19: 7827 switch (sel) { 7828 case CP0_REG19__WATCHHI0: 7829 case CP0_REG19__WATCHHI1: 7830 case CP0_REG19__WATCHHI2: 7831 case CP0_REG19__WATCHHI3: 7832 case CP0_REG19__WATCHHI4: 7833 case CP0_REG19__WATCHHI5: 7834 case CP0_REG19__WATCHHI6: 7835 case CP0_REG19__WATCHHI7: 7836 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7837 gen_helper_0e1i(mtc0_watchhi, arg, sel); 7838 register_name = "WatchHi"; 7839 break; 7840 default: 7841 goto cp0_unimplemented; 7842 } 7843 break; 7844 case CP0_REGISTER_20: 7845 switch (sel) { 7846 case CP0_REG20__XCONTEXT: 7847 check_insn(ctx, ISA_MIPS3); 7848 gen_helper_mtc0_xcontext(tcg_env, arg); 7849 register_name = "XContext"; 7850 break; 7851 default: 7852 goto cp0_unimplemented; 7853 } 7854 break; 7855 case CP0_REGISTER_21: 7856 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7857 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7858 switch (sel) { 7859 case 0: 7860 gen_helper_mtc0_framemask(tcg_env, arg); 7861 register_name = "Framemask"; 7862 break; 7863 default: 7864 goto cp0_unimplemented; 7865 } 7866 break; 7867 case CP0_REGISTER_22: 7868 /* ignored */ 7869 register_name = "Diagnostic"; /* implementation dependent */ 7870 break; 7871 case CP0_REGISTER_23: 7872 switch (sel) { 7873 case CP0_REG23__DEBUG: 7874 gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */ 7875 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7876 gen_save_pc(ctx->base.pc_next + 4); 7877 ctx->base.is_jmp = DISAS_EXIT; 7878 register_name = "Debug"; 7879 break; 7880 case CP0_REG23__TRACECONTROL: 7881 /* PDtrace support */ 7882 /* gen_helper_mtc0_tracecontrol(tcg_env, arg); */ 7883 /* Stop translation as we may have switched the execution mode */ 7884 ctx->base.is_jmp = DISAS_STOP; 7885 register_name = "TraceControl"; 7886 goto cp0_unimplemented; 7887 case CP0_REG23__TRACECONTROL2: 7888 /* PDtrace support */ 7889 /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */ 7890 /* Stop translation as we may have switched the execution mode */ 7891 ctx->base.is_jmp = DISAS_STOP; 7892 register_name = "TraceControl2"; 7893 goto cp0_unimplemented; 7894 case CP0_REG23__USERTRACEDATA1: 7895 /* PDtrace support */ 7896 /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/ 7897 /* Stop translation as we may have switched the execution mode */ 7898 ctx->base.is_jmp = DISAS_STOP; 7899 register_name = "UserTraceData1"; 7900 goto cp0_unimplemented; 7901 case CP0_REG23__TRACEIBPC: 7902 /* PDtrace support */ 7903 /* gen_helper_mtc0_traceibpc(tcg_env, arg); */ 7904 /* Stop translation as we may have switched the execution mode */ 7905 ctx->base.is_jmp = DISAS_STOP; 7906 register_name = "TraceIBPC"; 7907 goto cp0_unimplemented; 7908 case CP0_REG23__TRACEDBPC: 7909 /* PDtrace support */ 7910 /* gen_helper_mtc0_tracedbpc(tcg_env, arg); */ 7911 /* Stop translation as we may have switched the execution mode */ 7912 ctx->base.is_jmp = DISAS_STOP; 7913 register_name = "TraceDBPC"; 7914 goto cp0_unimplemented; 7915 default: 7916 goto cp0_unimplemented; 7917 } 7918 break; 7919 case CP0_REGISTER_24: 7920 switch (sel) { 7921 case CP0_REG24__DEPC: 7922 /* EJTAG support */ 7923 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 7924 register_name = "DEPC"; 7925 break; 7926 default: 7927 goto cp0_unimplemented; 7928 } 7929 break; 7930 case CP0_REGISTER_25: 7931 switch (sel) { 7932 case CP0_REG25__PERFCTL0: 7933 gen_helper_mtc0_performance0(tcg_env, arg); 7934 register_name = "Performance0"; 7935 break; 7936 case CP0_REG25__PERFCNT0: 7937 /* gen_helper_mtc0_performance1(tcg_env, arg); */ 7938 register_name = "Performance1"; 7939 goto cp0_unimplemented; 7940 case CP0_REG25__PERFCTL1: 7941 /* gen_helper_mtc0_performance2(tcg_env, arg); */ 7942 register_name = "Performance2"; 7943 goto cp0_unimplemented; 7944 case CP0_REG25__PERFCNT1: 7945 /* gen_helper_mtc0_performance3(tcg_env, arg); */ 7946 register_name = "Performance3"; 7947 goto cp0_unimplemented; 7948 case CP0_REG25__PERFCTL2: 7949 /* gen_helper_mtc0_performance4(tcg_env, arg); */ 7950 register_name = "Performance4"; 7951 goto cp0_unimplemented; 7952 case CP0_REG25__PERFCNT2: 7953 /* gen_helper_mtc0_performance5(tcg_env, arg); */ 7954 register_name = "Performance5"; 7955 goto cp0_unimplemented; 7956 case CP0_REG25__PERFCTL3: 7957 /* gen_helper_mtc0_performance6(tcg_env, arg); */ 7958 register_name = "Performance6"; 7959 goto cp0_unimplemented; 7960 case CP0_REG25__PERFCNT3: 7961 /* gen_helper_mtc0_performance7(tcg_env, arg); */ 7962 register_name = "Performance7"; 7963 goto cp0_unimplemented; 7964 default: 7965 goto cp0_unimplemented; 7966 } 7967 break; 7968 case CP0_REGISTER_26: 7969 switch (sel) { 7970 case CP0_REG26__ERRCTL: 7971 gen_helper_mtc0_errctl(tcg_env, arg); 7972 ctx->base.is_jmp = DISAS_STOP; 7973 register_name = "ErrCtl"; 7974 break; 7975 default: 7976 goto cp0_unimplemented; 7977 } 7978 break; 7979 case CP0_REGISTER_27: 7980 switch (sel) { 7981 case CP0_REG27__CACHERR: 7982 /* ignored */ 7983 register_name = "CacheErr"; 7984 break; 7985 default: 7986 goto cp0_unimplemented; 7987 } 7988 break; 7989 case CP0_REGISTER_28: 7990 switch (sel) { 7991 case CP0_REG28__TAGLO: 7992 case CP0_REG28__TAGLO1: 7993 case CP0_REG28__TAGLO2: 7994 case CP0_REG28__TAGLO3: 7995 gen_helper_mtc0_taglo(tcg_env, arg); 7996 register_name = "TagLo"; 7997 break; 7998 case CP0_REG28__DATALO: 7999 case CP0_REG28__DATALO1: 8000 case CP0_REG28__DATALO2: 8001 case CP0_REG28__DATALO3: 8002 gen_helper_mtc0_datalo(tcg_env, arg); 8003 register_name = "DataLo"; 8004 break; 8005 default: 8006 goto cp0_unimplemented; 8007 } 8008 break; 8009 case CP0_REGISTER_29: 8010 switch (sel) { 8011 case CP0_REG29__TAGHI: 8012 case CP0_REG29__TAGHI1: 8013 case CP0_REG29__TAGHI2: 8014 case CP0_REG29__TAGHI3: 8015 gen_helper_mtc0_taghi(tcg_env, arg); 8016 register_name = "TagHi"; 8017 break; 8018 case CP0_REG29__DATAHI: 8019 case CP0_REG29__DATAHI1: 8020 case CP0_REG29__DATAHI2: 8021 case CP0_REG29__DATAHI3: 8022 gen_helper_mtc0_datahi(tcg_env, arg); 8023 register_name = "DataHi"; 8024 break; 8025 default: 8026 register_name = "invalid sel"; 8027 goto cp0_unimplemented; 8028 } 8029 break; 8030 case CP0_REGISTER_30: 8031 switch (sel) { 8032 case CP0_REG30__ERROREPC: 8033 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 8034 register_name = "ErrorEPC"; 8035 break; 8036 default: 8037 goto cp0_unimplemented; 8038 } 8039 break; 8040 case CP0_REGISTER_31: 8041 switch (sel) { 8042 case CP0_REG31__DESAVE: 8043 /* EJTAG support */ 8044 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 8045 register_name = "DESAVE"; 8046 break; 8047 case CP0_REG31__KSCRATCH1: 8048 case CP0_REG31__KSCRATCH2: 8049 case CP0_REG31__KSCRATCH3: 8050 case CP0_REG31__KSCRATCH4: 8051 case CP0_REG31__KSCRATCH5: 8052 case CP0_REG31__KSCRATCH6: 8053 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8054 tcg_gen_st_tl(arg, tcg_env, 8055 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8056 register_name = "KScratch"; 8057 break; 8058 default: 8059 goto cp0_unimplemented; 8060 } 8061 break; 8062 default: 8063 goto cp0_unimplemented; 8064 } 8065 trace_mips_translate_c0("dmtc0", register_name, reg, sel); 8066 8067 /* For simplicity assume that all writes can cause interrupts. */ 8068 if (icount) { 8069 /* 8070 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8071 * translated code to check for pending interrupts. 8072 */ 8073 gen_save_pc(ctx->base.pc_next + 4); 8074 ctx->base.is_jmp = DISAS_EXIT; 8075 } 8076 return; 8077 8078 cp0_unimplemented: 8079 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", 8080 register_name, reg, sel); 8081 } 8082 #endif /* TARGET_MIPS64 */ 8083 8084 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 8085 int u, int sel, int h) 8086 { 8087 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8088 TCGv t0 = tcg_temp_new(); 8089 8090 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8091 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8092 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8093 tcg_gen_movi_tl(t0, -1); 8094 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8095 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8096 tcg_gen_movi_tl(t0, -1); 8097 } else if (u == 0) { 8098 switch (rt) { 8099 case 1: 8100 switch (sel) { 8101 case 1: 8102 gen_helper_mftc0_vpecontrol(t0, tcg_env); 8103 break; 8104 case 2: 8105 gen_helper_mftc0_vpeconf0(t0, tcg_env); 8106 break; 8107 default: 8108 goto die; 8109 break; 8110 } 8111 break; 8112 case 2: 8113 switch (sel) { 8114 case 1: 8115 gen_helper_mftc0_tcstatus(t0, tcg_env); 8116 break; 8117 case 2: 8118 gen_helper_mftc0_tcbind(t0, tcg_env); 8119 break; 8120 case 3: 8121 gen_helper_mftc0_tcrestart(t0, tcg_env); 8122 break; 8123 case 4: 8124 gen_helper_mftc0_tchalt(t0, tcg_env); 8125 break; 8126 case 5: 8127 gen_helper_mftc0_tccontext(t0, tcg_env); 8128 break; 8129 case 6: 8130 gen_helper_mftc0_tcschedule(t0, tcg_env); 8131 break; 8132 case 7: 8133 gen_helper_mftc0_tcschefback(t0, tcg_env); 8134 break; 8135 default: 8136 gen_mfc0(ctx, t0, rt, sel); 8137 break; 8138 } 8139 break; 8140 case 10: 8141 switch (sel) { 8142 case 0: 8143 gen_helper_mftc0_entryhi(t0, tcg_env); 8144 break; 8145 default: 8146 gen_mfc0(ctx, t0, rt, sel); 8147 break; 8148 } 8149 break; 8150 case 12: 8151 switch (sel) { 8152 case 0: 8153 gen_helper_mftc0_status(t0, tcg_env); 8154 break; 8155 default: 8156 gen_mfc0(ctx, t0, rt, sel); 8157 break; 8158 } 8159 break; 8160 case 13: 8161 switch (sel) { 8162 case 0: 8163 gen_helper_mftc0_cause(t0, tcg_env); 8164 break; 8165 default: 8166 goto die; 8167 break; 8168 } 8169 break; 8170 case 14: 8171 switch (sel) { 8172 case 0: 8173 gen_helper_mftc0_epc(t0, tcg_env); 8174 break; 8175 default: 8176 goto die; 8177 break; 8178 } 8179 break; 8180 case 15: 8181 switch (sel) { 8182 case 1: 8183 gen_helper_mftc0_ebase(t0, tcg_env); 8184 break; 8185 default: 8186 goto die; 8187 break; 8188 } 8189 break; 8190 case 16: 8191 switch (sel) { 8192 case 0: 8193 case 1: 8194 case 2: 8195 case 3: 8196 case 4: 8197 case 5: 8198 case 6: 8199 case 7: 8200 gen_helper_mftc0_configx(t0, tcg_env, tcg_constant_tl(sel)); 8201 break; 8202 default: 8203 goto die; 8204 break; 8205 } 8206 break; 8207 case 23: 8208 switch (sel) { 8209 case 0: 8210 gen_helper_mftc0_debug(t0, tcg_env); 8211 break; 8212 default: 8213 gen_mfc0(ctx, t0, rt, sel); 8214 break; 8215 } 8216 break; 8217 default: 8218 gen_mfc0(ctx, t0, rt, sel); 8219 } 8220 } else { 8221 switch (sel) { 8222 /* GPR registers. */ 8223 case 0: 8224 gen_helper_1e0i(mftgpr, t0, rt); 8225 break; 8226 /* Auxiliary CPU registers */ 8227 case 1: 8228 switch (rt) { 8229 case 0: 8230 gen_helper_1e0i(mftlo, t0, 0); 8231 break; 8232 case 1: 8233 gen_helper_1e0i(mfthi, t0, 0); 8234 break; 8235 case 2: 8236 gen_helper_1e0i(mftacx, t0, 0); 8237 break; 8238 case 4: 8239 gen_helper_1e0i(mftlo, t0, 1); 8240 break; 8241 case 5: 8242 gen_helper_1e0i(mfthi, t0, 1); 8243 break; 8244 case 6: 8245 gen_helper_1e0i(mftacx, t0, 1); 8246 break; 8247 case 8: 8248 gen_helper_1e0i(mftlo, t0, 2); 8249 break; 8250 case 9: 8251 gen_helper_1e0i(mfthi, t0, 2); 8252 break; 8253 case 10: 8254 gen_helper_1e0i(mftacx, t0, 2); 8255 break; 8256 case 12: 8257 gen_helper_1e0i(mftlo, t0, 3); 8258 break; 8259 case 13: 8260 gen_helper_1e0i(mfthi, t0, 3); 8261 break; 8262 case 14: 8263 gen_helper_1e0i(mftacx, t0, 3); 8264 break; 8265 case 16: 8266 gen_helper_mftdsp(t0, tcg_env); 8267 break; 8268 default: 8269 goto die; 8270 } 8271 break; 8272 /* Floating point (COP1). */ 8273 case 2: 8274 /* XXX: For now we support only a single FPU context. */ 8275 if (h == 0) { 8276 TCGv_i32 fp0 = tcg_temp_new_i32(); 8277 8278 gen_load_fpr32(ctx, fp0, rt); 8279 tcg_gen_ext_i32_tl(t0, fp0); 8280 } else { 8281 TCGv_i32 fp0 = tcg_temp_new_i32(); 8282 8283 gen_load_fpr32h(ctx, fp0, rt); 8284 tcg_gen_ext_i32_tl(t0, fp0); 8285 } 8286 break; 8287 case 3: 8288 /* XXX: For now we support only a single FPU context. */ 8289 gen_helper_1e0i(cfc1, t0, rt); 8290 break; 8291 /* COP2: Not implemented. */ 8292 case 4: 8293 case 5: 8294 /* fall through */ 8295 default: 8296 goto die; 8297 } 8298 } 8299 trace_mips_translate_tr("mftr", rt, u, sel, h); 8300 gen_store_gpr(t0, rd); 8301 return; 8302 8303 die: 8304 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 8305 gen_reserved_instruction(ctx); 8306 } 8307 8308 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 8309 int u, int sel, int h) 8310 { 8311 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8312 TCGv t0 = tcg_temp_new(); 8313 8314 gen_load_gpr(t0, rt); 8315 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8316 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8317 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8318 /* NOP */ 8319 ; 8320 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8321 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8322 /* NOP */ 8323 ; 8324 } else if (u == 0) { 8325 switch (rd) { 8326 case 1: 8327 switch (sel) { 8328 case 1: 8329 gen_helper_mttc0_vpecontrol(tcg_env, t0); 8330 break; 8331 case 2: 8332 gen_helper_mttc0_vpeconf0(tcg_env, t0); 8333 break; 8334 default: 8335 goto die; 8336 break; 8337 } 8338 break; 8339 case 2: 8340 switch (sel) { 8341 case 1: 8342 gen_helper_mttc0_tcstatus(tcg_env, t0); 8343 break; 8344 case 2: 8345 gen_helper_mttc0_tcbind(tcg_env, t0); 8346 break; 8347 case 3: 8348 gen_helper_mttc0_tcrestart(tcg_env, t0); 8349 break; 8350 case 4: 8351 gen_helper_mttc0_tchalt(tcg_env, t0); 8352 break; 8353 case 5: 8354 gen_helper_mttc0_tccontext(tcg_env, t0); 8355 break; 8356 case 6: 8357 gen_helper_mttc0_tcschedule(tcg_env, t0); 8358 break; 8359 case 7: 8360 gen_helper_mttc0_tcschefback(tcg_env, t0); 8361 break; 8362 default: 8363 gen_mtc0(ctx, t0, rd, sel); 8364 break; 8365 } 8366 break; 8367 case 10: 8368 switch (sel) { 8369 case 0: 8370 gen_helper_mttc0_entryhi(tcg_env, t0); 8371 break; 8372 default: 8373 gen_mtc0(ctx, t0, rd, sel); 8374 break; 8375 } 8376 break; 8377 case 12: 8378 switch (sel) { 8379 case 0: 8380 gen_helper_mttc0_status(tcg_env, t0); 8381 break; 8382 default: 8383 gen_mtc0(ctx, t0, rd, sel); 8384 break; 8385 } 8386 break; 8387 case 13: 8388 switch (sel) { 8389 case 0: 8390 gen_helper_mttc0_cause(tcg_env, t0); 8391 break; 8392 default: 8393 goto die; 8394 break; 8395 } 8396 break; 8397 case 15: 8398 switch (sel) { 8399 case 1: 8400 gen_helper_mttc0_ebase(tcg_env, t0); 8401 break; 8402 default: 8403 goto die; 8404 break; 8405 } 8406 break; 8407 case 23: 8408 switch (sel) { 8409 case 0: 8410 gen_helper_mttc0_debug(tcg_env, t0); 8411 break; 8412 default: 8413 gen_mtc0(ctx, t0, rd, sel); 8414 break; 8415 } 8416 break; 8417 default: 8418 gen_mtc0(ctx, t0, rd, sel); 8419 } 8420 } else { 8421 switch (sel) { 8422 /* GPR registers. */ 8423 case 0: 8424 gen_helper_0e1i(mttgpr, t0, rd); 8425 break; 8426 /* Auxiliary CPU registers */ 8427 case 1: 8428 switch (rd) { 8429 case 0: 8430 gen_helper_0e1i(mttlo, t0, 0); 8431 break; 8432 case 1: 8433 gen_helper_0e1i(mtthi, t0, 0); 8434 break; 8435 case 2: 8436 gen_helper_0e1i(mttacx, t0, 0); 8437 break; 8438 case 4: 8439 gen_helper_0e1i(mttlo, t0, 1); 8440 break; 8441 case 5: 8442 gen_helper_0e1i(mtthi, t0, 1); 8443 break; 8444 case 6: 8445 gen_helper_0e1i(mttacx, t0, 1); 8446 break; 8447 case 8: 8448 gen_helper_0e1i(mttlo, t0, 2); 8449 break; 8450 case 9: 8451 gen_helper_0e1i(mtthi, t0, 2); 8452 break; 8453 case 10: 8454 gen_helper_0e1i(mttacx, t0, 2); 8455 break; 8456 case 12: 8457 gen_helper_0e1i(mttlo, t0, 3); 8458 break; 8459 case 13: 8460 gen_helper_0e1i(mtthi, t0, 3); 8461 break; 8462 case 14: 8463 gen_helper_0e1i(mttacx, t0, 3); 8464 break; 8465 case 16: 8466 gen_helper_mttdsp(tcg_env, t0); 8467 break; 8468 default: 8469 goto die; 8470 } 8471 break; 8472 /* Floating point (COP1). */ 8473 case 2: 8474 /* XXX: For now we support only a single FPU context. */ 8475 if (h == 0) { 8476 TCGv_i32 fp0 = tcg_temp_new_i32(); 8477 8478 tcg_gen_trunc_tl_i32(fp0, t0); 8479 gen_store_fpr32(ctx, fp0, rd); 8480 } else { 8481 TCGv_i32 fp0 = tcg_temp_new_i32(); 8482 8483 tcg_gen_trunc_tl_i32(fp0, t0); 8484 gen_store_fpr32h(ctx, fp0, rd); 8485 } 8486 break; 8487 case 3: 8488 /* XXX: For now we support only a single FPU context. */ 8489 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt); 8490 /* Stop translation as we may have changed hflags */ 8491 ctx->base.is_jmp = DISAS_STOP; 8492 break; 8493 /* COP2: Not implemented. */ 8494 case 4: 8495 case 5: 8496 /* fall through */ 8497 default: 8498 goto die; 8499 } 8500 } 8501 trace_mips_translate_tr("mttr", rd, u, sel, h); 8502 return; 8503 8504 die: 8505 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 8506 gen_reserved_instruction(ctx); 8507 } 8508 8509 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 8510 int rt, int rd) 8511 { 8512 const char *opn = "ldst"; 8513 8514 check_cp0_enabled(ctx); 8515 switch (opc) { 8516 case OPC_MFC0: 8517 if (rt == 0) { 8518 /* Treat as NOP. */ 8519 return; 8520 } 8521 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8522 opn = "mfc0"; 8523 break; 8524 case OPC_MTC0: 8525 { 8526 TCGv t0 = tcg_temp_new(); 8527 8528 gen_load_gpr(t0, rt); 8529 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7); 8530 } 8531 opn = "mtc0"; 8532 break; 8533 #if defined(TARGET_MIPS64) 8534 case OPC_DMFC0: 8535 check_insn(ctx, ISA_MIPS3); 8536 if (rt == 0) { 8537 /* Treat as NOP. */ 8538 return; 8539 } 8540 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8541 opn = "dmfc0"; 8542 break; 8543 case OPC_DMTC0: 8544 check_insn(ctx, ISA_MIPS3); 8545 { 8546 TCGv t0 = tcg_temp_new(); 8547 8548 gen_load_gpr(t0, rt); 8549 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7); 8550 } 8551 opn = "dmtc0"; 8552 break; 8553 #endif 8554 case OPC_MFHC0: 8555 check_mvh(ctx); 8556 if (rt == 0) { 8557 /* Treat as NOP. */ 8558 return; 8559 } 8560 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8561 opn = "mfhc0"; 8562 break; 8563 case OPC_MTHC0: 8564 check_mvh(ctx); 8565 { 8566 TCGv t0 = tcg_temp_new(); 8567 gen_load_gpr(t0, rt); 8568 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7); 8569 } 8570 opn = "mthc0"; 8571 break; 8572 case OPC_MFTR: 8573 check_cp0_enabled(ctx); 8574 if (rd == 0) { 8575 /* Treat as NOP. */ 8576 return; 8577 } 8578 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 8579 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 8580 opn = "mftr"; 8581 break; 8582 case OPC_MTTR: 8583 check_cp0_enabled(ctx); 8584 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 8585 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 8586 opn = "mttr"; 8587 break; 8588 case OPC_TLBWI: 8589 opn = "tlbwi"; 8590 if (!env->tlb->helper_tlbwi) { 8591 goto die; 8592 } 8593 gen_helper_tlbwi(tcg_env); 8594 break; 8595 case OPC_TLBINV: 8596 opn = "tlbinv"; 8597 if (ctx->ie >= 2) { 8598 if (!env->tlb->helper_tlbinv) { 8599 goto die; 8600 } 8601 gen_helper_tlbinv(tcg_env); 8602 } /* treat as nop if TLBINV not supported */ 8603 break; 8604 case OPC_TLBINVF: 8605 opn = "tlbinvf"; 8606 if (ctx->ie >= 2) { 8607 if (!env->tlb->helper_tlbinvf) { 8608 goto die; 8609 } 8610 gen_helper_tlbinvf(tcg_env); 8611 } /* treat as nop if TLBINV not supported */ 8612 break; 8613 case OPC_TLBWR: 8614 opn = "tlbwr"; 8615 if (!env->tlb->helper_tlbwr) { 8616 goto die; 8617 } 8618 gen_helper_tlbwr(tcg_env); 8619 break; 8620 case OPC_TLBP: 8621 opn = "tlbp"; 8622 if (!env->tlb->helper_tlbp) { 8623 goto die; 8624 } 8625 gen_helper_tlbp(tcg_env); 8626 break; 8627 case OPC_TLBR: 8628 opn = "tlbr"; 8629 if (!env->tlb->helper_tlbr) { 8630 goto die; 8631 } 8632 gen_helper_tlbr(tcg_env); 8633 break; 8634 case OPC_ERET: /* OPC_ERETNC */ 8635 if ((ctx->insn_flags & ISA_MIPS_R6) && 8636 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8637 goto die; 8638 } else { 8639 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6; 8640 if (ctx->opcode & (1 << bit_shift)) { 8641 /* OPC_ERETNC */ 8642 opn = "eretnc"; 8643 check_insn(ctx, ISA_MIPS_R5); 8644 gen_helper_eretnc(tcg_env); 8645 } else { 8646 /* OPC_ERET */ 8647 opn = "eret"; 8648 check_insn(ctx, ISA_MIPS2); 8649 gen_helper_eret(tcg_env); 8650 } 8651 ctx->base.is_jmp = DISAS_EXIT; 8652 } 8653 break; 8654 case OPC_DERET: 8655 opn = "deret"; 8656 check_insn(ctx, ISA_MIPS_R1); 8657 if ((ctx->insn_flags & ISA_MIPS_R6) && 8658 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8659 goto die; 8660 } 8661 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 8662 MIPS_INVAL(opn); 8663 gen_reserved_instruction(ctx); 8664 } else { 8665 gen_helper_deret(tcg_env); 8666 ctx->base.is_jmp = DISAS_EXIT; 8667 } 8668 break; 8669 case OPC_WAIT: 8670 opn = "wait"; 8671 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 8672 if ((ctx->insn_flags & ISA_MIPS_R6) && 8673 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8674 goto die; 8675 } 8676 /* If we get an exception, we want to restart at next instruction */ 8677 ctx->base.pc_next += 4; 8678 save_cpu_state(ctx, 1); 8679 ctx->base.pc_next -= 4; 8680 gen_helper_wait(tcg_env); 8681 ctx->base.is_jmp = DISAS_NORETURN; 8682 break; 8683 default: 8684 die: 8685 MIPS_INVAL(opn); 8686 gen_reserved_instruction(ctx); 8687 return; 8688 } 8689 (void)opn; /* avoid a compiler warning */ 8690 } 8691 #endif /* !CONFIG_USER_ONLY */ 8692 8693 /* CP1 Branches (before delay slot) */ 8694 static void gen_compute_branch1(DisasContext *ctx, uint32_t op, 8695 int32_t cc, int32_t offset) 8696 { 8697 target_ulong btarget; 8698 TCGv_i32 t0 = tcg_temp_new_i32(); 8699 8700 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { 8701 gen_reserved_instruction(ctx); 8702 return; 8703 } 8704 8705 if (cc != 0) { 8706 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 8707 } 8708 8709 btarget = ctx->base.pc_next + 4 + offset; 8710 8711 switch (op) { 8712 case OPC_BC1F: 8713 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8714 tcg_gen_not_i32(t0, t0); 8715 tcg_gen_andi_i32(t0, t0, 1); 8716 tcg_gen_extu_i32_tl(bcond, t0); 8717 goto not_likely; 8718 case OPC_BC1FL: 8719 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8720 tcg_gen_not_i32(t0, t0); 8721 tcg_gen_andi_i32(t0, t0, 1); 8722 tcg_gen_extu_i32_tl(bcond, t0); 8723 goto likely; 8724 case OPC_BC1T: 8725 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8726 tcg_gen_andi_i32(t0, t0, 1); 8727 tcg_gen_extu_i32_tl(bcond, t0); 8728 goto not_likely; 8729 case OPC_BC1TL: 8730 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8731 tcg_gen_andi_i32(t0, t0, 1); 8732 tcg_gen_extu_i32_tl(bcond, t0); 8733 likely: 8734 ctx->hflags |= MIPS_HFLAG_BL; 8735 break; 8736 case OPC_BC1FANY2: 8737 { 8738 TCGv_i32 t1 = tcg_temp_new_i32(); 8739 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8740 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8741 tcg_gen_nand_i32(t0, t0, t1); 8742 tcg_gen_andi_i32(t0, t0, 1); 8743 tcg_gen_extu_i32_tl(bcond, t0); 8744 } 8745 goto not_likely; 8746 case OPC_BC1TANY2: 8747 { 8748 TCGv_i32 t1 = tcg_temp_new_i32(); 8749 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8750 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8751 tcg_gen_or_i32(t0, t0, t1); 8752 tcg_gen_andi_i32(t0, t0, 1); 8753 tcg_gen_extu_i32_tl(bcond, t0); 8754 } 8755 goto not_likely; 8756 case OPC_BC1FANY4: 8757 { 8758 TCGv_i32 t1 = tcg_temp_new_i32(); 8759 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8760 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8761 tcg_gen_and_i32(t0, t0, t1); 8762 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 8763 tcg_gen_and_i32(t0, t0, t1); 8764 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 8765 tcg_gen_nand_i32(t0, t0, t1); 8766 tcg_gen_andi_i32(t0, t0, 1); 8767 tcg_gen_extu_i32_tl(bcond, t0); 8768 } 8769 goto not_likely; 8770 case OPC_BC1TANY4: 8771 { 8772 TCGv_i32 t1 = tcg_temp_new_i32(); 8773 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8774 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8775 tcg_gen_or_i32(t0, t0, t1); 8776 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 8777 tcg_gen_or_i32(t0, t0, t1); 8778 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 8779 tcg_gen_or_i32(t0, t0, t1); 8780 tcg_gen_andi_i32(t0, t0, 1); 8781 tcg_gen_extu_i32_tl(bcond, t0); 8782 } 8783 not_likely: 8784 ctx->hflags |= MIPS_HFLAG_BC; 8785 break; 8786 default: 8787 MIPS_INVAL("cp1 cond branch"); 8788 gen_reserved_instruction(ctx); 8789 return; 8790 } 8791 ctx->btarget = btarget; 8792 ctx->hflags |= MIPS_HFLAG_BDS32; 8793 } 8794 8795 /* R6 CP1 Branches */ 8796 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, 8797 int32_t ft, int32_t offset, 8798 int delayslot_size) 8799 { 8800 target_ulong btarget; 8801 TCGv_i64 t0 = tcg_temp_new_i64(); 8802 8803 if (ctx->hflags & MIPS_HFLAG_BMASK) { 8804 #ifdef MIPS_DEBUG_DISAS 8805 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 8806 VADDR_PRIx "\n", ctx->base.pc_next); 8807 #endif 8808 gen_reserved_instruction(ctx); 8809 return; 8810 } 8811 8812 gen_load_fpr64(ctx, t0, ft); 8813 tcg_gen_andi_i64(t0, t0, 1); 8814 8815 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 8816 8817 switch (op) { 8818 case OPC_BC1EQZ: 8819 tcg_gen_xori_i64(t0, t0, 1); 8820 ctx->hflags |= MIPS_HFLAG_BC; 8821 break; 8822 case OPC_BC1NEZ: 8823 /* t0 already set */ 8824 ctx->hflags |= MIPS_HFLAG_BC; 8825 break; 8826 default: 8827 MIPS_INVAL("cp1 cond branch"); 8828 gen_reserved_instruction(ctx); 8829 return; 8830 } 8831 8832 tcg_gen_trunc_i64_tl(bcond, t0); 8833 8834 ctx->btarget = btarget; 8835 8836 switch (delayslot_size) { 8837 case 2: 8838 ctx->hflags |= MIPS_HFLAG_BDS16; 8839 break; 8840 case 4: 8841 ctx->hflags |= MIPS_HFLAG_BDS32; 8842 break; 8843 } 8844 } 8845 8846 /* Coprocessor 1 (FPU) */ 8847 8848 #define FOP(func, fmt) (((fmt) << 21) | (func)) 8849 8850 enum fopcode { 8851 OPC_ADD_S = FOP(0, FMT_S), 8852 OPC_SUB_S = FOP(1, FMT_S), 8853 OPC_MUL_S = FOP(2, FMT_S), 8854 OPC_DIV_S = FOP(3, FMT_S), 8855 OPC_SQRT_S = FOP(4, FMT_S), 8856 OPC_ABS_S = FOP(5, FMT_S), 8857 OPC_MOV_S = FOP(6, FMT_S), 8858 OPC_NEG_S = FOP(7, FMT_S), 8859 OPC_ROUND_L_S = FOP(8, FMT_S), 8860 OPC_TRUNC_L_S = FOP(9, FMT_S), 8861 OPC_CEIL_L_S = FOP(10, FMT_S), 8862 OPC_FLOOR_L_S = FOP(11, FMT_S), 8863 OPC_ROUND_W_S = FOP(12, FMT_S), 8864 OPC_TRUNC_W_S = FOP(13, FMT_S), 8865 OPC_CEIL_W_S = FOP(14, FMT_S), 8866 OPC_FLOOR_W_S = FOP(15, FMT_S), 8867 OPC_SEL_S = FOP(16, FMT_S), 8868 OPC_MOVCF_S = FOP(17, FMT_S), 8869 OPC_MOVZ_S = FOP(18, FMT_S), 8870 OPC_MOVN_S = FOP(19, FMT_S), 8871 OPC_SELEQZ_S = FOP(20, FMT_S), 8872 OPC_RECIP_S = FOP(21, FMT_S), 8873 OPC_RSQRT_S = FOP(22, FMT_S), 8874 OPC_SELNEZ_S = FOP(23, FMT_S), 8875 OPC_MADDF_S = FOP(24, FMT_S), 8876 OPC_MSUBF_S = FOP(25, FMT_S), 8877 OPC_RINT_S = FOP(26, FMT_S), 8878 OPC_CLASS_S = FOP(27, FMT_S), 8879 OPC_MIN_S = FOP(28, FMT_S), 8880 OPC_RECIP2_S = FOP(28, FMT_S), 8881 OPC_MINA_S = FOP(29, FMT_S), 8882 OPC_RECIP1_S = FOP(29, FMT_S), 8883 OPC_MAX_S = FOP(30, FMT_S), 8884 OPC_RSQRT1_S = FOP(30, FMT_S), 8885 OPC_MAXA_S = FOP(31, FMT_S), 8886 OPC_RSQRT2_S = FOP(31, FMT_S), 8887 OPC_CVT_D_S = FOP(33, FMT_S), 8888 OPC_CVT_W_S = FOP(36, FMT_S), 8889 OPC_CVT_L_S = FOP(37, FMT_S), 8890 OPC_CVT_PS_S = FOP(38, FMT_S), 8891 OPC_CMP_F_S = FOP(48, FMT_S), 8892 OPC_CMP_UN_S = FOP(49, FMT_S), 8893 OPC_CMP_EQ_S = FOP(50, FMT_S), 8894 OPC_CMP_UEQ_S = FOP(51, FMT_S), 8895 OPC_CMP_OLT_S = FOP(52, FMT_S), 8896 OPC_CMP_ULT_S = FOP(53, FMT_S), 8897 OPC_CMP_OLE_S = FOP(54, FMT_S), 8898 OPC_CMP_ULE_S = FOP(55, FMT_S), 8899 OPC_CMP_SF_S = FOP(56, FMT_S), 8900 OPC_CMP_NGLE_S = FOP(57, FMT_S), 8901 OPC_CMP_SEQ_S = FOP(58, FMT_S), 8902 OPC_CMP_NGL_S = FOP(59, FMT_S), 8903 OPC_CMP_LT_S = FOP(60, FMT_S), 8904 OPC_CMP_NGE_S = FOP(61, FMT_S), 8905 OPC_CMP_LE_S = FOP(62, FMT_S), 8906 OPC_CMP_NGT_S = FOP(63, FMT_S), 8907 8908 OPC_ADD_D = FOP(0, FMT_D), 8909 OPC_SUB_D = FOP(1, FMT_D), 8910 OPC_MUL_D = FOP(2, FMT_D), 8911 OPC_DIV_D = FOP(3, FMT_D), 8912 OPC_SQRT_D = FOP(4, FMT_D), 8913 OPC_ABS_D = FOP(5, FMT_D), 8914 OPC_MOV_D = FOP(6, FMT_D), 8915 OPC_NEG_D = FOP(7, FMT_D), 8916 OPC_ROUND_L_D = FOP(8, FMT_D), 8917 OPC_TRUNC_L_D = FOP(9, FMT_D), 8918 OPC_CEIL_L_D = FOP(10, FMT_D), 8919 OPC_FLOOR_L_D = FOP(11, FMT_D), 8920 OPC_ROUND_W_D = FOP(12, FMT_D), 8921 OPC_TRUNC_W_D = FOP(13, FMT_D), 8922 OPC_CEIL_W_D = FOP(14, FMT_D), 8923 OPC_FLOOR_W_D = FOP(15, FMT_D), 8924 OPC_SEL_D = FOP(16, FMT_D), 8925 OPC_MOVCF_D = FOP(17, FMT_D), 8926 OPC_MOVZ_D = FOP(18, FMT_D), 8927 OPC_MOVN_D = FOP(19, FMT_D), 8928 OPC_SELEQZ_D = FOP(20, FMT_D), 8929 OPC_RECIP_D = FOP(21, FMT_D), 8930 OPC_RSQRT_D = FOP(22, FMT_D), 8931 OPC_SELNEZ_D = FOP(23, FMT_D), 8932 OPC_MADDF_D = FOP(24, FMT_D), 8933 OPC_MSUBF_D = FOP(25, FMT_D), 8934 OPC_RINT_D = FOP(26, FMT_D), 8935 OPC_CLASS_D = FOP(27, FMT_D), 8936 OPC_MIN_D = FOP(28, FMT_D), 8937 OPC_RECIP2_D = FOP(28, FMT_D), 8938 OPC_MINA_D = FOP(29, FMT_D), 8939 OPC_RECIP1_D = FOP(29, FMT_D), 8940 OPC_MAX_D = FOP(30, FMT_D), 8941 OPC_RSQRT1_D = FOP(30, FMT_D), 8942 OPC_MAXA_D = FOP(31, FMT_D), 8943 OPC_RSQRT2_D = FOP(31, FMT_D), 8944 OPC_CVT_S_D = FOP(32, FMT_D), 8945 OPC_CVT_W_D = FOP(36, FMT_D), 8946 OPC_CVT_L_D = FOP(37, FMT_D), 8947 OPC_CMP_F_D = FOP(48, FMT_D), 8948 OPC_CMP_UN_D = FOP(49, FMT_D), 8949 OPC_CMP_EQ_D = FOP(50, FMT_D), 8950 OPC_CMP_UEQ_D = FOP(51, FMT_D), 8951 OPC_CMP_OLT_D = FOP(52, FMT_D), 8952 OPC_CMP_ULT_D = FOP(53, FMT_D), 8953 OPC_CMP_OLE_D = FOP(54, FMT_D), 8954 OPC_CMP_ULE_D = FOP(55, FMT_D), 8955 OPC_CMP_SF_D = FOP(56, FMT_D), 8956 OPC_CMP_NGLE_D = FOP(57, FMT_D), 8957 OPC_CMP_SEQ_D = FOP(58, FMT_D), 8958 OPC_CMP_NGL_D = FOP(59, FMT_D), 8959 OPC_CMP_LT_D = FOP(60, FMT_D), 8960 OPC_CMP_NGE_D = FOP(61, FMT_D), 8961 OPC_CMP_LE_D = FOP(62, FMT_D), 8962 OPC_CMP_NGT_D = FOP(63, FMT_D), 8963 8964 OPC_CVT_S_W = FOP(32, FMT_W), 8965 OPC_CVT_D_W = FOP(33, FMT_W), 8966 OPC_CVT_S_L = FOP(32, FMT_L), 8967 OPC_CVT_D_L = FOP(33, FMT_L), 8968 OPC_CVT_PS_PW = FOP(38, FMT_W), 8969 8970 OPC_ADD_PS = FOP(0, FMT_PS), 8971 OPC_SUB_PS = FOP(1, FMT_PS), 8972 OPC_MUL_PS = FOP(2, FMT_PS), 8973 OPC_DIV_PS = FOP(3, FMT_PS), 8974 OPC_ABS_PS = FOP(5, FMT_PS), 8975 OPC_MOV_PS = FOP(6, FMT_PS), 8976 OPC_NEG_PS = FOP(7, FMT_PS), 8977 OPC_MOVCF_PS = FOP(17, FMT_PS), 8978 OPC_MOVZ_PS = FOP(18, FMT_PS), 8979 OPC_MOVN_PS = FOP(19, FMT_PS), 8980 OPC_ADDR_PS = FOP(24, FMT_PS), 8981 OPC_MULR_PS = FOP(26, FMT_PS), 8982 OPC_RECIP2_PS = FOP(28, FMT_PS), 8983 OPC_RECIP1_PS = FOP(29, FMT_PS), 8984 OPC_RSQRT1_PS = FOP(30, FMT_PS), 8985 OPC_RSQRT2_PS = FOP(31, FMT_PS), 8986 8987 OPC_CVT_S_PU = FOP(32, FMT_PS), 8988 OPC_CVT_PW_PS = FOP(36, FMT_PS), 8989 OPC_CVT_S_PL = FOP(40, FMT_PS), 8990 OPC_PLL_PS = FOP(44, FMT_PS), 8991 OPC_PLU_PS = FOP(45, FMT_PS), 8992 OPC_PUL_PS = FOP(46, FMT_PS), 8993 OPC_PUU_PS = FOP(47, FMT_PS), 8994 OPC_CMP_F_PS = FOP(48, FMT_PS), 8995 OPC_CMP_UN_PS = FOP(49, FMT_PS), 8996 OPC_CMP_EQ_PS = FOP(50, FMT_PS), 8997 OPC_CMP_UEQ_PS = FOP(51, FMT_PS), 8998 OPC_CMP_OLT_PS = FOP(52, FMT_PS), 8999 OPC_CMP_ULT_PS = FOP(53, FMT_PS), 9000 OPC_CMP_OLE_PS = FOP(54, FMT_PS), 9001 OPC_CMP_ULE_PS = FOP(55, FMT_PS), 9002 OPC_CMP_SF_PS = FOP(56, FMT_PS), 9003 OPC_CMP_NGLE_PS = FOP(57, FMT_PS), 9004 OPC_CMP_SEQ_PS = FOP(58, FMT_PS), 9005 OPC_CMP_NGL_PS = FOP(59, FMT_PS), 9006 OPC_CMP_LT_PS = FOP(60, FMT_PS), 9007 OPC_CMP_NGE_PS = FOP(61, FMT_PS), 9008 OPC_CMP_LE_PS = FOP(62, FMT_PS), 9009 OPC_CMP_NGT_PS = FOP(63, FMT_PS), 9010 }; 9011 9012 enum r6_f_cmp_op { 9013 R6_OPC_CMP_AF_S = FOP(0, FMT_W), 9014 R6_OPC_CMP_UN_S = FOP(1, FMT_W), 9015 R6_OPC_CMP_EQ_S = FOP(2, FMT_W), 9016 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W), 9017 R6_OPC_CMP_LT_S = FOP(4, FMT_W), 9018 R6_OPC_CMP_ULT_S = FOP(5, FMT_W), 9019 R6_OPC_CMP_LE_S = FOP(6, FMT_W), 9020 R6_OPC_CMP_ULE_S = FOP(7, FMT_W), 9021 R6_OPC_CMP_SAF_S = FOP(8, FMT_W), 9022 R6_OPC_CMP_SUN_S = FOP(9, FMT_W), 9023 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W), 9024 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W), 9025 R6_OPC_CMP_SLT_S = FOP(12, FMT_W), 9026 R6_OPC_CMP_SULT_S = FOP(13, FMT_W), 9027 R6_OPC_CMP_SLE_S = FOP(14, FMT_W), 9028 R6_OPC_CMP_SULE_S = FOP(15, FMT_W), 9029 R6_OPC_CMP_OR_S = FOP(17, FMT_W), 9030 R6_OPC_CMP_UNE_S = FOP(18, FMT_W), 9031 R6_OPC_CMP_NE_S = FOP(19, FMT_W), 9032 R6_OPC_CMP_SOR_S = FOP(25, FMT_W), 9033 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W), 9034 R6_OPC_CMP_SNE_S = FOP(27, FMT_W), 9035 9036 R6_OPC_CMP_AF_D = FOP(0, FMT_L), 9037 R6_OPC_CMP_UN_D = FOP(1, FMT_L), 9038 R6_OPC_CMP_EQ_D = FOP(2, FMT_L), 9039 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L), 9040 R6_OPC_CMP_LT_D = FOP(4, FMT_L), 9041 R6_OPC_CMP_ULT_D = FOP(5, FMT_L), 9042 R6_OPC_CMP_LE_D = FOP(6, FMT_L), 9043 R6_OPC_CMP_ULE_D = FOP(7, FMT_L), 9044 R6_OPC_CMP_SAF_D = FOP(8, FMT_L), 9045 R6_OPC_CMP_SUN_D = FOP(9, FMT_L), 9046 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L), 9047 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L), 9048 R6_OPC_CMP_SLT_D = FOP(12, FMT_L), 9049 R6_OPC_CMP_SULT_D = FOP(13, FMT_L), 9050 R6_OPC_CMP_SLE_D = FOP(14, FMT_L), 9051 R6_OPC_CMP_SULE_D = FOP(15, FMT_L), 9052 R6_OPC_CMP_OR_D = FOP(17, FMT_L), 9053 R6_OPC_CMP_UNE_D = FOP(18, FMT_L), 9054 R6_OPC_CMP_NE_D = FOP(19, FMT_L), 9055 R6_OPC_CMP_SOR_D = FOP(25, FMT_L), 9056 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L), 9057 R6_OPC_CMP_SNE_D = FOP(27, FMT_L), 9058 }; 9059 9060 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) 9061 { 9062 TCGv t0 = tcg_temp_new(); 9063 9064 switch (opc) { 9065 case OPC_MFC1: 9066 { 9067 TCGv_i32 fp0 = tcg_temp_new_i32(); 9068 9069 gen_load_fpr32(ctx, fp0, fs); 9070 tcg_gen_ext_i32_tl(t0, fp0); 9071 } 9072 gen_store_gpr(t0, rt); 9073 break; 9074 case OPC_MTC1: 9075 gen_load_gpr(t0, rt); 9076 { 9077 TCGv_i32 fp0 = tcg_temp_new_i32(); 9078 9079 tcg_gen_trunc_tl_i32(fp0, t0); 9080 gen_store_fpr32(ctx, fp0, fs); 9081 } 9082 break; 9083 case OPC_CFC1: 9084 gen_helper_1e0i(cfc1, t0, fs); 9085 gen_store_gpr(t0, rt); 9086 break; 9087 case OPC_CTC1: 9088 gen_load_gpr(t0, rt); 9089 save_cpu_state(ctx, 0); 9090 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt); 9091 /* Stop translation as we may have changed hflags */ 9092 ctx->base.is_jmp = DISAS_STOP; 9093 break; 9094 #if defined(TARGET_MIPS64) 9095 case OPC_DMFC1: 9096 gen_load_fpr64(ctx, t0, fs); 9097 gen_store_gpr(t0, rt); 9098 break; 9099 case OPC_DMTC1: 9100 gen_load_gpr(t0, rt); 9101 gen_store_fpr64(ctx, t0, fs); 9102 break; 9103 #endif 9104 case OPC_MFHC1: 9105 { 9106 TCGv_i32 fp0 = tcg_temp_new_i32(); 9107 9108 gen_load_fpr32h(ctx, fp0, fs); 9109 tcg_gen_ext_i32_tl(t0, fp0); 9110 } 9111 gen_store_gpr(t0, rt); 9112 break; 9113 case OPC_MTHC1: 9114 gen_load_gpr(t0, rt); 9115 { 9116 TCGv_i32 fp0 = tcg_temp_new_i32(); 9117 9118 tcg_gen_trunc_tl_i32(fp0, t0); 9119 gen_store_fpr32h(ctx, fp0, fs); 9120 } 9121 break; 9122 default: 9123 MIPS_INVAL("cp1 move"); 9124 gen_reserved_instruction(ctx); 9125 return; 9126 } 9127 } 9128 9129 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf) 9130 { 9131 TCGLabel *l1; 9132 TCGCond cond; 9133 TCGv_i32 t0; 9134 9135 if (rd == 0) { 9136 /* Treat as NOP. */ 9137 return; 9138 } 9139 9140 if (tf) { 9141 cond = TCG_COND_EQ; 9142 } else { 9143 cond = TCG_COND_NE; 9144 } 9145 9146 l1 = gen_new_label(); 9147 t0 = tcg_temp_new_i32(); 9148 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9149 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9150 gen_load_gpr(cpu_gpr[rd], rs); 9151 gen_set_label(l1); 9152 } 9153 9154 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, 9155 int tf) 9156 { 9157 int cond; 9158 TCGv_i32 t0 = tcg_temp_new_i32(); 9159 TCGLabel *l1 = gen_new_label(); 9160 9161 if (tf) { 9162 cond = TCG_COND_EQ; 9163 } else { 9164 cond = TCG_COND_NE; 9165 } 9166 9167 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9168 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9169 gen_load_fpr32(ctx, t0, fs); 9170 gen_store_fpr32(ctx, t0, fd); 9171 gen_set_label(l1); 9172 } 9173 9174 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, 9175 int tf) 9176 { 9177 int cond; 9178 TCGv_i32 t0 = tcg_temp_new_i32(); 9179 TCGv_i64 fp0; 9180 TCGLabel *l1 = gen_new_label(); 9181 9182 if (tf) { 9183 cond = TCG_COND_EQ; 9184 } else { 9185 cond = TCG_COND_NE; 9186 } 9187 9188 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9189 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9190 fp0 = tcg_temp_new_i64(); 9191 gen_load_fpr64(ctx, fp0, fs); 9192 gen_store_fpr64(ctx, fp0, fd); 9193 gen_set_label(l1); 9194 } 9195 9196 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, 9197 int cc, int tf) 9198 { 9199 int cond; 9200 TCGv_i32 t0 = tcg_temp_new_i32(); 9201 TCGLabel *l1 = gen_new_label(); 9202 TCGLabel *l2 = gen_new_label(); 9203 9204 if (tf) { 9205 cond = TCG_COND_EQ; 9206 } else { 9207 cond = TCG_COND_NE; 9208 } 9209 9210 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9211 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9212 gen_load_fpr32(ctx, t0, fs); 9213 gen_store_fpr32(ctx, t0, fd); 9214 gen_set_label(l1); 9215 9216 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1)); 9217 tcg_gen_brcondi_i32(cond, t0, 0, l2); 9218 gen_load_fpr32h(ctx, t0, fs); 9219 gen_store_fpr32h(ctx, t0, fd); 9220 gen_set_label(l2); 9221 } 9222 9223 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9224 int fs) 9225 { 9226 TCGv_i32 t1 = tcg_constant_i32(0); 9227 TCGv_i32 fp0 = tcg_temp_new_i32(); 9228 TCGv_i32 fp1 = tcg_temp_new_i32(); 9229 TCGv_i32 fp2 = tcg_temp_new_i32(); 9230 gen_load_fpr32(ctx, fp0, fd); 9231 gen_load_fpr32(ctx, fp1, ft); 9232 gen_load_fpr32(ctx, fp2, fs); 9233 9234 switch (op1) { 9235 case OPC_SEL_S: 9236 tcg_gen_andi_i32(fp0, fp0, 1); 9237 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9238 break; 9239 case OPC_SELEQZ_S: 9240 tcg_gen_andi_i32(fp1, fp1, 1); 9241 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9242 break; 9243 case OPC_SELNEZ_S: 9244 tcg_gen_andi_i32(fp1, fp1, 1); 9245 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9246 break; 9247 default: 9248 MIPS_INVAL("gen_sel_s"); 9249 gen_reserved_instruction(ctx); 9250 break; 9251 } 9252 9253 gen_store_fpr32(ctx, fp0, fd); 9254 } 9255 9256 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9257 int fs) 9258 { 9259 TCGv_i64 t1 = tcg_constant_i64(0); 9260 TCGv_i64 fp0 = tcg_temp_new_i64(); 9261 TCGv_i64 fp1 = tcg_temp_new_i64(); 9262 TCGv_i64 fp2 = tcg_temp_new_i64(); 9263 gen_load_fpr64(ctx, fp0, fd); 9264 gen_load_fpr64(ctx, fp1, ft); 9265 gen_load_fpr64(ctx, fp2, fs); 9266 9267 switch (op1) { 9268 case OPC_SEL_D: 9269 tcg_gen_andi_i64(fp0, fp0, 1); 9270 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9271 break; 9272 case OPC_SELEQZ_D: 9273 tcg_gen_andi_i64(fp1, fp1, 1); 9274 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9275 break; 9276 case OPC_SELNEZ_D: 9277 tcg_gen_andi_i64(fp1, fp1, 1); 9278 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9279 break; 9280 default: 9281 MIPS_INVAL("gen_sel_d"); 9282 gen_reserved_instruction(ctx); 9283 break; 9284 } 9285 9286 gen_store_fpr64(ctx, fp0, fd); 9287 } 9288 9289 static void gen_farith(DisasContext *ctx, enum fopcode op1, 9290 int ft, int fs, int fd, int cc) 9291 { 9292 uint32_t func = ctx->opcode & 0x3f; 9293 switch (op1) { 9294 case OPC_ADD_S: 9295 { 9296 TCGv_i32 fp0 = tcg_temp_new_i32(); 9297 TCGv_i32 fp1 = tcg_temp_new_i32(); 9298 9299 gen_load_fpr32(ctx, fp0, fs); 9300 gen_load_fpr32(ctx, fp1, ft); 9301 gen_helper_float_add_s(fp0, tcg_env, fp0, fp1); 9302 gen_store_fpr32(ctx, fp0, fd); 9303 } 9304 break; 9305 case OPC_SUB_S: 9306 { 9307 TCGv_i32 fp0 = tcg_temp_new_i32(); 9308 TCGv_i32 fp1 = tcg_temp_new_i32(); 9309 9310 gen_load_fpr32(ctx, fp0, fs); 9311 gen_load_fpr32(ctx, fp1, ft); 9312 gen_helper_float_sub_s(fp0, tcg_env, fp0, fp1); 9313 gen_store_fpr32(ctx, fp0, fd); 9314 } 9315 break; 9316 case OPC_MUL_S: 9317 { 9318 TCGv_i32 fp0 = tcg_temp_new_i32(); 9319 TCGv_i32 fp1 = tcg_temp_new_i32(); 9320 9321 gen_load_fpr32(ctx, fp0, fs); 9322 gen_load_fpr32(ctx, fp1, ft); 9323 gen_helper_float_mul_s(fp0, tcg_env, fp0, fp1); 9324 gen_store_fpr32(ctx, fp0, fd); 9325 } 9326 break; 9327 case OPC_DIV_S: 9328 { 9329 TCGv_i32 fp0 = tcg_temp_new_i32(); 9330 TCGv_i32 fp1 = tcg_temp_new_i32(); 9331 9332 gen_load_fpr32(ctx, fp0, fs); 9333 gen_load_fpr32(ctx, fp1, ft); 9334 gen_helper_float_div_s(fp0, tcg_env, fp0, fp1); 9335 gen_store_fpr32(ctx, fp0, fd); 9336 } 9337 break; 9338 case OPC_SQRT_S: 9339 { 9340 TCGv_i32 fp0 = tcg_temp_new_i32(); 9341 9342 gen_load_fpr32(ctx, fp0, fs); 9343 gen_helper_float_sqrt_s(fp0, tcg_env, fp0); 9344 gen_store_fpr32(ctx, fp0, fd); 9345 } 9346 break; 9347 case OPC_ABS_S: 9348 { 9349 TCGv_i32 fp0 = tcg_temp_new_i32(); 9350 9351 gen_load_fpr32(ctx, fp0, fs); 9352 if (ctx->abs2008) { 9353 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL); 9354 } else { 9355 gen_helper_float_abs_s(fp0, fp0); 9356 } 9357 gen_store_fpr32(ctx, fp0, fd); 9358 } 9359 break; 9360 case OPC_MOV_S: 9361 { 9362 TCGv_i32 fp0 = tcg_temp_new_i32(); 9363 9364 gen_load_fpr32(ctx, fp0, fs); 9365 gen_store_fpr32(ctx, fp0, fd); 9366 } 9367 break; 9368 case OPC_NEG_S: 9369 { 9370 TCGv_i32 fp0 = tcg_temp_new_i32(); 9371 9372 gen_load_fpr32(ctx, fp0, fs); 9373 if (ctx->abs2008) { 9374 tcg_gen_xori_i32(fp0, fp0, 1UL << 31); 9375 } else { 9376 gen_helper_float_chs_s(fp0, fp0); 9377 } 9378 gen_store_fpr32(ctx, fp0, fd); 9379 } 9380 break; 9381 case OPC_ROUND_L_S: 9382 check_cp1_64bitmode(ctx); 9383 { 9384 TCGv_i32 fp32 = tcg_temp_new_i32(); 9385 TCGv_i64 fp64 = tcg_temp_new_i64(); 9386 9387 gen_load_fpr32(ctx, fp32, fs); 9388 if (ctx->nan2008) { 9389 gen_helper_float_round_2008_l_s(fp64, tcg_env, fp32); 9390 } else { 9391 gen_helper_float_round_l_s(fp64, tcg_env, fp32); 9392 } 9393 gen_store_fpr64(ctx, fp64, fd); 9394 } 9395 break; 9396 case OPC_TRUNC_L_S: 9397 check_cp1_64bitmode(ctx); 9398 { 9399 TCGv_i32 fp32 = tcg_temp_new_i32(); 9400 TCGv_i64 fp64 = tcg_temp_new_i64(); 9401 9402 gen_load_fpr32(ctx, fp32, fs); 9403 if (ctx->nan2008) { 9404 gen_helper_float_trunc_2008_l_s(fp64, tcg_env, fp32); 9405 } else { 9406 gen_helper_float_trunc_l_s(fp64, tcg_env, fp32); 9407 } 9408 gen_store_fpr64(ctx, fp64, fd); 9409 } 9410 break; 9411 case OPC_CEIL_L_S: 9412 check_cp1_64bitmode(ctx); 9413 { 9414 TCGv_i32 fp32 = tcg_temp_new_i32(); 9415 TCGv_i64 fp64 = tcg_temp_new_i64(); 9416 9417 gen_load_fpr32(ctx, fp32, fs); 9418 if (ctx->nan2008) { 9419 gen_helper_float_ceil_2008_l_s(fp64, tcg_env, fp32); 9420 } else { 9421 gen_helper_float_ceil_l_s(fp64, tcg_env, fp32); 9422 } 9423 gen_store_fpr64(ctx, fp64, fd); 9424 } 9425 break; 9426 case OPC_FLOOR_L_S: 9427 check_cp1_64bitmode(ctx); 9428 { 9429 TCGv_i32 fp32 = tcg_temp_new_i32(); 9430 TCGv_i64 fp64 = tcg_temp_new_i64(); 9431 9432 gen_load_fpr32(ctx, fp32, fs); 9433 if (ctx->nan2008) { 9434 gen_helper_float_floor_2008_l_s(fp64, tcg_env, fp32); 9435 } else { 9436 gen_helper_float_floor_l_s(fp64, tcg_env, fp32); 9437 } 9438 gen_store_fpr64(ctx, fp64, fd); 9439 } 9440 break; 9441 case OPC_ROUND_W_S: 9442 { 9443 TCGv_i32 fp0 = tcg_temp_new_i32(); 9444 9445 gen_load_fpr32(ctx, fp0, fs); 9446 if (ctx->nan2008) { 9447 gen_helper_float_round_2008_w_s(fp0, tcg_env, fp0); 9448 } else { 9449 gen_helper_float_round_w_s(fp0, tcg_env, fp0); 9450 } 9451 gen_store_fpr32(ctx, fp0, fd); 9452 } 9453 break; 9454 case OPC_TRUNC_W_S: 9455 { 9456 TCGv_i32 fp0 = tcg_temp_new_i32(); 9457 9458 gen_load_fpr32(ctx, fp0, fs); 9459 if (ctx->nan2008) { 9460 gen_helper_float_trunc_2008_w_s(fp0, tcg_env, fp0); 9461 } else { 9462 gen_helper_float_trunc_w_s(fp0, tcg_env, fp0); 9463 } 9464 gen_store_fpr32(ctx, fp0, fd); 9465 } 9466 break; 9467 case OPC_CEIL_W_S: 9468 { 9469 TCGv_i32 fp0 = tcg_temp_new_i32(); 9470 9471 gen_load_fpr32(ctx, fp0, fs); 9472 if (ctx->nan2008) { 9473 gen_helper_float_ceil_2008_w_s(fp0, tcg_env, fp0); 9474 } else { 9475 gen_helper_float_ceil_w_s(fp0, tcg_env, fp0); 9476 } 9477 gen_store_fpr32(ctx, fp0, fd); 9478 } 9479 break; 9480 case OPC_FLOOR_W_S: 9481 { 9482 TCGv_i32 fp0 = tcg_temp_new_i32(); 9483 9484 gen_load_fpr32(ctx, fp0, fs); 9485 if (ctx->nan2008) { 9486 gen_helper_float_floor_2008_w_s(fp0, tcg_env, fp0); 9487 } else { 9488 gen_helper_float_floor_w_s(fp0, tcg_env, fp0); 9489 } 9490 gen_store_fpr32(ctx, fp0, fd); 9491 } 9492 break; 9493 case OPC_SEL_S: 9494 check_insn(ctx, ISA_MIPS_R6); 9495 gen_sel_s(ctx, op1, fd, ft, fs); 9496 break; 9497 case OPC_SELEQZ_S: 9498 check_insn(ctx, ISA_MIPS_R6); 9499 gen_sel_s(ctx, op1, fd, ft, fs); 9500 break; 9501 case OPC_SELNEZ_S: 9502 check_insn(ctx, ISA_MIPS_R6); 9503 gen_sel_s(ctx, op1, fd, ft, fs); 9504 break; 9505 case OPC_MOVCF_S: 9506 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9507 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 9508 break; 9509 case OPC_MOVZ_S: 9510 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9511 { 9512 TCGLabel *l1 = gen_new_label(); 9513 TCGv_i32 fp0; 9514 9515 if (ft != 0) { 9516 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 9517 } 9518 fp0 = tcg_temp_new_i32(); 9519 gen_load_fpr32(ctx, fp0, fs); 9520 gen_store_fpr32(ctx, fp0, fd); 9521 gen_set_label(l1); 9522 } 9523 break; 9524 case OPC_MOVN_S: 9525 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9526 { 9527 TCGLabel *l1 = gen_new_label(); 9528 TCGv_i32 fp0; 9529 9530 if (ft != 0) { 9531 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 9532 fp0 = tcg_temp_new_i32(); 9533 gen_load_fpr32(ctx, fp0, fs); 9534 gen_store_fpr32(ctx, fp0, fd); 9535 gen_set_label(l1); 9536 } 9537 } 9538 break; 9539 case OPC_RECIP_S: 9540 { 9541 TCGv_i32 fp0 = tcg_temp_new_i32(); 9542 9543 gen_load_fpr32(ctx, fp0, fs); 9544 gen_helper_float_recip_s(fp0, tcg_env, fp0); 9545 gen_store_fpr32(ctx, fp0, fd); 9546 } 9547 break; 9548 case OPC_RSQRT_S: 9549 { 9550 TCGv_i32 fp0 = tcg_temp_new_i32(); 9551 9552 gen_load_fpr32(ctx, fp0, fs); 9553 gen_helper_float_rsqrt_s(fp0, tcg_env, fp0); 9554 gen_store_fpr32(ctx, fp0, fd); 9555 } 9556 break; 9557 case OPC_MADDF_S: 9558 check_insn(ctx, ISA_MIPS_R6); 9559 { 9560 TCGv_i32 fp0 = tcg_temp_new_i32(); 9561 TCGv_i32 fp1 = tcg_temp_new_i32(); 9562 TCGv_i32 fp2 = tcg_temp_new_i32(); 9563 gen_load_fpr32(ctx, fp0, fs); 9564 gen_load_fpr32(ctx, fp1, ft); 9565 gen_load_fpr32(ctx, fp2, fd); 9566 gen_helper_float_maddf_s(fp2, tcg_env, fp0, fp1, fp2); 9567 gen_store_fpr32(ctx, fp2, fd); 9568 } 9569 break; 9570 case OPC_MSUBF_S: 9571 check_insn(ctx, ISA_MIPS_R6); 9572 { 9573 TCGv_i32 fp0 = tcg_temp_new_i32(); 9574 TCGv_i32 fp1 = tcg_temp_new_i32(); 9575 TCGv_i32 fp2 = tcg_temp_new_i32(); 9576 gen_load_fpr32(ctx, fp0, fs); 9577 gen_load_fpr32(ctx, fp1, ft); 9578 gen_load_fpr32(ctx, fp2, fd); 9579 gen_helper_float_msubf_s(fp2, tcg_env, fp0, fp1, fp2); 9580 gen_store_fpr32(ctx, fp2, fd); 9581 } 9582 break; 9583 case OPC_RINT_S: 9584 check_insn(ctx, ISA_MIPS_R6); 9585 { 9586 TCGv_i32 fp0 = tcg_temp_new_i32(); 9587 gen_load_fpr32(ctx, fp0, fs); 9588 gen_helper_float_rint_s(fp0, tcg_env, fp0); 9589 gen_store_fpr32(ctx, fp0, fd); 9590 } 9591 break; 9592 case OPC_CLASS_S: 9593 check_insn(ctx, ISA_MIPS_R6); 9594 { 9595 TCGv_i32 fp0 = tcg_temp_new_i32(); 9596 gen_load_fpr32(ctx, fp0, fs); 9597 gen_helper_float_class_s(fp0, tcg_env, fp0); 9598 gen_store_fpr32(ctx, fp0, fd); 9599 } 9600 break; 9601 case OPC_MIN_S: /* OPC_RECIP2_S */ 9602 if (ctx->insn_flags & ISA_MIPS_R6) { 9603 /* OPC_MIN_S */ 9604 TCGv_i32 fp0 = tcg_temp_new_i32(); 9605 TCGv_i32 fp1 = tcg_temp_new_i32(); 9606 TCGv_i32 fp2 = tcg_temp_new_i32(); 9607 gen_load_fpr32(ctx, fp0, fs); 9608 gen_load_fpr32(ctx, fp1, ft); 9609 gen_helper_float_min_s(fp2, tcg_env, fp0, fp1); 9610 gen_store_fpr32(ctx, fp2, fd); 9611 } else { 9612 /* OPC_RECIP2_S */ 9613 check_cp1_64bitmode(ctx); 9614 { 9615 TCGv_i32 fp0 = tcg_temp_new_i32(); 9616 TCGv_i32 fp1 = tcg_temp_new_i32(); 9617 9618 gen_load_fpr32(ctx, fp0, fs); 9619 gen_load_fpr32(ctx, fp1, ft); 9620 gen_helper_float_recip2_s(fp0, tcg_env, fp0, fp1); 9621 gen_store_fpr32(ctx, fp0, fd); 9622 } 9623 } 9624 break; 9625 case OPC_MINA_S: /* OPC_RECIP1_S */ 9626 if (ctx->insn_flags & ISA_MIPS_R6) { 9627 /* OPC_MINA_S */ 9628 TCGv_i32 fp0 = tcg_temp_new_i32(); 9629 TCGv_i32 fp1 = tcg_temp_new_i32(); 9630 TCGv_i32 fp2 = tcg_temp_new_i32(); 9631 gen_load_fpr32(ctx, fp0, fs); 9632 gen_load_fpr32(ctx, fp1, ft); 9633 gen_helper_float_mina_s(fp2, tcg_env, fp0, fp1); 9634 gen_store_fpr32(ctx, fp2, fd); 9635 } else { 9636 /* OPC_RECIP1_S */ 9637 check_cp1_64bitmode(ctx); 9638 { 9639 TCGv_i32 fp0 = tcg_temp_new_i32(); 9640 9641 gen_load_fpr32(ctx, fp0, fs); 9642 gen_helper_float_recip1_s(fp0, tcg_env, fp0); 9643 gen_store_fpr32(ctx, fp0, fd); 9644 } 9645 } 9646 break; 9647 case OPC_MAX_S: /* OPC_RSQRT1_S */ 9648 if (ctx->insn_flags & ISA_MIPS_R6) { 9649 /* OPC_MAX_S */ 9650 TCGv_i32 fp0 = tcg_temp_new_i32(); 9651 TCGv_i32 fp1 = tcg_temp_new_i32(); 9652 gen_load_fpr32(ctx, fp0, fs); 9653 gen_load_fpr32(ctx, fp1, ft); 9654 gen_helper_float_max_s(fp1, tcg_env, fp0, fp1); 9655 gen_store_fpr32(ctx, fp1, fd); 9656 } else { 9657 /* OPC_RSQRT1_S */ 9658 check_cp1_64bitmode(ctx); 9659 { 9660 TCGv_i32 fp0 = tcg_temp_new_i32(); 9661 9662 gen_load_fpr32(ctx, fp0, fs); 9663 gen_helper_float_rsqrt1_s(fp0, tcg_env, fp0); 9664 gen_store_fpr32(ctx, fp0, fd); 9665 } 9666 } 9667 break; 9668 case OPC_MAXA_S: /* OPC_RSQRT2_S */ 9669 if (ctx->insn_flags & ISA_MIPS_R6) { 9670 /* OPC_MAXA_S */ 9671 TCGv_i32 fp0 = tcg_temp_new_i32(); 9672 TCGv_i32 fp1 = tcg_temp_new_i32(); 9673 gen_load_fpr32(ctx, fp0, fs); 9674 gen_load_fpr32(ctx, fp1, ft); 9675 gen_helper_float_maxa_s(fp1, tcg_env, fp0, fp1); 9676 gen_store_fpr32(ctx, fp1, fd); 9677 } else { 9678 /* OPC_RSQRT2_S */ 9679 check_cp1_64bitmode(ctx); 9680 { 9681 TCGv_i32 fp0 = tcg_temp_new_i32(); 9682 TCGv_i32 fp1 = tcg_temp_new_i32(); 9683 9684 gen_load_fpr32(ctx, fp0, fs); 9685 gen_load_fpr32(ctx, fp1, ft); 9686 gen_helper_float_rsqrt2_s(fp0, tcg_env, fp0, fp1); 9687 gen_store_fpr32(ctx, fp0, fd); 9688 } 9689 } 9690 break; 9691 case OPC_CVT_D_S: 9692 check_cp1_registers(ctx, fd); 9693 { 9694 TCGv_i32 fp32 = tcg_temp_new_i32(); 9695 TCGv_i64 fp64 = tcg_temp_new_i64(); 9696 9697 gen_load_fpr32(ctx, fp32, fs); 9698 gen_helper_float_cvtd_s(fp64, tcg_env, fp32); 9699 gen_store_fpr64(ctx, fp64, fd); 9700 } 9701 break; 9702 case OPC_CVT_W_S: 9703 { 9704 TCGv_i32 fp0 = tcg_temp_new_i32(); 9705 9706 gen_load_fpr32(ctx, fp0, fs); 9707 if (ctx->nan2008) { 9708 gen_helper_float_cvt_2008_w_s(fp0, tcg_env, fp0); 9709 } else { 9710 gen_helper_float_cvt_w_s(fp0, tcg_env, fp0); 9711 } 9712 gen_store_fpr32(ctx, fp0, fd); 9713 } 9714 break; 9715 case OPC_CVT_L_S: 9716 check_cp1_64bitmode(ctx); 9717 { 9718 TCGv_i32 fp32 = tcg_temp_new_i32(); 9719 TCGv_i64 fp64 = tcg_temp_new_i64(); 9720 9721 gen_load_fpr32(ctx, fp32, fs); 9722 if (ctx->nan2008) { 9723 gen_helper_float_cvt_2008_l_s(fp64, tcg_env, fp32); 9724 } else { 9725 gen_helper_float_cvt_l_s(fp64, tcg_env, fp32); 9726 } 9727 gen_store_fpr64(ctx, fp64, fd); 9728 } 9729 break; 9730 case OPC_CVT_PS_S: 9731 check_ps(ctx); 9732 { 9733 TCGv_i64 fp64 = tcg_temp_new_i64(); 9734 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 9735 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 9736 9737 gen_load_fpr32(ctx, fp32_0, fs); 9738 gen_load_fpr32(ctx, fp32_1, ft); 9739 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); 9740 gen_store_fpr64(ctx, fp64, fd); 9741 } 9742 break; 9743 case OPC_CMP_F_S: 9744 case OPC_CMP_UN_S: 9745 case OPC_CMP_EQ_S: 9746 case OPC_CMP_UEQ_S: 9747 case OPC_CMP_OLT_S: 9748 case OPC_CMP_ULT_S: 9749 case OPC_CMP_OLE_S: 9750 case OPC_CMP_ULE_S: 9751 case OPC_CMP_SF_S: 9752 case OPC_CMP_NGLE_S: 9753 case OPC_CMP_SEQ_S: 9754 case OPC_CMP_NGL_S: 9755 case OPC_CMP_LT_S: 9756 case OPC_CMP_NGE_S: 9757 case OPC_CMP_LE_S: 9758 case OPC_CMP_NGT_S: 9759 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9760 if (ctx->opcode & (1 << 6)) { 9761 gen_cmpabs_s(ctx, func - 48, ft, fs, cc); 9762 } else { 9763 gen_cmp_s(ctx, func - 48, ft, fs, cc); 9764 } 9765 break; 9766 case OPC_ADD_D: 9767 check_cp1_registers(ctx, fs | ft | fd); 9768 { 9769 TCGv_i64 fp0 = tcg_temp_new_i64(); 9770 TCGv_i64 fp1 = tcg_temp_new_i64(); 9771 9772 gen_load_fpr64(ctx, fp0, fs); 9773 gen_load_fpr64(ctx, fp1, ft); 9774 gen_helper_float_add_d(fp0, tcg_env, fp0, fp1); 9775 gen_store_fpr64(ctx, fp0, fd); 9776 } 9777 break; 9778 case OPC_SUB_D: 9779 check_cp1_registers(ctx, fs | ft | fd); 9780 { 9781 TCGv_i64 fp0 = tcg_temp_new_i64(); 9782 TCGv_i64 fp1 = tcg_temp_new_i64(); 9783 9784 gen_load_fpr64(ctx, fp0, fs); 9785 gen_load_fpr64(ctx, fp1, ft); 9786 gen_helper_float_sub_d(fp0, tcg_env, fp0, fp1); 9787 gen_store_fpr64(ctx, fp0, fd); 9788 } 9789 break; 9790 case OPC_MUL_D: 9791 check_cp1_registers(ctx, fs | ft | fd); 9792 { 9793 TCGv_i64 fp0 = tcg_temp_new_i64(); 9794 TCGv_i64 fp1 = tcg_temp_new_i64(); 9795 9796 gen_load_fpr64(ctx, fp0, fs); 9797 gen_load_fpr64(ctx, fp1, ft); 9798 gen_helper_float_mul_d(fp0, tcg_env, fp0, fp1); 9799 gen_store_fpr64(ctx, fp0, fd); 9800 } 9801 break; 9802 case OPC_DIV_D: 9803 check_cp1_registers(ctx, fs | ft | fd); 9804 { 9805 TCGv_i64 fp0 = tcg_temp_new_i64(); 9806 TCGv_i64 fp1 = tcg_temp_new_i64(); 9807 9808 gen_load_fpr64(ctx, fp0, fs); 9809 gen_load_fpr64(ctx, fp1, ft); 9810 gen_helper_float_div_d(fp0, tcg_env, fp0, fp1); 9811 gen_store_fpr64(ctx, fp0, fd); 9812 } 9813 break; 9814 case OPC_SQRT_D: 9815 check_cp1_registers(ctx, fs | fd); 9816 { 9817 TCGv_i64 fp0 = tcg_temp_new_i64(); 9818 9819 gen_load_fpr64(ctx, fp0, fs); 9820 gen_helper_float_sqrt_d(fp0, tcg_env, fp0); 9821 gen_store_fpr64(ctx, fp0, fd); 9822 } 9823 break; 9824 case OPC_ABS_D: 9825 check_cp1_registers(ctx, fs | fd); 9826 { 9827 TCGv_i64 fp0 = tcg_temp_new_i64(); 9828 9829 gen_load_fpr64(ctx, fp0, fs); 9830 if (ctx->abs2008) { 9831 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL); 9832 } else { 9833 gen_helper_float_abs_d(fp0, fp0); 9834 } 9835 gen_store_fpr64(ctx, fp0, fd); 9836 } 9837 break; 9838 case OPC_MOV_D: 9839 check_cp1_registers(ctx, fs | fd); 9840 { 9841 TCGv_i64 fp0 = tcg_temp_new_i64(); 9842 9843 gen_load_fpr64(ctx, fp0, fs); 9844 gen_store_fpr64(ctx, fp0, fd); 9845 } 9846 break; 9847 case OPC_NEG_D: 9848 check_cp1_registers(ctx, fs | fd); 9849 { 9850 TCGv_i64 fp0 = tcg_temp_new_i64(); 9851 9852 gen_load_fpr64(ctx, fp0, fs); 9853 if (ctx->abs2008) { 9854 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63); 9855 } else { 9856 gen_helper_float_chs_d(fp0, fp0); 9857 } 9858 gen_store_fpr64(ctx, fp0, fd); 9859 } 9860 break; 9861 case OPC_ROUND_L_D: 9862 check_cp1_64bitmode(ctx); 9863 { 9864 TCGv_i64 fp0 = tcg_temp_new_i64(); 9865 9866 gen_load_fpr64(ctx, fp0, fs); 9867 if (ctx->nan2008) { 9868 gen_helper_float_round_2008_l_d(fp0, tcg_env, fp0); 9869 } else { 9870 gen_helper_float_round_l_d(fp0, tcg_env, fp0); 9871 } 9872 gen_store_fpr64(ctx, fp0, fd); 9873 } 9874 break; 9875 case OPC_TRUNC_L_D: 9876 check_cp1_64bitmode(ctx); 9877 { 9878 TCGv_i64 fp0 = tcg_temp_new_i64(); 9879 9880 gen_load_fpr64(ctx, fp0, fs); 9881 if (ctx->nan2008) { 9882 gen_helper_float_trunc_2008_l_d(fp0, tcg_env, fp0); 9883 } else { 9884 gen_helper_float_trunc_l_d(fp0, tcg_env, fp0); 9885 } 9886 gen_store_fpr64(ctx, fp0, fd); 9887 } 9888 break; 9889 case OPC_CEIL_L_D: 9890 check_cp1_64bitmode(ctx); 9891 { 9892 TCGv_i64 fp0 = tcg_temp_new_i64(); 9893 9894 gen_load_fpr64(ctx, fp0, fs); 9895 if (ctx->nan2008) { 9896 gen_helper_float_ceil_2008_l_d(fp0, tcg_env, fp0); 9897 } else { 9898 gen_helper_float_ceil_l_d(fp0, tcg_env, fp0); 9899 } 9900 gen_store_fpr64(ctx, fp0, fd); 9901 } 9902 break; 9903 case OPC_FLOOR_L_D: 9904 check_cp1_64bitmode(ctx); 9905 { 9906 TCGv_i64 fp0 = tcg_temp_new_i64(); 9907 9908 gen_load_fpr64(ctx, fp0, fs); 9909 if (ctx->nan2008) { 9910 gen_helper_float_floor_2008_l_d(fp0, tcg_env, fp0); 9911 } else { 9912 gen_helper_float_floor_l_d(fp0, tcg_env, fp0); 9913 } 9914 gen_store_fpr64(ctx, fp0, fd); 9915 } 9916 break; 9917 case OPC_ROUND_W_D: 9918 check_cp1_registers(ctx, fs); 9919 { 9920 TCGv_i32 fp32 = tcg_temp_new_i32(); 9921 TCGv_i64 fp64 = tcg_temp_new_i64(); 9922 9923 gen_load_fpr64(ctx, fp64, fs); 9924 if (ctx->nan2008) { 9925 gen_helper_float_round_2008_w_d(fp32, tcg_env, fp64); 9926 } else { 9927 gen_helper_float_round_w_d(fp32, tcg_env, fp64); 9928 } 9929 gen_store_fpr32(ctx, fp32, fd); 9930 } 9931 break; 9932 case OPC_TRUNC_W_D: 9933 check_cp1_registers(ctx, fs); 9934 { 9935 TCGv_i32 fp32 = tcg_temp_new_i32(); 9936 TCGv_i64 fp64 = tcg_temp_new_i64(); 9937 9938 gen_load_fpr64(ctx, fp64, fs); 9939 if (ctx->nan2008) { 9940 gen_helper_float_trunc_2008_w_d(fp32, tcg_env, fp64); 9941 } else { 9942 gen_helper_float_trunc_w_d(fp32, tcg_env, fp64); 9943 } 9944 gen_store_fpr32(ctx, fp32, fd); 9945 } 9946 break; 9947 case OPC_CEIL_W_D: 9948 check_cp1_registers(ctx, fs); 9949 { 9950 TCGv_i32 fp32 = tcg_temp_new_i32(); 9951 TCGv_i64 fp64 = tcg_temp_new_i64(); 9952 9953 gen_load_fpr64(ctx, fp64, fs); 9954 if (ctx->nan2008) { 9955 gen_helper_float_ceil_2008_w_d(fp32, tcg_env, fp64); 9956 } else { 9957 gen_helper_float_ceil_w_d(fp32, tcg_env, fp64); 9958 } 9959 gen_store_fpr32(ctx, fp32, fd); 9960 } 9961 break; 9962 case OPC_FLOOR_W_D: 9963 check_cp1_registers(ctx, fs); 9964 { 9965 TCGv_i32 fp32 = tcg_temp_new_i32(); 9966 TCGv_i64 fp64 = tcg_temp_new_i64(); 9967 9968 gen_load_fpr64(ctx, fp64, fs); 9969 if (ctx->nan2008) { 9970 gen_helper_float_floor_2008_w_d(fp32, tcg_env, fp64); 9971 } else { 9972 gen_helper_float_floor_w_d(fp32, tcg_env, fp64); 9973 } 9974 gen_store_fpr32(ctx, fp32, fd); 9975 } 9976 break; 9977 case OPC_SEL_D: 9978 check_insn(ctx, ISA_MIPS_R6); 9979 gen_sel_d(ctx, op1, fd, ft, fs); 9980 break; 9981 case OPC_SELEQZ_D: 9982 check_insn(ctx, ISA_MIPS_R6); 9983 gen_sel_d(ctx, op1, fd, ft, fs); 9984 break; 9985 case OPC_SELNEZ_D: 9986 check_insn(ctx, ISA_MIPS_R6); 9987 gen_sel_d(ctx, op1, fd, ft, fs); 9988 break; 9989 case OPC_MOVCF_D: 9990 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9991 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 9992 break; 9993 case OPC_MOVZ_D: 9994 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9995 { 9996 TCGLabel *l1 = gen_new_label(); 9997 TCGv_i64 fp0; 9998 9999 if (ft != 0) { 10000 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10001 } 10002 fp0 = tcg_temp_new_i64(); 10003 gen_load_fpr64(ctx, fp0, fs); 10004 gen_store_fpr64(ctx, fp0, fd); 10005 gen_set_label(l1); 10006 } 10007 break; 10008 case OPC_MOVN_D: 10009 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10010 { 10011 TCGLabel *l1 = gen_new_label(); 10012 TCGv_i64 fp0; 10013 10014 if (ft != 0) { 10015 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10016 fp0 = tcg_temp_new_i64(); 10017 gen_load_fpr64(ctx, fp0, fs); 10018 gen_store_fpr64(ctx, fp0, fd); 10019 gen_set_label(l1); 10020 } 10021 } 10022 break; 10023 case OPC_RECIP_D: 10024 check_cp1_registers(ctx, fs | fd); 10025 { 10026 TCGv_i64 fp0 = tcg_temp_new_i64(); 10027 10028 gen_load_fpr64(ctx, fp0, fs); 10029 gen_helper_float_recip_d(fp0, tcg_env, fp0); 10030 gen_store_fpr64(ctx, fp0, fd); 10031 } 10032 break; 10033 case OPC_RSQRT_D: 10034 check_cp1_registers(ctx, fs | fd); 10035 { 10036 TCGv_i64 fp0 = tcg_temp_new_i64(); 10037 10038 gen_load_fpr64(ctx, fp0, fs); 10039 gen_helper_float_rsqrt_d(fp0, tcg_env, fp0); 10040 gen_store_fpr64(ctx, fp0, fd); 10041 } 10042 break; 10043 case OPC_MADDF_D: 10044 check_insn(ctx, ISA_MIPS_R6); 10045 { 10046 TCGv_i64 fp0 = tcg_temp_new_i64(); 10047 TCGv_i64 fp1 = tcg_temp_new_i64(); 10048 TCGv_i64 fp2 = tcg_temp_new_i64(); 10049 gen_load_fpr64(ctx, fp0, fs); 10050 gen_load_fpr64(ctx, fp1, ft); 10051 gen_load_fpr64(ctx, fp2, fd); 10052 gen_helper_float_maddf_d(fp2, tcg_env, fp0, fp1, fp2); 10053 gen_store_fpr64(ctx, fp2, fd); 10054 } 10055 break; 10056 case OPC_MSUBF_D: 10057 check_insn(ctx, ISA_MIPS_R6); 10058 { 10059 TCGv_i64 fp0 = tcg_temp_new_i64(); 10060 TCGv_i64 fp1 = tcg_temp_new_i64(); 10061 TCGv_i64 fp2 = tcg_temp_new_i64(); 10062 gen_load_fpr64(ctx, fp0, fs); 10063 gen_load_fpr64(ctx, fp1, ft); 10064 gen_load_fpr64(ctx, fp2, fd); 10065 gen_helper_float_msubf_d(fp2, tcg_env, fp0, fp1, fp2); 10066 gen_store_fpr64(ctx, fp2, fd); 10067 } 10068 break; 10069 case OPC_RINT_D: 10070 check_insn(ctx, ISA_MIPS_R6); 10071 { 10072 TCGv_i64 fp0 = tcg_temp_new_i64(); 10073 gen_load_fpr64(ctx, fp0, fs); 10074 gen_helper_float_rint_d(fp0, tcg_env, fp0); 10075 gen_store_fpr64(ctx, fp0, fd); 10076 } 10077 break; 10078 case OPC_CLASS_D: 10079 check_insn(ctx, ISA_MIPS_R6); 10080 { 10081 TCGv_i64 fp0 = tcg_temp_new_i64(); 10082 gen_load_fpr64(ctx, fp0, fs); 10083 gen_helper_float_class_d(fp0, tcg_env, fp0); 10084 gen_store_fpr64(ctx, fp0, fd); 10085 } 10086 break; 10087 case OPC_MIN_D: /* OPC_RECIP2_D */ 10088 if (ctx->insn_flags & ISA_MIPS_R6) { 10089 /* OPC_MIN_D */ 10090 TCGv_i64 fp0 = tcg_temp_new_i64(); 10091 TCGv_i64 fp1 = tcg_temp_new_i64(); 10092 gen_load_fpr64(ctx, fp0, fs); 10093 gen_load_fpr64(ctx, fp1, ft); 10094 gen_helper_float_min_d(fp1, tcg_env, fp0, fp1); 10095 gen_store_fpr64(ctx, fp1, fd); 10096 } else { 10097 /* OPC_RECIP2_D */ 10098 check_cp1_64bitmode(ctx); 10099 { 10100 TCGv_i64 fp0 = tcg_temp_new_i64(); 10101 TCGv_i64 fp1 = tcg_temp_new_i64(); 10102 10103 gen_load_fpr64(ctx, fp0, fs); 10104 gen_load_fpr64(ctx, fp1, ft); 10105 gen_helper_float_recip2_d(fp0, tcg_env, fp0, fp1); 10106 gen_store_fpr64(ctx, fp0, fd); 10107 } 10108 } 10109 break; 10110 case OPC_MINA_D: /* OPC_RECIP1_D */ 10111 if (ctx->insn_flags & ISA_MIPS_R6) { 10112 /* OPC_MINA_D */ 10113 TCGv_i64 fp0 = tcg_temp_new_i64(); 10114 TCGv_i64 fp1 = tcg_temp_new_i64(); 10115 gen_load_fpr64(ctx, fp0, fs); 10116 gen_load_fpr64(ctx, fp1, ft); 10117 gen_helper_float_mina_d(fp1, tcg_env, fp0, fp1); 10118 gen_store_fpr64(ctx, fp1, fd); 10119 } else { 10120 /* OPC_RECIP1_D */ 10121 check_cp1_64bitmode(ctx); 10122 { 10123 TCGv_i64 fp0 = tcg_temp_new_i64(); 10124 10125 gen_load_fpr64(ctx, fp0, fs); 10126 gen_helper_float_recip1_d(fp0, tcg_env, fp0); 10127 gen_store_fpr64(ctx, fp0, fd); 10128 } 10129 } 10130 break; 10131 case OPC_MAX_D: /* OPC_RSQRT1_D */ 10132 if (ctx->insn_flags & ISA_MIPS_R6) { 10133 /* OPC_MAX_D */ 10134 TCGv_i64 fp0 = tcg_temp_new_i64(); 10135 TCGv_i64 fp1 = tcg_temp_new_i64(); 10136 gen_load_fpr64(ctx, fp0, fs); 10137 gen_load_fpr64(ctx, fp1, ft); 10138 gen_helper_float_max_d(fp1, tcg_env, fp0, fp1); 10139 gen_store_fpr64(ctx, fp1, fd); 10140 } else { 10141 /* OPC_RSQRT1_D */ 10142 check_cp1_64bitmode(ctx); 10143 { 10144 TCGv_i64 fp0 = tcg_temp_new_i64(); 10145 10146 gen_load_fpr64(ctx, fp0, fs); 10147 gen_helper_float_rsqrt1_d(fp0, tcg_env, fp0); 10148 gen_store_fpr64(ctx, fp0, fd); 10149 } 10150 } 10151 break; 10152 case OPC_MAXA_D: /* OPC_RSQRT2_D */ 10153 if (ctx->insn_flags & ISA_MIPS_R6) { 10154 /* OPC_MAXA_D */ 10155 TCGv_i64 fp0 = tcg_temp_new_i64(); 10156 TCGv_i64 fp1 = tcg_temp_new_i64(); 10157 gen_load_fpr64(ctx, fp0, fs); 10158 gen_load_fpr64(ctx, fp1, ft); 10159 gen_helper_float_maxa_d(fp1, tcg_env, fp0, fp1); 10160 gen_store_fpr64(ctx, fp1, fd); 10161 } else { 10162 /* OPC_RSQRT2_D */ 10163 check_cp1_64bitmode(ctx); 10164 { 10165 TCGv_i64 fp0 = tcg_temp_new_i64(); 10166 TCGv_i64 fp1 = tcg_temp_new_i64(); 10167 10168 gen_load_fpr64(ctx, fp0, fs); 10169 gen_load_fpr64(ctx, fp1, ft); 10170 gen_helper_float_rsqrt2_d(fp0, tcg_env, fp0, fp1); 10171 gen_store_fpr64(ctx, fp0, fd); 10172 } 10173 } 10174 break; 10175 case OPC_CMP_F_D: 10176 case OPC_CMP_UN_D: 10177 case OPC_CMP_EQ_D: 10178 case OPC_CMP_UEQ_D: 10179 case OPC_CMP_OLT_D: 10180 case OPC_CMP_ULT_D: 10181 case OPC_CMP_OLE_D: 10182 case OPC_CMP_ULE_D: 10183 case OPC_CMP_SF_D: 10184 case OPC_CMP_NGLE_D: 10185 case OPC_CMP_SEQ_D: 10186 case OPC_CMP_NGL_D: 10187 case OPC_CMP_LT_D: 10188 case OPC_CMP_NGE_D: 10189 case OPC_CMP_LE_D: 10190 case OPC_CMP_NGT_D: 10191 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10192 if (ctx->opcode & (1 << 6)) { 10193 gen_cmpabs_d(ctx, func - 48, ft, fs, cc); 10194 } else { 10195 gen_cmp_d(ctx, func - 48, ft, fs, cc); 10196 } 10197 break; 10198 case OPC_CVT_S_D: 10199 check_cp1_registers(ctx, fs); 10200 { 10201 TCGv_i32 fp32 = tcg_temp_new_i32(); 10202 TCGv_i64 fp64 = tcg_temp_new_i64(); 10203 10204 gen_load_fpr64(ctx, fp64, fs); 10205 gen_helper_float_cvts_d(fp32, tcg_env, fp64); 10206 gen_store_fpr32(ctx, fp32, fd); 10207 } 10208 break; 10209 case OPC_CVT_W_D: 10210 check_cp1_registers(ctx, fs); 10211 { 10212 TCGv_i32 fp32 = tcg_temp_new_i32(); 10213 TCGv_i64 fp64 = tcg_temp_new_i64(); 10214 10215 gen_load_fpr64(ctx, fp64, fs); 10216 if (ctx->nan2008) { 10217 gen_helper_float_cvt_2008_w_d(fp32, tcg_env, fp64); 10218 } else { 10219 gen_helper_float_cvt_w_d(fp32, tcg_env, fp64); 10220 } 10221 gen_store_fpr32(ctx, fp32, fd); 10222 } 10223 break; 10224 case OPC_CVT_L_D: 10225 check_cp1_64bitmode(ctx); 10226 { 10227 TCGv_i64 fp0 = tcg_temp_new_i64(); 10228 10229 gen_load_fpr64(ctx, fp0, fs); 10230 if (ctx->nan2008) { 10231 gen_helper_float_cvt_2008_l_d(fp0, tcg_env, fp0); 10232 } else { 10233 gen_helper_float_cvt_l_d(fp0, tcg_env, fp0); 10234 } 10235 gen_store_fpr64(ctx, fp0, fd); 10236 } 10237 break; 10238 case OPC_CVT_S_W: 10239 { 10240 TCGv_i32 fp0 = tcg_temp_new_i32(); 10241 10242 gen_load_fpr32(ctx, fp0, fs); 10243 gen_helper_float_cvts_w(fp0, tcg_env, fp0); 10244 gen_store_fpr32(ctx, fp0, fd); 10245 } 10246 break; 10247 case OPC_CVT_D_W: 10248 check_cp1_registers(ctx, fd); 10249 { 10250 TCGv_i32 fp32 = tcg_temp_new_i32(); 10251 TCGv_i64 fp64 = tcg_temp_new_i64(); 10252 10253 gen_load_fpr32(ctx, fp32, fs); 10254 gen_helper_float_cvtd_w(fp64, tcg_env, fp32); 10255 gen_store_fpr64(ctx, fp64, fd); 10256 } 10257 break; 10258 case OPC_CVT_S_L: 10259 check_cp1_64bitmode(ctx); 10260 { 10261 TCGv_i32 fp32 = tcg_temp_new_i32(); 10262 TCGv_i64 fp64 = tcg_temp_new_i64(); 10263 10264 gen_load_fpr64(ctx, fp64, fs); 10265 gen_helper_float_cvts_l(fp32, tcg_env, fp64); 10266 gen_store_fpr32(ctx, fp32, fd); 10267 } 10268 break; 10269 case OPC_CVT_D_L: 10270 check_cp1_64bitmode(ctx); 10271 { 10272 TCGv_i64 fp0 = tcg_temp_new_i64(); 10273 10274 gen_load_fpr64(ctx, fp0, fs); 10275 gen_helper_float_cvtd_l(fp0, tcg_env, fp0); 10276 gen_store_fpr64(ctx, fp0, fd); 10277 } 10278 break; 10279 case OPC_CVT_PS_PW: 10280 check_ps(ctx); 10281 { 10282 TCGv_i64 fp0 = tcg_temp_new_i64(); 10283 10284 gen_load_fpr64(ctx, fp0, fs); 10285 gen_helper_float_cvtps_pw(fp0, tcg_env, fp0); 10286 gen_store_fpr64(ctx, fp0, fd); 10287 } 10288 break; 10289 case OPC_ADD_PS: 10290 check_ps(ctx); 10291 { 10292 TCGv_i64 fp0 = tcg_temp_new_i64(); 10293 TCGv_i64 fp1 = tcg_temp_new_i64(); 10294 10295 gen_load_fpr64(ctx, fp0, fs); 10296 gen_load_fpr64(ctx, fp1, ft); 10297 gen_helper_float_add_ps(fp0, tcg_env, fp0, fp1); 10298 gen_store_fpr64(ctx, fp0, fd); 10299 } 10300 break; 10301 case OPC_SUB_PS: 10302 check_ps(ctx); 10303 { 10304 TCGv_i64 fp0 = tcg_temp_new_i64(); 10305 TCGv_i64 fp1 = tcg_temp_new_i64(); 10306 10307 gen_load_fpr64(ctx, fp0, fs); 10308 gen_load_fpr64(ctx, fp1, ft); 10309 gen_helper_float_sub_ps(fp0, tcg_env, fp0, fp1); 10310 gen_store_fpr64(ctx, fp0, fd); 10311 } 10312 break; 10313 case OPC_MUL_PS: 10314 check_ps(ctx); 10315 { 10316 TCGv_i64 fp0 = tcg_temp_new_i64(); 10317 TCGv_i64 fp1 = tcg_temp_new_i64(); 10318 10319 gen_load_fpr64(ctx, fp0, fs); 10320 gen_load_fpr64(ctx, fp1, ft); 10321 gen_helper_float_mul_ps(fp0, tcg_env, fp0, fp1); 10322 gen_store_fpr64(ctx, fp0, fd); 10323 } 10324 break; 10325 case OPC_ABS_PS: 10326 check_ps(ctx); 10327 { 10328 TCGv_i64 fp0 = tcg_temp_new_i64(); 10329 10330 gen_load_fpr64(ctx, fp0, fs); 10331 gen_helper_float_abs_ps(fp0, fp0); 10332 gen_store_fpr64(ctx, fp0, fd); 10333 } 10334 break; 10335 case OPC_MOV_PS: 10336 check_ps(ctx); 10337 { 10338 TCGv_i64 fp0 = tcg_temp_new_i64(); 10339 10340 gen_load_fpr64(ctx, fp0, fs); 10341 gen_store_fpr64(ctx, fp0, fd); 10342 } 10343 break; 10344 case OPC_NEG_PS: 10345 check_ps(ctx); 10346 { 10347 TCGv_i64 fp0 = tcg_temp_new_i64(); 10348 10349 gen_load_fpr64(ctx, fp0, fs); 10350 gen_helper_float_chs_ps(fp0, fp0); 10351 gen_store_fpr64(ctx, fp0, fd); 10352 } 10353 break; 10354 case OPC_MOVCF_PS: 10355 check_ps(ctx); 10356 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10357 break; 10358 case OPC_MOVZ_PS: 10359 check_ps(ctx); 10360 { 10361 TCGLabel *l1 = gen_new_label(); 10362 TCGv_i64 fp0; 10363 10364 if (ft != 0) { 10365 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10366 } 10367 fp0 = tcg_temp_new_i64(); 10368 gen_load_fpr64(ctx, fp0, fs); 10369 gen_store_fpr64(ctx, fp0, fd); 10370 gen_set_label(l1); 10371 } 10372 break; 10373 case OPC_MOVN_PS: 10374 check_ps(ctx); 10375 { 10376 TCGLabel *l1 = gen_new_label(); 10377 TCGv_i64 fp0; 10378 10379 if (ft != 0) { 10380 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10381 fp0 = tcg_temp_new_i64(); 10382 gen_load_fpr64(ctx, fp0, fs); 10383 gen_store_fpr64(ctx, fp0, fd); 10384 gen_set_label(l1); 10385 } 10386 } 10387 break; 10388 case OPC_ADDR_PS: 10389 check_ps(ctx); 10390 { 10391 TCGv_i64 fp0 = tcg_temp_new_i64(); 10392 TCGv_i64 fp1 = tcg_temp_new_i64(); 10393 10394 gen_load_fpr64(ctx, fp0, ft); 10395 gen_load_fpr64(ctx, fp1, fs); 10396 gen_helper_float_addr_ps(fp0, tcg_env, fp0, fp1); 10397 gen_store_fpr64(ctx, fp0, fd); 10398 } 10399 break; 10400 case OPC_MULR_PS: 10401 check_ps(ctx); 10402 { 10403 TCGv_i64 fp0 = tcg_temp_new_i64(); 10404 TCGv_i64 fp1 = tcg_temp_new_i64(); 10405 10406 gen_load_fpr64(ctx, fp0, ft); 10407 gen_load_fpr64(ctx, fp1, fs); 10408 gen_helper_float_mulr_ps(fp0, tcg_env, fp0, fp1); 10409 gen_store_fpr64(ctx, fp0, fd); 10410 } 10411 break; 10412 case OPC_RECIP2_PS: 10413 check_ps(ctx); 10414 { 10415 TCGv_i64 fp0 = tcg_temp_new_i64(); 10416 TCGv_i64 fp1 = tcg_temp_new_i64(); 10417 10418 gen_load_fpr64(ctx, fp0, fs); 10419 gen_load_fpr64(ctx, fp1, ft); 10420 gen_helper_float_recip2_ps(fp0, tcg_env, fp0, fp1); 10421 gen_store_fpr64(ctx, fp0, fd); 10422 } 10423 break; 10424 case OPC_RECIP1_PS: 10425 check_ps(ctx); 10426 { 10427 TCGv_i64 fp0 = tcg_temp_new_i64(); 10428 10429 gen_load_fpr64(ctx, fp0, fs); 10430 gen_helper_float_recip1_ps(fp0, tcg_env, fp0); 10431 gen_store_fpr64(ctx, fp0, fd); 10432 } 10433 break; 10434 case OPC_RSQRT1_PS: 10435 check_ps(ctx); 10436 { 10437 TCGv_i64 fp0 = tcg_temp_new_i64(); 10438 10439 gen_load_fpr64(ctx, fp0, fs); 10440 gen_helper_float_rsqrt1_ps(fp0, tcg_env, fp0); 10441 gen_store_fpr64(ctx, fp0, fd); 10442 } 10443 break; 10444 case OPC_RSQRT2_PS: 10445 check_ps(ctx); 10446 { 10447 TCGv_i64 fp0 = tcg_temp_new_i64(); 10448 TCGv_i64 fp1 = tcg_temp_new_i64(); 10449 10450 gen_load_fpr64(ctx, fp0, fs); 10451 gen_load_fpr64(ctx, fp1, ft); 10452 gen_helper_float_rsqrt2_ps(fp0, tcg_env, fp0, fp1); 10453 gen_store_fpr64(ctx, fp0, fd); 10454 } 10455 break; 10456 case OPC_CVT_S_PU: 10457 check_cp1_64bitmode(ctx); 10458 { 10459 TCGv_i32 fp0 = tcg_temp_new_i32(); 10460 10461 gen_load_fpr32h(ctx, fp0, fs); 10462 gen_helper_float_cvts_pu(fp0, tcg_env, fp0); 10463 gen_store_fpr32(ctx, fp0, fd); 10464 } 10465 break; 10466 case OPC_CVT_PW_PS: 10467 check_ps(ctx); 10468 { 10469 TCGv_i64 fp0 = tcg_temp_new_i64(); 10470 10471 gen_load_fpr64(ctx, fp0, fs); 10472 gen_helper_float_cvtpw_ps(fp0, tcg_env, fp0); 10473 gen_store_fpr64(ctx, fp0, fd); 10474 } 10475 break; 10476 case OPC_CVT_S_PL: 10477 check_cp1_64bitmode(ctx); 10478 { 10479 TCGv_i32 fp0 = tcg_temp_new_i32(); 10480 10481 gen_load_fpr32(ctx, fp0, fs); 10482 gen_helper_float_cvts_pl(fp0, tcg_env, fp0); 10483 gen_store_fpr32(ctx, fp0, fd); 10484 } 10485 break; 10486 case OPC_PLL_PS: 10487 check_ps(ctx); 10488 { 10489 TCGv_i32 fp0 = tcg_temp_new_i32(); 10490 TCGv_i32 fp1 = tcg_temp_new_i32(); 10491 10492 gen_load_fpr32(ctx, fp0, fs); 10493 gen_load_fpr32(ctx, fp1, ft); 10494 gen_store_fpr32h(ctx, fp0, fd); 10495 gen_store_fpr32(ctx, fp1, fd); 10496 } 10497 break; 10498 case OPC_PLU_PS: 10499 check_ps(ctx); 10500 { 10501 TCGv_i32 fp0 = tcg_temp_new_i32(); 10502 TCGv_i32 fp1 = tcg_temp_new_i32(); 10503 10504 gen_load_fpr32(ctx, fp0, fs); 10505 gen_load_fpr32h(ctx, fp1, ft); 10506 gen_store_fpr32(ctx, fp1, fd); 10507 gen_store_fpr32h(ctx, fp0, fd); 10508 } 10509 break; 10510 case OPC_PUL_PS: 10511 check_ps(ctx); 10512 { 10513 TCGv_i32 fp0 = tcg_temp_new_i32(); 10514 TCGv_i32 fp1 = tcg_temp_new_i32(); 10515 10516 gen_load_fpr32h(ctx, fp0, fs); 10517 gen_load_fpr32(ctx, fp1, ft); 10518 gen_store_fpr32(ctx, fp1, fd); 10519 gen_store_fpr32h(ctx, fp0, fd); 10520 } 10521 break; 10522 case OPC_PUU_PS: 10523 check_ps(ctx); 10524 { 10525 TCGv_i32 fp0 = tcg_temp_new_i32(); 10526 TCGv_i32 fp1 = tcg_temp_new_i32(); 10527 10528 gen_load_fpr32h(ctx, fp0, fs); 10529 gen_load_fpr32h(ctx, fp1, ft); 10530 gen_store_fpr32(ctx, fp1, fd); 10531 gen_store_fpr32h(ctx, fp0, fd); 10532 } 10533 break; 10534 case OPC_CMP_F_PS: 10535 case OPC_CMP_UN_PS: 10536 case OPC_CMP_EQ_PS: 10537 case OPC_CMP_UEQ_PS: 10538 case OPC_CMP_OLT_PS: 10539 case OPC_CMP_ULT_PS: 10540 case OPC_CMP_OLE_PS: 10541 case OPC_CMP_ULE_PS: 10542 case OPC_CMP_SF_PS: 10543 case OPC_CMP_NGLE_PS: 10544 case OPC_CMP_SEQ_PS: 10545 case OPC_CMP_NGL_PS: 10546 case OPC_CMP_LT_PS: 10547 case OPC_CMP_NGE_PS: 10548 case OPC_CMP_LE_PS: 10549 case OPC_CMP_NGT_PS: 10550 if (ctx->opcode & (1 << 6)) { 10551 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc); 10552 } else { 10553 gen_cmp_ps(ctx, func - 48, ft, fs, cc); 10554 } 10555 break; 10556 default: 10557 MIPS_INVAL("farith"); 10558 gen_reserved_instruction(ctx); 10559 return; 10560 } 10561 } 10562 10563 /* Coprocessor 3 (FPU) */ 10564 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, 10565 int fd, int fs, int base, int index) 10566 { 10567 TCGv t0 = tcg_temp_new(); 10568 10569 gen_base_index_addr(ctx, t0, base, index); 10570 /* 10571 * Don't do NOP if destination is zero: we must perform the actual 10572 * memory access. 10573 */ 10574 switch (opc) { 10575 case OPC_LWXC1: 10576 check_cop1x(ctx); 10577 { 10578 TCGv_i32 fp0 = tcg_temp_new_i32(); 10579 10580 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 10581 tcg_gen_trunc_tl_i32(fp0, t0); 10582 gen_store_fpr32(ctx, fp0, fd); 10583 } 10584 break; 10585 case OPC_LDXC1: 10586 check_cop1x(ctx); 10587 check_cp1_registers(ctx, fd); 10588 { 10589 TCGv_i64 fp0 = tcg_temp_new_i64(); 10590 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10591 gen_store_fpr64(ctx, fp0, fd); 10592 } 10593 break; 10594 case OPC_LUXC1: 10595 check_cp1_64bitmode(ctx); 10596 tcg_gen_andi_tl(t0, t0, ~0x7); 10597 { 10598 TCGv_i64 fp0 = tcg_temp_new_i64(); 10599 10600 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10601 gen_store_fpr64(ctx, fp0, fd); 10602 } 10603 break; 10604 case OPC_SWXC1: 10605 check_cop1x(ctx); 10606 { 10607 TCGv_i32 fp0 = tcg_temp_new_i32(); 10608 gen_load_fpr32(ctx, fp0, fs); 10609 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 10610 } 10611 break; 10612 case OPC_SDXC1: 10613 check_cop1x(ctx); 10614 check_cp1_registers(ctx, fs); 10615 { 10616 TCGv_i64 fp0 = tcg_temp_new_i64(); 10617 gen_load_fpr64(ctx, fp0, fs); 10618 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10619 } 10620 break; 10621 case OPC_SUXC1: 10622 check_cp1_64bitmode(ctx); 10623 tcg_gen_andi_tl(t0, t0, ~0x7); 10624 { 10625 TCGv_i64 fp0 = tcg_temp_new_i64(); 10626 gen_load_fpr64(ctx, fp0, fs); 10627 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10628 } 10629 break; 10630 } 10631 } 10632 10633 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, 10634 int fd, int fr, int fs, int ft) 10635 { 10636 switch (opc) { 10637 case OPC_ALNV_PS: 10638 check_ps(ctx); 10639 { 10640 TCGv t0 = tcg_temp_new(); 10641 TCGv_i32 fp = tcg_temp_new_i32(); 10642 TCGv_i32 fph = tcg_temp_new_i32(); 10643 TCGLabel *l1 = gen_new_label(); 10644 TCGLabel *l2 = gen_new_label(); 10645 10646 gen_load_gpr(t0, fr); 10647 tcg_gen_andi_tl(t0, t0, 0x7); 10648 10649 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 10650 gen_load_fpr32(ctx, fp, fs); 10651 gen_load_fpr32h(ctx, fph, fs); 10652 gen_store_fpr32(ctx, fp, fd); 10653 gen_store_fpr32h(ctx, fph, fd); 10654 tcg_gen_br(l2); 10655 gen_set_label(l1); 10656 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 10657 if (disas_is_bigendian(ctx)) { 10658 gen_load_fpr32(ctx, fp, fs); 10659 gen_load_fpr32h(ctx, fph, ft); 10660 gen_store_fpr32h(ctx, fp, fd); 10661 gen_store_fpr32(ctx, fph, fd); 10662 } else { 10663 gen_load_fpr32h(ctx, fph, fs); 10664 gen_load_fpr32(ctx, fp, ft); 10665 gen_store_fpr32(ctx, fph, fd); 10666 gen_store_fpr32h(ctx, fp, fd); 10667 } 10668 gen_set_label(l2); 10669 } 10670 break; 10671 case OPC_MADD_S: 10672 check_cop1x(ctx); 10673 { 10674 TCGv_i32 fp0 = tcg_temp_new_i32(); 10675 TCGv_i32 fp1 = tcg_temp_new_i32(); 10676 TCGv_i32 fp2 = tcg_temp_new_i32(); 10677 10678 gen_load_fpr32(ctx, fp0, fs); 10679 gen_load_fpr32(ctx, fp1, ft); 10680 gen_load_fpr32(ctx, fp2, fr); 10681 gen_helper_float_madd_s(fp2, tcg_env, fp0, fp1, fp2); 10682 gen_store_fpr32(ctx, fp2, fd); 10683 } 10684 break; 10685 case OPC_MADD_D: 10686 check_cop1x(ctx); 10687 check_cp1_registers(ctx, fd | fs | ft | fr); 10688 { 10689 TCGv_i64 fp0 = tcg_temp_new_i64(); 10690 TCGv_i64 fp1 = tcg_temp_new_i64(); 10691 TCGv_i64 fp2 = tcg_temp_new_i64(); 10692 10693 gen_load_fpr64(ctx, fp0, fs); 10694 gen_load_fpr64(ctx, fp1, ft); 10695 gen_load_fpr64(ctx, fp2, fr); 10696 gen_helper_float_madd_d(fp2, tcg_env, fp0, fp1, fp2); 10697 gen_store_fpr64(ctx, fp2, fd); 10698 } 10699 break; 10700 case OPC_MADD_PS: 10701 check_ps(ctx); 10702 { 10703 TCGv_i64 fp0 = tcg_temp_new_i64(); 10704 TCGv_i64 fp1 = tcg_temp_new_i64(); 10705 TCGv_i64 fp2 = tcg_temp_new_i64(); 10706 10707 gen_load_fpr64(ctx, fp0, fs); 10708 gen_load_fpr64(ctx, fp1, ft); 10709 gen_load_fpr64(ctx, fp2, fr); 10710 gen_helper_float_madd_ps(fp2, tcg_env, fp0, fp1, fp2); 10711 gen_store_fpr64(ctx, fp2, fd); 10712 } 10713 break; 10714 case OPC_MSUB_S: 10715 check_cop1x(ctx); 10716 { 10717 TCGv_i32 fp0 = tcg_temp_new_i32(); 10718 TCGv_i32 fp1 = tcg_temp_new_i32(); 10719 TCGv_i32 fp2 = tcg_temp_new_i32(); 10720 10721 gen_load_fpr32(ctx, fp0, fs); 10722 gen_load_fpr32(ctx, fp1, ft); 10723 gen_load_fpr32(ctx, fp2, fr); 10724 gen_helper_float_msub_s(fp2, tcg_env, fp0, fp1, fp2); 10725 gen_store_fpr32(ctx, fp2, fd); 10726 } 10727 break; 10728 case OPC_MSUB_D: 10729 check_cop1x(ctx); 10730 check_cp1_registers(ctx, fd | fs | ft | fr); 10731 { 10732 TCGv_i64 fp0 = tcg_temp_new_i64(); 10733 TCGv_i64 fp1 = tcg_temp_new_i64(); 10734 TCGv_i64 fp2 = tcg_temp_new_i64(); 10735 10736 gen_load_fpr64(ctx, fp0, fs); 10737 gen_load_fpr64(ctx, fp1, ft); 10738 gen_load_fpr64(ctx, fp2, fr); 10739 gen_helper_float_msub_d(fp2, tcg_env, fp0, fp1, fp2); 10740 gen_store_fpr64(ctx, fp2, fd); 10741 } 10742 break; 10743 case OPC_MSUB_PS: 10744 check_ps(ctx); 10745 { 10746 TCGv_i64 fp0 = tcg_temp_new_i64(); 10747 TCGv_i64 fp1 = tcg_temp_new_i64(); 10748 TCGv_i64 fp2 = tcg_temp_new_i64(); 10749 10750 gen_load_fpr64(ctx, fp0, fs); 10751 gen_load_fpr64(ctx, fp1, ft); 10752 gen_load_fpr64(ctx, fp2, fr); 10753 gen_helper_float_msub_ps(fp2, tcg_env, fp0, fp1, fp2); 10754 gen_store_fpr64(ctx, fp2, fd); 10755 } 10756 break; 10757 case OPC_NMADD_S: 10758 check_cop1x(ctx); 10759 { 10760 TCGv_i32 fp0 = tcg_temp_new_i32(); 10761 TCGv_i32 fp1 = tcg_temp_new_i32(); 10762 TCGv_i32 fp2 = tcg_temp_new_i32(); 10763 10764 gen_load_fpr32(ctx, fp0, fs); 10765 gen_load_fpr32(ctx, fp1, ft); 10766 gen_load_fpr32(ctx, fp2, fr); 10767 gen_helper_float_nmadd_s(fp2, tcg_env, fp0, fp1, fp2); 10768 gen_store_fpr32(ctx, fp2, fd); 10769 } 10770 break; 10771 case OPC_NMADD_D: 10772 check_cop1x(ctx); 10773 check_cp1_registers(ctx, fd | fs | ft | fr); 10774 { 10775 TCGv_i64 fp0 = tcg_temp_new_i64(); 10776 TCGv_i64 fp1 = tcg_temp_new_i64(); 10777 TCGv_i64 fp2 = tcg_temp_new_i64(); 10778 10779 gen_load_fpr64(ctx, fp0, fs); 10780 gen_load_fpr64(ctx, fp1, ft); 10781 gen_load_fpr64(ctx, fp2, fr); 10782 gen_helper_float_nmadd_d(fp2, tcg_env, fp0, fp1, fp2); 10783 gen_store_fpr64(ctx, fp2, fd); 10784 } 10785 break; 10786 case OPC_NMADD_PS: 10787 check_ps(ctx); 10788 { 10789 TCGv_i64 fp0 = tcg_temp_new_i64(); 10790 TCGv_i64 fp1 = tcg_temp_new_i64(); 10791 TCGv_i64 fp2 = tcg_temp_new_i64(); 10792 10793 gen_load_fpr64(ctx, fp0, fs); 10794 gen_load_fpr64(ctx, fp1, ft); 10795 gen_load_fpr64(ctx, fp2, fr); 10796 gen_helper_float_nmadd_ps(fp2, tcg_env, fp0, fp1, fp2); 10797 gen_store_fpr64(ctx, fp2, fd); 10798 } 10799 break; 10800 case OPC_NMSUB_S: 10801 check_cop1x(ctx); 10802 { 10803 TCGv_i32 fp0 = tcg_temp_new_i32(); 10804 TCGv_i32 fp1 = tcg_temp_new_i32(); 10805 TCGv_i32 fp2 = tcg_temp_new_i32(); 10806 10807 gen_load_fpr32(ctx, fp0, fs); 10808 gen_load_fpr32(ctx, fp1, ft); 10809 gen_load_fpr32(ctx, fp2, fr); 10810 gen_helper_float_nmsub_s(fp2, tcg_env, fp0, fp1, fp2); 10811 gen_store_fpr32(ctx, fp2, fd); 10812 } 10813 break; 10814 case OPC_NMSUB_D: 10815 check_cop1x(ctx); 10816 check_cp1_registers(ctx, fd | fs | ft | fr); 10817 { 10818 TCGv_i64 fp0 = tcg_temp_new_i64(); 10819 TCGv_i64 fp1 = tcg_temp_new_i64(); 10820 TCGv_i64 fp2 = tcg_temp_new_i64(); 10821 10822 gen_load_fpr64(ctx, fp0, fs); 10823 gen_load_fpr64(ctx, fp1, ft); 10824 gen_load_fpr64(ctx, fp2, fr); 10825 gen_helper_float_nmsub_d(fp2, tcg_env, fp0, fp1, fp2); 10826 gen_store_fpr64(ctx, fp2, fd); 10827 } 10828 break; 10829 case OPC_NMSUB_PS: 10830 check_ps(ctx); 10831 { 10832 TCGv_i64 fp0 = tcg_temp_new_i64(); 10833 TCGv_i64 fp1 = tcg_temp_new_i64(); 10834 TCGv_i64 fp2 = tcg_temp_new_i64(); 10835 10836 gen_load_fpr64(ctx, fp0, fs); 10837 gen_load_fpr64(ctx, fp1, ft); 10838 gen_load_fpr64(ctx, fp2, fr); 10839 gen_helper_float_nmsub_ps(fp2, tcg_env, fp0, fp1, fp2); 10840 gen_store_fpr64(ctx, fp2, fd); 10841 } 10842 break; 10843 default: 10844 MIPS_INVAL("flt3_arith"); 10845 gen_reserved_instruction(ctx); 10846 return; 10847 } 10848 } 10849 10850 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) 10851 { 10852 TCGv t0; 10853 10854 #if !defined(CONFIG_USER_ONLY) 10855 /* 10856 * The Linux kernel will emulate rdhwr if it's not supported natively. 10857 * Therefore only check the ISA in system mode. 10858 */ 10859 check_insn(ctx, ISA_MIPS_R2); 10860 #endif 10861 t0 = tcg_temp_new(); 10862 10863 switch (rd) { 10864 case 0: 10865 gen_helper_rdhwr_cpunum(t0, tcg_env); 10866 gen_store_gpr(t0, rt); 10867 break; 10868 case 1: 10869 gen_helper_rdhwr_synci_step(t0, tcg_env); 10870 gen_store_gpr(t0, rt); 10871 break; 10872 case 2: 10873 translator_io_start(&ctx->base); 10874 gen_helper_rdhwr_cc(t0, tcg_env); 10875 gen_store_gpr(t0, rt); 10876 /* 10877 * Break the TB to be able to take timer interrupts immediately 10878 * after reading count. DISAS_STOP isn't sufficient, we need to ensure 10879 * we break completely out of translated code. 10880 */ 10881 gen_save_pc(ctx->base.pc_next + 4); 10882 ctx->base.is_jmp = DISAS_EXIT; 10883 break; 10884 case 3: 10885 gen_helper_rdhwr_ccres(t0, tcg_env); 10886 gen_store_gpr(t0, rt); 10887 break; 10888 case 4: 10889 check_insn(ctx, ISA_MIPS_R6); 10890 if (sel != 0) { 10891 /* 10892 * Performance counter registers are not implemented other than 10893 * control register 0. 10894 */ 10895 generate_exception(ctx, EXCP_RI); 10896 } 10897 gen_helper_rdhwr_performance(t0, tcg_env); 10898 gen_store_gpr(t0, rt); 10899 break; 10900 case 5: 10901 check_insn(ctx, ISA_MIPS_R6); 10902 gen_helper_rdhwr_xnp(t0, tcg_env); 10903 gen_store_gpr(t0, rt); 10904 break; 10905 case 29: 10906 #if defined(CONFIG_USER_ONLY) 10907 tcg_gen_ld_tl(t0, tcg_env, 10908 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 10909 gen_store_gpr(t0, rt); 10910 break; 10911 #else 10912 if ((ctx->hflags & MIPS_HFLAG_CP0) || 10913 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) { 10914 tcg_gen_ld_tl(t0, tcg_env, 10915 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 10916 gen_store_gpr(t0, rt); 10917 } else { 10918 gen_reserved_instruction(ctx); 10919 } 10920 break; 10921 #endif 10922 default: /* Invalid */ 10923 MIPS_INVAL("rdhwr"); 10924 gen_reserved_instruction(ctx); 10925 break; 10926 } 10927 } 10928 10929 static inline void clear_branch_hflags(DisasContext *ctx) 10930 { 10931 ctx->hflags &= ~MIPS_HFLAG_BMASK; 10932 if (ctx->base.is_jmp == DISAS_NEXT) { 10933 save_cpu_state(ctx, 0); 10934 } else { 10935 /* 10936 * It is not safe to save ctx->hflags as hflags may be changed 10937 * in execution time by the instruction in delay / forbidden slot. 10938 */ 10939 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK); 10940 } 10941 } 10942 10943 static void gen_branch(DisasContext *ctx, int insn_bytes) 10944 { 10945 if (ctx->hflags & MIPS_HFLAG_BMASK) { 10946 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK; 10947 /* Branches completion */ 10948 clear_branch_hflags(ctx); 10949 ctx->base.is_jmp = DISAS_NORETURN; 10950 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) { 10951 case MIPS_HFLAG_FBNSLOT: 10952 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes); 10953 break; 10954 case MIPS_HFLAG_B: 10955 /* unconditional branch */ 10956 if (proc_hflags & MIPS_HFLAG_BX) { 10957 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16); 10958 } 10959 gen_goto_tb(ctx, 0, ctx->btarget); 10960 break; 10961 case MIPS_HFLAG_BL: 10962 /* blikely taken case */ 10963 gen_goto_tb(ctx, 0, ctx->btarget); 10964 break; 10965 case MIPS_HFLAG_BC: 10966 /* Conditional branch */ 10967 { 10968 TCGLabel *l1 = gen_new_label(); 10969 10970 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 10971 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); 10972 gen_set_label(l1); 10973 gen_goto_tb(ctx, 0, ctx->btarget); 10974 } 10975 break; 10976 case MIPS_HFLAG_BR: 10977 /* unconditional branch to register */ 10978 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) { 10979 TCGv t0 = tcg_temp_new(); 10980 TCGv_i32 t1 = tcg_temp_new_i32(); 10981 10982 tcg_gen_andi_tl(t0, btarget, 0x1); 10983 tcg_gen_trunc_tl_i32(t1, t0); 10984 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16); 10985 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT); 10986 tcg_gen_or_i32(hflags, hflags, t1); 10987 10988 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1); 10989 } else { 10990 tcg_gen_mov_tl(cpu_PC, btarget); 10991 } 10992 tcg_gen_lookup_and_goto_ptr(); 10993 break; 10994 default: 10995 LOG_DISAS("unknown branch 0x%x\n", proc_hflags); 10996 gen_reserved_instruction(ctx); 10997 } 10998 } 10999 } 11000 11001 /* Compact Branches */ 11002 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, 11003 int rs, int rt, int32_t offset) 11004 { 11005 int bcond_compute = 0; 11006 TCGv t0 = tcg_temp_new(); 11007 TCGv t1 = tcg_temp_new(); 11008 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; 11009 11010 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11011 #ifdef MIPS_DEBUG_DISAS 11012 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 11013 VADDR_PRIx "\n", ctx->base.pc_next); 11014 #endif 11015 gen_reserved_instruction(ctx); 11016 return; 11017 } 11018 11019 /* Load needed operands and calculate btarget */ 11020 switch (opc) { 11021 /* compact branch */ 11022 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11023 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11024 gen_load_gpr(t0, rs); 11025 gen_load_gpr(t1, rt); 11026 bcond_compute = 1; 11027 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11028 if (rs <= rt && rs == 0) { 11029 /* OPC_BEQZALC, OPC_BNEZALC */ 11030 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11031 } 11032 break; 11033 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11034 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11035 gen_load_gpr(t0, rs); 11036 gen_load_gpr(t1, rt); 11037 bcond_compute = 1; 11038 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11039 break; 11040 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11041 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11042 if (rs == 0 || rs == rt) { 11043 /* OPC_BLEZALC, OPC_BGEZALC */ 11044 /* OPC_BGTZALC, OPC_BLTZALC */ 11045 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11046 } 11047 gen_load_gpr(t0, rs); 11048 gen_load_gpr(t1, rt); 11049 bcond_compute = 1; 11050 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11051 break; 11052 case OPC_BC: 11053 case OPC_BALC: 11054 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11055 break; 11056 case OPC_BEQZC: 11057 case OPC_BNEZC: 11058 if (rs != 0) { 11059 /* OPC_BEQZC, OPC_BNEZC */ 11060 gen_load_gpr(t0, rs); 11061 bcond_compute = 1; 11062 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11063 } else { 11064 /* OPC_JIC, OPC_JIALC */ 11065 TCGv tbase = tcg_temp_new(); 11066 11067 gen_load_gpr(tbase, rt); 11068 gen_op_addr_addi(ctx, btarget, tbase, offset); 11069 } 11070 break; 11071 default: 11072 MIPS_INVAL("Compact branch/jump"); 11073 gen_reserved_instruction(ctx); 11074 return; 11075 } 11076 11077 if (bcond_compute == 0) { 11078 /* Unconditional compact branch */ 11079 switch (opc) { 11080 case OPC_JIALC: 11081 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11082 /* Fallthrough */ 11083 case OPC_JIC: 11084 ctx->hflags |= MIPS_HFLAG_BR; 11085 break; 11086 case OPC_BALC: 11087 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11088 /* Fallthrough */ 11089 case OPC_BC: 11090 ctx->hflags |= MIPS_HFLAG_B; 11091 break; 11092 default: 11093 MIPS_INVAL("Compact branch/jump"); 11094 gen_reserved_instruction(ctx); 11095 return; 11096 } 11097 11098 /* Generating branch here as compact branches don't have delay slot */ 11099 gen_branch(ctx, 4); 11100 } else { 11101 /* Conditional compact branch */ 11102 TCGLabel *fs = gen_new_label(); 11103 save_cpu_state(ctx, 0); 11104 11105 switch (opc) { 11106 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11107 if (rs == 0 && rt != 0) { 11108 /* OPC_BLEZALC */ 11109 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11110 } else if (rs != 0 && rt != 0 && rs == rt) { 11111 /* OPC_BGEZALC */ 11112 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11113 } else { 11114 /* OPC_BGEUC */ 11115 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 11116 } 11117 break; 11118 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11119 if (rs == 0 && rt != 0) { 11120 /* OPC_BGTZALC */ 11121 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11122 } else if (rs != 0 && rt != 0 && rs == rt) { 11123 /* OPC_BLTZALC */ 11124 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11125 } else { 11126 /* OPC_BLTUC */ 11127 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 11128 } 11129 break; 11130 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11131 if (rs == 0 && rt != 0) { 11132 /* OPC_BLEZC */ 11133 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11134 } else if (rs != 0 && rt != 0 && rs == rt) { 11135 /* OPC_BGEZC */ 11136 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11137 } else { 11138 /* OPC_BGEC */ 11139 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 11140 } 11141 break; 11142 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11143 if (rs == 0 && rt != 0) { 11144 /* OPC_BGTZC */ 11145 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11146 } else if (rs != 0 && rt != 0 && rs == rt) { 11147 /* OPC_BLTZC */ 11148 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11149 } else { 11150 /* OPC_BLTC */ 11151 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 11152 } 11153 break; 11154 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11155 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11156 if (rs >= rt) { 11157 /* OPC_BOVC, OPC_BNVC */ 11158 TCGv t2 = tcg_temp_new(); 11159 TCGv t3 = tcg_temp_new(); 11160 TCGv t4 = tcg_temp_new(); 11161 TCGv input_overflow = tcg_temp_new(); 11162 11163 gen_load_gpr(t0, rs); 11164 gen_load_gpr(t1, rt); 11165 tcg_gen_ext32s_tl(t2, t0); 11166 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0); 11167 tcg_gen_ext32s_tl(t3, t1); 11168 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1); 11169 tcg_gen_or_tl(input_overflow, input_overflow, t4); 11170 11171 tcg_gen_add_tl(t4, t2, t3); 11172 tcg_gen_ext32s_tl(t4, t4); 11173 tcg_gen_xor_tl(t2, t2, t3); 11174 tcg_gen_xor_tl(t3, t4, t3); 11175 tcg_gen_andc_tl(t2, t3, t2); 11176 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0); 11177 tcg_gen_or_tl(t4, t4, input_overflow); 11178 if (opc == OPC_BOVC) { 11179 /* OPC_BOVC */ 11180 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs); 11181 } else { 11182 /* OPC_BNVC */ 11183 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs); 11184 } 11185 } else if (rs < rt && rs == 0) { 11186 /* OPC_BEQZALC, OPC_BNEZALC */ 11187 if (opc == OPC_BEQZALC) { 11188 /* OPC_BEQZALC */ 11189 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs); 11190 } else { 11191 /* OPC_BNEZALC */ 11192 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs); 11193 } 11194 } else { 11195 /* OPC_BEQC, OPC_BNEC */ 11196 if (opc == OPC_BEQC) { 11197 /* OPC_BEQC */ 11198 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); 11199 } else { 11200 /* OPC_BNEC */ 11201 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); 11202 } 11203 } 11204 break; 11205 case OPC_BEQZC: 11206 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 11207 break; 11208 case OPC_BNEZC: 11209 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs); 11210 break; 11211 default: 11212 MIPS_INVAL("Compact conditional branch/jump"); 11213 gen_reserved_instruction(ctx); 11214 return; 11215 } 11216 11217 /* Generating branch here as compact branches don't have delay slot */ 11218 gen_goto_tb(ctx, 1, ctx->btarget); 11219 gen_set_label(fs); 11220 11221 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 11222 } 11223 } 11224 11225 void gen_addiupc(DisasContext *ctx, int rx, int imm, 11226 int is_64_bit, int extended) 11227 { 11228 target_ulong npc; 11229 11230 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { 11231 gen_reserved_instruction(ctx); 11232 return; 11233 } 11234 11235 npc = pc_relative_pc(ctx) + imm; 11236 if (!is_64_bit) { 11237 npc = (int32_t)npc; 11238 } 11239 tcg_gen_movi_tl(cpu_gpr[rx], npc); 11240 } 11241 11242 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, 11243 int16_t offset) 11244 { 11245 TCGv_i32 t0 = tcg_constant_i32(op); 11246 TCGv t1 = tcg_temp_new(); 11247 gen_base_offset_addr(ctx, t1, base, offset); 11248 gen_helper_cache(tcg_env, t1, t0); 11249 } 11250 11251 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code) 11252 { 11253 #ifdef CONFIG_USER_ONLY 11254 return false; 11255 #else 11256 bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM; 11257 return semihosting_enabled(is_user) && sdbbp_code == 1; 11258 #endif 11259 } 11260 11261 void gen_ldxs(DisasContext *ctx, int base, int index, int rd) 11262 { 11263 TCGv t0 = tcg_temp_new(); 11264 TCGv t1 = tcg_temp_new(); 11265 11266 gen_load_gpr(t0, base); 11267 11268 if (index != 0) { 11269 gen_load_gpr(t1, index); 11270 tcg_gen_shli_tl(t1, t1, 2); 11271 gen_op_addr_add(ctx, t0, t1, t0); 11272 } 11273 11274 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 11275 gen_store_gpr(t1, rd); 11276 } 11277 11278 static void gen_sync(int stype) 11279 { 11280 TCGBar tcg_mo = TCG_BAR_SC; 11281 11282 switch (stype) { 11283 case 0x4: /* SYNC_WMB */ 11284 tcg_mo |= TCG_MO_ST_ST; 11285 break; 11286 case 0x10: /* SYNC_MB */ 11287 tcg_mo |= TCG_MO_ALL; 11288 break; 11289 case 0x11: /* SYNC_ACQUIRE */ 11290 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; 11291 break; 11292 case 0x12: /* SYNC_RELEASE */ 11293 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; 11294 break; 11295 case 0x13: /* SYNC_RMB */ 11296 tcg_mo |= TCG_MO_LD_LD; 11297 break; 11298 default: 11299 tcg_mo |= TCG_MO_ALL; 11300 break; 11301 } 11302 11303 tcg_gen_mb(tcg_mo); 11304 } 11305 11306 /* ISA extensions (ASEs) */ 11307 11308 /* MIPS16 extension to MIPS32 */ 11309 #include "mips16e_translate.c.inc" 11310 11311 /* microMIPS extension to MIPS32/MIPS64 */ 11312 11313 /* 11314 * Values for microMIPS fmt field. Variable-width, depending on which 11315 * formats the instruction supports. 11316 */ 11317 enum { 11318 FMT_SD_S = 0, 11319 FMT_SD_D = 1, 11320 11321 FMT_SDPS_S = 0, 11322 FMT_SDPS_D = 1, 11323 FMT_SDPS_PS = 2, 11324 11325 FMT_SWL_S = 0, 11326 FMT_SWL_W = 1, 11327 FMT_SWL_L = 2, 11328 11329 FMT_DWL_D = 0, 11330 FMT_DWL_W = 1, 11331 FMT_DWL_L = 2 11332 }; 11333 11334 #include "micromips_translate.c.inc" 11335 11336 #include "nanomips_translate.c.inc" 11337 11338 /* MIPSDSP functions. */ 11339 11340 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2, 11341 int ret, int v1, int v2) 11342 { 11343 TCGv v1_t; 11344 TCGv v2_t; 11345 11346 if (ret == 0) { 11347 /* Treat as NOP. */ 11348 return; 11349 } 11350 11351 v1_t = tcg_temp_new(); 11352 v2_t = tcg_temp_new(); 11353 11354 gen_load_gpr(v1_t, v1); 11355 gen_load_gpr(v2_t, v2); 11356 11357 switch (op1) { 11358 case OPC_ADDUH_QB_DSP: 11359 check_dsp_r2(ctx); 11360 switch (op2) { 11361 case OPC_ADDUH_QB: 11362 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); 11363 break; 11364 case OPC_ADDUH_R_QB: 11365 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); 11366 break; 11367 case OPC_ADDQH_PH: 11368 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); 11369 break; 11370 case OPC_ADDQH_R_PH: 11371 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 11372 break; 11373 case OPC_ADDQH_W: 11374 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); 11375 break; 11376 case OPC_ADDQH_R_W: 11377 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); 11378 break; 11379 case OPC_SUBUH_QB: 11380 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); 11381 break; 11382 case OPC_SUBUH_R_QB: 11383 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); 11384 break; 11385 case OPC_SUBQH_PH: 11386 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); 11387 break; 11388 case OPC_SUBQH_R_PH: 11389 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 11390 break; 11391 case OPC_SUBQH_W: 11392 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); 11393 break; 11394 case OPC_SUBQH_R_W: 11395 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); 11396 break; 11397 } 11398 break; 11399 case OPC_ABSQ_S_PH_DSP: 11400 switch (op2) { 11401 case OPC_ABSQ_S_QB: 11402 check_dsp_r2(ctx); 11403 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, tcg_env); 11404 break; 11405 case OPC_ABSQ_S_PH: 11406 check_dsp(ctx); 11407 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, tcg_env); 11408 break; 11409 case OPC_ABSQ_S_W: 11410 check_dsp(ctx); 11411 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, tcg_env); 11412 break; 11413 case OPC_PRECEQ_W_PHL: 11414 check_dsp(ctx); 11415 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); 11416 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 11417 break; 11418 case OPC_PRECEQ_W_PHR: 11419 check_dsp(ctx); 11420 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); 11421 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); 11422 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 11423 break; 11424 case OPC_PRECEQU_PH_QBL: 11425 check_dsp(ctx); 11426 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); 11427 break; 11428 case OPC_PRECEQU_PH_QBR: 11429 check_dsp(ctx); 11430 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); 11431 break; 11432 case OPC_PRECEQU_PH_QBLA: 11433 check_dsp(ctx); 11434 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); 11435 break; 11436 case OPC_PRECEQU_PH_QBRA: 11437 check_dsp(ctx); 11438 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); 11439 break; 11440 case OPC_PRECEU_PH_QBL: 11441 check_dsp(ctx); 11442 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); 11443 break; 11444 case OPC_PRECEU_PH_QBR: 11445 check_dsp(ctx); 11446 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); 11447 break; 11448 case OPC_PRECEU_PH_QBLA: 11449 check_dsp(ctx); 11450 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); 11451 break; 11452 case OPC_PRECEU_PH_QBRA: 11453 check_dsp(ctx); 11454 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); 11455 break; 11456 } 11457 break; 11458 case OPC_ADDU_QB_DSP: 11459 switch (op2) { 11460 case OPC_ADDQ_PH: 11461 check_dsp(ctx); 11462 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11463 break; 11464 case OPC_ADDQ_S_PH: 11465 check_dsp(ctx); 11466 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11467 break; 11468 case OPC_ADDQ_S_W: 11469 check_dsp(ctx); 11470 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11471 break; 11472 case OPC_ADDU_QB: 11473 check_dsp(ctx); 11474 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11475 break; 11476 case OPC_ADDU_S_QB: 11477 check_dsp(ctx); 11478 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11479 break; 11480 case OPC_ADDU_PH: 11481 check_dsp_r2(ctx); 11482 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11483 break; 11484 case OPC_ADDU_S_PH: 11485 check_dsp_r2(ctx); 11486 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11487 break; 11488 case OPC_SUBQ_PH: 11489 check_dsp(ctx); 11490 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11491 break; 11492 case OPC_SUBQ_S_PH: 11493 check_dsp(ctx); 11494 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11495 break; 11496 case OPC_SUBQ_S_W: 11497 check_dsp(ctx); 11498 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11499 break; 11500 case OPC_SUBU_QB: 11501 check_dsp(ctx); 11502 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11503 break; 11504 case OPC_SUBU_S_QB: 11505 check_dsp(ctx); 11506 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11507 break; 11508 case OPC_SUBU_PH: 11509 check_dsp_r2(ctx); 11510 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11511 break; 11512 case OPC_SUBU_S_PH: 11513 check_dsp_r2(ctx); 11514 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11515 break; 11516 case OPC_ADDSC: 11517 check_dsp(ctx); 11518 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11519 break; 11520 case OPC_ADDWC: 11521 check_dsp(ctx); 11522 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11523 break; 11524 case OPC_MODSUB: 11525 check_dsp(ctx); 11526 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); 11527 break; 11528 case OPC_RADDU_W_QB: 11529 check_dsp(ctx); 11530 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); 11531 break; 11532 } 11533 break; 11534 case OPC_CMPU_EQ_QB_DSP: 11535 switch (op2) { 11536 case OPC_PRECR_QB_PH: 11537 check_dsp_r2(ctx); 11538 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); 11539 break; 11540 case OPC_PRECRQ_QB_PH: 11541 check_dsp(ctx); 11542 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); 11543 break; 11544 case OPC_PRECR_SRA_PH_W: 11545 check_dsp_r2(ctx); 11546 { 11547 TCGv_i32 sa_t = tcg_constant_i32(v2); 11548 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, 11549 cpu_gpr[ret]); 11550 break; 11551 } 11552 case OPC_PRECR_SRA_R_PH_W: 11553 check_dsp_r2(ctx); 11554 { 11555 TCGv_i32 sa_t = tcg_constant_i32(v2); 11556 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, 11557 cpu_gpr[ret]); 11558 break; 11559 } 11560 case OPC_PRECRQ_PH_W: 11561 check_dsp(ctx); 11562 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); 11563 break; 11564 case OPC_PRECRQ_RS_PH_W: 11565 check_dsp(ctx); 11566 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11567 break; 11568 case OPC_PRECRQU_S_QB_PH: 11569 check_dsp(ctx); 11570 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11571 break; 11572 } 11573 break; 11574 #ifdef TARGET_MIPS64 11575 case OPC_ABSQ_S_QH_DSP: 11576 switch (op2) { 11577 case OPC_PRECEQ_L_PWL: 11578 check_dsp(ctx); 11579 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); 11580 break; 11581 case OPC_PRECEQ_L_PWR: 11582 check_dsp(ctx); 11583 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); 11584 break; 11585 case OPC_PRECEQ_PW_QHL: 11586 check_dsp(ctx); 11587 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); 11588 break; 11589 case OPC_PRECEQ_PW_QHR: 11590 check_dsp(ctx); 11591 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); 11592 break; 11593 case OPC_PRECEQ_PW_QHLA: 11594 check_dsp(ctx); 11595 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); 11596 break; 11597 case OPC_PRECEQ_PW_QHRA: 11598 check_dsp(ctx); 11599 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); 11600 break; 11601 case OPC_PRECEQU_QH_OBL: 11602 check_dsp(ctx); 11603 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); 11604 break; 11605 case OPC_PRECEQU_QH_OBR: 11606 check_dsp(ctx); 11607 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); 11608 break; 11609 case OPC_PRECEQU_QH_OBLA: 11610 check_dsp(ctx); 11611 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); 11612 break; 11613 case OPC_PRECEQU_QH_OBRA: 11614 check_dsp(ctx); 11615 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); 11616 break; 11617 case OPC_PRECEU_QH_OBL: 11618 check_dsp(ctx); 11619 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); 11620 break; 11621 case OPC_PRECEU_QH_OBR: 11622 check_dsp(ctx); 11623 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); 11624 break; 11625 case OPC_PRECEU_QH_OBLA: 11626 check_dsp(ctx); 11627 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); 11628 break; 11629 case OPC_PRECEU_QH_OBRA: 11630 check_dsp(ctx); 11631 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); 11632 break; 11633 case OPC_ABSQ_S_OB: 11634 check_dsp_r2(ctx); 11635 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, tcg_env); 11636 break; 11637 case OPC_ABSQ_S_PW: 11638 check_dsp(ctx); 11639 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, tcg_env); 11640 break; 11641 case OPC_ABSQ_S_QH: 11642 check_dsp(ctx); 11643 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, tcg_env); 11644 break; 11645 } 11646 break; 11647 case OPC_ADDU_OB_DSP: 11648 switch (op2) { 11649 case OPC_RADDU_L_OB: 11650 check_dsp(ctx); 11651 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); 11652 break; 11653 case OPC_SUBQ_PW: 11654 check_dsp(ctx); 11655 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11656 break; 11657 case OPC_SUBQ_S_PW: 11658 check_dsp(ctx); 11659 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11660 break; 11661 case OPC_SUBQ_QH: 11662 check_dsp(ctx); 11663 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11664 break; 11665 case OPC_SUBQ_S_QH: 11666 check_dsp(ctx); 11667 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11668 break; 11669 case OPC_SUBU_OB: 11670 check_dsp(ctx); 11671 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11672 break; 11673 case OPC_SUBU_S_OB: 11674 check_dsp(ctx); 11675 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11676 break; 11677 case OPC_SUBU_QH: 11678 check_dsp_r2(ctx); 11679 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11680 break; 11681 case OPC_SUBU_S_QH: 11682 check_dsp_r2(ctx); 11683 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11684 break; 11685 case OPC_SUBUH_OB: 11686 check_dsp_r2(ctx); 11687 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); 11688 break; 11689 case OPC_SUBUH_R_OB: 11690 check_dsp_r2(ctx); 11691 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); 11692 break; 11693 case OPC_ADDQ_PW: 11694 check_dsp(ctx); 11695 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11696 break; 11697 case OPC_ADDQ_S_PW: 11698 check_dsp(ctx); 11699 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11700 break; 11701 case OPC_ADDQ_QH: 11702 check_dsp(ctx); 11703 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11704 break; 11705 case OPC_ADDQ_S_QH: 11706 check_dsp(ctx); 11707 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11708 break; 11709 case OPC_ADDU_OB: 11710 check_dsp(ctx); 11711 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11712 break; 11713 case OPC_ADDU_S_OB: 11714 check_dsp(ctx); 11715 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11716 break; 11717 case OPC_ADDU_QH: 11718 check_dsp_r2(ctx); 11719 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11720 break; 11721 case OPC_ADDU_S_QH: 11722 check_dsp_r2(ctx); 11723 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11724 break; 11725 case OPC_ADDUH_OB: 11726 check_dsp_r2(ctx); 11727 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); 11728 break; 11729 case OPC_ADDUH_R_OB: 11730 check_dsp_r2(ctx); 11731 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); 11732 break; 11733 } 11734 break; 11735 case OPC_CMPU_EQ_OB_DSP: 11736 switch (op2) { 11737 case OPC_PRECR_OB_QH: 11738 check_dsp_r2(ctx); 11739 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); 11740 break; 11741 case OPC_PRECR_SRA_QH_PW: 11742 check_dsp_r2(ctx); 11743 { 11744 TCGv_i32 ret_t = tcg_constant_i32(ret); 11745 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); 11746 break; 11747 } 11748 case OPC_PRECR_SRA_R_QH_PW: 11749 check_dsp_r2(ctx); 11750 { 11751 TCGv_i32 sa_v = tcg_constant_i32(ret); 11752 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); 11753 break; 11754 } 11755 case OPC_PRECRQ_OB_QH: 11756 check_dsp(ctx); 11757 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); 11758 break; 11759 case OPC_PRECRQ_PW_L: 11760 check_dsp(ctx); 11761 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); 11762 break; 11763 case OPC_PRECRQ_QH_PW: 11764 check_dsp(ctx); 11765 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); 11766 break; 11767 case OPC_PRECRQ_RS_QH_PW: 11768 check_dsp(ctx); 11769 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11770 break; 11771 case OPC_PRECRQU_S_OB_QH: 11772 check_dsp(ctx); 11773 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11774 break; 11775 } 11776 break; 11777 #endif 11778 } 11779 } 11780 11781 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, 11782 int ret, int v1, int v2) 11783 { 11784 uint32_t op2; 11785 TCGv t0; 11786 TCGv v1_t; 11787 TCGv v2_t; 11788 11789 if (ret == 0) { 11790 /* Treat as NOP. */ 11791 return; 11792 } 11793 11794 t0 = tcg_temp_new(); 11795 v1_t = tcg_temp_new(); 11796 v2_t = tcg_temp_new(); 11797 11798 tcg_gen_movi_tl(t0, v1); 11799 gen_load_gpr(v1_t, v1); 11800 gen_load_gpr(v2_t, v2); 11801 11802 switch (opc) { 11803 case OPC_SHLL_QB_DSP: 11804 { 11805 op2 = MASK_SHLL_QB(ctx->opcode); 11806 switch (op2) { 11807 case OPC_SHLL_QB: 11808 check_dsp(ctx); 11809 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, tcg_env); 11810 break; 11811 case OPC_SHLLV_QB: 11812 check_dsp(ctx); 11813 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11814 break; 11815 case OPC_SHLL_PH: 11816 check_dsp(ctx); 11817 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, tcg_env); 11818 break; 11819 case OPC_SHLLV_PH: 11820 check_dsp(ctx); 11821 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11822 break; 11823 case OPC_SHLL_S_PH: 11824 check_dsp(ctx); 11825 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, tcg_env); 11826 break; 11827 case OPC_SHLLV_S_PH: 11828 check_dsp(ctx); 11829 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11830 break; 11831 case OPC_SHLL_S_W: 11832 check_dsp(ctx); 11833 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, tcg_env); 11834 break; 11835 case OPC_SHLLV_S_W: 11836 check_dsp(ctx); 11837 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11838 break; 11839 case OPC_SHRL_QB: 11840 check_dsp(ctx); 11841 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); 11842 break; 11843 case OPC_SHRLV_QB: 11844 check_dsp(ctx); 11845 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); 11846 break; 11847 case OPC_SHRL_PH: 11848 check_dsp_r2(ctx); 11849 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); 11850 break; 11851 case OPC_SHRLV_PH: 11852 check_dsp_r2(ctx); 11853 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); 11854 break; 11855 case OPC_SHRA_QB: 11856 check_dsp_r2(ctx); 11857 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); 11858 break; 11859 case OPC_SHRA_R_QB: 11860 check_dsp_r2(ctx); 11861 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); 11862 break; 11863 case OPC_SHRAV_QB: 11864 check_dsp_r2(ctx); 11865 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); 11866 break; 11867 case OPC_SHRAV_R_QB: 11868 check_dsp_r2(ctx); 11869 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); 11870 break; 11871 case OPC_SHRA_PH: 11872 check_dsp(ctx); 11873 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); 11874 break; 11875 case OPC_SHRA_R_PH: 11876 check_dsp(ctx); 11877 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); 11878 break; 11879 case OPC_SHRAV_PH: 11880 check_dsp(ctx); 11881 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); 11882 break; 11883 case OPC_SHRAV_R_PH: 11884 check_dsp(ctx); 11885 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); 11886 break; 11887 case OPC_SHRA_R_W: 11888 check_dsp(ctx); 11889 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); 11890 break; 11891 case OPC_SHRAV_R_W: 11892 check_dsp(ctx); 11893 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); 11894 break; 11895 default: /* Invalid */ 11896 MIPS_INVAL("MASK SHLL.QB"); 11897 gen_reserved_instruction(ctx); 11898 break; 11899 } 11900 break; 11901 } 11902 #ifdef TARGET_MIPS64 11903 case OPC_SHLL_OB_DSP: 11904 op2 = MASK_SHLL_OB(ctx->opcode); 11905 switch (op2) { 11906 case OPC_SHLL_PW: 11907 check_dsp(ctx); 11908 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, tcg_env); 11909 break; 11910 case OPC_SHLLV_PW: 11911 check_dsp(ctx); 11912 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11913 break; 11914 case OPC_SHLL_S_PW: 11915 check_dsp(ctx); 11916 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, tcg_env); 11917 break; 11918 case OPC_SHLLV_S_PW: 11919 check_dsp(ctx); 11920 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11921 break; 11922 case OPC_SHLL_OB: 11923 check_dsp(ctx); 11924 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, tcg_env); 11925 break; 11926 case OPC_SHLLV_OB: 11927 check_dsp(ctx); 11928 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11929 break; 11930 case OPC_SHLL_QH: 11931 check_dsp(ctx); 11932 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, tcg_env); 11933 break; 11934 case OPC_SHLLV_QH: 11935 check_dsp(ctx); 11936 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11937 break; 11938 case OPC_SHLL_S_QH: 11939 check_dsp(ctx); 11940 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, tcg_env); 11941 break; 11942 case OPC_SHLLV_S_QH: 11943 check_dsp(ctx); 11944 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11945 break; 11946 case OPC_SHRA_OB: 11947 check_dsp_r2(ctx); 11948 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); 11949 break; 11950 case OPC_SHRAV_OB: 11951 check_dsp_r2(ctx); 11952 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); 11953 break; 11954 case OPC_SHRA_R_OB: 11955 check_dsp_r2(ctx); 11956 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); 11957 break; 11958 case OPC_SHRAV_R_OB: 11959 check_dsp_r2(ctx); 11960 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); 11961 break; 11962 case OPC_SHRA_PW: 11963 check_dsp(ctx); 11964 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); 11965 break; 11966 case OPC_SHRAV_PW: 11967 check_dsp(ctx); 11968 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); 11969 break; 11970 case OPC_SHRA_R_PW: 11971 check_dsp(ctx); 11972 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); 11973 break; 11974 case OPC_SHRAV_R_PW: 11975 check_dsp(ctx); 11976 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); 11977 break; 11978 case OPC_SHRA_QH: 11979 check_dsp(ctx); 11980 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); 11981 break; 11982 case OPC_SHRAV_QH: 11983 check_dsp(ctx); 11984 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); 11985 break; 11986 case OPC_SHRA_R_QH: 11987 check_dsp(ctx); 11988 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); 11989 break; 11990 case OPC_SHRAV_R_QH: 11991 check_dsp(ctx); 11992 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); 11993 break; 11994 case OPC_SHRL_OB: 11995 check_dsp(ctx); 11996 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); 11997 break; 11998 case OPC_SHRLV_OB: 11999 check_dsp(ctx); 12000 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); 12001 break; 12002 case OPC_SHRL_QH: 12003 check_dsp_r2(ctx); 12004 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); 12005 break; 12006 case OPC_SHRLV_QH: 12007 check_dsp_r2(ctx); 12008 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); 12009 break; 12010 default: /* Invalid */ 12011 MIPS_INVAL("MASK SHLL.OB"); 12012 gen_reserved_instruction(ctx); 12013 break; 12014 } 12015 break; 12016 #endif 12017 } 12018 } 12019 12020 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2, 12021 int ret, int v1, int v2, int check_ret) 12022 { 12023 TCGv_i32 t0; 12024 TCGv v1_t; 12025 TCGv v2_t; 12026 12027 if ((ret == 0) && (check_ret == 1)) { 12028 /* Treat as NOP. */ 12029 return; 12030 } 12031 12032 t0 = tcg_temp_new_i32(); 12033 v1_t = tcg_temp_new(); 12034 v2_t = tcg_temp_new(); 12035 12036 tcg_gen_movi_i32(t0, ret); 12037 gen_load_gpr(v1_t, v1); 12038 gen_load_gpr(v2_t, v2); 12039 12040 switch (op1) { 12041 case OPC_MUL_PH_DSP: 12042 check_dsp_r2(ctx); 12043 switch (op2) { 12044 case OPC_MUL_PH: 12045 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12046 break; 12047 case OPC_MUL_S_PH: 12048 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12049 break; 12050 case OPC_MULQ_S_W: 12051 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12052 break; 12053 case OPC_MULQ_RS_W: 12054 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12055 break; 12056 } 12057 break; 12058 case OPC_DPA_W_PH_DSP: 12059 switch (op2) { 12060 case OPC_DPAU_H_QBL: 12061 check_dsp(ctx); 12062 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, tcg_env); 12063 break; 12064 case OPC_DPAU_H_QBR: 12065 check_dsp(ctx); 12066 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, tcg_env); 12067 break; 12068 case OPC_DPSU_H_QBL: 12069 check_dsp(ctx); 12070 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, tcg_env); 12071 break; 12072 case OPC_DPSU_H_QBR: 12073 check_dsp(ctx); 12074 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, tcg_env); 12075 break; 12076 case OPC_DPA_W_PH: 12077 check_dsp_r2(ctx); 12078 gen_helper_dpa_w_ph(t0, v1_t, v2_t, tcg_env); 12079 break; 12080 case OPC_DPAX_W_PH: 12081 check_dsp_r2(ctx); 12082 gen_helper_dpax_w_ph(t0, v1_t, v2_t, tcg_env); 12083 break; 12084 case OPC_DPAQ_S_W_PH: 12085 check_dsp(ctx); 12086 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12087 break; 12088 case OPC_DPAQX_S_W_PH: 12089 check_dsp_r2(ctx); 12090 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, tcg_env); 12091 break; 12092 case OPC_DPAQX_SA_W_PH: 12093 check_dsp_r2(ctx); 12094 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, tcg_env); 12095 break; 12096 case OPC_DPS_W_PH: 12097 check_dsp_r2(ctx); 12098 gen_helper_dps_w_ph(t0, v1_t, v2_t, tcg_env); 12099 break; 12100 case OPC_DPSX_W_PH: 12101 check_dsp_r2(ctx); 12102 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, tcg_env); 12103 break; 12104 case OPC_DPSQ_S_W_PH: 12105 check_dsp(ctx); 12106 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12107 break; 12108 case OPC_DPSQX_S_W_PH: 12109 check_dsp_r2(ctx); 12110 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, tcg_env); 12111 break; 12112 case OPC_DPSQX_SA_W_PH: 12113 check_dsp_r2(ctx); 12114 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, tcg_env); 12115 break; 12116 case OPC_MULSAQ_S_W_PH: 12117 check_dsp(ctx); 12118 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12119 break; 12120 case OPC_DPAQ_SA_L_W: 12121 check_dsp(ctx); 12122 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, tcg_env); 12123 break; 12124 case OPC_DPSQ_SA_L_W: 12125 check_dsp(ctx); 12126 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, tcg_env); 12127 break; 12128 case OPC_MAQ_S_W_PHL: 12129 check_dsp(ctx); 12130 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, tcg_env); 12131 break; 12132 case OPC_MAQ_S_W_PHR: 12133 check_dsp(ctx); 12134 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, tcg_env); 12135 break; 12136 case OPC_MAQ_SA_W_PHL: 12137 check_dsp(ctx); 12138 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, tcg_env); 12139 break; 12140 case OPC_MAQ_SA_W_PHR: 12141 check_dsp(ctx); 12142 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, tcg_env); 12143 break; 12144 case OPC_MULSA_W_PH: 12145 check_dsp_r2(ctx); 12146 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, tcg_env); 12147 break; 12148 } 12149 break; 12150 #ifdef TARGET_MIPS64 12151 case OPC_DPAQ_W_QH_DSP: 12152 { 12153 int ac = ret & 0x03; 12154 tcg_gen_movi_i32(t0, ac); 12155 12156 switch (op2) { 12157 case OPC_DMADD: 12158 check_dsp(ctx); 12159 gen_helper_dmadd(v1_t, v2_t, t0, tcg_env); 12160 break; 12161 case OPC_DMADDU: 12162 check_dsp(ctx); 12163 gen_helper_dmaddu(v1_t, v2_t, t0, tcg_env); 12164 break; 12165 case OPC_DMSUB: 12166 check_dsp(ctx); 12167 gen_helper_dmsub(v1_t, v2_t, t0, tcg_env); 12168 break; 12169 case OPC_DMSUBU: 12170 check_dsp(ctx); 12171 gen_helper_dmsubu(v1_t, v2_t, t0, tcg_env); 12172 break; 12173 case OPC_DPA_W_QH: 12174 check_dsp_r2(ctx); 12175 gen_helper_dpa_w_qh(v1_t, v2_t, t0, tcg_env); 12176 break; 12177 case OPC_DPAQ_S_W_QH: 12178 check_dsp(ctx); 12179 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12180 break; 12181 case OPC_DPAQ_SA_L_PW: 12182 check_dsp(ctx); 12183 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, tcg_env); 12184 break; 12185 case OPC_DPAU_H_OBL: 12186 check_dsp(ctx); 12187 gen_helper_dpau_h_obl(v1_t, v2_t, t0, tcg_env); 12188 break; 12189 case OPC_DPAU_H_OBR: 12190 check_dsp(ctx); 12191 gen_helper_dpau_h_obr(v1_t, v2_t, t0, tcg_env); 12192 break; 12193 case OPC_DPS_W_QH: 12194 check_dsp_r2(ctx); 12195 gen_helper_dps_w_qh(v1_t, v2_t, t0, tcg_env); 12196 break; 12197 case OPC_DPSQ_S_W_QH: 12198 check_dsp(ctx); 12199 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12200 break; 12201 case OPC_DPSQ_SA_L_PW: 12202 check_dsp(ctx); 12203 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, tcg_env); 12204 break; 12205 case OPC_DPSU_H_OBL: 12206 check_dsp(ctx); 12207 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, tcg_env); 12208 break; 12209 case OPC_DPSU_H_OBR: 12210 check_dsp(ctx); 12211 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, tcg_env); 12212 break; 12213 case OPC_MAQ_S_L_PWL: 12214 check_dsp(ctx); 12215 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, tcg_env); 12216 break; 12217 case OPC_MAQ_S_L_PWR: 12218 check_dsp(ctx); 12219 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, tcg_env); 12220 break; 12221 case OPC_MAQ_S_W_QHLL: 12222 check_dsp(ctx); 12223 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, tcg_env); 12224 break; 12225 case OPC_MAQ_SA_W_QHLL: 12226 check_dsp(ctx); 12227 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, tcg_env); 12228 break; 12229 case OPC_MAQ_S_W_QHLR: 12230 check_dsp(ctx); 12231 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, tcg_env); 12232 break; 12233 case OPC_MAQ_SA_W_QHLR: 12234 check_dsp(ctx); 12235 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, tcg_env); 12236 break; 12237 case OPC_MAQ_S_W_QHRL: 12238 check_dsp(ctx); 12239 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, tcg_env); 12240 break; 12241 case OPC_MAQ_SA_W_QHRL: 12242 check_dsp(ctx); 12243 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, tcg_env); 12244 break; 12245 case OPC_MAQ_S_W_QHRR: 12246 check_dsp(ctx); 12247 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, tcg_env); 12248 break; 12249 case OPC_MAQ_SA_W_QHRR: 12250 check_dsp(ctx); 12251 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, tcg_env); 12252 break; 12253 case OPC_MULSAQ_S_L_PW: 12254 check_dsp(ctx); 12255 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, tcg_env); 12256 break; 12257 case OPC_MULSAQ_S_W_QH: 12258 check_dsp(ctx); 12259 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12260 break; 12261 } 12262 } 12263 break; 12264 #endif 12265 case OPC_ADDU_QB_DSP: 12266 switch (op2) { 12267 case OPC_MULEU_S_PH_QBL: 12268 check_dsp(ctx); 12269 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12270 break; 12271 case OPC_MULEU_S_PH_QBR: 12272 check_dsp(ctx); 12273 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12274 break; 12275 case OPC_MULQ_RS_PH: 12276 check_dsp(ctx); 12277 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12278 break; 12279 case OPC_MULEQ_S_W_PHL: 12280 check_dsp(ctx); 12281 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12282 break; 12283 case OPC_MULEQ_S_W_PHR: 12284 check_dsp(ctx); 12285 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12286 break; 12287 case OPC_MULQ_S_PH: 12288 check_dsp_r2(ctx); 12289 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12290 break; 12291 } 12292 break; 12293 #ifdef TARGET_MIPS64 12294 case OPC_ADDU_OB_DSP: 12295 switch (op2) { 12296 case OPC_MULEQ_S_PW_QHL: 12297 check_dsp(ctx); 12298 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12299 break; 12300 case OPC_MULEQ_S_PW_QHR: 12301 check_dsp(ctx); 12302 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12303 break; 12304 case OPC_MULEU_S_QH_OBL: 12305 check_dsp(ctx); 12306 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12307 break; 12308 case OPC_MULEU_S_QH_OBR: 12309 check_dsp(ctx); 12310 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12311 break; 12312 case OPC_MULQ_RS_QH: 12313 check_dsp(ctx); 12314 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12315 break; 12316 } 12317 break; 12318 #endif 12319 } 12320 } 12321 12322 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 12323 int ret, int val) 12324 { 12325 int16_t imm; 12326 TCGv t0; 12327 TCGv val_t; 12328 12329 if (ret == 0) { 12330 /* Treat as NOP. */ 12331 return; 12332 } 12333 12334 t0 = tcg_temp_new(); 12335 val_t = tcg_temp_new(); 12336 gen_load_gpr(val_t, val); 12337 12338 switch (op1) { 12339 case OPC_ABSQ_S_PH_DSP: 12340 switch (op2) { 12341 case OPC_BITREV: 12342 check_dsp(ctx); 12343 gen_helper_bitrev(cpu_gpr[ret], val_t); 12344 break; 12345 case OPC_REPL_QB: 12346 check_dsp(ctx); 12347 { 12348 target_long result; 12349 imm = (ctx->opcode >> 16) & 0xFF; 12350 result = (uint32_t)imm << 24 | 12351 (uint32_t)imm << 16 | 12352 (uint32_t)imm << 8 | 12353 (uint32_t)imm; 12354 result = (int32_t)result; 12355 tcg_gen_movi_tl(cpu_gpr[ret], result); 12356 } 12357 break; 12358 case OPC_REPLV_QB: 12359 check_dsp(ctx); 12360 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 12361 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 12362 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12363 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12364 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12365 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12366 break; 12367 case OPC_REPL_PH: 12368 check_dsp(ctx); 12369 { 12370 imm = (ctx->opcode >> 16) & 0x03FF; 12371 imm = (int16_t)(imm << 6) >> 6; 12372 tcg_gen_movi_tl(cpu_gpr[ret], \ 12373 (target_long)((int32_t)imm << 16 | \ 12374 (uint16_t)imm)); 12375 } 12376 break; 12377 case OPC_REPLV_PH: 12378 check_dsp(ctx); 12379 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 12380 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12381 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12382 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12383 break; 12384 } 12385 break; 12386 #ifdef TARGET_MIPS64 12387 case OPC_ABSQ_S_QH_DSP: 12388 switch (op2) { 12389 case OPC_REPL_OB: 12390 check_dsp(ctx); 12391 { 12392 target_long temp; 12393 12394 imm = (ctx->opcode >> 16) & 0xFF; 12395 temp = ((uint64_t)imm << 8) | (uint64_t)imm; 12396 temp = (temp << 16) | temp; 12397 temp = (temp << 32) | temp; 12398 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12399 break; 12400 } 12401 case OPC_REPL_PW: 12402 check_dsp(ctx); 12403 { 12404 target_long temp; 12405 12406 imm = (ctx->opcode >> 16) & 0x03FF; 12407 imm = (int16_t)(imm << 6) >> 6; 12408 temp = ((target_long)imm << 32) \ 12409 | ((target_long)imm & 0xFFFFFFFF); 12410 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12411 break; 12412 } 12413 case OPC_REPL_QH: 12414 check_dsp(ctx); 12415 { 12416 target_long temp; 12417 12418 imm = (ctx->opcode >> 16) & 0x03FF; 12419 imm = (int16_t)(imm << 6) >> 6; 12420 12421 temp = ((uint64_t)(uint16_t)imm << 48) | 12422 ((uint64_t)(uint16_t)imm << 32) | 12423 ((uint64_t)(uint16_t)imm << 16) | 12424 (uint64_t)(uint16_t)imm; 12425 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12426 break; 12427 } 12428 case OPC_REPLV_OB: 12429 check_dsp(ctx); 12430 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 12431 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 12432 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12433 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12434 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12435 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12436 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12437 break; 12438 case OPC_REPLV_PW: 12439 check_dsp(ctx); 12440 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); 12441 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12442 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12443 break; 12444 case OPC_REPLV_QH: 12445 check_dsp(ctx); 12446 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 12447 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12448 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12449 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12450 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12451 break; 12452 } 12453 break; 12454 #endif 12455 } 12456 } 12457 12458 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, 12459 uint32_t op1, uint32_t op2, 12460 int ret, int v1, int v2, int check_ret) 12461 { 12462 TCGv t1; 12463 TCGv v1_t; 12464 TCGv v2_t; 12465 12466 if ((ret == 0) && (check_ret == 1)) { 12467 /* Treat as NOP. */ 12468 return; 12469 } 12470 12471 t1 = tcg_temp_new(); 12472 v1_t = tcg_temp_new(); 12473 v2_t = tcg_temp_new(); 12474 12475 gen_load_gpr(v1_t, v1); 12476 gen_load_gpr(v2_t, v2); 12477 12478 switch (op1) { 12479 case OPC_CMPU_EQ_QB_DSP: 12480 switch (op2) { 12481 case OPC_CMPU_EQ_QB: 12482 check_dsp(ctx); 12483 gen_helper_cmpu_eq_qb(v1_t, v2_t, tcg_env); 12484 break; 12485 case OPC_CMPU_LT_QB: 12486 check_dsp(ctx); 12487 gen_helper_cmpu_lt_qb(v1_t, v2_t, tcg_env); 12488 break; 12489 case OPC_CMPU_LE_QB: 12490 check_dsp(ctx); 12491 gen_helper_cmpu_le_qb(v1_t, v2_t, tcg_env); 12492 break; 12493 case OPC_CMPGU_EQ_QB: 12494 check_dsp(ctx); 12495 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); 12496 break; 12497 case OPC_CMPGU_LT_QB: 12498 check_dsp(ctx); 12499 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); 12500 break; 12501 case OPC_CMPGU_LE_QB: 12502 check_dsp(ctx); 12503 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); 12504 break; 12505 case OPC_CMPGDU_EQ_QB: 12506 check_dsp_r2(ctx); 12507 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); 12508 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12509 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12510 tcg_gen_shli_tl(t1, t1, 24); 12511 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12512 break; 12513 case OPC_CMPGDU_LT_QB: 12514 check_dsp_r2(ctx); 12515 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); 12516 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12517 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12518 tcg_gen_shli_tl(t1, t1, 24); 12519 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12520 break; 12521 case OPC_CMPGDU_LE_QB: 12522 check_dsp_r2(ctx); 12523 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); 12524 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12525 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12526 tcg_gen_shli_tl(t1, t1, 24); 12527 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12528 break; 12529 case OPC_CMP_EQ_PH: 12530 check_dsp(ctx); 12531 gen_helper_cmp_eq_ph(v1_t, v2_t, tcg_env); 12532 break; 12533 case OPC_CMP_LT_PH: 12534 check_dsp(ctx); 12535 gen_helper_cmp_lt_ph(v1_t, v2_t, tcg_env); 12536 break; 12537 case OPC_CMP_LE_PH: 12538 check_dsp(ctx); 12539 gen_helper_cmp_le_ph(v1_t, v2_t, tcg_env); 12540 break; 12541 case OPC_PICK_QB: 12542 check_dsp(ctx); 12543 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12544 break; 12545 case OPC_PICK_PH: 12546 check_dsp(ctx); 12547 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12548 break; 12549 case OPC_PACKRL_PH: 12550 check_dsp(ctx); 12551 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); 12552 break; 12553 } 12554 break; 12555 #ifdef TARGET_MIPS64 12556 case OPC_CMPU_EQ_OB_DSP: 12557 switch (op2) { 12558 case OPC_CMP_EQ_PW: 12559 check_dsp(ctx); 12560 gen_helper_cmp_eq_pw(v1_t, v2_t, tcg_env); 12561 break; 12562 case OPC_CMP_LT_PW: 12563 check_dsp(ctx); 12564 gen_helper_cmp_lt_pw(v1_t, v2_t, tcg_env); 12565 break; 12566 case OPC_CMP_LE_PW: 12567 check_dsp(ctx); 12568 gen_helper_cmp_le_pw(v1_t, v2_t, tcg_env); 12569 break; 12570 case OPC_CMP_EQ_QH: 12571 check_dsp(ctx); 12572 gen_helper_cmp_eq_qh(v1_t, v2_t, tcg_env); 12573 break; 12574 case OPC_CMP_LT_QH: 12575 check_dsp(ctx); 12576 gen_helper_cmp_lt_qh(v1_t, v2_t, tcg_env); 12577 break; 12578 case OPC_CMP_LE_QH: 12579 check_dsp(ctx); 12580 gen_helper_cmp_le_qh(v1_t, v2_t, tcg_env); 12581 break; 12582 case OPC_CMPGDU_EQ_OB: 12583 check_dsp_r2(ctx); 12584 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12585 break; 12586 case OPC_CMPGDU_LT_OB: 12587 check_dsp_r2(ctx); 12588 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12589 break; 12590 case OPC_CMPGDU_LE_OB: 12591 check_dsp_r2(ctx); 12592 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12593 break; 12594 case OPC_CMPGU_EQ_OB: 12595 check_dsp(ctx); 12596 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); 12597 break; 12598 case OPC_CMPGU_LT_OB: 12599 check_dsp(ctx); 12600 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); 12601 break; 12602 case OPC_CMPGU_LE_OB: 12603 check_dsp(ctx); 12604 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); 12605 break; 12606 case OPC_CMPU_EQ_OB: 12607 check_dsp(ctx); 12608 gen_helper_cmpu_eq_ob(v1_t, v2_t, tcg_env); 12609 break; 12610 case OPC_CMPU_LT_OB: 12611 check_dsp(ctx); 12612 gen_helper_cmpu_lt_ob(v1_t, v2_t, tcg_env); 12613 break; 12614 case OPC_CMPU_LE_OB: 12615 check_dsp(ctx); 12616 gen_helper_cmpu_le_ob(v1_t, v2_t, tcg_env); 12617 break; 12618 case OPC_PACKRL_PW: 12619 check_dsp(ctx); 12620 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); 12621 break; 12622 case OPC_PICK_OB: 12623 check_dsp(ctx); 12624 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12625 break; 12626 case OPC_PICK_PW: 12627 check_dsp(ctx); 12628 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12629 break; 12630 case OPC_PICK_QH: 12631 check_dsp(ctx); 12632 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12633 break; 12634 } 12635 break; 12636 #endif 12637 } 12638 } 12639 12640 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, 12641 uint32_t op1, int rt, int rs, int sa) 12642 { 12643 TCGv t0; 12644 12645 check_dsp_r2(ctx); 12646 12647 if (rt == 0) { 12648 /* Treat as NOP. */ 12649 return; 12650 } 12651 12652 t0 = tcg_temp_new(); 12653 gen_load_gpr(t0, rs); 12654 12655 switch (op1) { 12656 case OPC_APPEND_DSP: 12657 switch (MASK_APPEND(ctx->opcode)) { 12658 case OPC_APPEND: 12659 if (sa != 0) { 12660 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa); 12661 } 12662 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12663 break; 12664 case OPC_PREPEND: 12665 if (sa != 0) { 12666 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); 12667 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 12668 tcg_gen_shli_tl(t0, t0, 32 - sa); 12669 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12670 } 12671 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12672 break; 12673 case OPC_BALIGN: 12674 sa &= 3; 12675 if (sa != 0 && sa != 2) { 12676 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 12677 tcg_gen_ext32u_tl(t0, t0); 12678 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); 12679 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12680 } 12681 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12682 break; 12683 default: /* Invalid */ 12684 MIPS_INVAL("MASK APPEND"); 12685 gen_reserved_instruction(ctx); 12686 break; 12687 } 12688 break; 12689 #ifdef TARGET_MIPS64 12690 case OPC_DAPPEND_DSP: 12691 switch (MASK_DAPPEND(ctx->opcode)) { 12692 case OPC_DAPPEND: 12693 if (sa != 0) { 12694 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa); 12695 } 12696 break; 12697 case OPC_PREPENDD: 12698 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); 12699 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); 12700 tcg_gen_or_tl(cpu_gpr[rt], t0, t0); 12701 break; 12702 case OPC_PREPENDW: 12703 if (sa != 0) { 12704 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 12705 tcg_gen_shli_tl(t0, t0, 64 - sa); 12706 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12707 } 12708 break; 12709 case OPC_DBALIGN: 12710 sa &= 7; 12711 if (sa != 0 && sa != 2 && sa != 4) { 12712 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 12713 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); 12714 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12715 } 12716 break; 12717 default: /* Invalid */ 12718 MIPS_INVAL("MASK DAPPEND"); 12719 gen_reserved_instruction(ctx); 12720 break; 12721 } 12722 break; 12723 #endif 12724 } 12725 } 12726 12727 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 12728 int ret, int v1, int v2, int check_ret) 12729 12730 { 12731 TCGv t0; 12732 TCGv t1; 12733 TCGv v1_t; 12734 int16_t imm; 12735 12736 if ((ret == 0) && (check_ret == 1)) { 12737 /* Treat as NOP. */ 12738 return; 12739 } 12740 12741 t0 = tcg_temp_new(); 12742 t1 = tcg_temp_new(); 12743 v1_t = tcg_temp_new(); 12744 12745 gen_load_gpr(v1_t, v1); 12746 12747 switch (op1) { 12748 case OPC_EXTR_W_DSP: 12749 check_dsp(ctx); 12750 switch (op2) { 12751 case OPC_EXTR_W: 12752 tcg_gen_movi_tl(t0, v2); 12753 tcg_gen_movi_tl(t1, v1); 12754 gen_helper_extr_w(cpu_gpr[ret], t0, t1, tcg_env); 12755 break; 12756 case OPC_EXTR_R_W: 12757 tcg_gen_movi_tl(t0, v2); 12758 tcg_gen_movi_tl(t1, v1); 12759 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, tcg_env); 12760 break; 12761 case OPC_EXTR_RS_W: 12762 tcg_gen_movi_tl(t0, v2); 12763 tcg_gen_movi_tl(t1, v1); 12764 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, tcg_env); 12765 break; 12766 case OPC_EXTR_S_H: 12767 tcg_gen_movi_tl(t0, v2); 12768 tcg_gen_movi_tl(t1, v1); 12769 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, tcg_env); 12770 break; 12771 case OPC_EXTRV_S_H: 12772 tcg_gen_movi_tl(t0, v2); 12773 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env); 12774 break; 12775 case OPC_EXTRV_W: 12776 tcg_gen_movi_tl(t0, v2); 12777 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12778 break; 12779 case OPC_EXTRV_R_W: 12780 tcg_gen_movi_tl(t0, v2); 12781 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12782 break; 12783 case OPC_EXTRV_RS_W: 12784 tcg_gen_movi_tl(t0, v2); 12785 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12786 break; 12787 case OPC_EXTP: 12788 tcg_gen_movi_tl(t0, v2); 12789 tcg_gen_movi_tl(t1, v1); 12790 gen_helper_extp(cpu_gpr[ret], t0, t1, tcg_env); 12791 break; 12792 case OPC_EXTPV: 12793 tcg_gen_movi_tl(t0, v2); 12794 gen_helper_extp(cpu_gpr[ret], t0, v1_t, tcg_env); 12795 break; 12796 case OPC_EXTPDP: 12797 tcg_gen_movi_tl(t0, v2); 12798 tcg_gen_movi_tl(t1, v1); 12799 gen_helper_extpdp(cpu_gpr[ret], t0, t1, tcg_env); 12800 break; 12801 case OPC_EXTPDPV: 12802 tcg_gen_movi_tl(t0, v2); 12803 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, tcg_env); 12804 break; 12805 case OPC_SHILO: 12806 imm = (ctx->opcode >> 20) & 0x3F; 12807 tcg_gen_movi_tl(t0, ret); 12808 tcg_gen_movi_tl(t1, imm); 12809 gen_helper_shilo(t0, t1, tcg_env); 12810 break; 12811 case OPC_SHILOV: 12812 tcg_gen_movi_tl(t0, ret); 12813 gen_helper_shilo(t0, v1_t, tcg_env); 12814 break; 12815 case OPC_MTHLIP: 12816 tcg_gen_movi_tl(t0, ret); 12817 gen_helper_mthlip(t0, v1_t, tcg_env); 12818 break; 12819 case OPC_WRDSP: 12820 imm = (ctx->opcode >> 11) & 0x3FF; 12821 tcg_gen_movi_tl(t0, imm); 12822 gen_helper_wrdsp(v1_t, t0, tcg_env); 12823 break; 12824 case OPC_RDDSP: 12825 imm = (ctx->opcode >> 16) & 0x03FF; 12826 tcg_gen_movi_tl(t0, imm); 12827 gen_helper_rddsp(cpu_gpr[ret], t0, tcg_env); 12828 break; 12829 } 12830 break; 12831 #ifdef TARGET_MIPS64 12832 case OPC_DEXTR_W_DSP: 12833 check_dsp(ctx); 12834 switch (op2) { 12835 case OPC_DMTHLIP: 12836 tcg_gen_movi_tl(t0, ret); 12837 gen_helper_dmthlip(v1_t, t0, tcg_env); 12838 break; 12839 case OPC_DSHILO: 12840 { 12841 int shift = (ctx->opcode >> 19) & 0x7F; 12842 int ac = (ctx->opcode >> 11) & 0x03; 12843 tcg_gen_movi_tl(t0, shift); 12844 tcg_gen_movi_tl(t1, ac); 12845 gen_helper_dshilo(t0, t1, tcg_env); 12846 break; 12847 } 12848 case OPC_DSHILOV: 12849 { 12850 int ac = (ctx->opcode >> 11) & 0x03; 12851 tcg_gen_movi_tl(t0, ac); 12852 gen_helper_dshilo(v1_t, t0, tcg_env); 12853 break; 12854 } 12855 case OPC_DEXTP: 12856 tcg_gen_movi_tl(t0, v2); 12857 tcg_gen_movi_tl(t1, v1); 12858 12859 gen_helper_dextp(cpu_gpr[ret], t0, t1, tcg_env); 12860 break; 12861 case OPC_DEXTPV: 12862 tcg_gen_movi_tl(t0, v2); 12863 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, tcg_env); 12864 break; 12865 case OPC_DEXTPDP: 12866 tcg_gen_movi_tl(t0, v2); 12867 tcg_gen_movi_tl(t1, v1); 12868 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, tcg_env); 12869 break; 12870 case OPC_DEXTPDPV: 12871 tcg_gen_movi_tl(t0, v2); 12872 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, tcg_env); 12873 break; 12874 case OPC_DEXTR_L: 12875 tcg_gen_movi_tl(t0, v2); 12876 tcg_gen_movi_tl(t1, v1); 12877 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, tcg_env); 12878 break; 12879 case OPC_DEXTR_R_L: 12880 tcg_gen_movi_tl(t0, v2); 12881 tcg_gen_movi_tl(t1, v1); 12882 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, tcg_env); 12883 break; 12884 case OPC_DEXTR_RS_L: 12885 tcg_gen_movi_tl(t0, v2); 12886 tcg_gen_movi_tl(t1, v1); 12887 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, tcg_env); 12888 break; 12889 case OPC_DEXTR_W: 12890 tcg_gen_movi_tl(t0, v2); 12891 tcg_gen_movi_tl(t1, v1); 12892 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, tcg_env); 12893 break; 12894 case OPC_DEXTR_R_W: 12895 tcg_gen_movi_tl(t0, v2); 12896 tcg_gen_movi_tl(t1, v1); 12897 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, tcg_env); 12898 break; 12899 case OPC_DEXTR_RS_W: 12900 tcg_gen_movi_tl(t0, v2); 12901 tcg_gen_movi_tl(t1, v1); 12902 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, tcg_env); 12903 break; 12904 case OPC_DEXTR_S_H: 12905 tcg_gen_movi_tl(t0, v2); 12906 tcg_gen_movi_tl(t1, v1); 12907 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, tcg_env); 12908 break; 12909 case OPC_DEXTRV_S_H: 12910 tcg_gen_movi_tl(t0, v2); 12911 gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env); 12912 break; 12913 case OPC_DEXTRV_L: 12914 tcg_gen_movi_tl(t0, v2); 12915 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, tcg_env); 12916 break; 12917 case OPC_DEXTRV_R_L: 12918 tcg_gen_movi_tl(t0, v2); 12919 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, tcg_env); 12920 break; 12921 case OPC_DEXTRV_RS_L: 12922 tcg_gen_movi_tl(t0, v2); 12923 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, tcg_env); 12924 break; 12925 case OPC_DEXTRV_W: 12926 tcg_gen_movi_tl(t0, v2); 12927 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12928 break; 12929 case OPC_DEXTRV_R_W: 12930 tcg_gen_movi_tl(t0, v2); 12931 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12932 break; 12933 case OPC_DEXTRV_RS_W: 12934 tcg_gen_movi_tl(t0, v2); 12935 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12936 break; 12937 } 12938 break; 12939 #endif 12940 } 12941 } 12942 12943 /* End MIPSDSP functions. */ 12944 12945 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) 12946 { 12947 int rs, rt, rd, sa; 12948 uint32_t op1, op2; 12949 12950 rs = (ctx->opcode >> 21) & 0x1f; 12951 rt = (ctx->opcode >> 16) & 0x1f; 12952 rd = (ctx->opcode >> 11) & 0x1f; 12953 sa = (ctx->opcode >> 6) & 0x1f; 12954 12955 op1 = MASK_SPECIAL(ctx->opcode); 12956 switch (op1) { 12957 case OPC_MULT: 12958 case OPC_MULTU: 12959 case OPC_DIV: 12960 case OPC_DIVU: 12961 op2 = MASK_R6_MULDIV(ctx->opcode); 12962 switch (op2) { 12963 case R6_OPC_MUL: 12964 case R6_OPC_MUH: 12965 case R6_OPC_MULU: 12966 case R6_OPC_MUHU: 12967 case R6_OPC_DIV: 12968 case R6_OPC_MOD: 12969 case R6_OPC_DIVU: 12970 case R6_OPC_MODU: 12971 gen_r6_muldiv(ctx, op2, rd, rs, rt); 12972 break; 12973 default: 12974 MIPS_INVAL("special_r6 muldiv"); 12975 gen_reserved_instruction(ctx); 12976 break; 12977 } 12978 break; 12979 case OPC_SELEQZ: 12980 case OPC_SELNEZ: 12981 gen_cond_move(ctx, op1, rd, rs, rt); 12982 break; 12983 case R6_OPC_CLO: 12984 case R6_OPC_CLZ: 12985 if (rt == 0 && sa == 1) { 12986 /* 12987 * Major opcode and function field is shared with preR6 MFHI/MTHI. 12988 * We need additionally to check other fields. 12989 */ 12990 gen_cl(ctx, op1, rd, rs); 12991 } else { 12992 gen_reserved_instruction(ctx); 12993 } 12994 break; 12995 case R6_OPC_SDBBP: 12996 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 12997 ctx->base.is_jmp = DISAS_SEMIHOST; 12998 } else { 12999 if (ctx->hflags & MIPS_HFLAG_SBRI) { 13000 gen_reserved_instruction(ctx); 13001 } else { 13002 generate_exception_end(ctx, EXCP_DBp); 13003 } 13004 } 13005 break; 13006 #if defined(TARGET_MIPS64) 13007 case R6_OPC_DCLO: 13008 case R6_OPC_DCLZ: 13009 if (rt == 0 && sa == 1) { 13010 /* 13011 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13012 * We need additionally to check other fields. 13013 */ 13014 check_mips_64(ctx); 13015 gen_cl(ctx, op1, rd, rs); 13016 } else { 13017 gen_reserved_instruction(ctx); 13018 } 13019 break; 13020 case OPC_DMULT: 13021 case OPC_DMULTU: 13022 case OPC_DDIV: 13023 case OPC_DDIVU: 13024 13025 op2 = MASK_R6_MULDIV(ctx->opcode); 13026 switch (op2) { 13027 case R6_OPC_DMUL: 13028 case R6_OPC_DMUH: 13029 case R6_OPC_DMULU: 13030 case R6_OPC_DMUHU: 13031 case R6_OPC_DDIV: 13032 case R6_OPC_DMOD: 13033 case R6_OPC_DDIVU: 13034 case R6_OPC_DMODU: 13035 check_mips_64(ctx); 13036 gen_r6_muldiv(ctx, op2, rd, rs, rt); 13037 break; 13038 default: 13039 MIPS_INVAL("special_r6 muldiv"); 13040 gen_reserved_instruction(ctx); 13041 break; 13042 } 13043 break; 13044 #endif 13045 default: /* Invalid */ 13046 MIPS_INVAL("special_r6"); 13047 gen_reserved_instruction(ctx); 13048 break; 13049 } 13050 } 13051 13052 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) 13053 { 13054 int rs = extract32(ctx->opcode, 21, 5); 13055 int rt = extract32(ctx->opcode, 16, 5); 13056 int rd = extract32(ctx->opcode, 11, 5); 13057 uint32_t op1 = MASK_SPECIAL(ctx->opcode); 13058 13059 switch (op1) { 13060 case OPC_MOVN: /* Conditional move */ 13061 case OPC_MOVZ: 13062 gen_cond_move(ctx, op1, rd, rs, rt); 13063 break; 13064 case OPC_MFHI: /* Move from HI/LO */ 13065 case OPC_MFLO: 13066 gen_HILO(ctx, op1, 0, rd); 13067 break; 13068 case OPC_MTHI: 13069 case OPC_MTLO: /* Move to HI/LO */ 13070 gen_HILO(ctx, op1, 0, rs); 13071 break; 13072 case OPC_MULT: 13073 case OPC_MULTU: 13074 gen_mul_txx9(ctx, op1, rd, rs, rt); 13075 break; 13076 case OPC_DIV: 13077 case OPC_DIVU: 13078 gen_muldiv(ctx, op1, 0, rs, rt); 13079 break; 13080 #if defined(TARGET_MIPS64) 13081 case OPC_DMULT: 13082 case OPC_DMULTU: 13083 case OPC_DDIV: 13084 case OPC_DDIVU: 13085 check_insn_opc_user_only(ctx, INSN_R5900); 13086 gen_muldiv(ctx, op1, 0, rs, rt); 13087 break; 13088 #endif 13089 case OPC_JR: 13090 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13091 break; 13092 default: /* Invalid */ 13093 MIPS_INVAL("special_tx79"); 13094 gen_reserved_instruction(ctx); 13095 break; 13096 } 13097 } 13098 13099 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) 13100 { 13101 int rs, rt, rd; 13102 uint32_t op1; 13103 13104 rs = (ctx->opcode >> 21) & 0x1f; 13105 rt = (ctx->opcode >> 16) & 0x1f; 13106 rd = (ctx->opcode >> 11) & 0x1f; 13107 13108 op1 = MASK_SPECIAL(ctx->opcode); 13109 switch (op1) { 13110 case OPC_MOVN: /* Conditional move */ 13111 case OPC_MOVZ: 13112 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | 13113 INSN_LOONGSON2E | INSN_LOONGSON2F); 13114 gen_cond_move(ctx, op1, rd, rs, rt); 13115 break; 13116 case OPC_MFHI: /* Move from HI/LO */ 13117 case OPC_MFLO: 13118 gen_HILO(ctx, op1, rs & 3, rd); 13119 break; 13120 case OPC_MTHI: 13121 case OPC_MTLO: /* Move to HI/LO */ 13122 gen_HILO(ctx, op1, rd & 3, rs); 13123 break; 13124 case OPC_MOVCI: 13125 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 13126 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 13127 check_cp1_enabled(ctx); 13128 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 13129 (ctx->opcode >> 16) & 1); 13130 } else { 13131 generate_exception_err(ctx, EXCP_CpU, 1); 13132 } 13133 break; 13134 case OPC_MULT: 13135 case OPC_MULTU: 13136 gen_muldiv(ctx, op1, rd & 3, rs, rt); 13137 break; 13138 case OPC_DIV: 13139 case OPC_DIVU: 13140 gen_muldiv(ctx, op1, 0, rs, rt); 13141 break; 13142 #if defined(TARGET_MIPS64) 13143 case OPC_DMULT: 13144 case OPC_DMULTU: 13145 case OPC_DDIV: 13146 case OPC_DDIVU: 13147 check_insn(ctx, ISA_MIPS3); 13148 check_mips_64(ctx); 13149 gen_muldiv(ctx, op1, 0, rs, rt); 13150 break; 13151 #endif 13152 case OPC_JR: 13153 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13154 break; 13155 case OPC_SPIM: 13156 #ifdef MIPS_STRICT_STANDARD 13157 MIPS_INVAL("SPIM"); 13158 gen_reserved_instruction(ctx); 13159 #else 13160 /* Implemented as RI exception for now. */ 13161 MIPS_INVAL("spim (unofficial)"); 13162 gen_reserved_instruction(ctx); 13163 #endif 13164 break; 13165 default: /* Invalid */ 13166 MIPS_INVAL("special_legacy"); 13167 gen_reserved_instruction(ctx); 13168 break; 13169 } 13170 } 13171 13172 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) 13173 { 13174 int rs, rt, rd, sa; 13175 uint32_t op1; 13176 13177 rs = (ctx->opcode >> 21) & 0x1f; 13178 rt = (ctx->opcode >> 16) & 0x1f; 13179 rd = (ctx->opcode >> 11) & 0x1f; 13180 sa = (ctx->opcode >> 6) & 0x1f; 13181 13182 op1 = MASK_SPECIAL(ctx->opcode); 13183 switch (op1) { 13184 case OPC_SLL: /* Shift with immediate */ 13185 if (sa == 5 && rd == 0 && 13186 rs == 0 && rt == 0) { /* PAUSE */ 13187 if ((ctx->insn_flags & ISA_MIPS_R6) && 13188 (ctx->hflags & MIPS_HFLAG_BMASK)) { 13189 gen_reserved_instruction(ctx); 13190 break; 13191 } 13192 } 13193 /* Fallthrough */ 13194 case OPC_SRA: 13195 gen_shift_imm(ctx, op1, rd, rt, sa); 13196 break; 13197 case OPC_SRL: 13198 switch ((ctx->opcode >> 21) & 0x1f) { 13199 case 1: 13200 /* rotr is decoded as srl on non-R2 CPUs */ 13201 if (ctx->insn_flags & ISA_MIPS_R2) { 13202 op1 = OPC_ROTR; 13203 } 13204 /* Fallthrough */ 13205 case 0: 13206 gen_shift_imm(ctx, op1, rd, rt, sa); 13207 break; 13208 default: 13209 gen_reserved_instruction(ctx); 13210 break; 13211 } 13212 break; 13213 case OPC_ADD: 13214 case OPC_ADDU: 13215 case OPC_SUB: 13216 case OPC_SUBU: 13217 gen_arith(ctx, op1, rd, rs, rt); 13218 break; 13219 case OPC_SLLV: /* Shifts */ 13220 case OPC_SRAV: 13221 gen_shift(ctx, op1, rd, rs, rt); 13222 break; 13223 case OPC_SRLV: 13224 switch ((ctx->opcode >> 6) & 0x1f) { 13225 case 1: 13226 /* rotrv is decoded as srlv on non-R2 CPUs */ 13227 if (ctx->insn_flags & ISA_MIPS_R2) { 13228 op1 = OPC_ROTRV; 13229 } 13230 /* Fallthrough */ 13231 case 0: 13232 gen_shift(ctx, op1, rd, rs, rt); 13233 break; 13234 default: 13235 gen_reserved_instruction(ctx); 13236 break; 13237 } 13238 break; 13239 case OPC_SLT: /* Set on less than */ 13240 case OPC_SLTU: 13241 gen_slt(ctx, op1, rd, rs, rt); 13242 break; 13243 case OPC_AND: /* Logic*/ 13244 case OPC_OR: 13245 case OPC_NOR: 13246 case OPC_XOR: 13247 gen_logic(ctx, op1, rd, rs, rt); 13248 break; 13249 case OPC_JALR: 13250 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 13251 break; 13252 case OPC_TGE: /* Traps */ 13253 case OPC_TGEU: 13254 case OPC_TLT: 13255 case OPC_TLTU: 13256 case OPC_TEQ: 13257 case OPC_TNE: 13258 check_insn(ctx, ISA_MIPS2); 13259 gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10)); 13260 break; 13261 case OPC_PMON: 13262 /* Pmon entry point, also R4010 selsl */ 13263 #ifdef MIPS_STRICT_STANDARD 13264 MIPS_INVAL("PMON / selsl"); 13265 gen_reserved_instruction(ctx); 13266 #else 13267 gen_helper_pmon(tcg_env, tcg_constant_i32(sa)); 13268 #endif 13269 break; 13270 case OPC_SYSCALL: 13271 generate_exception_end(ctx, EXCP_SYSCALL); 13272 break; 13273 case OPC_BREAK: 13274 generate_exception_break(ctx, extract32(ctx->opcode, 6, 20)); 13275 break; 13276 case OPC_SYNC: 13277 check_insn(ctx, ISA_MIPS2); 13278 gen_sync(extract32(ctx->opcode, 6, 5)); 13279 break; 13280 13281 #if defined(TARGET_MIPS64) 13282 /* MIPS64 specific opcodes */ 13283 case OPC_DSLL: 13284 case OPC_DSRA: 13285 case OPC_DSLL32: 13286 case OPC_DSRA32: 13287 check_insn(ctx, ISA_MIPS3); 13288 check_mips_64(ctx); 13289 gen_shift_imm(ctx, op1, rd, rt, sa); 13290 break; 13291 case OPC_DSRL: 13292 switch ((ctx->opcode >> 21) & 0x1f) { 13293 case 1: 13294 /* drotr is decoded as dsrl on non-R2 CPUs */ 13295 if (ctx->insn_flags & ISA_MIPS_R2) { 13296 op1 = OPC_DROTR; 13297 } 13298 /* Fallthrough */ 13299 case 0: 13300 check_insn(ctx, ISA_MIPS3); 13301 check_mips_64(ctx); 13302 gen_shift_imm(ctx, op1, rd, rt, sa); 13303 break; 13304 default: 13305 gen_reserved_instruction(ctx); 13306 break; 13307 } 13308 break; 13309 case OPC_DSRL32: 13310 switch ((ctx->opcode >> 21) & 0x1f) { 13311 case 1: 13312 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 13313 if (ctx->insn_flags & ISA_MIPS_R2) { 13314 op1 = OPC_DROTR32; 13315 } 13316 /* Fallthrough */ 13317 case 0: 13318 check_insn(ctx, ISA_MIPS3); 13319 check_mips_64(ctx); 13320 gen_shift_imm(ctx, op1, rd, rt, sa); 13321 break; 13322 default: 13323 gen_reserved_instruction(ctx); 13324 break; 13325 } 13326 break; 13327 case OPC_DADD: 13328 case OPC_DADDU: 13329 case OPC_DSUB: 13330 case OPC_DSUBU: 13331 check_insn(ctx, ISA_MIPS3); 13332 check_mips_64(ctx); 13333 gen_arith(ctx, op1, rd, rs, rt); 13334 break; 13335 case OPC_DSLLV: 13336 case OPC_DSRAV: 13337 check_insn(ctx, ISA_MIPS3); 13338 check_mips_64(ctx); 13339 gen_shift(ctx, op1, rd, rs, rt); 13340 break; 13341 case OPC_DSRLV: 13342 switch ((ctx->opcode >> 6) & 0x1f) { 13343 case 1: 13344 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 13345 if (ctx->insn_flags & ISA_MIPS_R2) { 13346 op1 = OPC_DROTRV; 13347 } 13348 /* Fallthrough */ 13349 case 0: 13350 check_insn(ctx, ISA_MIPS3); 13351 check_mips_64(ctx); 13352 gen_shift(ctx, op1, rd, rs, rt); 13353 break; 13354 default: 13355 gen_reserved_instruction(ctx); 13356 break; 13357 } 13358 break; 13359 #endif 13360 default: 13361 if (ctx->insn_flags & ISA_MIPS_R6) { 13362 decode_opc_special_r6(env, ctx); 13363 } else if (ctx->insn_flags & INSN_R5900) { 13364 decode_opc_special_tx79(env, ctx); 13365 } else { 13366 decode_opc_special_legacy(env, ctx); 13367 } 13368 } 13369 } 13370 13371 13372 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) 13373 { 13374 int rs, rt, rd; 13375 uint32_t op1; 13376 13377 rs = (ctx->opcode >> 21) & 0x1f; 13378 rt = (ctx->opcode >> 16) & 0x1f; 13379 rd = (ctx->opcode >> 11) & 0x1f; 13380 13381 op1 = MASK_SPECIAL2(ctx->opcode); 13382 switch (op1) { 13383 case OPC_MADD: /* Multiply and add/sub */ 13384 case OPC_MADDU: 13385 case OPC_MSUB: 13386 case OPC_MSUBU: 13387 check_insn(ctx, ISA_MIPS_R1); 13388 gen_muldiv(ctx, op1, rd & 3, rs, rt); 13389 break; 13390 case OPC_MUL: 13391 gen_arith(ctx, op1, rd, rs, rt); 13392 break; 13393 case OPC_CLO: 13394 case OPC_CLZ: 13395 check_insn(ctx, ISA_MIPS_R1); 13396 gen_cl(ctx, op1, rd, rs); 13397 break; 13398 case OPC_SDBBP: 13399 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 13400 ctx->base.is_jmp = DISAS_SEMIHOST; 13401 } else { 13402 /* 13403 * XXX: not clear which exception should be raised 13404 * when in debug mode... 13405 */ 13406 check_insn(ctx, ISA_MIPS_R1); 13407 generate_exception_end(ctx, EXCP_DBp); 13408 } 13409 break; 13410 #if defined(TARGET_MIPS64) 13411 case OPC_DCLO: 13412 case OPC_DCLZ: 13413 check_insn(ctx, ISA_MIPS_R1); 13414 check_mips_64(ctx); 13415 gen_cl(ctx, op1, rd, rs); 13416 break; 13417 #endif 13418 default: /* Invalid */ 13419 MIPS_INVAL("special2_legacy"); 13420 gen_reserved_instruction(ctx); 13421 break; 13422 } 13423 } 13424 13425 void gen_crc32(DisasContext *ctx, int rd, int rs, int rt, int sz, 13426 int crc32c) 13427 { 13428 TCGv t0; 13429 TCGv t1; 13430 TCGv_i32 tsz = tcg_constant_i32(1 << sz); 13431 if (rd == 0) { 13432 /* Treat as NOP. */ 13433 return; 13434 } 13435 t0 = tcg_temp_new(); 13436 t1 = tcg_temp_new(); 13437 13438 gen_load_gpr(t0, rt); 13439 gen_load_gpr(t1, rs); 13440 13441 if (crc32c) { 13442 gen_helper_crc32c(cpu_gpr[rd], t0, t1, tsz); 13443 } else { 13444 gen_helper_crc32(cpu_gpr[rd], t0, t1, tsz); 13445 } 13446 } 13447 13448 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) 13449 { 13450 int rs, rt, rd, sa; 13451 uint32_t op1, op2; 13452 int16_t imm; 13453 13454 rs = (ctx->opcode >> 21) & 0x1f; 13455 rt = (ctx->opcode >> 16) & 0x1f; 13456 rd = (ctx->opcode >> 11) & 0x1f; 13457 sa = (ctx->opcode >> 6) & 0x1f; 13458 imm = (int16_t)ctx->opcode >> 7; 13459 13460 op1 = MASK_SPECIAL3(ctx->opcode); 13461 switch (op1) { 13462 case R6_OPC_PREF: 13463 if (rt >= 24) { 13464 /* hint codes 24-31 are reserved and signal RI */ 13465 gen_reserved_instruction(ctx); 13466 } 13467 /* Treat as NOP. */ 13468 break; 13469 case R6_OPC_CACHE: 13470 check_cp0_enabled(ctx); 13471 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 13472 gen_cache_operation(ctx, rt, rs, imm); 13473 } 13474 break; 13475 case R6_OPC_SC: 13476 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false); 13477 break; 13478 case R6_OPC_LL: 13479 gen_ld(ctx, op1, rt, rs, imm); 13480 break; 13481 case OPC_BSHFL: 13482 { 13483 if (rd == 0) { 13484 /* Treat as NOP. */ 13485 break; 13486 } 13487 op2 = MASK_BSHFL(ctx->opcode); 13488 switch (op2) { 13489 case OPC_ALIGN: 13490 case OPC_ALIGN_1: 13491 case OPC_ALIGN_2: 13492 case OPC_ALIGN_3: 13493 gen_align(ctx, 32, rd, rs, rt, sa & 3); 13494 break; 13495 case OPC_BITSWAP: 13496 gen_bitswap(ctx, op2, rd, rt); 13497 break; 13498 } 13499 } 13500 break; 13501 #ifndef CONFIG_USER_ONLY 13502 case OPC_GINV: 13503 if (unlikely(ctx->gi <= 1)) { 13504 gen_reserved_instruction(ctx); 13505 } 13506 check_cp0_enabled(ctx); 13507 switch ((ctx->opcode >> 6) & 3) { 13508 case 0: /* GINVI */ 13509 /* Treat as NOP. */ 13510 break; 13511 case 2: /* GINVT */ 13512 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); 13513 break; 13514 default: 13515 gen_reserved_instruction(ctx); 13516 break; 13517 } 13518 break; 13519 #endif 13520 #if defined(TARGET_MIPS64) 13521 case R6_OPC_SCD: 13522 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false); 13523 break; 13524 case R6_OPC_LLD: 13525 gen_ld(ctx, op1, rt, rs, imm); 13526 break; 13527 case OPC_DBSHFL: 13528 check_mips_64(ctx); 13529 { 13530 if (rd == 0) { 13531 /* Treat as NOP. */ 13532 break; 13533 } 13534 op2 = MASK_DBSHFL(ctx->opcode); 13535 switch (op2) { 13536 case OPC_DALIGN: 13537 case OPC_DALIGN_1: 13538 case OPC_DALIGN_2: 13539 case OPC_DALIGN_3: 13540 case OPC_DALIGN_4: 13541 case OPC_DALIGN_5: 13542 case OPC_DALIGN_6: 13543 case OPC_DALIGN_7: 13544 gen_align(ctx, 64, rd, rs, rt, sa & 7); 13545 break; 13546 case OPC_DBITSWAP: 13547 gen_bitswap(ctx, op2, rd, rt); 13548 break; 13549 } 13550 13551 } 13552 break; 13553 #endif 13554 default: /* Invalid */ 13555 MIPS_INVAL("special3_r6"); 13556 gen_reserved_instruction(ctx); 13557 break; 13558 } 13559 } 13560 13561 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) 13562 { 13563 int rs, rt, rd; 13564 uint32_t op1, op2; 13565 13566 rs = (ctx->opcode >> 21) & 0x1f; 13567 rt = (ctx->opcode >> 16) & 0x1f; 13568 rd = (ctx->opcode >> 11) & 0x1f; 13569 13570 op1 = MASK_SPECIAL3(ctx->opcode); 13571 switch (op1) { 13572 case OPC_MUL_PH_DSP: 13573 /* 13574 * OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 13575 * the same mask and op1. 13576 */ 13577 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MUL_PH_DSP)) { 13578 op2 = MASK_ADDUH_QB(ctx->opcode); 13579 switch (op2) { 13580 case OPC_ADDUH_QB: 13581 case OPC_ADDUH_R_QB: 13582 case OPC_ADDQH_PH: 13583 case OPC_ADDQH_R_PH: 13584 case OPC_ADDQH_W: 13585 case OPC_ADDQH_R_W: 13586 case OPC_SUBUH_QB: 13587 case OPC_SUBUH_R_QB: 13588 case OPC_SUBQH_PH: 13589 case OPC_SUBQH_R_PH: 13590 case OPC_SUBQH_W: 13591 case OPC_SUBQH_R_W: 13592 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13593 break; 13594 case OPC_MUL_PH: 13595 case OPC_MUL_S_PH: 13596 case OPC_MULQ_S_W: 13597 case OPC_MULQ_RS_W: 13598 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13599 break; 13600 default: 13601 MIPS_INVAL("MASK ADDUH.QB"); 13602 gen_reserved_instruction(ctx); 13603 break; 13604 } 13605 } else { 13606 gen_reserved_instruction(ctx); 13607 } 13608 break; 13609 case OPC_LX_DSP: 13610 check_dsp(ctx); 13611 op2 = MASK_LX(ctx->opcode); 13612 switch (op2) { 13613 #if defined(TARGET_MIPS64) 13614 case OPC_LDX: 13615 gen_lx(ctx, rd, rs, rt, MO_UQ); 13616 break; 13617 #endif 13618 case OPC_LBUX: 13619 gen_lx(ctx, rd, rs, rt, MO_UB); 13620 break; 13621 case OPC_LHX: 13622 gen_lx(ctx, rd, rs, rt, MO_SW); 13623 break; 13624 case OPC_LWX: 13625 gen_lx(ctx, rd, rs, rt, MO_SL); 13626 break; 13627 default: /* Invalid */ 13628 MIPS_INVAL("MASK LX"); 13629 gen_reserved_instruction(ctx); 13630 break; 13631 } 13632 break; 13633 case OPC_ABSQ_S_PH_DSP: 13634 op2 = MASK_ABSQ_S_PH(ctx->opcode); 13635 switch (op2) { 13636 case OPC_ABSQ_S_QB: 13637 case OPC_ABSQ_S_PH: 13638 case OPC_ABSQ_S_W: 13639 case OPC_PRECEQ_W_PHL: 13640 case OPC_PRECEQ_W_PHR: 13641 case OPC_PRECEQU_PH_QBL: 13642 case OPC_PRECEQU_PH_QBR: 13643 case OPC_PRECEQU_PH_QBLA: 13644 case OPC_PRECEQU_PH_QBRA: 13645 case OPC_PRECEU_PH_QBL: 13646 case OPC_PRECEU_PH_QBR: 13647 case OPC_PRECEU_PH_QBLA: 13648 case OPC_PRECEU_PH_QBRA: 13649 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13650 break; 13651 case OPC_BITREV: 13652 case OPC_REPL_QB: 13653 case OPC_REPLV_QB: 13654 case OPC_REPL_PH: 13655 case OPC_REPLV_PH: 13656 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 13657 break; 13658 default: 13659 MIPS_INVAL("MASK ABSQ_S.PH"); 13660 gen_reserved_instruction(ctx); 13661 break; 13662 } 13663 break; 13664 case OPC_ADDU_QB_DSP: 13665 op2 = MASK_ADDU_QB(ctx->opcode); 13666 switch (op2) { 13667 case OPC_ADDQ_PH: 13668 case OPC_ADDQ_S_PH: 13669 case OPC_ADDQ_S_W: 13670 case OPC_ADDU_QB: 13671 case OPC_ADDU_S_QB: 13672 case OPC_ADDU_PH: 13673 case OPC_ADDU_S_PH: 13674 case OPC_SUBQ_PH: 13675 case OPC_SUBQ_S_PH: 13676 case OPC_SUBQ_S_W: 13677 case OPC_SUBU_QB: 13678 case OPC_SUBU_S_QB: 13679 case OPC_SUBU_PH: 13680 case OPC_SUBU_S_PH: 13681 case OPC_ADDSC: 13682 case OPC_ADDWC: 13683 case OPC_MODSUB: 13684 case OPC_RADDU_W_QB: 13685 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13686 break; 13687 case OPC_MULEU_S_PH_QBL: 13688 case OPC_MULEU_S_PH_QBR: 13689 case OPC_MULQ_RS_PH: 13690 case OPC_MULEQ_S_W_PHL: 13691 case OPC_MULEQ_S_W_PHR: 13692 case OPC_MULQ_S_PH: 13693 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13694 break; 13695 default: /* Invalid */ 13696 MIPS_INVAL("MASK ADDU.QB"); 13697 gen_reserved_instruction(ctx); 13698 break; 13699 13700 } 13701 break; 13702 case OPC_CMPU_EQ_QB_DSP: 13703 op2 = MASK_CMPU_EQ_QB(ctx->opcode); 13704 switch (op2) { 13705 case OPC_PRECR_SRA_PH_W: 13706 case OPC_PRECR_SRA_R_PH_W: 13707 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 13708 break; 13709 case OPC_PRECR_QB_PH: 13710 case OPC_PRECRQ_QB_PH: 13711 case OPC_PRECRQ_PH_W: 13712 case OPC_PRECRQ_RS_PH_W: 13713 case OPC_PRECRQU_S_QB_PH: 13714 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13715 break; 13716 case OPC_CMPU_EQ_QB: 13717 case OPC_CMPU_LT_QB: 13718 case OPC_CMPU_LE_QB: 13719 case OPC_CMP_EQ_PH: 13720 case OPC_CMP_LT_PH: 13721 case OPC_CMP_LE_PH: 13722 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 13723 break; 13724 case OPC_CMPGU_EQ_QB: 13725 case OPC_CMPGU_LT_QB: 13726 case OPC_CMPGU_LE_QB: 13727 case OPC_CMPGDU_EQ_QB: 13728 case OPC_CMPGDU_LT_QB: 13729 case OPC_CMPGDU_LE_QB: 13730 case OPC_PICK_QB: 13731 case OPC_PICK_PH: 13732 case OPC_PACKRL_PH: 13733 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 13734 break; 13735 default: /* Invalid */ 13736 MIPS_INVAL("MASK CMPU.EQ.QB"); 13737 gen_reserved_instruction(ctx); 13738 break; 13739 } 13740 break; 13741 case OPC_SHLL_QB_DSP: 13742 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 13743 break; 13744 case OPC_DPA_W_PH_DSP: 13745 op2 = MASK_DPA_W_PH(ctx->opcode); 13746 switch (op2) { 13747 case OPC_DPAU_H_QBL: 13748 case OPC_DPAU_H_QBR: 13749 case OPC_DPSU_H_QBL: 13750 case OPC_DPSU_H_QBR: 13751 case OPC_DPA_W_PH: 13752 case OPC_DPAX_W_PH: 13753 case OPC_DPAQ_S_W_PH: 13754 case OPC_DPAQX_S_W_PH: 13755 case OPC_DPAQX_SA_W_PH: 13756 case OPC_DPS_W_PH: 13757 case OPC_DPSX_W_PH: 13758 case OPC_DPSQ_S_W_PH: 13759 case OPC_DPSQX_S_W_PH: 13760 case OPC_DPSQX_SA_W_PH: 13761 case OPC_MULSAQ_S_W_PH: 13762 case OPC_DPAQ_SA_L_W: 13763 case OPC_DPSQ_SA_L_W: 13764 case OPC_MAQ_S_W_PHL: 13765 case OPC_MAQ_S_W_PHR: 13766 case OPC_MAQ_SA_W_PHL: 13767 case OPC_MAQ_SA_W_PHR: 13768 case OPC_MULSA_W_PH: 13769 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 13770 break; 13771 default: /* Invalid */ 13772 MIPS_INVAL("MASK DPAW.PH"); 13773 gen_reserved_instruction(ctx); 13774 break; 13775 } 13776 break; 13777 case OPC_INSV_DSP: 13778 op2 = MASK_INSV(ctx->opcode); 13779 switch (op2) { 13780 case OPC_INSV: 13781 check_dsp(ctx); 13782 { 13783 TCGv t0, t1; 13784 13785 if (rt == 0) { 13786 break; 13787 } 13788 13789 t0 = tcg_temp_new(); 13790 t1 = tcg_temp_new(); 13791 13792 gen_load_gpr(t0, rt); 13793 gen_load_gpr(t1, rs); 13794 13795 gen_helper_insv(cpu_gpr[rt], tcg_env, t1, t0); 13796 break; 13797 } 13798 default: /* Invalid */ 13799 MIPS_INVAL("MASK INSV"); 13800 gen_reserved_instruction(ctx); 13801 break; 13802 } 13803 break; 13804 case OPC_APPEND_DSP: 13805 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 13806 break; 13807 case OPC_EXTR_W_DSP: 13808 op2 = MASK_EXTR_W(ctx->opcode); 13809 switch (op2) { 13810 case OPC_EXTR_W: 13811 case OPC_EXTR_R_W: 13812 case OPC_EXTR_RS_W: 13813 case OPC_EXTR_S_H: 13814 case OPC_EXTRV_S_H: 13815 case OPC_EXTRV_W: 13816 case OPC_EXTRV_R_W: 13817 case OPC_EXTRV_RS_W: 13818 case OPC_EXTP: 13819 case OPC_EXTPV: 13820 case OPC_EXTPDP: 13821 case OPC_EXTPDPV: 13822 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 13823 break; 13824 case OPC_RDDSP: 13825 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1); 13826 break; 13827 case OPC_SHILO: 13828 case OPC_SHILOV: 13829 case OPC_MTHLIP: 13830 case OPC_WRDSP: 13831 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 13832 break; 13833 default: /* Invalid */ 13834 MIPS_INVAL("MASK EXTR.W"); 13835 gen_reserved_instruction(ctx); 13836 break; 13837 } 13838 break; 13839 #if defined(TARGET_MIPS64) 13840 case OPC_ABSQ_S_QH_DSP: 13841 op2 = MASK_ABSQ_S_QH(ctx->opcode); 13842 switch (op2) { 13843 case OPC_PRECEQ_L_PWL: 13844 case OPC_PRECEQ_L_PWR: 13845 case OPC_PRECEQ_PW_QHL: 13846 case OPC_PRECEQ_PW_QHR: 13847 case OPC_PRECEQ_PW_QHLA: 13848 case OPC_PRECEQ_PW_QHRA: 13849 case OPC_PRECEQU_QH_OBL: 13850 case OPC_PRECEQU_QH_OBR: 13851 case OPC_PRECEQU_QH_OBLA: 13852 case OPC_PRECEQU_QH_OBRA: 13853 case OPC_PRECEU_QH_OBL: 13854 case OPC_PRECEU_QH_OBR: 13855 case OPC_PRECEU_QH_OBLA: 13856 case OPC_PRECEU_QH_OBRA: 13857 case OPC_ABSQ_S_OB: 13858 case OPC_ABSQ_S_PW: 13859 case OPC_ABSQ_S_QH: 13860 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13861 break; 13862 case OPC_REPL_OB: 13863 case OPC_REPL_PW: 13864 case OPC_REPL_QH: 13865 case OPC_REPLV_OB: 13866 case OPC_REPLV_PW: 13867 case OPC_REPLV_QH: 13868 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 13869 break; 13870 default: /* Invalid */ 13871 MIPS_INVAL("MASK ABSQ_S.QH"); 13872 gen_reserved_instruction(ctx); 13873 break; 13874 } 13875 break; 13876 case OPC_ADDU_OB_DSP: 13877 op2 = MASK_ADDU_OB(ctx->opcode); 13878 switch (op2) { 13879 case OPC_RADDU_L_OB: 13880 case OPC_SUBQ_PW: 13881 case OPC_SUBQ_S_PW: 13882 case OPC_SUBQ_QH: 13883 case OPC_SUBQ_S_QH: 13884 case OPC_SUBU_OB: 13885 case OPC_SUBU_S_OB: 13886 case OPC_SUBU_QH: 13887 case OPC_SUBU_S_QH: 13888 case OPC_SUBUH_OB: 13889 case OPC_SUBUH_R_OB: 13890 case OPC_ADDQ_PW: 13891 case OPC_ADDQ_S_PW: 13892 case OPC_ADDQ_QH: 13893 case OPC_ADDQ_S_QH: 13894 case OPC_ADDU_OB: 13895 case OPC_ADDU_S_OB: 13896 case OPC_ADDU_QH: 13897 case OPC_ADDU_S_QH: 13898 case OPC_ADDUH_OB: 13899 case OPC_ADDUH_R_OB: 13900 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13901 break; 13902 case OPC_MULEQ_S_PW_QHL: 13903 case OPC_MULEQ_S_PW_QHR: 13904 case OPC_MULEU_S_QH_OBL: 13905 case OPC_MULEU_S_QH_OBR: 13906 case OPC_MULQ_RS_QH: 13907 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13908 break; 13909 default: /* Invalid */ 13910 MIPS_INVAL("MASK ADDU.OB"); 13911 gen_reserved_instruction(ctx); 13912 break; 13913 } 13914 break; 13915 case OPC_CMPU_EQ_OB_DSP: 13916 op2 = MASK_CMPU_EQ_OB(ctx->opcode); 13917 switch (op2) { 13918 case OPC_PRECR_SRA_QH_PW: 13919 case OPC_PRECR_SRA_R_QH_PW: 13920 /* Return value is rt. */ 13921 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 13922 break; 13923 case OPC_PRECR_OB_QH: 13924 case OPC_PRECRQ_OB_QH: 13925 case OPC_PRECRQ_PW_L: 13926 case OPC_PRECRQ_QH_PW: 13927 case OPC_PRECRQ_RS_QH_PW: 13928 case OPC_PRECRQU_S_OB_QH: 13929 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13930 break; 13931 case OPC_CMPU_EQ_OB: 13932 case OPC_CMPU_LT_OB: 13933 case OPC_CMPU_LE_OB: 13934 case OPC_CMP_EQ_QH: 13935 case OPC_CMP_LT_QH: 13936 case OPC_CMP_LE_QH: 13937 case OPC_CMP_EQ_PW: 13938 case OPC_CMP_LT_PW: 13939 case OPC_CMP_LE_PW: 13940 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 13941 break; 13942 case OPC_CMPGDU_EQ_OB: 13943 case OPC_CMPGDU_LT_OB: 13944 case OPC_CMPGDU_LE_OB: 13945 case OPC_CMPGU_EQ_OB: 13946 case OPC_CMPGU_LT_OB: 13947 case OPC_CMPGU_LE_OB: 13948 case OPC_PACKRL_PW: 13949 case OPC_PICK_OB: 13950 case OPC_PICK_PW: 13951 case OPC_PICK_QH: 13952 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 13953 break; 13954 default: /* Invalid */ 13955 MIPS_INVAL("MASK CMPU_EQ.OB"); 13956 gen_reserved_instruction(ctx); 13957 break; 13958 } 13959 break; 13960 case OPC_DAPPEND_DSP: 13961 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 13962 break; 13963 case OPC_DEXTR_W_DSP: 13964 op2 = MASK_DEXTR_W(ctx->opcode); 13965 switch (op2) { 13966 case OPC_DEXTP: 13967 case OPC_DEXTPDP: 13968 case OPC_DEXTPDPV: 13969 case OPC_DEXTPV: 13970 case OPC_DEXTR_L: 13971 case OPC_DEXTR_R_L: 13972 case OPC_DEXTR_RS_L: 13973 case OPC_DEXTR_W: 13974 case OPC_DEXTR_R_W: 13975 case OPC_DEXTR_RS_W: 13976 case OPC_DEXTR_S_H: 13977 case OPC_DEXTRV_L: 13978 case OPC_DEXTRV_R_L: 13979 case OPC_DEXTRV_RS_L: 13980 case OPC_DEXTRV_S_H: 13981 case OPC_DEXTRV_W: 13982 case OPC_DEXTRV_R_W: 13983 case OPC_DEXTRV_RS_W: 13984 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 13985 break; 13986 case OPC_DMTHLIP: 13987 case OPC_DSHILO: 13988 case OPC_DSHILOV: 13989 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 13990 break; 13991 default: /* Invalid */ 13992 MIPS_INVAL("MASK EXTR.W"); 13993 gen_reserved_instruction(ctx); 13994 break; 13995 } 13996 break; 13997 case OPC_DPAQ_W_QH_DSP: 13998 op2 = MASK_DPAQ_W_QH(ctx->opcode); 13999 switch (op2) { 14000 case OPC_DPAU_H_OBL: 14001 case OPC_DPAU_H_OBR: 14002 case OPC_DPSU_H_OBL: 14003 case OPC_DPSU_H_OBR: 14004 case OPC_DPA_W_QH: 14005 case OPC_DPAQ_S_W_QH: 14006 case OPC_DPS_W_QH: 14007 case OPC_DPSQ_S_W_QH: 14008 case OPC_MULSAQ_S_W_QH: 14009 case OPC_DPAQ_SA_L_PW: 14010 case OPC_DPSQ_SA_L_PW: 14011 case OPC_MULSAQ_S_L_PW: 14012 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14013 break; 14014 case OPC_MAQ_S_W_QHLL: 14015 case OPC_MAQ_S_W_QHLR: 14016 case OPC_MAQ_S_W_QHRL: 14017 case OPC_MAQ_S_W_QHRR: 14018 case OPC_MAQ_SA_W_QHLL: 14019 case OPC_MAQ_SA_W_QHLR: 14020 case OPC_MAQ_SA_W_QHRL: 14021 case OPC_MAQ_SA_W_QHRR: 14022 case OPC_MAQ_S_L_PWL: 14023 case OPC_MAQ_S_L_PWR: 14024 case OPC_DMADD: 14025 case OPC_DMADDU: 14026 case OPC_DMSUB: 14027 case OPC_DMSUBU: 14028 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14029 break; 14030 default: /* Invalid */ 14031 MIPS_INVAL("MASK DPAQ.W.QH"); 14032 gen_reserved_instruction(ctx); 14033 break; 14034 } 14035 break; 14036 case OPC_DINSV_DSP: 14037 op2 = MASK_INSV(ctx->opcode); 14038 switch (op2) { 14039 case OPC_DINSV: 14040 { 14041 TCGv t0, t1; 14042 14043 check_dsp(ctx); 14044 14045 if (rt == 0) { 14046 break; 14047 } 14048 14049 t0 = tcg_temp_new(); 14050 t1 = tcg_temp_new(); 14051 14052 gen_load_gpr(t0, rt); 14053 gen_load_gpr(t1, rs); 14054 14055 gen_helper_dinsv(cpu_gpr[rt], tcg_env, t1, t0); 14056 break; 14057 } 14058 default: /* Invalid */ 14059 MIPS_INVAL("MASK DINSV"); 14060 gen_reserved_instruction(ctx); 14061 break; 14062 } 14063 break; 14064 case OPC_SHLL_OB_DSP: 14065 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14066 break; 14067 #endif 14068 default: /* Invalid */ 14069 MIPS_INVAL("special3_legacy"); 14070 gen_reserved_instruction(ctx); 14071 break; 14072 } 14073 } 14074 14075 14076 #if defined(TARGET_MIPS64) 14077 14078 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) 14079 { 14080 uint32_t opc = MASK_MMI(ctx->opcode); 14081 int rs = extract32(ctx->opcode, 21, 5); 14082 int rt = extract32(ctx->opcode, 16, 5); 14083 int rd = extract32(ctx->opcode, 11, 5); 14084 14085 switch (opc) { 14086 case MMI_OPC_MULT1: 14087 case MMI_OPC_MULTU1: 14088 case MMI_OPC_MADD: 14089 case MMI_OPC_MADDU: 14090 case MMI_OPC_MADD1: 14091 case MMI_OPC_MADDU1: 14092 gen_mul_txx9(ctx, opc, rd, rs, rt); 14093 break; 14094 case MMI_OPC_DIV1: 14095 case MMI_OPC_DIVU1: 14096 gen_div1_tx79(ctx, opc, rs, rt); 14097 break; 14098 default: 14099 MIPS_INVAL("TX79 MMI class"); 14100 gen_reserved_instruction(ctx); 14101 break; 14102 } 14103 } 14104 14105 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset) 14106 { 14107 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */ 14108 } 14109 14110 /* 14111 * The TX79-specific instruction Store Quadword 14112 * 14113 * +--------+-------+-------+------------------------+ 14114 * | 011111 | base | rt | offset | SQ 14115 * +--------+-------+-------+------------------------+ 14116 * 6 5 5 16 14117 * 14118 * has the same opcode as the Read Hardware Register instruction 14119 * 14120 * +--------+-------+-------+-------+-------+--------+ 14121 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR 14122 * +--------+-------+-------+-------+-------+--------+ 14123 * 6 5 5 5 5 6 14124 * 14125 * that is required, trapped and emulated by the Linux kernel. However, all 14126 * RDHWR encodings yield address error exceptions on the TX79 since the SQ 14127 * offset is odd. Therefore all valid SQ instructions can execute normally. 14128 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish 14129 * between SQ and RDHWR, as the Linux kernel does. 14130 */ 14131 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx) 14132 { 14133 int base = extract32(ctx->opcode, 21, 5); 14134 int rt = extract32(ctx->opcode, 16, 5); 14135 int offset = extract32(ctx->opcode, 0, 16); 14136 14137 #ifdef CONFIG_USER_ONLY 14138 uint32_t op1 = MASK_SPECIAL3(ctx->opcode); 14139 uint32_t op2 = extract32(ctx->opcode, 6, 5); 14140 14141 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) { 14142 int rd = extract32(ctx->opcode, 11, 5); 14143 14144 gen_rdhwr(ctx, rt, rd, 0); 14145 return; 14146 } 14147 #endif 14148 14149 gen_mmi_sq(ctx, base, rt, offset); 14150 } 14151 14152 #endif 14153 14154 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) 14155 { 14156 int rs, rt, rd, sa; 14157 uint32_t op1, op2; 14158 int16_t imm; 14159 14160 rs = (ctx->opcode >> 21) & 0x1f; 14161 rt = (ctx->opcode >> 16) & 0x1f; 14162 rd = (ctx->opcode >> 11) & 0x1f; 14163 sa = (ctx->opcode >> 6) & 0x1f; 14164 imm = sextract32(ctx->opcode, 7, 9); 14165 14166 op1 = MASK_SPECIAL3(ctx->opcode); 14167 14168 /* 14169 * EVA loads and stores overlap Loongson 2E instructions decoded by 14170 * decode_opc_special3_legacy(), so be careful to allow their decoding when 14171 * EVA is absent. 14172 */ 14173 if (ctx->eva) { 14174 switch (op1) { 14175 case OPC_LWLE: 14176 case OPC_LWRE: 14177 case OPC_LBUE: 14178 case OPC_LHUE: 14179 case OPC_LBE: 14180 case OPC_LHE: 14181 case OPC_LLE: 14182 case OPC_LWE: 14183 check_cp0_enabled(ctx); 14184 gen_ld(ctx, op1, rt, rs, imm); 14185 return; 14186 case OPC_SWLE: 14187 case OPC_SWRE: 14188 case OPC_SBE: 14189 case OPC_SHE: 14190 case OPC_SWE: 14191 check_cp0_enabled(ctx); 14192 gen_st(ctx, op1, rt, rs, imm); 14193 return; 14194 case OPC_SCE: 14195 check_cp0_enabled(ctx); 14196 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, true); 14197 return; 14198 case OPC_CACHEE: 14199 check_eva(ctx); 14200 check_cp0_enabled(ctx); 14201 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14202 gen_cache_operation(ctx, rt, rs, imm); 14203 } 14204 return; 14205 case OPC_PREFE: 14206 check_cp0_enabled(ctx); 14207 /* Treat as NOP. */ 14208 return; 14209 } 14210 } 14211 14212 switch (op1) { 14213 case OPC_EXT: 14214 case OPC_INS: 14215 check_insn(ctx, ISA_MIPS_R2); 14216 gen_bitops(ctx, op1, rt, rs, sa, rd); 14217 break; 14218 case OPC_BSHFL: 14219 op2 = MASK_BSHFL(ctx->opcode); 14220 switch (op2) { 14221 case OPC_ALIGN: 14222 case OPC_ALIGN_1: 14223 case OPC_ALIGN_2: 14224 case OPC_ALIGN_3: 14225 case OPC_BITSWAP: 14226 check_insn(ctx, ISA_MIPS_R6); 14227 decode_opc_special3_r6(env, ctx); 14228 break; 14229 default: 14230 check_insn(ctx, ISA_MIPS_R2); 14231 gen_bshfl(ctx, op2, rt, rd); 14232 break; 14233 } 14234 break; 14235 #if defined(TARGET_MIPS64) 14236 case OPC_DEXTM: 14237 case OPC_DEXTU: 14238 case OPC_DEXT: 14239 case OPC_DINSM: 14240 case OPC_DINSU: 14241 case OPC_DINS: 14242 check_insn(ctx, ISA_MIPS_R2); 14243 check_mips_64(ctx); 14244 gen_bitops(ctx, op1, rt, rs, sa, rd); 14245 break; 14246 case OPC_DBSHFL: 14247 op2 = MASK_DBSHFL(ctx->opcode); 14248 switch (op2) { 14249 case OPC_DALIGN: 14250 case OPC_DALIGN_1: 14251 case OPC_DALIGN_2: 14252 case OPC_DALIGN_3: 14253 case OPC_DALIGN_4: 14254 case OPC_DALIGN_5: 14255 case OPC_DALIGN_6: 14256 case OPC_DALIGN_7: 14257 case OPC_DBITSWAP: 14258 check_insn(ctx, ISA_MIPS_R6); 14259 decode_opc_special3_r6(env, ctx); 14260 break; 14261 default: 14262 check_insn(ctx, ISA_MIPS_R2); 14263 check_mips_64(ctx); 14264 op2 = MASK_DBSHFL(ctx->opcode); 14265 gen_bshfl(ctx, op2, rt, rd); 14266 break; 14267 } 14268 break; 14269 #endif 14270 case OPC_RDHWR: 14271 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3)); 14272 break; 14273 case OPC_FORK: 14274 check_mt(ctx); 14275 { 14276 TCGv t0 = tcg_temp_new(); 14277 TCGv t1 = tcg_temp_new(); 14278 14279 gen_load_gpr(t0, rt); 14280 gen_load_gpr(t1, rs); 14281 gen_helper_fork(t0, t1); 14282 } 14283 break; 14284 case OPC_YIELD: 14285 check_mt(ctx); 14286 { 14287 TCGv t0 = tcg_temp_new(); 14288 14289 gen_load_gpr(t0, rs); 14290 gen_helper_yield(t0, tcg_env, t0); 14291 gen_store_gpr(t0, rd); 14292 } 14293 break; 14294 default: 14295 if (ctx->insn_flags & ISA_MIPS_R6) { 14296 decode_opc_special3_r6(env, ctx); 14297 } else { 14298 decode_opc_special3_legacy(env, ctx); 14299 } 14300 } 14301 } 14302 14303 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) 14304 { 14305 int32_t offset; 14306 int rs, rt, rd, sa; 14307 uint32_t op, op1; 14308 int16_t imm; 14309 14310 op = MASK_OP_MAJOR(ctx->opcode); 14311 rs = (ctx->opcode >> 21) & 0x1f; 14312 rt = (ctx->opcode >> 16) & 0x1f; 14313 rd = (ctx->opcode >> 11) & 0x1f; 14314 sa = (ctx->opcode >> 6) & 0x1f; 14315 imm = (int16_t)ctx->opcode; 14316 switch (op) { 14317 case OPC_SPECIAL: 14318 decode_opc_special(env, ctx); 14319 break; 14320 case OPC_SPECIAL2: 14321 #if defined(TARGET_MIPS64) 14322 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { 14323 decode_mmi(env, ctx); 14324 break; 14325 } 14326 #endif 14327 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) { 14328 if (decode_ase_mxu(ctx, ctx->opcode)) { 14329 break; 14330 } 14331 } 14332 decode_opc_special2_legacy(env, ctx); 14333 break; 14334 case OPC_SPECIAL3: 14335 #if defined(TARGET_MIPS64) 14336 if (ctx->insn_flags & INSN_R5900) { 14337 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ 14338 } else { 14339 decode_opc_special3(env, ctx); 14340 } 14341 #else 14342 decode_opc_special3(env, ctx); 14343 #endif 14344 break; 14345 case OPC_REGIMM: 14346 op1 = MASK_REGIMM(ctx->opcode); 14347 switch (op1) { 14348 case OPC_BLTZL: /* REGIMM branches */ 14349 case OPC_BGEZL: 14350 case OPC_BLTZALL: 14351 case OPC_BGEZALL: 14352 check_insn(ctx, ISA_MIPS2); 14353 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14354 /* Fallthrough */ 14355 case OPC_BLTZ: 14356 case OPC_BGEZ: 14357 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 14358 break; 14359 case OPC_BLTZAL: 14360 case OPC_BGEZAL: 14361 if (ctx->insn_flags & ISA_MIPS_R6) { 14362 if (rs == 0) { 14363 /* OPC_NAL, OPC_BAL */ 14364 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); 14365 } else { 14366 gen_reserved_instruction(ctx); 14367 } 14368 } else { 14369 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 14370 } 14371 break; 14372 case OPC_TGEI: /* REGIMM traps */ 14373 case OPC_TGEIU: 14374 case OPC_TLTI: 14375 case OPC_TLTIU: 14376 case OPC_TEQI: 14377 case OPC_TNEI: 14378 check_insn(ctx, ISA_MIPS2); 14379 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14380 gen_trap(ctx, op1, rs, -1, imm, 0); 14381 break; 14382 case OPC_SIGRIE: 14383 check_insn(ctx, ISA_MIPS_R6); 14384 gen_reserved_instruction(ctx); 14385 break; 14386 case OPC_SYNCI: 14387 check_insn(ctx, ISA_MIPS_R2); 14388 /* 14389 * Break the TB to be able to sync copied instructions 14390 * immediately. 14391 */ 14392 ctx->base.is_jmp = DISAS_STOP; 14393 break; 14394 case OPC_BPOSGE32: /* MIPS DSP branch */ 14395 #if defined(TARGET_MIPS64) 14396 case OPC_BPOSGE64: 14397 #endif 14398 check_dsp(ctx); 14399 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); 14400 break; 14401 #if defined(TARGET_MIPS64) 14402 case OPC_DAHI: 14403 check_insn(ctx, ISA_MIPS_R6); 14404 check_mips_64(ctx); 14405 if (rs != 0) { 14406 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); 14407 } 14408 break; 14409 case OPC_DATI: 14410 check_insn(ctx, ISA_MIPS_R6); 14411 check_mips_64(ctx); 14412 if (rs != 0) { 14413 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); 14414 } 14415 break; 14416 #endif 14417 default: /* Invalid */ 14418 MIPS_INVAL("regimm"); 14419 gen_reserved_instruction(ctx); 14420 break; 14421 } 14422 break; 14423 case OPC_CP0: 14424 check_cp0_enabled(ctx); 14425 op1 = MASK_CP0(ctx->opcode); 14426 switch (op1) { 14427 case OPC_MFC0: 14428 case OPC_MTC0: 14429 case OPC_MFTR: 14430 case OPC_MTTR: 14431 case OPC_MFHC0: 14432 case OPC_MTHC0: 14433 #if defined(TARGET_MIPS64) 14434 case OPC_DMFC0: 14435 case OPC_DMTC0: 14436 #endif 14437 #ifndef CONFIG_USER_ONLY 14438 gen_cp0(env, ctx, op1, rt, rd); 14439 #endif /* !CONFIG_USER_ONLY */ 14440 break; 14441 case OPC_C0: 14442 case OPC_C0_1: 14443 case OPC_C0_2: 14444 case OPC_C0_3: 14445 case OPC_C0_4: 14446 case OPC_C0_5: 14447 case OPC_C0_6: 14448 case OPC_C0_7: 14449 case OPC_C0_8: 14450 case OPC_C0_9: 14451 case OPC_C0_A: 14452 case OPC_C0_B: 14453 case OPC_C0_C: 14454 case OPC_C0_D: 14455 case OPC_C0_E: 14456 case OPC_C0_F: 14457 #ifndef CONFIG_USER_ONLY 14458 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 14459 #endif /* !CONFIG_USER_ONLY */ 14460 break; 14461 case OPC_MFMC0: 14462 #ifndef CONFIG_USER_ONLY 14463 { 14464 uint32_t op2; 14465 TCGv t0 = tcg_temp_new(); 14466 14467 op2 = MASK_MFMC0(ctx->opcode); 14468 switch (op2) { 14469 case OPC_DMT: 14470 check_cp0_mt(ctx); 14471 gen_helper_dmt(t0); 14472 gen_store_gpr(t0, rt); 14473 break; 14474 case OPC_EMT: 14475 check_cp0_mt(ctx); 14476 gen_helper_emt(t0); 14477 gen_store_gpr(t0, rt); 14478 break; 14479 case OPC_DVPE: 14480 check_cp0_mt(ctx); 14481 gen_helper_dvpe(t0, tcg_env); 14482 gen_store_gpr(t0, rt); 14483 break; 14484 case OPC_EVPE: 14485 check_cp0_mt(ctx); 14486 gen_helper_evpe(t0, tcg_env); 14487 gen_store_gpr(t0, rt); 14488 break; 14489 case OPC_DVP: 14490 check_insn(ctx, ISA_MIPS_R6); 14491 if (ctx->vp) { 14492 gen_helper_dvp(t0, tcg_env); 14493 gen_store_gpr(t0, rt); 14494 } 14495 break; 14496 case OPC_EVP: 14497 check_insn(ctx, ISA_MIPS_R6); 14498 if (ctx->vp) { 14499 gen_helper_evp(t0, tcg_env); 14500 gen_store_gpr(t0, rt); 14501 } 14502 break; 14503 case OPC_DI: 14504 check_insn(ctx, ISA_MIPS_R2); 14505 save_cpu_state(ctx, 1); 14506 gen_helper_di(t0, tcg_env); 14507 gen_store_gpr(t0, rt); 14508 /* 14509 * Stop translation as we may have switched 14510 * the execution mode. 14511 */ 14512 ctx->base.is_jmp = DISAS_STOP; 14513 break; 14514 case OPC_EI: 14515 check_insn(ctx, ISA_MIPS_R2); 14516 save_cpu_state(ctx, 1); 14517 gen_helper_ei(t0, tcg_env); 14518 gen_store_gpr(t0, rt); 14519 /* 14520 * DISAS_STOP isn't sufficient, we need to ensure we break 14521 * out of translated code to check for pending interrupts. 14522 */ 14523 gen_save_pc(ctx->base.pc_next + 4); 14524 ctx->base.is_jmp = DISAS_EXIT; 14525 break; 14526 default: /* Invalid */ 14527 MIPS_INVAL("mfmc0"); 14528 gen_reserved_instruction(ctx); 14529 break; 14530 } 14531 } 14532 #endif /* !CONFIG_USER_ONLY */ 14533 break; 14534 case OPC_RDPGPR: 14535 check_insn(ctx, ISA_MIPS_R2); 14536 gen_load_srsgpr(rt, rd); 14537 break; 14538 case OPC_WRPGPR: 14539 check_insn(ctx, ISA_MIPS_R2); 14540 gen_store_srsgpr(rt, rd); 14541 break; 14542 default: 14543 MIPS_INVAL("cp0"); 14544 gen_reserved_instruction(ctx); 14545 break; 14546 } 14547 break; 14548 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */ 14549 if (ctx->insn_flags & ISA_MIPS_R6) { 14550 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */ 14551 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14552 } else { 14553 /* OPC_ADDI */ 14554 /* Arithmetic with immediate opcode */ 14555 gen_arith_imm(ctx, op, rt, rs, imm); 14556 } 14557 break; 14558 case OPC_ADDIU: 14559 gen_arith_imm(ctx, op, rt, rs, imm); 14560 break; 14561 case OPC_SLTI: /* Set on less than with immediate opcode */ 14562 case OPC_SLTIU: 14563 gen_slt_imm(ctx, op, rt, rs, imm); 14564 break; 14565 case OPC_ANDI: /* Arithmetic with immediate opcode */ 14566 case OPC_LUI: /* OPC_AUI */ 14567 case OPC_ORI: 14568 case OPC_XORI: 14569 gen_logic_imm(ctx, op, rt, rs, imm); 14570 break; 14571 case OPC_J: /* Jump */ 14572 case OPC_JAL: 14573 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 14574 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 14575 break; 14576 /* Branch */ 14577 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ 14578 if (ctx->insn_flags & ISA_MIPS_R6) { 14579 if (rt == 0) { 14580 gen_reserved_instruction(ctx); 14581 break; 14582 } 14583 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */ 14584 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14585 } else { 14586 /* OPC_BLEZL */ 14587 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14588 } 14589 break; 14590 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ 14591 if (ctx->insn_flags & ISA_MIPS_R6) { 14592 if (rt == 0) { 14593 gen_reserved_instruction(ctx); 14594 break; 14595 } 14596 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */ 14597 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14598 } else { 14599 /* OPC_BGTZL */ 14600 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14601 } 14602 break; 14603 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */ 14604 if (rt == 0) { 14605 /* OPC_BLEZ */ 14606 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14607 } else { 14608 check_insn(ctx, ISA_MIPS_R6); 14609 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */ 14610 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14611 } 14612 break; 14613 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */ 14614 if (rt == 0) { 14615 /* OPC_BGTZ */ 14616 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14617 } else { 14618 check_insn(ctx, ISA_MIPS_R6); 14619 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */ 14620 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14621 } 14622 break; 14623 case OPC_BEQL: 14624 case OPC_BNEL: 14625 check_insn(ctx, ISA_MIPS2); 14626 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14627 /* Fallthrough */ 14628 case OPC_BEQ: 14629 case OPC_BNE: 14630 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14631 break; 14632 case OPC_LL: /* Load and stores */ 14633 check_insn(ctx, ISA_MIPS2); 14634 if (ctx->insn_flags & INSN_R5900) { 14635 check_insn_opc_user_only(ctx, INSN_R5900); 14636 } 14637 /* Fallthrough */ 14638 case OPC_LWL: 14639 case OPC_LWR: 14640 case OPC_LB: 14641 case OPC_LH: 14642 case OPC_LW: 14643 case OPC_LWPC: 14644 case OPC_LBU: 14645 case OPC_LHU: 14646 gen_ld(ctx, op, rt, rs, imm); 14647 break; 14648 case OPC_SWL: 14649 case OPC_SWR: 14650 case OPC_SB: 14651 case OPC_SH: 14652 case OPC_SW: 14653 gen_st(ctx, op, rt, rs, imm); 14654 break; 14655 case OPC_SC: 14656 check_insn(ctx, ISA_MIPS2); 14657 if (ctx->insn_flags & INSN_R5900) { 14658 check_insn_opc_user_only(ctx, INSN_R5900); 14659 } 14660 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false); 14661 break; 14662 case OPC_CACHE: 14663 check_cp0_enabled(ctx); 14664 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 14665 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14666 gen_cache_operation(ctx, rt, rs, imm); 14667 } 14668 /* Treat as NOP. */ 14669 break; 14670 case OPC_PREF: 14671 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900); 14672 /* Treat as NOP. */ 14673 break; 14674 14675 /* Floating point (COP1). */ 14676 case OPC_LWC1: 14677 case OPC_LDC1: 14678 case OPC_SWC1: 14679 case OPC_SDC1: 14680 gen_cop1_ldst(ctx, op, rt, rs, imm); 14681 break; 14682 14683 case OPC_CP1: 14684 op1 = MASK_CP1(ctx->opcode); 14685 14686 switch (op1) { 14687 case OPC_MFHC1: 14688 case OPC_MTHC1: 14689 check_cp1_enabled(ctx); 14690 check_insn(ctx, ISA_MIPS_R2); 14691 /* fall through */ 14692 case OPC_MFC1: 14693 case OPC_CFC1: 14694 case OPC_MTC1: 14695 case OPC_CTC1: 14696 check_cp1_enabled(ctx); 14697 gen_cp1(ctx, op1, rt, rd); 14698 break; 14699 #if defined(TARGET_MIPS64) 14700 case OPC_DMFC1: 14701 case OPC_DMTC1: 14702 check_cp1_enabled(ctx); 14703 check_insn(ctx, ISA_MIPS3); 14704 check_mips_64(ctx); 14705 gen_cp1(ctx, op1, rt, rd); 14706 break; 14707 #endif 14708 case OPC_BC1EQZ: /* OPC_BC1ANY2 */ 14709 check_cp1_enabled(ctx); 14710 if (ctx->insn_flags & ISA_MIPS_R6) { 14711 /* OPC_BC1EQZ */ 14712 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 14713 rt, imm << 2, 4); 14714 } else { 14715 /* OPC_BC1ANY2 */ 14716 check_cop1x(ctx); 14717 if (!ase_3d_available(env)) { 14718 return false; 14719 } 14720 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 14721 (rt >> 2) & 0x7, imm << 2); 14722 } 14723 break; 14724 case OPC_BC1NEZ: 14725 check_cp1_enabled(ctx); 14726 check_insn(ctx, ISA_MIPS_R6); 14727 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 14728 rt, imm << 2, 4); 14729 break; 14730 case OPC_BC1ANY4: 14731 check_cp1_enabled(ctx); 14732 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14733 check_cop1x(ctx); 14734 if (!ase_3d_available(env)) { 14735 return false; 14736 } 14737 /* fall through */ 14738 case OPC_BC1: 14739 check_cp1_enabled(ctx); 14740 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14741 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 14742 (rt >> 2) & 0x7, imm << 2); 14743 break; 14744 case OPC_PS_FMT: 14745 check_ps(ctx); 14746 /* fall through */ 14747 case OPC_S_FMT: 14748 case OPC_D_FMT: 14749 check_cp1_enabled(ctx); 14750 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 14751 (imm >> 8) & 0x7); 14752 break; 14753 case OPC_W_FMT: 14754 case OPC_L_FMT: 14755 { 14756 int r6_op = ctx->opcode & FOP(0x3f, 0x1f); 14757 check_cp1_enabled(ctx); 14758 if (ctx->insn_flags & ISA_MIPS_R6) { 14759 switch (r6_op) { 14760 case R6_OPC_CMP_AF_S: 14761 case R6_OPC_CMP_UN_S: 14762 case R6_OPC_CMP_EQ_S: 14763 case R6_OPC_CMP_UEQ_S: 14764 case R6_OPC_CMP_LT_S: 14765 case R6_OPC_CMP_ULT_S: 14766 case R6_OPC_CMP_LE_S: 14767 case R6_OPC_CMP_ULE_S: 14768 case R6_OPC_CMP_SAF_S: 14769 case R6_OPC_CMP_SUN_S: 14770 case R6_OPC_CMP_SEQ_S: 14771 case R6_OPC_CMP_SEUQ_S: 14772 case R6_OPC_CMP_SLT_S: 14773 case R6_OPC_CMP_SULT_S: 14774 case R6_OPC_CMP_SLE_S: 14775 case R6_OPC_CMP_SULE_S: 14776 case R6_OPC_CMP_OR_S: 14777 case R6_OPC_CMP_UNE_S: 14778 case R6_OPC_CMP_NE_S: 14779 case R6_OPC_CMP_SOR_S: 14780 case R6_OPC_CMP_SUNE_S: 14781 case R6_OPC_CMP_SNE_S: 14782 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa); 14783 break; 14784 case R6_OPC_CMP_AF_D: 14785 case R6_OPC_CMP_UN_D: 14786 case R6_OPC_CMP_EQ_D: 14787 case R6_OPC_CMP_UEQ_D: 14788 case R6_OPC_CMP_LT_D: 14789 case R6_OPC_CMP_ULT_D: 14790 case R6_OPC_CMP_LE_D: 14791 case R6_OPC_CMP_ULE_D: 14792 case R6_OPC_CMP_SAF_D: 14793 case R6_OPC_CMP_SUN_D: 14794 case R6_OPC_CMP_SEQ_D: 14795 case R6_OPC_CMP_SEUQ_D: 14796 case R6_OPC_CMP_SLT_D: 14797 case R6_OPC_CMP_SULT_D: 14798 case R6_OPC_CMP_SLE_D: 14799 case R6_OPC_CMP_SULE_D: 14800 case R6_OPC_CMP_OR_D: 14801 case R6_OPC_CMP_UNE_D: 14802 case R6_OPC_CMP_NE_D: 14803 case R6_OPC_CMP_SOR_D: 14804 case R6_OPC_CMP_SUNE_D: 14805 case R6_OPC_CMP_SNE_D: 14806 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa); 14807 break; 14808 default: 14809 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), 14810 rt, rd, sa, (imm >> 8) & 0x7); 14811 14812 break; 14813 } 14814 } else { 14815 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 14816 (imm >> 8) & 0x7); 14817 } 14818 break; 14819 } 14820 default: 14821 MIPS_INVAL("cp1"); 14822 gen_reserved_instruction(ctx); 14823 break; 14824 } 14825 break; 14826 14827 /* Compact branches [R6] and COP2 [non-R6] */ 14828 case OPC_BC: /* OPC_LWC2 */ 14829 case OPC_BALC: /* OPC_SWC2 */ 14830 if (ctx->insn_flags & ISA_MIPS_R6) { 14831 /* OPC_BC, OPC_BALC */ 14832 gen_compute_compact_branch(ctx, op, 0, 0, 14833 sextract32(ctx->opcode << 2, 0, 28)); 14834 } else if (ctx->insn_flags & ASE_LEXT) { 14835 gen_loongson_lswc2(ctx, rt, rs, rd); 14836 } else { 14837 /* OPC_LWC2, OPC_SWC2 */ 14838 /* COP2: Not implemented. */ 14839 generate_exception_err(ctx, EXCP_CpU, 2); 14840 } 14841 break; 14842 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */ 14843 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */ 14844 if (ctx->insn_flags & ISA_MIPS_R6) { 14845 if (rs != 0) { 14846 /* OPC_BEQZC, OPC_BNEZC */ 14847 gen_compute_compact_branch(ctx, op, rs, 0, 14848 sextract32(ctx->opcode << 2, 0, 23)); 14849 } else { 14850 /* OPC_JIC, OPC_JIALC */ 14851 gen_compute_compact_branch(ctx, op, 0, rt, imm); 14852 } 14853 } else if (ctx->insn_flags & ASE_LEXT) { 14854 gen_loongson_lsdc2(ctx, rt, rs, rd); 14855 } else { 14856 /* OPC_LWC2, OPC_SWC2 */ 14857 /* COP2: Not implemented. */ 14858 generate_exception_err(ctx, EXCP_CpU, 2); 14859 } 14860 break; 14861 case OPC_CP2: 14862 check_insn(ctx, ASE_LMMI); 14863 /* Note that these instructions use different fields. */ 14864 gen_loongson_multimedia(ctx, sa, rd, rt); 14865 break; 14866 14867 case OPC_CP3: 14868 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 14869 check_cp1_enabled(ctx); 14870 op1 = MASK_CP3(ctx->opcode); 14871 switch (op1) { 14872 case OPC_LUXC1: 14873 case OPC_SUXC1: 14874 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 14875 /* Fallthrough */ 14876 case OPC_LWXC1: 14877 case OPC_LDXC1: 14878 case OPC_SWXC1: 14879 case OPC_SDXC1: 14880 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14881 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 14882 break; 14883 case OPC_PREFX: 14884 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14885 /* Treat as NOP. */ 14886 break; 14887 case OPC_ALNV_PS: 14888 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 14889 /* Fallthrough */ 14890 case OPC_MADD_S: 14891 case OPC_MADD_D: 14892 case OPC_MADD_PS: 14893 case OPC_MSUB_S: 14894 case OPC_MSUB_D: 14895 case OPC_MSUB_PS: 14896 case OPC_NMADD_S: 14897 case OPC_NMADD_D: 14898 case OPC_NMADD_PS: 14899 case OPC_NMSUB_S: 14900 case OPC_NMSUB_D: 14901 case OPC_NMSUB_PS: 14902 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14903 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 14904 break; 14905 default: 14906 MIPS_INVAL("cp3"); 14907 gen_reserved_instruction(ctx); 14908 break; 14909 } 14910 } else { 14911 generate_exception_err(ctx, EXCP_CpU, 1); 14912 } 14913 break; 14914 14915 #if defined(TARGET_MIPS64) 14916 /* MIPS64 opcodes */ 14917 case OPC_LLD: 14918 if (ctx->insn_flags & INSN_R5900) { 14919 check_insn_opc_user_only(ctx, INSN_R5900); 14920 } 14921 /* fall through */ 14922 case OPC_LDL: 14923 case OPC_LDR: 14924 case OPC_LWU: 14925 case OPC_LD: 14926 check_insn(ctx, ISA_MIPS3); 14927 check_mips_64(ctx); 14928 gen_ld(ctx, op, rt, rs, imm); 14929 break; 14930 case OPC_SDL: 14931 case OPC_SDR: 14932 case OPC_SD: 14933 check_insn(ctx, ISA_MIPS3); 14934 check_mips_64(ctx); 14935 gen_st(ctx, op, rt, rs, imm); 14936 break; 14937 case OPC_SCD: 14938 check_insn(ctx, ISA_MIPS3); 14939 if (ctx->insn_flags & INSN_R5900) { 14940 check_insn_opc_user_only(ctx, INSN_R5900); 14941 } 14942 check_mips_64(ctx); 14943 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false); 14944 break; 14945 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ 14946 if (ctx->insn_flags & ISA_MIPS_R6) { 14947 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */ 14948 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14949 } else { 14950 /* OPC_DADDI */ 14951 check_insn(ctx, ISA_MIPS3); 14952 check_mips_64(ctx); 14953 gen_arith_imm(ctx, op, rt, rs, imm); 14954 } 14955 break; 14956 case OPC_DADDIU: 14957 check_insn(ctx, ISA_MIPS3); 14958 check_mips_64(ctx); 14959 gen_arith_imm(ctx, op, rt, rs, imm); 14960 break; 14961 #else 14962 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 14963 if (ctx->insn_flags & ISA_MIPS_R6) { 14964 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14965 } else { 14966 MIPS_INVAL("major opcode"); 14967 gen_reserved_instruction(ctx); 14968 } 14969 break; 14970 #endif 14971 case OPC_DAUI: /* OPC_JALX */ 14972 if (ctx->insn_flags & ISA_MIPS_R6) { 14973 #if defined(TARGET_MIPS64) 14974 /* OPC_DAUI */ 14975 check_mips_64(ctx); 14976 if (rs == 0) { 14977 generate_exception(ctx, EXCP_RI); 14978 } else if (rt != 0) { 14979 TCGv t0 = tcg_temp_new(); 14980 gen_load_gpr(t0, rs); 14981 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16); 14982 } 14983 #else 14984 gen_reserved_instruction(ctx); 14985 MIPS_INVAL("major opcode"); 14986 #endif 14987 } else { 14988 /* OPC_JALX */ 14989 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS); 14990 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 14991 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 14992 } 14993 break; 14994 case OPC_MDMX: 14995 /* MDMX: Not implemented. */ 14996 break; 14997 case OPC_PCREL: 14998 check_insn(ctx, ISA_MIPS_R6); 14999 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs); 15000 break; 15001 default: /* Invalid */ 15002 MIPS_INVAL("major opcode"); 15003 return false; 15004 } 15005 return true; 15006 } 15007 15008 static void decode_opc(CPUMIPSState *env, DisasContext *ctx) 15009 { 15010 /* make sure instructions are on a word boundary */ 15011 if (ctx->base.pc_next & 0x3) { 15012 env->CP0_BadVAddr = ctx->base.pc_next; 15013 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); 15014 return; 15015 } 15016 15017 /* Handle blikely not taken case */ 15018 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { 15019 TCGLabel *l1 = gen_new_label(); 15020 15021 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 15022 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 15023 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); 15024 gen_set_label(l1); 15025 } 15026 15027 /* Transition to the auto-generated decoder. */ 15028 15029 /* Vendor specific extensions */ 15030 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { 15031 return; 15032 } 15033 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) { 15034 return; 15035 } 15036 if (TARGET_LONG_BITS == 64 && decode_ext_loongson(ctx, ctx->opcode)) { 15037 return; 15038 } 15039 #if defined(TARGET_MIPS64) 15040 if (ase_lcsr_available(env) && decode_ase_lcsr(ctx, ctx->opcode)) { 15041 return; 15042 } 15043 if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) { 15044 return; 15045 } 15046 #endif 15047 15048 /* ISA extensions */ 15049 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) { 15050 return; 15051 } 15052 15053 /* ISA (from latest to oldest) */ 15054 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) { 15055 return; 15056 } 15057 15058 if (decode_opc_legacy(env, ctx)) { 15059 return; 15060 } 15061 15062 gen_reserved_instruction(ctx); 15063 } 15064 15065 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 15066 { 15067 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15068 CPUMIPSState *env = cpu_env(cs); 15069 15070 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; 15071 ctx->saved_pc = -1; 15072 ctx->insn_flags = env->insn_flags; 15073 ctx->CP0_Config0 = env->CP0_Config0; 15074 ctx->CP0_Config1 = env->CP0_Config1; 15075 ctx->CP0_Config2 = env->CP0_Config2; 15076 ctx->CP0_Config3 = env->CP0_Config3; 15077 ctx->CP0_Config5 = env->CP0_Config5; 15078 ctx->btarget = 0; 15079 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; 15080 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; 15081 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3; 15082 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1; 15083 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1; 15084 ctx->PAMask = env->PAMask; 15085 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; 15086 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; 15087 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1; 15088 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift; 15089 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; 15090 /* Restore delay slot state from the tb context. */ 15091 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ 15092 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; 15093 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || 15094 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); 15095 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1; 15096 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; 15097 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; 15098 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; 15099 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1; 15100 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3; 15101 ctx->crcp = (env->CP0_Config5 >> CP0C5_CRCP) & 1; 15102 restore_cpu_state(env, ctx); 15103 #ifdef CONFIG_USER_ONLY 15104 ctx->mem_idx = MIPS_HFLAG_UM; 15105 #else 15106 ctx->mem_idx = hflags_mmu_index(ctx->hflags); 15107 #endif 15108 ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) && 15109 (ctx->insn_flags & (ISA_MIPS_R6 | 15110 INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN; 15111 15112 /* 15113 * Execute a branch and its delay slot as a single instruction. 15114 * This is what GDB expects and is consistent with what the 15115 * hardware does (e.g. if a delay slot instruction faults, the 15116 * reported PC is the PC of the branch). 15117 */ 15118 if ((tb_cflags(ctx->base.tb) & CF_SINGLE_STEP) && 15119 (ctx->hflags & MIPS_HFLAG_BMASK)) { 15120 ctx->base.max_insns = 2; 15121 } 15122 15123 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, 15124 ctx->hflags); 15125 } 15126 15127 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) 15128 { 15129 } 15130 15131 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 15132 { 15133 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15134 15135 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, 15136 ctx->btarget); 15137 } 15138 15139 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 15140 { 15141 CPUMIPSState *env = cpu_env(cs); 15142 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15143 int insn_bytes; 15144 int is_slot; 15145 15146 is_slot = ctx->hflags & MIPS_HFLAG_BMASK; 15147 if (ctx->insn_flags & ISA_NANOMIPS32) { 15148 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15149 insn_bytes = decode_isa_nanomips(env, ctx); 15150 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) { 15151 ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next); 15152 insn_bytes = 4; 15153 decode_opc(env, ctx); 15154 } else if (ctx->insn_flags & ASE_MICROMIPS) { 15155 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15156 insn_bytes = decode_isa_micromips(env, ctx); 15157 } else if (ctx->insn_flags & ASE_MIPS16) { 15158 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15159 insn_bytes = decode_ase_mips16e(env, ctx); 15160 } else { 15161 gen_reserved_instruction(ctx); 15162 g_assert(ctx->base.is_jmp == DISAS_NORETURN); 15163 return; 15164 } 15165 15166 if (ctx->hflags & MIPS_HFLAG_BMASK) { 15167 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 | 15168 MIPS_HFLAG_FBNSLOT))) { 15169 /* 15170 * Force to generate branch as there is neither delay nor 15171 * forbidden slot. 15172 */ 15173 is_slot = 1; 15174 } 15175 if ((ctx->hflags & MIPS_HFLAG_M16) && 15176 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) { 15177 /* 15178 * Force to generate branch as microMIPS R6 doesn't restrict 15179 * branches in the forbidden slot. 15180 */ 15181 is_slot = 1; 15182 } 15183 } 15184 if (is_slot) { 15185 gen_branch(ctx, insn_bytes); 15186 } 15187 if (ctx->base.is_jmp == DISAS_SEMIHOST) { 15188 generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes); 15189 } 15190 ctx->base.pc_next += insn_bytes; 15191 15192 if (ctx->base.is_jmp != DISAS_NEXT) { 15193 return; 15194 } 15195 15196 /* 15197 * End the TB on (most) page crossings. 15198 * See mips_tr_init_disas_context about single-stepping a branch 15199 * together with its delay slot. 15200 */ 15201 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE 15202 && !(tb_cflags(ctx->base.tb) & CF_SINGLE_STEP)) { 15203 ctx->base.is_jmp = DISAS_TOO_MANY; 15204 } 15205 } 15206 15207 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 15208 { 15209 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15210 15211 switch (ctx->base.is_jmp) { 15212 case DISAS_STOP: 15213 gen_save_pc(ctx->base.pc_next); 15214 tcg_gen_lookup_and_goto_ptr(); 15215 break; 15216 case DISAS_NEXT: 15217 case DISAS_TOO_MANY: 15218 save_cpu_state(ctx, 0); 15219 gen_goto_tb(ctx, 0, ctx->base.pc_next); 15220 break; 15221 case DISAS_EXIT: 15222 tcg_gen_exit_tb(NULL, 0); 15223 break; 15224 case DISAS_NORETURN: 15225 break; 15226 default: 15227 g_assert_not_reached(); 15228 } 15229 } 15230 15231 static const TranslatorOps mips_tr_ops = { 15232 .init_disas_context = mips_tr_init_disas_context, 15233 .tb_start = mips_tr_tb_start, 15234 .insn_start = mips_tr_insn_start, 15235 .translate_insn = mips_tr_translate_insn, 15236 .tb_stop = mips_tr_tb_stop, 15237 }; 15238 15239 void mips_translate_code(CPUState *cs, TranslationBlock *tb, 15240 int *max_insns, vaddr pc, void *host_pc) 15241 { 15242 DisasContext ctx; 15243 15244 translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base); 15245 } 15246 15247 void mips_tcg_init(void) 15248 { 15249 cpu_gpr[0] = NULL; 15250 for (unsigned i = 1; i < 32; i++) 15251 cpu_gpr[i] = tcg_global_mem_new(tcg_env, 15252 offsetof(CPUMIPSState, 15253 active_tc.gpr[i]), 15254 regnames[i]); 15255 #if defined(TARGET_MIPS64) 15256 cpu_gpr_hi[0] = NULL; 15257 15258 for (unsigned i = 1; i < 32; i++) { 15259 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]); 15260 15261 cpu_gpr_hi[i] = tcg_global_mem_new_i64(tcg_env, 15262 offsetof(CPUMIPSState, 15263 active_tc.gpr_hi[i]), 15264 rname); 15265 } 15266 #endif /* !TARGET_MIPS64 */ 15267 for (unsigned i = 0; i < 32; i++) { 15268 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); 15269 15270 fpu_f64[i] = tcg_global_mem_new_i64(tcg_env, off, fregnames[i]); 15271 } 15272 msa_translate_init(); 15273 cpu_PC = tcg_global_mem_new(tcg_env, 15274 offsetof(CPUMIPSState, active_tc.PC), "PC"); 15275 for (unsigned i = 0; i < MIPS_DSP_ACC; i++) { 15276 cpu_HI[i] = tcg_global_mem_new(tcg_env, 15277 offsetof(CPUMIPSState, active_tc.HI[i]), 15278 regnames_HI[i]); 15279 cpu_LO[i] = tcg_global_mem_new(tcg_env, 15280 offsetof(CPUMIPSState, active_tc.LO[i]), 15281 regnames_LO[i]); 15282 } 15283 cpu_dspctrl = tcg_global_mem_new(tcg_env, 15284 offsetof(CPUMIPSState, 15285 active_tc.DSPControl), 15286 "DSPControl"); 15287 bcond = tcg_global_mem_new(tcg_env, 15288 offsetof(CPUMIPSState, bcond), "bcond"); 15289 btarget = tcg_global_mem_new(tcg_env, 15290 offsetof(CPUMIPSState, btarget), "btarget"); 15291 hflags = tcg_global_mem_new_i32(tcg_env, 15292 offsetof(CPUMIPSState, hflags), "hflags"); 15293 15294 fpu_fcr0 = tcg_global_mem_new_i32(tcg_env, 15295 offsetof(CPUMIPSState, active_fpu.fcr0), 15296 "fcr0"); 15297 fpu_fcr31 = tcg_global_mem_new_i32(tcg_env, 15298 offsetof(CPUMIPSState, active_fpu.fcr31), 15299 "fcr31"); 15300 cpu_lladdr = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, lladdr), 15301 "lladdr"); 15302 cpu_llval = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, llval), 15303 "llval"); 15304 15305 if (TARGET_LONG_BITS == 32) { 15306 mxu_translate_init(); 15307 } 15308 } 15309 15310 void mips_restore_state_to_opc(CPUState *cs, 15311 const TranslationBlock *tb, 15312 const uint64_t *data) 15313 { 15314 CPUMIPSState *env = cpu_env(cs); 15315 15316 env->active_tc.PC = data[0]; 15317 env->hflags &= ~MIPS_HFLAG_BMASK; 15318 env->hflags |= data[1]; 15319 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) { 15320 case MIPS_HFLAG_BR: 15321 break; 15322 case MIPS_HFLAG_BC: 15323 case MIPS_HFLAG_BL: 15324 case MIPS_HFLAG_B: 15325 env->btarget = data[2]; 15326 break; 15327 } 15328 } 15329