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 "semihosting/semihost.h" 31 #include "trace.h" 32 #include "fpu_helper.h" 33 34 #define HELPER_H "helper.h" 35 #include "exec/helper-info.c.inc" 36 #undef HELPER_H 37 38 39 /* 40 * Many sysemu-only helpers are not reachable for user-only. 41 * Define stub generators here, so that we need not either sprinkle 42 * ifdefs through the translator, nor provide the helper function. 43 */ 44 #define STUB_HELPER(NAME, ...) \ 45 static inline void gen_helper_##NAME(__VA_ARGS__) \ 46 { g_assert_not_reached(); } 47 48 #ifdef CONFIG_USER_ONLY 49 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg) 50 #endif 51 52 enum { 53 /* indirect opcode tables */ 54 OPC_SPECIAL = (0x00 << 26), 55 OPC_REGIMM = (0x01 << 26), 56 OPC_CP0 = (0x10 << 26), 57 OPC_CP2 = (0x12 << 26), 58 OPC_CP3 = (0x13 << 26), 59 OPC_SPECIAL2 = (0x1C << 26), 60 OPC_SPECIAL3 = (0x1F << 26), 61 /* arithmetic with immediate */ 62 OPC_ADDI = (0x08 << 26), 63 OPC_ADDIU = (0x09 << 26), 64 OPC_SLTI = (0x0A << 26), 65 OPC_SLTIU = (0x0B << 26), 66 /* logic with immediate */ 67 OPC_ANDI = (0x0C << 26), 68 OPC_ORI = (0x0D << 26), 69 OPC_XORI = (0x0E << 26), 70 OPC_LUI = (0x0F << 26), 71 /* arithmetic with immediate */ 72 OPC_DADDI = (0x18 << 26), 73 OPC_DADDIU = (0x19 << 26), 74 /* Jump and branches */ 75 OPC_J = (0x02 << 26), 76 OPC_JAL = (0x03 << 26), 77 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */ 78 OPC_BEQL = (0x14 << 26), 79 OPC_BNE = (0x05 << 26), 80 OPC_BNEL = (0x15 << 26), 81 OPC_BLEZ = (0x06 << 26), 82 OPC_BLEZL = (0x16 << 26), 83 OPC_BGTZ = (0x07 << 26), 84 OPC_BGTZL = (0x17 << 26), 85 OPC_JALX = (0x1D << 26), 86 OPC_DAUI = (0x1D << 26), 87 /* Load and stores */ 88 OPC_LDL = (0x1A << 26), 89 OPC_LDR = (0x1B << 26), 90 OPC_LB = (0x20 << 26), 91 OPC_LH = (0x21 << 26), 92 OPC_LWL = (0x22 << 26), 93 OPC_LW = (0x23 << 26), 94 OPC_LWPC = OPC_LW | 0x5, 95 OPC_LBU = (0x24 << 26), 96 OPC_LHU = (0x25 << 26), 97 OPC_LWR = (0x26 << 26), 98 OPC_LWU = (0x27 << 26), 99 OPC_SB = (0x28 << 26), 100 OPC_SH = (0x29 << 26), 101 OPC_SWL = (0x2A << 26), 102 OPC_SW = (0x2B << 26), 103 OPC_SDL = (0x2C << 26), 104 OPC_SDR = (0x2D << 26), 105 OPC_SWR = (0x2E << 26), 106 OPC_LL = (0x30 << 26), 107 OPC_LLD = (0x34 << 26), 108 OPC_LD = (0x37 << 26), 109 OPC_LDPC = OPC_LD | 0x5, 110 OPC_SC = (0x38 << 26), 111 OPC_SCD = (0x3C << 26), 112 OPC_SD = (0x3F << 26), 113 /* Floating point load/store */ 114 OPC_LWC1 = (0x31 << 26), 115 OPC_LWC2 = (0x32 << 26), 116 OPC_LDC1 = (0x35 << 26), 117 OPC_LDC2 = (0x36 << 26), 118 OPC_SWC1 = (0x39 << 26), 119 OPC_SWC2 = (0x3A << 26), 120 OPC_SDC1 = (0x3D << 26), 121 OPC_SDC2 = (0x3E << 26), 122 /* Compact Branches */ 123 OPC_BLEZALC = (0x06 << 26), 124 OPC_BGEZALC = (0x06 << 26), 125 OPC_BGEUC = (0x06 << 26), 126 OPC_BGTZALC = (0x07 << 26), 127 OPC_BLTZALC = (0x07 << 26), 128 OPC_BLTUC = (0x07 << 26), 129 OPC_BOVC = (0x08 << 26), 130 OPC_BEQZALC = (0x08 << 26), 131 OPC_BEQC = (0x08 << 26), 132 OPC_BLEZC = (0x16 << 26), 133 OPC_BGEZC = (0x16 << 26), 134 OPC_BGEC = (0x16 << 26), 135 OPC_BGTZC = (0x17 << 26), 136 OPC_BLTZC = (0x17 << 26), 137 OPC_BLTC = (0x17 << 26), 138 OPC_BNVC = (0x18 << 26), 139 OPC_BNEZALC = (0x18 << 26), 140 OPC_BNEC = (0x18 << 26), 141 OPC_BC = (0x32 << 26), 142 OPC_BEQZC = (0x36 << 26), 143 OPC_JIC = (0x36 << 26), 144 OPC_BALC = (0x3A << 26), 145 OPC_BNEZC = (0x3E << 26), 146 OPC_JIALC = (0x3E << 26), 147 /* MDMX ASE specific */ 148 OPC_MDMX = (0x1E << 26), 149 /* Cache and prefetch */ 150 OPC_CACHE = (0x2F << 26), 151 OPC_PREF = (0x33 << 26), 152 /* PC-relative address computation / loads */ 153 OPC_PCREL = (0x3B << 26), 154 }; 155 156 /* PC-relative address computation / loads */ 157 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19))) 158 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16))) 159 enum { 160 /* Instructions determined by bits 19 and 20 */ 161 OPC_ADDIUPC = OPC_PCREL | (0 << 19), 162 R6_OPC_LWPC = OPC_PCREL | (1 << 19), 163 OPC_LWUPC = OPC_PCREL | (2 << 19), 164 165 /* Instructions determined by bits 16 ... 20 */ 166 OPC_AUIPC = OPC_PCREL | (0x1e << 16), 167 OPC_ALUIPC = OPC_PCREL | (0x1f << 16), 168 169 /* Other */ 170 R6_OPC_LDPC = OPC_PCREL | (6 << 18), 171 }; 172 173 /* MIPS special opcodes */ 174 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 175 176 enum { 177 /* Shifts */ 178 OPC_SLL = 0x00 | OPC_SPECIAL, 179 /* NOP is SLL r0, r0, 0 */ 180 /* SSNOP is SLL r0, r0, 1 */ 181 /* EHB is SLL r0, r0, 3 */ 182 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */ 183 OPC_ROTR = OPC_SRL | (1 << 21), 184 OPC_SRA = 0x03 | OPC_SPECIAL, 185 OPC_SLLV = 0x04 | OPC_SPECIAL, 186 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */ 187 OPC_ROTRV = OPC_SRLV | (1 << 6), 188 OPC_SRAV = 0x07 | OPC_SPECIAL, 189 OPC_DSLLV = 0x14 | OPC_SPECIAL, 190 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */ 191 OPC_DROTRV = OPC_DSRLV | (1 << 6), 192 OPC_DSRAV = 0x17 | OPC_SPECIAL, 193 OPC_DSLL = 0x38 | OPC_SPECIAL, 194 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */ 195 OPC_DROTR = OPC_DSRL | (1 << 21), 196 OPC_DSRA = 0x3B | OPC_SPECIAL, 197 OPC_DSLL32 = 0x3C | OPC_SPECIAL, 198 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */ 199 OPC_DROTR32 = OPC_DSRL32 | (1 << 21), 200 OPC_DSRA32 = 0x3F | OPC_SPECIAL, 201 /* Multiplication / division */ 202 OPC_MULT = 0x18 | OPC_SPECIAL, 203 OPC_MULTU = 0x19 | OPC_SPECIAL, 204 OPC_DIV = 0x1A | OPC_SPECIAL, 205 OPC_DIVU = 0x1B | OPC_SPECIAL, 206 OPC_DMULT = 0x1C | OPC_SPECIAL, 207 OPC_DMULTU = 0x1D | OPC_SPECIAL, 208 OPC_DDIV = 0x1E | OPC_SPECIAL, 209 OPC_DDIVU = 0x1F | OPC_SPECIAL, 210 211 /* 2 registers arithmetic / logic */ 212 OPC_ADD = 0x20 | OPC_SPECIAL, 213 OPC_ADDU = 0x21 | OPC_SPECIAL, 214 OPC_SUB = 0x22 | OPC_SPECIAL, 215 OPC_SUBU = 0x23 | OPC_SPECIAL, 216 OPC_AND = 0x24 | OPC_SPECIAL, 217 OPC_OR = 0x25 | OPC_SPECIAL, 218 OPC_XOR = 0x26 | OPC_SPECIAL, 219 OPC_NOR = 0x27 | OPC_SPECIAL, 220 OPC_SLT = 0x2A | OPC_SPECIAL, 221 OPC_SLTU = 0x2B | OPC_SPECIAL, 222 OPC_DADD = 0x2C | OPC_SPECIAL, 223 OPC_DADDU = 0x2D | OPC_SPECIAL, 224 OPC_DSUB = 0x2E | OPC_SPECIAL, 225 OPC_DSUBU = 0x2F | OPC_SPECIAL, 226 /* Jumps */ 227 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ 228 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ 229 /* Traps */ 230 OPC_TGE = 0x30 | OPC_SPECIAL, 231 OPC_TGEU = 0x31 | OPC_SPECIAL, 232 OPC_TLT = 0x32 | OPC_SPECIAL, 233 OPC_TLTU = 0x33 | OPC_SPECIAL, 234 OPC_TEQ = 0x34 | OPC_SPECIAL, 235 OPC_TNE = 0x36 | OPC_SPECIAL, 236 /* HI / LO registers load & stores */ 237 OPC_MFHI = 0x10 | OPC_SPECIAL, 238 OPC_MTHI = 0x11 | OPC_SPECIAL, 239 OPC_MFLO = 0x12 | OPC_SPECIAL, 240 OPC_MTLO = 0x13 | OPC_SPECIAL, 241 /* Conditional moves */ 242 OPC_MOVZ = 0x0A | OPC_SPECIAL, 243 OPC_MOVN = 0x0B | OPC_SPECIAL, 244 245 OPC_SELEQZ = 0x35 | OPC_SPECIAL, 246 OPC_SELNEZ = 0x37 | OPC_SPECIAL, 247 248 OPC_MOVCI = 0x01 | OPC_SPECIAL, 249 250 /* Special */ 251 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */ 252 OPC_SYSCALL = 0x0C | OPC_SPECIAL, 253 OPC_BREAK = 0x0D | OPC_SPECIAL, 254 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */ 255 OPC_SYNC = 0x0F | OPC_SPECIAL, 256 257 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, 258 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, 259 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, 260 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, 261 }; 262 263 /* 264 * R6 Multiply and Divide instructions have the same opcode 265 * and function field as legacy OPC_MULT[U]/OPC_DIV[U] 266 */ 267 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff))) 268 269 enum { 270 R6_OPC_MUL = OPC_MULT | (2 << 6), 271 R6_OPC_MUH = OPC_MULT | (3 << 6), 272 R6_OPC_MULU = OPC_MULTU | (2 << 6), 273 R6_OPC_MUHU = OPC_MULTU | (3 << 6), 274 R6_OPC_DIV = OPC_DIV | (2 << 6), 275 R6_OPC_MOD = OPC_DIV | (3 << 6), 276 R6_OPC_DIVU = OPC_DIVU | (2 << 6), 277 R6_OPC_MODU = OPC_DIVU | (3 << 6), 278 279 R6_OPC_DMUL = OPC_DMULT | (2 << 6), 280 R6_OPC_DMUH = OPC_DMULT | (3 << 6), 281 R6_OPC_DMULU = OPC_DMULTU | (2 << 6), 282 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6), 283 R6_OPC_DDIV = OPC_DDIV | (2 << 6), 284 R6_OPC_DMOD = OPC_DDIV | (3 << 6), 285 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6), 286 R6_OPC_DMODU = OPC_DDIVU | (3 << 6), 287 288 R6_OPC_CLZ = 0x10 | OPC_SPECIAL, 289 R6_OPC_CLO = 0x11 | OPC_SPECIAL, 290 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL, 291 R6_OPC_DCLO = 0x13 | OPC_SPECIAL, 292 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL, 293 }; 294 295 /* REGIMM (rt field) opcodes */ 296 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16))) 297 298 enum { 299 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM, 300 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM, 301 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM, 302 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM, 303 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM, 304 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM, 305 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM, 306 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM, 307 OPC_TGEI = (0x08 << 16) | OPC_REGIMM, 308 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM, 309 OPC_TLTI = (0x0A << 16) | OPC_REGIMM, 310 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM, 311 OPC_TEQI = (0x0C << 16) | OPC_REGIMM, 312 OPC_TNEI = (0x0E << 16) | OPC_REGIMM, 313 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM, 314 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM, 315 316 OPC_DAHI = (0x06 << 16) | OPC_REGIMM, 317 OPC_DATI = (0x1e << 16) | OPC_REGIMM, 318 }; 319 320 /* Special2 opcodes */ 321 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 322 323 enum { 324 /* Multiply & xxx operations */ 325 OPC_MADD = 0x00 | OPC_SPECIAL2, 326 OPC_MADDU = 0x01 | OPC_SPECIAL2, 327 OPC_MUL = 0x02 | OPC_SPECIAL2, 328 OPC_MSUB = 0x04 | OPC_SPECIAL2, 329 OPC_MSUBU = 0x05 | OPC_SPECIAL2, 330 /* Misc */ 331 OPC_CLZ = 0x20 | OPC_SPECIAL2, 332 OPC_CLO = 0x21 | OPC_SPECIAL2, 333 OPC_DCLZ = 0x24 | OPC_SPECIAL2, 334 OPC_DCLO = 0x25 | OPC_SPECIAL2, 335 /* Special */ 336 OPC_SDBBP = 0x3F | OPC_SPECIAL2, 337 }; 338 339 /* Special3 opcodes */ 340 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 341 342 enum { 343 OPC_EXT = 0x00 | OPC_SPECIAL3, 344 OPC_DEXTM = 0x01 | OPC_SPECIAL3, 345 OPC_DEXTU = 0x02 | OPC_SPECIAL3, 346 OPC_DEXT = 0x03 | OPC_SPECIAL3, 347 OPC_INS = 0x04 | OPC_SPECIAL3, 348 OPC_DINSM = 0x05 | OPC_SPECIAL3, 349 OPC_DINSU = 0x06 | OPC_SPECIAL3, 350 OPC_DINS = 0x07 | OPC_SPECIAL3, 351 OPC_FORK = 0x08 | OPC_SPECIAL3, 352 OPC_YIELD = 0x09 | OPC_SPECIAL3, 353 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 354 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 355 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 356 OPC_GINV = 0x3D | OPC_SPECIAL3, 357 358 /* MIPS DSP Load */ 359 OPC_LX_DSP = 0x0A | OPC_SPECIAL3, 360 /* MIPS DSP Arithmetic */ 361 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3, 362 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3, 363 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3, 364 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3, 365 OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, 366 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3, 367 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3, 368 /* MIPS DSP GPR-Based Shift Sub-class */ 369 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3, 370 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3, 371 /* MIPS DSP Multiply Sub-class insns */ 372 OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, 373 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3, 374 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3, 375 /* DSP Bit/Manipulation Sub-class */ 376 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, 377 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3, 378 /* MIPS DSP Append Sub-class */ 379 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3, 380 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3, 381 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 382 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, 383 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, 384 385 /* EVA */ 386 OPC_LWLE = 0x19 | OPC_SPECIAL3, 387 OPC_LWRE = 0x1A | OPC_SPECIAL3, 388 OPC_CACHEE = 0x1B | OPC_SPECIAL3, 389 OPC_SBE = 0x1C | OPC_SPECIAL3, 390 OPC_SHE = 0x1D | OPC_SPECIAL3, 391 OPC_SCE = 0x1E | OPC_SPECIAL3, 392 OPC_SWE = 0x1F | OPC_SPECIAL3, 393 OPC_SWLE = 0x21 | OPC_SPECIAL3, 394 OPC_SWRE = 0x22 | OPC_SPECIAL3, 395 OPC_PREFE = 0x23 | OPC_SPECIAL3, 396 OPC_LBUE = 0x28 | OPC_SPECIAL3, 397 OPC_LHUE = 0x29 | OPC_SPECIAL3, 398 OPC_LBE = 0x2C | OPC_SPECIAL3, 399 OPC_LHE = 0x2D | OPC_SPECIAL3, 400 OPC_LLE = 0x2E | OPC_SPECIAL3, 401 OPC_LWE = 0x2F | OPC_SPECIAL3, 402 403 /* R6 */ 404 R6_OPC_PREF = 0x35 | OPC_SPECIAL3, 405 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, 406 R6_OPC_LL = 0x36 | OPC_SPECIAL3, 407 R6_OPC_SC = 0x26 | OPC_SPECIAL3, 408 R6_OPC_LLD = 0x37 | OPC_SPECIAL3, 409 R6_OPC_SCD = 0x27 | OPC_SPECIAL3, 410 }; 411 412 /* Loongson EXT load/store quad word opcodes */ 413 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020)) 414 enum { 415 OPC_GSLQ = 0x0020 | OPC_LWC2, 416 OPC_GSLQC1 = 0x8020 | OPC_LWC2, 417 OPC_GSSHFL = OPC_LWC2, 418 OPC_GSSQ = 0x0020 | OPC_SWC2, 419 OPC_GSSQC1 = 0x8020 | OPC_SWC2, 420 OPC_GSSHFS = OPC_SWC2, 421 }; 422 423 /* Loongson EXT shifted load/store opcodes */ 424 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f)) 425 enum { 426 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL, 427 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL, 428 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL, 429 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL, 430 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS, 431 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS, 432 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS, 433 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS, 434 }; 435 436 /* Loongson EXT LDC2/SDC2 opcodes */ 437 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7)) 438 439 enum { 440 OPC_GSLBX = 0x0 | OPC_LDC2, 441 OPC_GSLHX = 0x1 | OPC_LDC2, 442 OPC_GSLWX = 0x2 | OPC_LDC2, 443 OPC_GSLDX = 0x3 | OPC_LDC2, 444 OPC_GSLWXC1 = 0x6 | OPC_LDC2, 445 OPC_GSLDXC1 = 0x7 | OPC_LDC2, 446 OPC_GSSBX = 0x0 | OPC_SDC2, 447 OPC_GSSHX = 0x1 | OPC_SDC2, 448 OPC_GSSWX = 0x2 | OPC_SDC2, 449 OPC_GSSDX = 0x3 | OPC_SDC2, 450 OPC_GSSWXC1 = 0x6 | OPC_SDC2, 451 OPC_GSSDXC1 = 0x7 | OPC_SDC2, 452 }; 453 454 /* BSHFL opcodes */ 455 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 456 457 enum { 458 OPC_WSBH = (0x02 << 6) | OPC_BSHFL, 459 OPC_SEB = (0x10 << 6) | OPC_BSHFL, 460 OPC_SEH = (0x18 << 6) | OPC_BSHFL, 461 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */ 462 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL, 463 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL, 464 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL, 465 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */ 466 }; 467 468 /* DBSHFL opcodes */ 469 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 470 471 enum { 472 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, 473 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, 474 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */ 475 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL, 476 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL, 477 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL, 478 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL, 479 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL, 480 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL, 481 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL, 482 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */ 483 }; 484 485 /* MIPS DSP REGIMM opcodes */ 486 enum { 487 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM, 488 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM, 489 }; 490 491 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 492 /* MIPS DSP Load */ 493 enum { 494 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP, 495 OPC_LHX = (0x04 << 6) | OPC_LX_DSP, 496 OPC_LWX = (0x00 << 6) | OPC_LX_DSP, 497 OPC_LDX = (0x08 << 6) | OPC_LX_DSP, 498 }; 499 500 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 501 enum { 502 /* MIPS DSP Arithmetic Sub-class */ 503 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP, 504 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP, 505 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP, 506 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP, 507 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP, 508 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP, 509 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP, 510 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP, 511 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP, 512 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP, 513 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP, 514 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP, 515 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP, 516 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP, 517 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP, 518 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP, 519 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP, 520 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP, 521 /* MIPS DSP Multiply Sub-class insns */ 522 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP, 523 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP, 524 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP, 525 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP, 526 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP, 527 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP, 528 }; 529 530 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 531 enum { 532 /* MIPS DSP Arithmetic Sub-class */ 533 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP, 534 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP, 535 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP, 536 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP, 537 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP, 538 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP, 539 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP, 540 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP, 541 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP, 542 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP, 543 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP, 544 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP, 545 /* MIPS DSP Multiply Sub-class insns */ 546 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP, 547 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP, 548 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP, 549 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP, 550 }; 551 552 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 553 enum { 554 /* MIPS DSP Arithmetic Sub-class */ 555 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP, 556 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP, 557 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP, 558 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP, 559 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP, 560 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP, 561 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP, 562 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP, 563 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP, 564 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP, 565 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP, 566 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP, 567 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP, 568 /* DSP Bit/Manipulation Sub-class */ 569 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP, 570 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP, 571 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP, 572 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP, 573 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP, 574 }; 575 576 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 577 enum { 578 /* MIPS DSP Arithmetic Sub-class */ 579 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP, 580 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP, 581 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP, 582 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP, 583 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP, 584 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP, 585 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP, 586 /* DSP Compare-Pick Sub-class */ 587 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP, 588 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP, 589 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP, 590 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP, 591 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP, 592 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP, 593 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP, 594 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP, 595 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP, 596 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP, 597 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP, 598 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP, 599 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, 600 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, 601 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, 602 }; 603 604 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 605 enum { 606 /* MIPS DSP GPR-Based Shift Sub-class */ 607 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP, 608 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP, 609 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP, 610 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP, 611 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP, 612 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP, 613 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP, 614 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP, 615 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP, 616 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP, 617 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP, 618 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP, 619 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP, 620 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP, 621 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP, 622 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP, 623 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP, 624 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP, 625 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP, 626 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP, 627 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP, 628 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP, 629 }; 630 631 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 632 enum { 633 /* MIPS DSP Multiply Sub-class insns */ 634 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP, 635 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP, 636 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP, 637 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP, 638 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP, 639 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP, 640 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP, 641 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP, 642 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP, 643 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP, 644 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP, 645 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP, 646 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP, 647 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP, 648 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP, 649 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP, 650 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP, 651 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP, 652 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP, 653 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP, 654 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP, 655 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP, 656 }; 657 658 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 659 enum { 660 /* DSP Bit/Manipulation Sub-class */ 661 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP, 662 }; 663 664 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 665 enum { 666 /* MIPS DSP Append Sub-class */ 667 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP, 668 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP, 669 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP, 670 }; 671 672 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 673 enum { 674 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 675 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP, 676 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP, 677 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP, 678 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP, 679 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP, 680 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP, 681 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP, 682 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP, 683 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP, 684 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP, 685 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP, 686 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP, 687 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP, 688 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP, 689 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP, 690 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP, 691 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP, 692 }; 693 694 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 695 enum { 696 /* MIPS DSP Arithmetic Sub-class */ 697 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP, 698 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP, 699 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP, 700 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP, 701 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP, 702 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP, 703 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP, 704 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP, 705 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP, 706 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP, 707 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP, 708 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP, 709 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP, 710 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP, 711 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP, 712 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP, 713 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP, 714 /* DSP Bit/Manipulation Sub-class */ 715 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP, 716 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP, 717 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP, 718 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP, 719 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP, 720 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP, 721 }; 722 723 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 724 enum { 725 /* MIPS DSP Multiply Sub-class insns */ 726 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP, 727 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP, 728 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP, 729 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP, 730 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP, 731 /* MIPS DSP Arithmetic Sub-class */ 732 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP, 733 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP, 734 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP, 735 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP, 736 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP, 737 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP, 738 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP, 739 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP, 740 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP, 741 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP, 742 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP, 743 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP, 744 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP, 745 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP, 746 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP, 747 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP, 748 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP, 749 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP, 750 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP, 751 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP, 752 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP, 753 }; 754 755 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 756 enum { 757 /* DSP Compare-Pick Sub-class */ 758 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP, 759 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP, 760 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP, 761 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP, 762 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP, 763 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP, 764 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP, 765 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP, 766 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP, 767 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP, 768 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP, 769 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP, 770 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP, 771 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP, 772 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP, 773 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP, 774 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP, 775 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP, 776 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP, 777 /* MIPS DSP Arithmetic Sub-class */ 778 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP, 779 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP, 780 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP, 781 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP, 782 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP, 783 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP, 784 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP, 785 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP, 786 }; 787 788 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 789 enum { 790 /* DSP Append Sub-class */ 791 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP, 792 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP, 793 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP, 794 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP, 795 }; 796 797 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 798 enum { 799 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 800 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP, 801 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP, 802 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP, 803 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP, 804 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP, 805 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP, 806 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP, 807 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP, 808 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP, 809 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP, 810 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP, 811 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP, 812 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP, 813 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP, 814 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP, 815 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP, 816 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP, 817 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP, 818 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP, 819 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP, 820 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP, 821 }; 822 823 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 824 enum { 825 /* DSP Bit/Manipulation Sub-class */ 826 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP, 827 }; 828 829 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 830 enum { 831 /* MIPS DSP Multiply Sub-class insns */ 832 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP, 833 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP, 834 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP, 835 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP, 836 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP, 837 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP, 838 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP, 839 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP, 840 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP, 841 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP, 842 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP, 843 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP, 844 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP, 845 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP, 846 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP, 847 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP, 848 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP, 849 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP, 850 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP, 851 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP, 852 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP, 853 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP, 854 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP, 855 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP, 856 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP, 857 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP, 858 }; 859 860 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 861 enum { 862 /* MIPS DSP GPR-Based Shift Sub-class */ 863 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP, 864 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP, 865 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP, 866 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP, 867 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP, 868 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP, 869 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP, 870 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP, 871 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP, 872 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP, 873 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP, 874 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP, 875 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP, 876 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP, 877 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP, 878 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP, 879 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP, 880 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP, 881 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP, 882 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP, 883 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP, 884 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP, 885 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP, 886 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP, 887 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP, 888 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP, 889 }; 890 891 /* Coprocessor 0 (rs field) */ 892 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 893 894 enum { 895 OPC_MFC0 = (0x00 << 21) | OPC_CP0, 896 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 897 OPC_MFHC0 = (0x02 << 21) | OPC_CP0, 898 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 899 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 900 OPC_MTHC0 = (0x06 << 21) | OPC_CP0, 901 OPC_MFTR = (0x08 << 21) | OPC_CP0, 902 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 903 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 904 OPC_MTTR = (0x0C << 21) | OPC_CP0, 905 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 906 OPC_C0 = (0x10 << 21) | OPC_CP0, 907 OPC_C0_1 = (0x11 << 21) | OPC_CP0, 908 OPC_C0_2 = (0x12 << 21) | OPC_CP0, 909 OPC_C0_3 = (0x13 << 21) | OPC_CP0, 910 OPC_C0_4 = (0x14 << 21) | OPC_CP0, 911 OPC_C0_5 = (0x15 << 21) | OPC_CP0, 912 OPC_C0_6 = (0x16 << 21) | OPC_CP0, 913 OPC_C0_7 = (0x17 << 21) | OPC_CP0, 914 OPC_C0_8 = (0x18 << 21) | OPC_CP0, 915 OPC_C0_9 = (0x19 << 21) | OPC_CP0, 916 OPC_C0_A = (0x1A << 21) | OPC_CP0, 917 OPC_C0_B = (0x1B << 21) | OPC_CP0, 918 OPC_C0_C = (0x1C << 21) | OPC_CP0, 919 OPC_C0_D = (0x1D << 21) | OPC_CP0, 920 OPC_C0_E = (0x1E << 21) | OPC_CP0, 921 OPC_C0_F = (0x1F << 21) | OPC_CP0, 922 }; 923 924 /* MFMC0 opcodes */ 925 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF)) 926 927 enum { 928 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 929 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 930 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0, 931 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0, 932 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 933 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 934 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0, 935 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0, 936 }; 937 938 /* Coprocessor 0 (with rs == C0) */ 939 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F)) 940 941 enum { 942 OPC_TLBR = 0x01 | OPC_C0, 943 OPC_TLBWI = 0x02 | OPC_C0, 944 OPC_TLBINV = 0x03 | OPC_C0, 945 OPC_TLBINVF = 0x04 | OPC_C0, 946 OPC_TLBWR = 0x06 | OPC_C0, 947 OPC_TLBP = 0x08 | OPC_C0, 948 OPC_RFE = 0x10 | OPC_C0, 949 OPC_ERET = 0x18 | OPC_C0, 950 OPC_DERET = 0x1F | OPC_C0, 951 OPC_WAIT = 0x20 | OPC_C0, 952 }; 953 954 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 955 956 enum { 957 OPC_MFC2 = (0x00 << 21) | OPC_CP2, 958 OPC_DMFC2 = (0x01 << 21) | OPC_CP2, 959 OPC_CFC2 = (0x02 << 21) | OPC_CP2, 960 OPC_MFHC2 = (0x03 << 21) | OPC_CP2, 961 OPC_MTC2 = (0x04 << 21) | OPC_CP2, 962 OPC_DMTC2 = (0x05 << 21) | OPC_CP2, 963 OPC_CTC2 = (0x06 << 21) | OPC_CP2, 964 OPC_MTHC2 = (0x07 << 21) | OPC_CP2, 965 OPC_BC2 = (0x08 << 21) | OPC_CP2, 966 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2, 967 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2, 968 }; 969 970 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F)) 971 972 enum { 973 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2, 974 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2, 975 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2, 976 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2, 977 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2, 978 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2, 979 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2, 980 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2, 981 982 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2, 983 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2, 984 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2, 985 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2, 986 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2, 987 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2, 988 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2, 989 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2, 990 991 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2, 992 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2, 993 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2, 994 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2, 995 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2, 996 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2, 997 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2, 998 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2, 999 1000 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2, 1001 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2, 1002 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2, 1003 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2, 1004 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2, 1005 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2, 1006 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2, 1007 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2, 1008 1009 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2, 1010 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2, 1011 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2, 1012 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2, 1013 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2, 1014 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2, 1015 1016 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2, 1017 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2, 1018 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2, 1019 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2, 1020 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2, 1021 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2, 1022 1023 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2, 1024 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2, 1025 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2, 1026 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2, 1027 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2, 1028 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2, 1029 1030 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2, 1031 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2, 1032 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2, 1033 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2, 1034 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2, 1035 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2, 1036 1037 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2, 1038 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2, 1039 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2, 1040 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2, 1041 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2, 1042 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2, 1043 1044 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2, 1045 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2, 1046 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2, 1047 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2, 1048 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2, 1049 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2, 1050 1051 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2, 1052 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2, 1053 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2, 1054 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2, 1055 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2, 1056 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2, 1057 1058 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2, 1059 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2, 1060 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2, 1061 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2, 1062 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2, 1063 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2, 1064 }; 1065 1066 1067 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 1068 1069 enum { 1070 OPC_LWXC1 = 0x00 | OPC_CP3, 1071 OPC_LDXC1 = 0x01 | OPC_CP3, 1072 OPC_LUXC1 = 0x05 | OPC_CP3, 1073 OPC_SWXC1 = 0x08 | OPC_CP3, 1074 OPC_SDXC1 = 0x09 | OPC_CP3, 1075 OPC_SUXC1 = 0x0D | OPC_CP3, 1076 OPC_PREFX = 0x0F | OPC_CP3, 1077 OPC_ALNV_PS = 0x1E | OPC_CP3, 1078 OPC_MADD_S = 0x20 | OPC_CP3, 1079 OPC_MADD_D = 0x21 | OPC_CP3, 1080 OPC_MADD_PS = 0x26 | OPC_CP3, 1081 OPC_MSUB_S = 0x28 | OPC_CP3, 1082 OPC_MSUB_D = 0x29 | OPC_CP3, 1083 OPC_MSUB_PS = 0x2E | OPC_CP3, 1084 OPC_NMADD_S = 0x30 | OPC_CP3, 1085 OPC_NMADD_D = 0x31 | OPC_CP3, 1086 OPC_NMADD_PS = 0x36 | OPC_CP3, 1087 OPC_NMSUB_S = 0x38 | OPC_CP3, 1088 OPC_NMSUB_D = 0x39 | OPC_CP3, 1089 OPC_NMSUB_PS = 0x3E | OPC_CP3, 1090 }; 1091 1092 /* 1093 * MMI (MultiMedia Instruction) encodings 1094 * ====================================== 1095 * 1096 * MMI instructions encoding table keys: 1097 * 1098 * * This code is reserved for future use. An attempt to execute it 1099 * causes a Reserved Instruction exception. 1100 * % This code indicates an instruction class. The instruction word 1101 * must be further decoded by examining additional tables that show 1102 * the values for other instruction fields. 1103 * # This code is reserved for the unsupported instructions DMULT, 1104 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt 1105 * to execute it causes a Reserved Instruction exception. 1106 * 1107 * MMI instructions encoded by opcode field (MMI, LQ, SQ): 1108 * 1109 * 31 26 0 1110 * +--------+----------------------------------------+ 1111 * | opcode | | 1112 * +--------+----------------------------------------+ 1113 * 1114 * opcode bits 28..26 1115 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1116 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1117 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1118 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ 1119 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI 1120 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL 1121 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ 1122 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU 1123 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE 1124 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD 1125 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD 1126 */ 1127 1128 enum { 1129 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */ 1130 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */ 1131 }; 1132 1133 /* 1134 * MMI instructions with opcode field = MMI: 1135 * 1136 * 31 26 5 0 1137 * +--------+-------------------------------+--------+ 1138 * | MMI | |function| 1139 * +--------+-------------------------------+--------+ 1140 * 1141 * function bits 2..0 1142 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1143 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1144 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1145 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * 1146 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * 1147 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * 1148 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * 1149 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * 1150 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * 1151 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH 1152 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW 1153 */ 1154 1155 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) 1156 enum { 1157 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */ 1158 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */ 1159 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */ 1160 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */ 1161 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */ 1162 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */ 1163 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI, 1164 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI, 1165 }; 1166 1167 /* global register indices */ 1168 TCGv cpu_gpr[32], cpu_PC; 1169 /* 1170 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[]) 1171 * and the upper halves in cpu_gpr_hi[]. 1172 */ 1173 TCGv_i64 cpu_gpr_hi[32]; 1174 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; 1175 static TCGv cpu_dspctrl, btarget; 1176 TCGv bcond; 1177 static TCGv cpu_lladdr, cpu_llval; 1178 static TCGv_i32 hflags; 1179 TCGv_i32 fpu_fcr0, fpu_fcr31; 1180 TCGv_i64 fpu_f64[32]; 1181 1182 static const char regnames_HI[][4] = { 1183 "HI0", "HI1", "HI2", "HI3", 1184 }; 1185 1186 static const char regnames_LO[][4] = { 1187 "LO0", "LO1", "LO2", "LO3", 1188 }; 1189 1190 /* General purpose registers moves. */ 1191 void gen_load_gpr(TCGv t, int reg) 1192 { 1193 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr)); 1194 if (reg == 0) { 1195 tcg_gen_movi_tl(t, 0); 1196 } else { 1197 tcg_gen_mov_tl(t, cpu_gpr[reg]); 1198 } 1199 } 1200 1201 void gen_store_gpr(TCGv t, int reg) 1202 { 1203 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr)); 1204 if (reg != 0) { 1205 tcg_gen_mov_tl(cpu_gpr[reg], t); 1206 } 1207 } 1208 1209 #if defined(TARGET_MIPS64) 1210 void gen_load_gpr_hi(TCGv_i64 t, int reg) 1211 { 1212 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi)); 1213 if (reg == 0) { 1214 tcg_gen_movi_i64(t, 0); 1215 } else { 1216 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]); 1217 } 1218 } 1219 1220 void gen_store_gpr_hi(TCGv_i64 t, int reg) 1221 { 1222 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi)); 1223 if (reg != 0) { 1224 tcg_gen_mov_i64(cpu_gpr_hi[reg], t); 1225 } 1226 } 1227 #endif /* TARGET_MIPS64 */ 1228 1229 /* Moves to/from shadow registers. */ 1230 static inline void gen_load_srsgpr(int from, int to) 1231 { 1232 TCGv t0 = tcg_temp_new(); 1233 1234 if (from == 0) { 1235 tcg_gen_movi_tl(t0, 0); 1236 } else { 1237 TCGv_i32 t2 = tcg_temp_new_i32(); 1238 TCGv_ptr addr = tcg_temp_new_ptr(); 1239 1240 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1241 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1242 tcg_gen_andi_i32(t2, t2, 0xf); 1243 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1244 tcg_gen_ext_i32_ptr(addr, t2); 1245 tcg_gen_add_ptr(addr, tcg_env, addr); 1246 1247 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 1248 } 1249 gen_store_gpr(t0, to); 1250 } 1251 1252 static inline void gen_store_srsgpr(int from, int to) 1253 { 1254 if (to != 0) { 1255 TCGv t0 = tcg_temp_new(); 1256 TCGv_i32 t2 = tcg_temp_new_i32(); 1257 TCGv_ptr addr = tcg_temp_new_ptr(); 1258 1259 gen_load_gpr(t0, from); 1260 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1261 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1262 tcg_gen_andi_i32(t2, t2, 0xf); 1263 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1264 tcg_gen_ext_i32_ptr(addr, t2); 1265 tcg_gen_add_ptr(addr, tcg_env, addr); 1266 1267 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 1268 } 1269 } 1270 1271 /* Tests */ 1272 static inline void gen_save_pc(target_ulong pc) 1273 { 1274 tcg_gen_movi_tl(cpu_PC, pc); 1275 } 1276 1277 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) 1278 { 1279 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 1280 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { 1281 gen_save_pc(ctx->base.pc_next); 1282 ctx->saved_pc = ctx->base.pc_next; 1283 } 1284 if (ctx->hflags != ctx->saved_hflags) { 1285 tcg_gen_movi_i32(hflags, ctx->hflags); 1286 ctx->saved_hflags = ctx->hflags; 1287 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1288 case MIPS_HFLAG_BR: 1289 break; 1290 case MIPS_HFLAG_BC: 1291 case MIPS_HFLAG_BL: 1292 case MIPS_HFLAG_B: 1293 tcg_gen_movi_tl(btarget, ctx->btarget); 1294 break; 1295 } 1296 } 1297 } 1298 1299 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) 1300 { 1301 ctx->saved_hflags = ctx->hflags; 1302 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1303 case MIPS_HFLAG_BR: 1304 break; 1305 case MIPS_HFLAG_BC: 1306 case MIPS_HFLAG_BL: 1307 case MIPS_HFLAG_B: 1308 ctx->btarget = env->btarget; 1309 break; 1310 } 1311 } 1312 1313 void generate_exception_err(DisasContext *ctx, int excp, int err) 1314 { 1315 save_cpu_state(ctx, 1); 1316 gen_helper_raise_exception_err(tcg_env, tcg_constant_i32(excp), 1317 tcg_constant_i32(err)); 1318 ctx->base.is_jmp = DISAS_NORETURN; 1319 } 1320 1321 void generate_exception(DisasContext *ctx, int excp) 1322 { 1323 gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp)); 1324 } 1325 1326 void generate_exception_end(DisasContext *ctx, int excp) 1327 { 1328 generate_exception_err(ctx, excp, 0); 1329 } 1330 1331 void generate_exception_break(DisasContext *ctx, int code) 1332 { 1333 #ifdef CONFIG_USER_ONLY 1334 /* Pass the break code along to cpu_loop. */ 1335 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 1336 offsetof(CPUMIPSState, error_code)); 1337 #endif 1338 generate_exception_end(ctx, EXCP_BREAK); 1339 } 1340 1341 void gen_reserved_instruction(DisasContext *ctx) 1342 { 1343 generate_exception_end(ctx, EXCP_RI); 1344 } 1345 1346 /* Floating point register moves. */ 1347 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1348 { 1349 if (ctx->hflags & MIPS_HFLAG_FRE) { 1350 generate_exception(ctx, EXCP_RI); 1351 } 1352 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); 1353 } 1354 1355 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1356 { 1357 TCGv_i64 t64; 1358 if (ctx->hflags & MIPS_HFLAG_FRE) { 1359 generate_exception(ctx, EXCP_RI); 1360 } 1361 t64 = tcg_temp_new_i64(); 1362 tcg_gen_extu_i32_i64(t64, t); 1363 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); 1364 } 1365 1366 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1367 { 1368 if (ctx->hflags & MIPS_HFLAG_F64) { 1369 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); 1370 } else { 1371 gen_load_fpr32(ctx, t, reg | 1); 1372 } 1373 } 1374 1375 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1376 { 1377 if (ctx->hflags & MIPS_HFLAG_F64) { 1378 TCGv_i64 t64 = tcg_temp_new_i64(); 1379 tcg_gen_extu_i32_i64(t64, t); 1380 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); 1381 } else { 1382 gen_store_fpr32(ctx, t, reg | 1); 1383 } 1384 } 1385 1386 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1387 { 1388 if (ctx->hflags & MIPS_HFLAG_F64) { 1389 tcg_gen_mov_i64(t, fpu_f64[reg]); 1390 } else { 1391 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]); 1392 } 1393 } 1394 1395 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1396 { 1397 if (ctx->hflags & MIPS_HFLAG_F64) { 1398 tcg_gen_mov_i64(fpu_f64[reg], t); 1399 } else { 1400 TCGv_i64 t0; 1401 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32); 1402 t0 = tcg_temp_new_i64(); 1403 tcg_gen_shri_i64(t0, t, 32); 1404 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32); 1405 } 1406 } 1407 1408 int get_fp_bit(int cc) 1409 { 1410 if (cc) { 1411 return 24 + cc; 1412 } else { 1413 return 23; 1414 } 1415 } 1416 1417 /* Addresses computation */ 1418 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 1419 { 1420 tcg_gen_add_tl(ret, arg0, arg1); 1421 1422 #if defined(TARGET_MIPS64) 1423 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1424 tcg_gen_ext32s_i64(ret, ret); 1425 } 1426 #endif 1427 } 1428 1429 void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, target_long ofs) 1430 { 1431 tcg_gen_addi_tl(ret, base, ofs); 1432 1433 #if defined(TARGET_MIPS64) 1434 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1435 tcg_gen_ext32s_i64(ret, ret); 1436 } 1437 #endif 1438 } 1439 1440 /* Addresses computation (translation time) */ 1441 static target_long addr_add(DisasContext *ctx, target_long base, 1442 target_long offset) 1443 { 1444 target_long sum = base + offset; 1445 1446 #if defined(TARGET_MIPS64) 1447 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1448 sum = (int32_t)sum; 1449 } 1450 #endif 1451 return sum; 1452 } 1453 1454 /* Sign-extract the low 32-bits to a target_long. */ 1455 void gen_move_low32(TCGv ret, TCGv_i64 arg) 1456 { 1457 #if defined(TARGET_MIPS64) 1458 tcg_gen_ext32s_i64(ret, arg); 1459 #else 1460 tcg_gen_extrl_i64_i32(ret, arg); 1461 #endif 1462 } 1463 1464 /* Sign-extract the high 32-bits to a target_long. */ 1465 void gen_move_high32(TCGv ret, TCGv_i64 arg) 1466 { 1467 #if defined(TARGET_MIPS64) 1468 tcg_gen_sari_i64(ret, arg, 32); 1469 #else 1470 tcg_gen_extrh_i64_i32(ret, arg); 1471 #endif 1472 } 1473 1474 bool check_cp0_enabled(DisasContext *ctx) 1475 { 1476 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1477 generate_exception_end(ctx, EXCP_CpU); 1478 return false; 1479 } 1480 return true; 1481 } 1482 1483 void check_cp1_enabled(DisasContext *ctx) 1484 { 1485 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) { 1486 generate_exception_err(ctx, EXCP_CpU, 1); 1487 } 1488 } 1489 1490 /* 1491 * Verify that the processor is running with COP1X instructions enabled. 1492 * This is associated with the nabla symbol in the MIPS32 and MIPS64 1493 * opcode tables. 1494 */ 1495 void check_cop1x(DisasContext *ctx) 1496 { 1497 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { 1498 gen_reserved_instruction(ctx); 1499 } 1500 } 1501 1502 /* 1503 * Verify that the processor is running with 64-bit floating-point 1504 * operations enabled. 1505 */ 1506 void check_cp1_64bitmode(DisasContext *ctx) 1507 { 1508 if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) { 1509 gen_reserved_instruction(ctx); 1510 } 1511 } 1512 1513 /* 1514 * Verify if floating point register is valid; an operation is not defined 1515 * if bit 0 of any register specification is set and the FR bit in the 1516 * Status register equals zero, since the register numbers specify an 1517 * even-odd pair of adjacent coprocessor general registers. When the FR bit 1518 * in the Status register equals one, both even and odd register numbers 1519 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 1520 * 1521 * Multiple 64 bit wide registers can be checked by calling 1522 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 1523 */ 1524 void check_cp1_registers(DisasContext *ctx, int regs) 1525 { 1526 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { 1527 gen_reserved_instruction(ctx); 1528 } 1529 } 1530 1531 /* 1532 * Verify that the processor is running with DSP instructions enabled. 1533 * This is enabled by CP0 Status register MX(24) bit. 1534 */ 1535 static inline void check_dsp(DisasContext *ctx) 1536 { 1537 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { 1538 if (ctx->insn_flags & ASE_DSP) { 1539 generate_exception_end(ctx, EXCP_DSPDIS); 1540 } else { 1541 gen_reserved_instruction(ctx); 1542 } 1543 } 1544 } 1545 1546 static inline void check_dsp_r2(DisasContext *ctx) 1547 { 1548 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { 1549 if (ctx->insn_flags & ASE_DSP) { 1550 generate_exception_end(ctx, EXCP_DSPDIS); 1551 } else { 1552 gen_reserved_instruction(ctx); 1553 } 1554 } 1555 } 1556 1557 static inline void check_dsp_r3(DisasContext *ctx) 1558 { 1559 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { 1560 if (ctx->insn_flags & ASE_DSP) { 1561 generate_exception_end(ctx, EXCP_DSPDIS); 1562 } else { 1563 gen_reserved_instruction(ctx); 1564 } 1565 } 1566 } 1567 1568 /* 1569 * This code generates a "reserved instruction" exception if the 1570 * CPU does not support the instruction set corresponding to flags. 1571 */ 1572 void check_insn(DisasContext *ctx, uint64_t flags) 1573 { 1574 if (unlikely(!(ctx->insn_flags & flags))) { 1575 gen_reserved_instruction(ctx); 1576 } 1577 } 1578 1579 /* 1580 * This code generates a "reserved instruction" exception if the 1581 * CPU has corresponding flag set which indicates that the instruction 1582 * has been removed. 1583 */ 1584 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) 1585 { 1586 if (unlikely(ctx->insn_flags & flags)) { 1587 gen_reserved_instruction(ctx); 1588 } 1589 } 1590 1591 /* 1592 * The Linux kernel traps certain reserved instruction exceptions to 1593 * emulate the corresponding instructions. QEMU is the kernel in user 1594 * mode, so those traps are emulated by accepting the instructions. 1595 * 1596 * A reserved instruction exception is generated for flagged CPUs if 1597 * QEMU runs in system mode. 1598 */ 1599 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) 1600 { 1601 #ifndef CONFIG_USER_ONLY 1602 check_insn_opc_removed(ctx, flags); 1603 #endif 1604 } 1605 1606 /* 1607 * This code generates a "reserved instruction" exception if the 1608 * CPU does not support 64-bit paired-single (PS) floating point data type. 1609 */ 1610 static inline void check_ps(DisasContext *ctx) 1611 { 1612 if (unlikely(!ctx->ps)) { 1613 generate_exception(ctx, EXCP_RI); 1614 } 1615 check_cp1_64bitmode(ctx); 1616 } 1617 1618 bool decode_64bit_enabled(DisasContext *ctx) 1619 { 1620 return ctx->hflags & MIPS_HFLAG_64; 1621 } 1622 1623 /* 1624 * This code generates a "reserved instruction" exception if cpu is not 1625 * 64-bit or 64-bit instructions are not enabled. 1626 */ 1627 void check_mips_64(DisasContext *ctx) 1628 { 1629 if (unlikely((TARGET_LONG_BITS != 64) || !decode_64bit_enabled(ctx))) { 1630 gen_reserved_instruction(ctx); 1631 } 1632 } 1633 1634 #ifndef CONFIG_USER_ONLY 1635 static inline void check_mvh(DisasContext *ctx) 1636 { 1637 if (unlikely(!ctx->mvh)) { 1638 generate_exception(ctx, EXCP_RI); 1639 } 1640 } 1641 #endif 1642 1643 /* 1644 * This code generates a "reserved instruction" exception if the 1645 * Config5 XNP bit is set. 1646 */ 1647 static inline void check_xnp(DisasContext *ctx) 1648 { 1649 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) { 1650 gen_reserved_instruction(ctx); 1651 } 1652 } 1653 1654 #ifndef CONFIG_USER_ONLY 1655 /* 1656 * This code generates a "reserved instruction" exception if the 1657 * Config3 PW bit is NOT set. 1658 */ 1659 static inline void check_pw(DisasContext *ctx) 1660 { 1661 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) { 1662 gen_reserved_instruction(ctx); 1663 } 1664 } 1665 #endif 1666 1667 /* 1668 * This code generates a "reserved instruction" exception if the 1669 * Config3 MT bit is NOT set. 1670 */ 1671 static inline void check_mt(DisasContext *ctx) 1672 { 1673 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1674 gen_reserved_instruction(ctx); 1675 } 1676 } 1677 1678 #ifndef CONFIG_USER_ONLY 1679 /* 1680 * This code generates a "coprocessor unusable" exception if CP0 is not 1681 * available, and, if that is not the case, generates a "reserved instruction" 1682 * exception if the Config5 MT bit is NOT set. This is needed for availability 1683 * control of some of MT ASE instructions. 1684 */ 1685 static inline void check_cp0_mt(DisasContext *ctx) 1686 { 1687 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1688 generate_exception_end(ctx, EXCP_CpU); 1689 } else { 1690 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1691 gen_reserved_instruction(ctx); 1692 } 1693 } 1694 } 1695 #endif 1696 1697 /* 1698 * This code generates a "reserved instruction" exception if the 1699 * Config5 NMS bit is set. 1700 */ 1701 static inline void check_nms(DisasContext *ctx) 1702 { 1703 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) { 1704 gen_reserved_instruction(ctx); 1705 } 1706 } 1707 1708 /* 1709 * This code generates a "reserved instruction" exception if the 1710 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, 1711 * Config2 TL, and Config5 L2C are unset. 1712 */ 1713 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) 1714 { 1715 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) && 1716 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) && 1717 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) && 1718 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && 1719 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && 1720 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) { 1721 gen_reserved_instruction(ctx); 1722 } 1723 } 1724 1725 /* 1726 * This code generates a "reserved instruction" exception if the 1727 * Config5 EVA bit is NOT set. 1728 */ 1729 static inline void check_eva(DisasContext *ctx) 1730 { 1731 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) { 1732 gen_reserved_instruction(ctx); 1733 } 1734 } 1735 1736 1737 /* 1738 * Define small wrappers for gen_load_fpr* so that we have a uniform 1739 * calling interface for 32 and 64-bit FPRs. No sense in changing 1740 * all callers for gen_load_fpr32 when we need the CTX parameter for 1741 * this one use. 1742 */ 1743 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) 1744 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) 1745 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \ 1746 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ 1747 int ft, int fs, int cc) \ 1748 { \ 1749 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ 1750 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ 1751 switch (ifmt) { \ 1752 case FMT_PS: \ 1753 check_ps(ctx); \ 1754 break; \ 1755 case FMT_D: \ 1756 if (abs) { \ 1757 check_cop1x(ctx); \ 1758 } \ 1759 check_cp1_registers(ctx, fs | ft); \ 1760 break; \ 1761 case FMT_S: \ 1762 if (abs) { \ 1763 check_cop1x(ctx); \ 1764 } \ 1765 break; \ 1766 } \ 1767 gen_ldcmp_fpr##bits(ctx, fp0, fs); \ 1768 gen_ldcmp_fpr##bits(ctx, fp1, ft); \ 1769 switch (n) { \ 1770 case 0: \ 1771 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \ 1772 break; \ 1773 case 1: \ 1774 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \ 1775 break; \ 1776 case 2: \ 1777 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \ 1778 break; \ 1779 case 3: \ 1780 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \ 1781 break; \ 1782 case 4: \ 1783 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \ 1784 break; \ 1785 case 5: \ 1786 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \ 1787 break; \ 1788 case 6: \ 1789 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \ 1790 break; \ 1791 case 7: \ 1792 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \ 1793 break; \ 1794 case 8: \ 1795 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \ 1796 break; \ 1797 case 9: \ 1798 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \ 1799 break; \ 1800 case 10: \ 1801 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \ 1802 break; \ 1803 case 11: \ 1804 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \ 1805 break; \ 1806 case 12: \ 1807 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \ 1808 break; \ 1809 case 13: \ 1810 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \ 1811 break; \ 1812 case 14: \ 1813 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \ 1814 break; \ 1815 case 15: \ 1816 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \ 1817 break; \ 1818 default: \ 1819 abort(); \ 1820 } \ 1821 } 1822 1823 FOP_CONDS(, 0, d, FMT_D, 64) 1824 FOP_CONDS(abs, 1, d, FMT_D, 64) 1825 FOP_CONDS(, 0, s, FMT_S, 32) 1826 FOP_CONDS(abs, 1, s, FMT_S, 32) 1827 FOP_CONDS(, 0, ps, FMT_PS, 64) 1828 FOP_CONDS(abs, 1, ps, FMT_PS, 64) 1829 #undef FOP_CONDS 1830 1831 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \ 1832 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \ 1833 int ft, int fs, int fd) \ 1834 { \ 1835 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ 1836 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ 1837 if (ifmt == FMT_D) { \ 1838 check_cp1_registers(ctx, fs | ft | fd); \ 1839 } \ 1840 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ 1841 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ 1842 switch (n) { \ 1843 case 0: \ 1844 gen_helper_r6_cmp_ ## fmt ## _af(fp0, tcg_env, fp0, fp1); \ 1845 break; \ 1846 case 1: \ 1847 gen_helper_r6_cmp_ ## fmt ## _un(fp0, tcg_env, fp0, fp1); \ 1848 break; \ 1849 case 2: \ 1850 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, tcg_env, fp0, fp1); \ 1851 break; \ 1852 case 3: \ 1853 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, tcg_env, fp0, fp1); \ 1854 break; \ 1855 case 4: \ 1856 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, tcg_env, fp0, fp1); \ 1857 break; \ 1858 case 5: \ 1859 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, tcg_env, fp0, fp1); \ 1860 break; \ 1861 case 6: \ 1862 gen_helper_r6_cmp_ ## fmt ## _le(fp0, tcg_env, fp0, fp1); \ 1863 break; \ 1864 case 7: \ 1865 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, tcg_env, fp0, fp1); \ 1866 break; \ 1867 case 8: \ 1868 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, tcg_env, fp0, fp1); \ 1869 break; \ 1870 case 9: \ 1871 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, tcg_env, fp0, fp1); \ 1872 break; \ 1873 case 10: \ 1874 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, tcg_env, fp0, fp1); \ 1875 break; \ 1876 case 11: \ 1877 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, tcg_env, fp0, fp1); \ 1878 break; \ 1879 case 12: \ 1880 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, tcg_env, fp0, fp1); \ 1881 break; \ 1882 case 13: \ 1883 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, tcg_env, fp0, fp1); \ 1884 break; \ 1885 case 14: \ 1886 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, tcg_env, fp0, fp1); \ 1887 break; \ 1888 case 15: \ 1889 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, tcg_env, fp0, fp1); \ 1890 break; \ 1891 case 17: \ 1892 gen_helper_r6_cmp_ ## fmt ## _or(fp0, tcg_env, fp0, fp1); \ 1893 break; \ 1894 case 18: \ 1895 gen_helper_r6_cmp_ ## fmt ## _une(fp0, tcg_env, fp0, fp1); \ 1896 break; \ 1897 case 19: \ 1898 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, tcg_env, fp0, fp1); \ 1899 break; \ 1900 case 25: \ 1901 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, tcg_env, fp0, fp1); \ 1902 break; \ 1903 case 26: \ 1904 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, tcg_env, fp0, fp1); \ 1905 break; \ 1906 case 27: \ 1907 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, tcg_env, fp0, fp1); \ 1908 break; \ 1909 default: \ 1910 abort(); \ 1911 } \ 1912 STORE; \ 1913 } 1914 1915 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) 1916 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd)) 1917 #undef FOP_CONDNS 1918 #undef gen_ldcmp_fpr32 1919 #undef gen_ldcmp_fpr64 1920 1921 /* load/store instructions. */ 1922 #ifdef CONFIG_USER_ONLY 1923 #define OP_LD_ATOMIC(insn, memop) \ 1924 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1925 DisasContext *ctx) \ 1926 { \ 1927 TCGv t0 = tcg_temp_new(); \ 1928 tcg_gen_mov_tl(t0, arg1); \ 1929 tcg_gen_qemu_ld_tl(ret, arg1, ctx->mem_idx, memop); \ 1930 tcg_gen_st_tl(t0, tcg_env, offsetof(CPUMIPSState, lladdr)); \ 1931 tcg_gen_st_tl(ret, tcg_env, offsetof(CPUMIPSState, llval)); \ 1932 } 1933 #else 1934 #define OP_LD_ATOMIC(insn, ignored_memop) \ 1935 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1936 DisasContext *ctx) \ 1937 { \ 1938 gen_helper_##insn(ret, tcg_env, arg1, tcg_constant_i32(mem_idx)); \ 1939 } 1940 #endif 1941 OP_LD_ATOMIC(ll, mo_endian(ctx) | MO_SL); 1942 #if defined(TARGET_MIPS64) 1943 OP_LD_ATOMIC(lld, mo_endian(ctx) | MO_UQ); 1944 #endif 1945 #undef OP_LD_ATOMIC 1946 1947 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset) 1948 { 1949 if (base == 0) { 1950 tcg_gen_movi_tl(addr, offset); 1951 } else if (offset == 0) { 1952 gen_load_gpr(addr, base); 1953 } else { 1954 tcg_gen_movi_tl(addr, offset); 1955 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); 1956 } 1957 } 1958 1959 static target_ulong pc_relative_pc(DisasContext *ctx) 1960 { 1961 target_ulong pc = ctx->base.pc_next; 1962 1963 if (ctx->hflags & MIPS_HFLAG_BMASK) { 1964 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4; 1965 1966 pc -= branch_bytes; 1967 } 1968 1969 pc &= ~(target_ulong)3; 1970 return pc; 1971 } 1972 1973 /* LWL or LDL, depending on MemOp. */ 1974 static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr, 1975 int mem_idx, MemOp mop) 1976 { 1977 int sizem1 = memop_size(mop) - 1; 1978 TCGv t0 = tcg_temp_new(); 1979 TCGv t1 = tcg_temp_new(); 1980 1981 /* 1982 * Do a byte access to possibly trigger a page 1983 * fault with the unaligned address. 1984 */ 1985 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); 1986 tcg_gen_andi_tl(t1, addr, sizem1); 1987 if (!disas_is_bigendian(ctx)) { 1988 tcg_gen_xori_tl(t1, t1, sizem1); 1989 } 1990 tcg_gen_shli_tl(t1, t1, 3); 1991 tcg_gen_andi_tl(t0, addr, ~sizem1); 1992 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); 1993 tcg_gen_shl_tl(t0, t0, t1); 1994 tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1); 1995 tcg_gen_andc_tl(t1, reg, t1); 1996 tcg_gen_or_tl(reg, t0, t1); 1997 } 1998 1999 /* LWR or LDR, depending on MemOp. */ 2000 static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr, 2001 int mem_idx, MemOp mop) 2002 { 2003 int size = memop_size(mop); 2004 int sizem1 = size - 1; 2005 TCGv t0 = tcg_temp_new(); 2006 TCGv t1 = tcg_temp_new(); 2007 2008 /* 2009 * Do a byte access to possibly trigger a page 2010 * fault with the unaligned address. 2011 */ 2012 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); 2013 tcg_gen_andi_tl(t1, addr, sizem1); 2014 if (disas_is_bigendian(ctx)) { 2015 tcg_gen_xori_tl(t1, t1, sizem1); 2016 } 2017 tcg_gen_shli_tl(t1, t1, 3); 2018 tcg_gen_andi_tl(t0, addr, ~sizem1); 2019 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); 2020 tcg_gen_shr_tl(t0, t0, t1); 2021 tcg_gen_xori_tl(t1, t1, size * 8 - 1); 2022 tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1); 2023 tcg_gen_and_tl(t1, reg, t1); 2024 tcg_gen_or_tl(reg, t0, t1); 2025 } 2026 2027 /* Load */ 2028 static void gen_ld(DisasContext *ctx, uint32_t opc, 2029 int rt, int base, int offset) 2030 { 2031 TCGv t0, t1; 2032 int mem_idx = ctx->mem_idx; 2033 2034 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F | 2035 INSN_LOONGSON3A)) { 2036 /* 2037 * Loongson CPU uses a load to zero register for prefetch. 2038 * We emulate it as a NOP. On other CPU we must perform the 2039 * actual memory access. 2040 */ 2041 return; 2042 } 2043 2044 t0 = tcg_temp_new(); 2045 gen_base_offset_addr(ctx, t0, base, offset); 2046 2047 switch (opc) { 2048 #if defined(TARGET_MIPS64) 2049 case OPC_LWU: 2050 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UL | 2051 ctx->default_tcg_memop_mask); 2052 gen_store_gpr(t0, rt); 2053 break; 2054 case OPC_LD: 2055 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ | 2056 ctx->default_tcg_memop_mask); 2057 gen_store_gpr(t0, rt); 2058 break; 2059 case OPC_LLD: 2060 case R6_OPC_LLD: 2061 op_ld_lld(t0, t0, mem_idx, ctx); 2062 gen_store_gpr(t0, rt); 2063 break; 2064 case OPC_LDL: 2065 t1 = tcg_temp_new(); 2066 gen_load_gpr(t1, rt); 2067 gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2068 gen_store_gpr(t1, rt); 2069 break; 2070 case OPC_LDR: 2071 t1 = tcg_temp_new(); 2072 gen_load_gpr(t1, rt); 2073 gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2074 gen_store_gpr(t1, rt); 2075 break; 2076 case OPC_LDPC: 2077 t1 = tcg_constant_tl(pc_relative_pc(ctx)); 2078 gen_op_addr_add(ctx, t0, t0, t1); 2079 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2080 gen_store_gpr(t0, rt); 2081 break; 2082 #endif 2083 case OPC_LWPC: 2084 t1 = tcg_constant_tl(pc_relative_pc(ctx)); 2085 gen_op_addr_add(ctx, t0, t0, t1); 2086 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL); 2087 gen_store_gpr(t0, rt); 2088 break; 2089 case OPC_LWE: 2090 mem_idx = MIPS_HFLAG_UM; 2091 /* fall through */ 2092 case OPC_LW: 2093 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL | 2094 ctx->default_tcg_memop_mask); 2095 gen_store_gpr(t0, rt); 2096 break; 2097 case OPC_LHE: 2098 mem_idx = MIPS_HFLAG_UM; 2099 /* fall through */ 2100 case OPC_LH: 2101 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SW | 2102 ctx->default_tcg_memop_mask); 2103 gen_store_gpr(t0, rt); 2104 break; 2105 case OPC_LHUE: 2106 mem_idx = MIPS_HFLAG_UM; 2107 /* fall through */ 2108 case OPC_LHU: 2109 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UW | 2110 ctx->default_tcg_memop_mask); 2111 gen_store_gpr(t0, rt); 2112 break; 2113 case OPC_LBE: 2114 mem_idx = MIPS_HFLAG_UM; 2115 /* fall through */ 2116 case OPC_LB: 2117 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); 2118 gen_store_gpr(t0, rt); 2119 break; 2120 case OPC_LBUE: 2121 mem_idx = MIPS_HFLAG_UM; 2122 /* fall through */ 2123 case OPC_LBU: 2124 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); 2125 gen_store_gpr(t0, rt); 2126 break; 2127 case OPC_LWLE: 2128 mem_idx = MIPS_HFLAG_UM; 2129 /* fall through */ 2130 case OPC_LWL: 2131 t1 = tcg_temp_new(); 2132 gen_load_gpr(t1, rt); 2133 gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL); 2134 tcg_gen_ext32s_tl(t1, t1); 2135 gen_store_gpr(t1, rt); 2136 break; 2137 case OPC_LWRE: 2138 mem_idx = MIPS_HFLAG_UM; 2139 /* fall through */ 2140 case OPC_LWR: 2141 t1 = tcg_temp_new(); 2142 gen_load_gpr(t1, rt); 2143 gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL); 2144 tcg_gen_ext32s_tl(t1, t1); 2145 gen_store_gpr(t1, rt); 2146 break; 2147 case OPC_LLE: 2148 mem_idx = MIPS_HFLAG_UM; 2149 /* fall through */ 2150 case OPC_LL: 2151 case R6_OPC_LL: 2152 op_ld_ll(t0, t0, mem_idx, ctx); 2153 gen_store_gpr(t0, rt); 2154 break; 2155 } 2156 } 2157 2158 /* Store */ 2159 static void gen_st(DisasContext *ctx, uint32_t opc, int rt, 2160 int base, int offset) 2161 { 2162 TCGv t0 = tcg_temp_new(); 2163 TCGv t1 = tcg_temp_new(); 2164 int mem_idx = ctx->mem_idx; 2165 2166 gen_base_offset_addr(ctx, t0, base, offset); 2167 gen_load_gpr(t1, rt); 2168 switch (opc) { 2169 #if defined(TARGET_MIPS64) 2170 case OPC_SD: 2171 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UQ | 2172 ctx->default_tcg_memop_mask); 2173 break; 2174 case OPC_SDL: 2175 gen_helper_0e2i(sdl, t1, t0, mem_idx); 2176 break; 2177 case OPC_SDR: 2178 gen_helper_0e2i(sdr, t1, t0, mem_idx); 2179 break; 2180 #endif 2181 case OPC_SWE: 2182 mem_idx = MIPS_HFLAG_UM; 2183 /* fall through */ 2184 case OPC_SW: 2185 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UL | 2186 ctx->default_tcg_memop_mask); 2187 break; 2188 case OPC_SHE: 2189 mem_idx = MIPS_HFLAG_UM; 2190 /* fall through */ 2191 case OPC_SH: 2192 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UW | 2193 ctx->default_tcg_memop_mask); 2194 break; 2195 case OPC_SBE: 2196 mem_idx = MIPS_HFLAG_UM; 2197 /* fall through */ 2198 case OPC_SB: 2199 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); 2200 break; 2201 case OPC_SWLE: 2202 mem_idx = MIPS_HFLAG_UM; 2203 /* fall through */ 2204 case OPC_SWL: 2205 gen_helper_0e2i(swl, t1, t0, mem_idx); 2206 break; 2207 case OPC_SWRE: 2208 mem_idx = MIPS_HFLAG_UM; 2209 /* fall through */ 2210 case OPC_SWR: 2211 gen_helper_0e2i(swr, t1, t0, mem_idx); 2212 break; 2213 } 2214 } 2215 2216 2217 /* Store conditional */ 2218 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, 2219 MemOp tcg_mo, bool eva) 2220 { 2221 TCGv addr, t0, val; 2222 TCGLabel *l1 = gen_new_label(); 2223 TCGLabel *done = gen_new_label(); 2224 2225 t0 = tcg_temp_new(); 2226 addr = tcg_temp_new(); 2227 /* compare the address against that of the preceding LL */ 2228 gen_base_offset_addr(ctx, addr, base, offset); 2229 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); 2230 gen_store_gpr(tcg_constant_tl(0), rt); 2231 tcg_gen_br(done); 2232 2233 gen_set_label(l1); 2234 /* generate cmpxchg */ 2235 val = tcg_temp_new(); 2236 gen_load_gpr(val, rt); 2237 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, 2238 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo); 2239 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); 2240 gen_store_gpr(t0, rt); 2241 2242 gen_set_label(done); 2243 } 2244 2245 /* Load and store */ 2246 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, 2247 TCGv t0) 2248 { 2249 /* 2250 * Don't do NOP if destination is zero: we must perform the actual 2251 * memory access. 2252 */ 2253 switch (opc) { 2254 case OPC_LWC1: 2255 { 2256 TCGv_i32 fp0 = tcg_temp_new_i32(); 2257 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 2258 ctx->default_tcg_memop_mask); 2259 gen_store_fpr32(ctx, fp0, ft); 2260 } 2261 break; 2262 case OPC_SWC1: 2263 { 2264 TCGv_i32 fp0 = tcg_temp_new_i32(); 2265 gen_load_fpr32(ctx, fp0, ft); 2266 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 2267 ctx->default_tcg_memop_mask); 2268 } 2269 break; 2270 case OPC_LDC1: 2271 { 2272 TCGv_i64 fp0 = tcg_temp_new_i64(); 2273 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 2274 ctx->default_tcg_memop_mask); 2275 gen_store_fpr64(ctx, fp0, ft); 2276 } 2277 break; 2278 case OPC_SDC1: 2279 { 2280 TCGv_i64 fp0 = tcg_temp_new_i64(); 2281 gen_load_fpr64(ctx, fp0, ft); 2282 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 2283 ctx->default_tcg_memop_mask); 2284 } 2285 break; 2286 default: 2287 MIPS_INVAL("flt_ldst"); 2288 gen_reserved_instruction(ctx); 2289 break; 2290 } 2291 } 2292 2293 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, 2294 int rs, int16_t imm) 2295 { 2296 TCGv t0 = tcg_temp_new(); 2297 2298 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2299 check_cp1_enabled(ctx); 2300 switch (op) { 2301 case OPC_LDC1: 2302 case OPC_SDC1: 2303 check_insn(ctx, ISA_MIPS2); 2304 /* Fallthrough */ 2305 default: 2306 gen_base_offset_addr(ctx, t0, rs, imm); 2307 gen_flt_ldst(ctx, op, rt, t0); 2308 } 2309 } else { 2310 generate_exception_err(ctx, EXCP_CpU, 1); 2311 } 2312 } 2313 2314 /* Arithmetic with immediate operand */ 2315 static void gen_arith_imm(DisasContext *ctx, uint32_t opc, 2316 int rt, int rs, int imm) 2317 { 2318 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2319 2320 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 2321 /* 2322 * If no destination, treat it as a NOP. 2323 * For addi, we must generate the overflow exception when needed. 2324 */ 2325 return; 2326 } 2327 switch (opc) { 2328 case OPC_ADDI: 2329 { 2330 TCGv t0 = tcg_temp_new(); 2331 TCGv t1 = tcg_temp_new(); 2332 TCGv t2 = tcg_temp_new(); 2333 TCGLabel *l1 = gen_new_label(); 2334 2335 gen_load_gpr(t1, rs); 2336 tcg_gen_addi_tl(t0, t1, uimm); 2337 tcg_gen_ext32s_tl(t0, t0); 2338 2339 tcg_gen_xori_tl(t1, t1, ~uimm); 2340 tcg_gen_xori_tl(t2, t0, uimm); 2341 tcg_gen_and_tl(t1, t1, t2); 2342 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2343 /* operands of same sign, result different sign */ 2344 generate_exception(ctx, EXCP_OVERFLOW); 2345 gen_set_label(l1); 2346 tcg_gen_ext32s_tl(t0, t0); 2347 gen_store_gpr(t0, rt); 2348 } 2349 break; 2350 case OPC_ADDIU: 2351 if (rs != 0) { 2352 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2353 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2354 } else { 2355 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2356 } 2357 break; 2358 #if defined(TARGET_MIPS64) 2359 case OPC_DADDI: 2360 { 2361 TCGv t0 = tcg_temp_new(); 2362 TCGv t1 = tcg_temp_new(); 2363 TCGv t2 = tcg_temp_new(); 2364 TCGLabel *l1 = gen_new_label(); 2365 2366 gen_load_gpr(t1, rs); 2367 tcg_gen_addi_tl(t0, t1, uimm); 2368 2369 tcg_gen_xori_tl(t1, t1, ~uimm); 2370 tcg_gen_xori_tl(t2, t0, uimm); 2371 tcg_gen_and_tl(t1, t1, t2); 2372 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2373 /* operands of same sign, result different sign */ 2374 generate_exception(ctx, EXCP_OVERFLOW); 2375 gen_set_label(l1); 2376 gen_store_gpr(t0, rt); 2377 } 2378 break; 2379 case OPC_DADDIU: 2380 if (rs != 0) { 2381 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2382 } else { 2383 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2384 } 2385 break; 2386 #endif 2387 } 2388 } 2389 2390 /* Logic with immediate operand */ 2391 static void gen_logic_imm(DisasContext *ctx, uint32_t opc, 2392 int rt, int rs, int16_t imm) 2393 { 2394 target_ulong uimm; 2395 2396 if (rt == 0) { 2397 /* If no destination, treat it as a NOP. */ 2398 return; 2399 } 2400 uimm = (uint16_t)imm; 2401 switch (opc) { 2402 case OPC_ANDI: 2403 if (likely(rs != 0)) { 2404 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2405 } else { 2406 tcg_gen_movi_tl(cpu_gpr[rt], 0); 2407 } 2408 break; 2409 case OPC_ORI: 2410 if (rs != 0) { 2411 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2412 } else { 2413 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2414 } 2415 break; 2416 case OPC_XORI: 2417 if (likely(rs != 0)) { 2418 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2419 } else { 2420 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2421 } 2422 break; 2423 case OPC_LUI: 2424 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) { 2425 /* OPC_AUI */ 2426 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16); 2427 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2428 } else { 2429 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 2430 } 2431 break; 2432 2433 default: 2434 break; 2435 } 2436 } 2437 2438 /* Set on less than with immediate operand */ 2439 static void gen_slt_imm(DisasContext *ctx, uint32_t opc, 2440 int rt, int rs, int16_t imm) 2441 { 2442 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2443 TCGv t0; 2444 2445 if (rt == 0) { 2446 /* If no destination, treat it as a NOP. */ 2447 return; 2448 } 2449 t0 = tcg_temp_new(); 2450 gen_load_gpr(t0, rs); 2451 switch (opc) { 2452 case OPC_SLTI: 2453 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); 2454 break; 2455 case OPC_SLTIU: 2456 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); 2457 break; 2458 } 2459 } 2460 2461 /* Shifts with immediate operand */ 2462 static void gen_shift_imm(DisasContext *ctx, uint32_t opc, 2463 int rt, int rs, int16_t imm) 2464 { 2465 target_ulong uimm = ((uint16_t)imm) & 0x1f; 2466 TCGv t0; 2467 2468 if (rt == 0) { 2469 /* If no destination, treat it as a NOP. */ 2470 return; 2471 } 2472 2473 t0 = tcg_temp_new(); 2474 gen_load_gpr(t0, rs); 2475 switch (opc) { 2476 case OPC_SLL: 2477 tcg_gen_shli_tl(t0, t0, uimm); 2478 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2479 break; 2480 case OPC_SRA: 2481 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2482 break; 2483 case OPC_SRL: 2484 if (uimm != 0) { 2485 tcg_gen_ext32u_tl(t0, t0); 2486 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2487 } else { 2488 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2489 } 2490 break; 2491 case OPC_ROTR: 2492 if (uimm != 0) { 2493 TCGv_i32 t1 = tcg_temp_new_i32(); 2494 2495 tcg_gen_trunc_tl_i32(t1, t0); 2496 tcg_gen_rotri_i32(t1, t1, uimm); 2497 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 2498 } else { 2499 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2500 } 2501 break; 2502 #if defined(TARGET_MIPS64) 2503 case OPC_DSLL: 2504 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 2505 break; 2506 case OPC_DSRA: 2507 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2508 break; 2509 case OPC_DSRL: 2510 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2511 break; 2512 case OPC_DROTR: 2513 if (uimm != 0) { 2514 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 2515 } else { 2516 tcg_gen_mov_tl(cpu_gpr[rt], t0); 2517 } 2518 break; 2519 case OPC_DSLL32: 2520 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 2521 break; 2522 case OPC_DSRA32: 2523 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 2524 break; 2525 case OPC_DSRL32: 2526 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 2527 break; 2528 case OPC_DROTR32: 2529 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 2530 break; 2531 #endif 2532 } 2533 } 2534 2535 /* Arithmetic */ 2536 static void gen_arith(DisasContext *ctx, uint32_t opc, 2537 int rd, int rs, int rt) 2538 { 2539 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 2540 && opc != OPC_DADD && opc != OPC_DSUB) { 2541 /* 2542 * If no destination, treat it as a NOP. 2543 * For add & sub, we must generate the overflow exception when needed. 2544 */ 2545 return; 2546 } 2547 2548 switch (opc) { 2549 case OPC_ADD: 2550 { 2551 TCGv t0 = tcg_temp_new(); 2552 TCGv t1 = tcg_temp_new(); 2553 TCGv t2 = tcg_temp_new(); 2554 TCGLabel *l1 = gen_new_label(); 2555 2556 gen_load_gpr(t1, rs); 2557 gen_load_gpr(t2, rt); 2558 tcg_gen_add_tl(t0, t1, t2); 2559 tcg_gen_ext32s_tl(t0, t0); 2560 tcg_gen_xor_tl(t1, t1, t2); 2561 tcg_gen_xor_tl(t2, t0, t2); 2562 tcg_gen_andc_tl(t1, t2, t1); 2563 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2564 /* operands of same sign, result different sign */ 2565 generate_exception(ctx, EXCP_OVERFLOW); 2566 gen_set_label(l1); 2567 gen_store_gpr(t0, rd); 2568 } 2569 break; 2570 case OPC_ADDU: 2571 if (rs != 0 && rt != 0) { 2572 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2573 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2574 } else if (rs == 0 && rt != 0) { 2575 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2576 } else if (rs != 0 && rt == 0) { 2577 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2578 } else { 2579 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2580 } 2581 break; 2582 case OPC_SUB: 2583 { 2584 TCGv t0 = tcg_temp_new(); 2585 TCGv t1 = tcg_temp_new(); 2586 TCGv t2 = tcg_temp_new(); 2587 TCGLabel *l1 = gen_new_label(); 2588 2589 gen_load_gpr(t1, rs); 2590 gen_load_gpr(t2, rt); 2591 tcg_gen_sub_tl(t0, t1, t2); 2592 tcg_gen_ext32s_tl(t0, t0); 2593 tcg_gen_xor_tl(t2, t1, t2); 2594 tcg_gen_xor_tl(t1, t0, t1); 2595 tcg_gen_and_tl(t1, t1, t2); 2596 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2597 /* 2598 * operands of different sign, first operand and the result 2599 * of different sign 2600 */ 2601 generate_exception(ctx, EXCP_OVERFLOW); 2602 gen_set_label(l1); 2603 gen_store_gpr(t0, rd); 2604 } 2605 break; 2606 case OPC_SUBU: 2607 if (rs != 0 && rt != 0) { 2608 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2609 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2610 } else if (rs == 0 && rt != 0) { 2611 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2612 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2613 } else if (rs != 0 && rt == 0) { 2614 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2615 } else { 2616 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2617 } 2618 break; 2619 #if defined(TARGET_MIPS64) 2620 case OPC_DADD: 2621 { 2622 TCGv t0 = tcg_temp_new(); 2623 TCGv t1 = tcg_temp_new(); 2624 TCGv t2 = tcg_temp_new(); 2625 TCGLabel *l1 = gen_new_label(); 2626 2627 gen_load_gpr(t1, rs); 2628 gen_load_gpr(t2, rt); 2629 tcg_gen_add_tl(t0, t1, t2); 2630 tcg_gen_xor_tl(t1, t1, t2); 2631 tcg_gen_xor_tl(t2, t0, t2); 2632 tcg_gen_andc_tl(t1, t2, t1); 2633 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2634 /* operands of same sign, result different sign */ 2635 generate_exception(ctx, EXCP_OVERFLOW); 2636 gen_set_label(l1); 2637 gen_store_gpr(t0, rd); 2638 } 2639 break; 2640 case OPC_DADDU: 2641 if (rs != 0 && rt != 0) { 2642 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2643 } else if (rs == 0 && rt != 0) { 2644 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2645 } else if (rs != 0 && rt == 0) { 2646 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2647 } else { 2648 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2649 } 2650 break; 2651 case OPC_DSUB: 2652 { 2653 TCGv t0 = tcg_temp_new(); 2654 TCGv t1 = tcg_temp_new(); 2655 TCGv t2 = tcg_temp_new(); 2656 TCGLabel *l1 = gen_new_label(); 2657 2658 gen_load_gpr(t1, rs); 2659 gen_load_gpr(t2, rt); 2660 tcg_gen_sub_tl(t0, t1, t2); 2661 tcg_gen_xor_tl(t2, t1, t2); 2662 tcg_gen_xor_tl(t1, t0, t1); 2663 tcg_gen_and_tl(t1, t1, t2); 2664 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2665 /* 2666 * Operands of different sign, first operand and result different 2667 * sign. 2668 */ 2669 generate_exception(ctx, EXCP_OVERFLOW); 2670 gen_set_label(l1); 2671 gen_store_gpr(t0, rd); 2672 } 2673 break; 2674 case OPC_DSUBU: 2675 if (rs != 0 && rt != 0) { 2676 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2677 } else if (rs == 0 && rt != 0) { 2678 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2679 } else if (rs != 0 && rt == 0) { 2680 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2681 } else { 2682 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2683 } 2684 break; 2685 #endif 2686 case OPC_MUL: 2687 if (likely(rs != 0 && rt != 0)) { 2688 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2689 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2690 } else { 2691 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2692 } 2693 break; 2694 } 2695 } 2696 2697 /* Conditional move */ 2698 static void gen_cond_move(DisasContext *ctx, uint32_t opc, 2699 int rd, int rs, int rt) 2700 { 2701 TCGv t0, t1, t2; 2702 2703 if (rd == 0) { 2704 /* If no destination, treat it as a NOP. */ 2705 return; 2706 } 2707 2708 t0 = tcg_temp_new(); 2709 gen_load_gpr(t0, rt); 2710 t1 = tcg_constant_tl(0); 2711 t2 = tcg_temp_new(); 2712 gen_load_gpr(t2, rs); 2713 switch (opc) { 2714 case OPC_MOVN: 2715 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2716 break; 2717 case OPC_MOVZ: 2718 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2719 break; 2720 case OPC_SELNEZ: 2721 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); 2722 break; 2723 case OPC_SELEQZ: 2724 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); 2725 break; 2726 } 2727 } 2728 2729 /* Logic */ 2730 static void gen_logic(DisasContext *ctx, uint32_t opc, 2731 int rd, int rs, int rt) 2732 { 2733 if (rd == 0) { 2734 /* If no destination, treat it as a NOP. */ 2735 return; 2736 } 2737 2738 switch (opc) { 2739 case OPC_AND: 2740 if (likely(rs != 0 && rt != 0)) { 2741 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2742 } else { 2743 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2744 } 2745 break; 2746 case OPC_NOR: 2747 if (rs != 0 && rt != 0) { 2748 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2749 } else if (rs == 0 && rt != 0) { 2750 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 2751 } else if (rs != 0 && rt == 0) { 2752 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 2753 } else { 2754 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 2755 } 2756 break; 2757 case OPC_OR: 2758 if (likely(rs != 0 && rt != 0)) { 2759 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2760 } else if (rs == 0 && rt != 0) { 2761 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2762 } else if (rs != 0 && rt == 0) { 2763 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2764 } else { 2765 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2766 } 2767 break; 2768 case OPC_XOR: 2769 if (likely(rs != 0 && rt != 0)) { 2770 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2771 } else if (rs == 0 && rt != 0) { 2772 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2773 } else if (rs != 0 && rt == 0) { 2774 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2775 } else { 2776 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2777 } 2778 break; 2779 } 2780 } 2781 2782 /* Set on lower than */ 2783 static void gen_slt(DisasContext *ctx, uint32_t opc, 2784 int rd, int rs, int rt) 2785 { 2786 TCGv t0, t1; 2787 2788 if (rd == 0) { 2789 /* If no destination, treat it as a NOP. */ 2790 return; 2791 } 2792 2793 t0 = tcg_temp_new(); 2794 t1 = tcg_temp_new(); 2795 gen_load_gpr(t0, rs); 2796 gen_load_gpr(t1, rt); 2797 switch (opc) { 2798 case OPC_SLT: 2799 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); 2800 break; 2801 case OPC_SLTU: 2802 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); 2803 break; 2804 } 2805 } 2806 2807 /* Shifts */ 2808 static void gen_shift(DisasContext *ctx, uint32_t opc, 2809 int rd, int rs, int rt) 2810 { 2811 TCGv t0, t1; 2812 2813 if (rd == 0) { 2814 /* 2815 * If no destination, treat it as a NOP. 2816 * For add & sub, we must generate the overflow exception when needed. 2817 */ 2818 return; 2819 } 2820 2821 t0 = tcg_temp_new(); 2822 t1 = tcg_temp_new(); 2823 gen_load_gpr(t0, rs); 2824 gen_load_gpr(t1, rt); 2825 switch (opc) { 2826 case OPC_SLLV: 2827 tcg_gen_andi_tl(t0, t0, 0x1f); 2828 tcg_gen_shl_tl(t0, t1, t0); 2829 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2830 break; 2831 case OPC_SRAV: 2832 tcg_gen_andi_tl(t0, t0, 0x1f); 2833 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2834 break; 2835 case OPC_SRLV: 2836 tcg_gen_ext32u_tl(t1, t1); 2837 tcg_gen_andi_tl(t0, t0, 0x1f); 2838 tcg_gen_shr_tl(t0, t1, t0); 2839 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2840 break; 2841 case OPC_ROTRV: 2842 { 2843 TCGv_i32 t2 = tcg_temp_new_i32(); 2844 TCGv_i32 t3 = tcg_temp_new_i32(); 2845 2846 tcg_gen_trunc_tl_i32(t2, t0); 2847 tcg_gen_trunc_tl_i32(t3, t1); 2848 tcg_gen_andi_i32(t2, t2, 0x1f); 2849 tcg_gen_rotr_i32(t2, t3, t2); 2850 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 2851 } 2852 break; 2853 #if defined(TARGET_MIPS64) 2854 case OPC_DSLLV: 2855 tcg_gen_andi_tl(t0, t0, 0x3f); 2856 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 2857 break; 2858 case OPC_DSRAV: 2859 tcg_gen_andi_tl(t0, t0, 0x3f); 2860 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2861 break; 2862 case OPC_DSRLV: 2863 tcg_gen_andi_tl(t0, t0, 0x3f); 2864 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 2865 break; 2866 case OPC_DROTRV: 2867 tcg_gen_andi_tl(t0, t0, 0x3f); 2868 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 2869 break; 2870 #endif 2871 } 2872 } 2873 2874 /* Arithmetic on HI/LO registers */ 2875 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) 2876 { 2877 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 2878 /* Treat as NOP. */ 2879 return; 2880 } 2881 2882 if (acc != 0) { 2883 check_dsp(ctx); 2884 } 2885 2886 switch (opc) { 2887 case OPC_MFHI: 2888 #if defined(TARGET_MIPS64) 2889 if (acc != 0) { 2890 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); 2891 } else 2892 #endif 2893 { 2894 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); 2895 } 2896 break; 2897 case OPC_MFLO: 2898 #if defined(TARGET_MIPS64) 2899 if (acc != 0) { 2900 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); 2901 } else 2902 #endif 2903 { 2904 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); 2905 } 2906 break; 2907 case OPC_MTHI: 2908 if (reg != 0) { 2909 #if defined(TARGET_MIPS64) 2910 if (acc != 0) { 2911 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); 2912 } else 2913 #endif 2914 { 2915 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); 2916 } 2917 } else { 2918 tcg_gen_movi_tl(cpu_HI[acc], 0); 2919 } 2920 break; 2921 case OPC_MTLO: 2922 if (reg != 0) { 2923 #if defined(TARGET_MIPS64) 2924 if (acc != 0) { 2925 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); 2926 } else 2927 #endif 2928 { 2929 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); 2930 } 2931 } else { 2932 tcg_gen_movi_tl(cpu_LO[acc], 0); 2933 } 2934 break; 2935 } 2936 } 2937 2938 static inline void gen_r6_ld(target_long addr, int reg, int memidx, 2939 MemOp memop) 2940 { 2941 TCGv t0 = tcg_temp_new(); 2942 tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop); 2943 gen_store_gpr(t0, reg); 2944 } 2945 2946 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, 2947 int rs) 2948 { 2949 target_long offset; 2950 target_long addr; 2951 2952 switch (MASK_OPC_PCREL_TOP2BITS(opc)) { 2953 case OPC_ADDIUPC: 2954 if (rs != 0) { 2955 offset = sextract32(ctx->opcode << 2, 0, 21); 2956 addr = addr_add(ctx, pc, offset); 2957 tcg_gen_movi_tl(cpu_gpr[rs], addr); 2958 } 2959 break; 2960 case R6_OPC_LWPC: 2961 offset = sextract32(ctx->opcode << 2, 0, 21); 2962 addr = addr_add(ctx, pc, offset); 2963 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_SL); 2964 break; 2965 #if defined(TARGET_MIPS64) 2966 case OPC_LWUPC: 2967 check_mips_64(ctx); 2968 offset = sextract32(ctx->opcode << 2, 0, 21); 2969 addr = addr_add(ctx, pc, offset); 2970 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UL); 2971 break; 2972 #endif 2973 default: 2974 switch (MASK_OPC_PCREL_TOP5BITS(opc)) { 2975 case OPC_AUIPC: 2976 if (rs != 0) { 2977 offset = sextract32(ctx->opcode, 0, 16) << 16; 2978 addr = addr_add(ctx, pc, offset); 2979 tcg_gen_movi_tl(cpu_gpr[rs], addr); 2980 } 2981 break; 2982 case OPC_ALUIPC: 2983 if (rs != 0) { 2984 offset = sextract32(ctx->opcode, 0, 16) << 16; 2985 addr = ~0xFFFF & addr_add(ctx, pc, offset); 2986 tcg_gen_movi_tl(cpu_gpr[rs], addr); 2987 } 2988 break; 2989 #if defined(TARGET_MIPS64) 2990 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */ 2991 case R6_OPC_LDPC + (1 << 16): 2992 case R6_OPC_LDPC + (2 << 16): 2993 case R6_OPC_LDPC + (3 << 16): 2994 check_mips_64(ctx); 2995 offset = sextract32(ctx->opcode << 3, 0, 21); 2996 addr = addr_add(ctx, (pc & ~0x7), offset); 2997 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 2998 break; 2999 #endif 3000 default: 3001 MIPS_INVAL("OPC_PCREL"); 3002 gen_reserved_instruction(ctx); 3003 break; 3004 } 3005 break; 3006 } 3007 } 3008 3009 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) 3010 { 3011 TCGv t0, t1; 3012 3013 if (rd == 0) { 3014 /* Treat as NOP. */ 3015 return; 3016 } 3017 3018 t0 = tcg_temp_new(); 3019 t1 = tcg_temp_new(); 3020 3021 gen_load_gpr(t0, rs); 3022 gen_load_gpr(t1, rt); 3023 3024 switch (opc) { 3025 case R6_OPC_DIV: 3026 { 3027 TCGv t2 = tcg_temp_new(); 3028 TCGv t3 = tcg_temp_new(); 3029 tcg_gen_ext32s_tl(t0, t0); 3030 tcg_gen_ext32s_tl(t1, t1); 3031 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3032 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3033 tcg_gen_and_tl(t2, t2, t3); 3034 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3035 tcg_gen_or_tl(t2, t2, t3); 3036 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3037 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3038 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3039 } 3040 break; 3041 case R6_OPC_MOD: 3042 { 3043 TCGv t2 = tcg_temp_new(); 3044 TCGv t3 = tcg_temp_new(); 3045 tcg_gen_ext32s_tl(t0, t0); 3046 tcg_gen_ext32s_tl(t1, t1); 3047 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3048 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3049 tcg_gen_and_tl(t2, t2, t3); 3050 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3051 tcg_gen_or_tl(t2, t2, t3); 3052 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3053 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3054 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3055 } 3056 break; 3057 case R6_OPC_DIVU: 3058 { 3059 tcg_gen_ext32u_tl(t0, t0); 3060 tcg_gen_ext32u_tl(t1, t1); 3061 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3062 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3063 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3064 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3065 } 3066 break; 3067 case R6_OPC_MODU: 3068 { 3069 tcg_gen_ext32u_tl(t0, t0); 3070 tcg_gen_ext32u_tl(t1, t1); 3071 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3072 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3073 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3074 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3075 } 3076 break; 3077 case R6_OPC_MUL: 3078 { 3079 TCGv_i32 t2 = tcg_temp_new_i32(); 3080 TCGv_i32 t3 = tcg_temp_new_i32(); 3081 tcg_gen_trunc_tl_i32(t2, t0); 3082 tcg_gen_trunc_tl_i32(t3, t1); 3083 tcg_gen_mul_i32(t2, t2, t3); 3084 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3085 } 3086 break; 3087 case R6_OPC_MUH: 3088 { 3089 TCGv_i32 t2 = tcg_temp_new_i32(); 3090 TCGv_i32 t3 = tcg_temp_new_i32(); 3091 tcg_gen_trunc_tl_i32(t2, t0); 3092 tcg_gen_trunc_tl_i32(t3, t1); 3093 tcg_gen_muls2_i32(t2, t3, t2, t3); 3094 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3095 } 3096 break; 3097 case R6_OPC_MULU: 3098 { 3099 TCGv_i32 t2 = tcg_temp_new_i32(); 3100 TCGv_i32 t3 = tcg_temp_new_i32(); 3101 tcg_gen_trunc_tl_i32(t2, t0); 3102 tcg_gen_trunc_tl_i32(t3, t1); 3103 tcg_gen_mul_i32(t2, t2, t3); 3104 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3105 } 3106 break; 3107 case R6_OPC_MUHU: 3108 { 3109 TCGv_i32 t2 = tcg_temp_new_i32(); 3110 TCGv_i32 t3 = tcg_temp_new_i32(); 3111 tcg_gen_trunc_tl_i32(t2, t0); 3112 tcg_gen_trunc_tl_i32(t3, t1); 3113 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3114 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3115 } 3116 break; 3117 #if defined(TARGET_MIPS64) 3118 case R6_OPC_DDIV: 3119 { 3120 TCGv t2 = tcg_temp_new(); 3121 TCGv t3 = tcg_temp_new(); 3122 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3123 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3124 tcg_gen_and_tl(t2, t2, t3); 3125 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3126 tcg_gen_or_tl(t2, t2, t3); 3127 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3128 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3129 } 3130 break; 3131 case R6_OPC_DMOD: 3132 { 3133 TCGv t2 = tcg_temp_new(); 3134 TCGv t3 = tcg_temp_new(); 3135 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3136 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3137 tcg_gen_and_tl(t2, t2, t3); 3138 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3139 tcg_gen_or_tl(t2, t2, t3); 3140 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3141 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3142 } 3143 break; 3144 case R6_OPC_DDIVU: 3145 { 3146 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3147 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3148 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); 3149 } 3150 break; 3151 case R6_OPC_DMODU: 3152 { 3153 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3154 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3155 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); 3156 } 3157 break; 3158 case R6_OPC_DMUL: 3159 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3160 break; 3161 case R6_OPC_DMUH: 3162 { 3163 TCGv t2 = tcg_temp_new(); 3164 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); 3165 } 3166 break; 3167 case R6_OPC_DMULU: 3168 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3169 break; 3170 case R6_OPC_DMUHU: 3171 { 3172 TCGv t2 = tcg_temp_new(); 3173 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); 3174 } 3175 break; 3176 #endif 3177 default: 3178 MIPS_INVAL("r6 mul/div"); 3179 gen_reserved_instruction(ctx); 3180 break; 3181 } 3182 } 3183 3184 #if defined(TARGET_MIPS64) 3185 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) 3186 { 3187 TCGv t0, t1; 3188 3189 t0 = tcg_temp_new(); 3190 t1 = tcg_temp_new(); 3191 3192 gen_load_gpr(t0, rs); 3193 gen_load_gpr(t1, rt); 3194 3195 switch (opc) { 3196 case MMI_OPC_DIV1: 3197 { 3198 TCGv t2 = tcg_temp_new(); 3199 TCGv t3 = tcg_temp_new(); 3200 tcg_gen_ext32s_tl(t0, t0); 3201 tcg_gen_ext32s_tl(t1, t1); 3202 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3203 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3204 tcg_gen_and_tl(t2, t2, t3); 3205 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3206 tcg_gen_or_tl(t2, t2, t3); 3207 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3208 tcg_gen_div_tl(cpu_LO[1], t0, t1); 3209 tcg_gen_rem_tl(cpu_HI[1], t0, t1); 3210 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3211 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3212 } 3213 break; 3214 case MMI_OPC_DIVU1: 3215 { 3216 TCGv t2 = tcg_constant_tl(0); 3217 TCGv t3 = tcg_constant_tl(1); 3218 tcg_gen_ext32u_tl(t0, t0); 3219 tcg_gen_ext32u_tl(t1, t1); 3220 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3221 tcg_gen_divu_tl(cpu_LO[1], t0, t1); 3222 tcg_gen_remu_tl(cpu_HI[1], t0, t1); 3223 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3224 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3225 } 3226 break; 3227 default: 3228 MIPS_INVAL("div1 TX79"); 3229 gen_reserved_instruction(ctx); 3230 break; 3231 } 3232 } 3233 #endif 3234 3235 static void gen_muldiv(DisasContext *ctx, uint32_t opc, 3236 int acc, int rs, int rt) 3237 { 3238 TCGv t0, t1; 3239 3240 t0 = tcg_temp_new(); 3241 t1 = tcg_temp_new(); 3242 3243 gen_load_gpr(t0, rs); 3244 gen_load_gpr(t1, rt); 3245 3246 if (acc != 0) { 3247 check_dsp(ctx); 3248 } 3249 3250 switch (opc) { 3251 case OPC_DIV: 3252 { 3253 TCGv t2 = tcg_temp_new(); 3254 TCGv t3 = tcg_temp_new(); 3255 tcg_gen_ext32s_tl(t0, t0); 3256 tcg_gen_ext32s_tl(t1, t1); 3257 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3258 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3259 tcg_gen_and_tl(t2, t2, t3); 3260 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3261 tcg_gen_or_tl(t2, t2, t3); 3262 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3263 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3264 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3265 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3266 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3267 } 3268 break; 3269 case OPC_DIVU: 3270 { 3271 TCGv t2 = tcg_constant_tl(0); 3272 TCGv t3 = tcg_constant_tl(1); 3273 tcg_gen_ext32u_tl(t0, t0); 3274 tcg_gen_ext32u_tl(t1, t1); 3275 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3276 tcg_gen_divu_tl(cpu_LO[acc], t0, t1); 3277 tcg_gen_remu_tl(cpu_HI[acc], t0, t1); 3278 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3279 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3280 } 3281 break; 3282 case OPC_MULT: 3283 { 3284 TCGv_i32 t2 = tcg_temp_new_i32(); 3285 TCGv_i32 t3 = tcg_temp_new_i32(); 3286 tcg_gen_trunc_tl_i32(t2, t0); 3287 tcg_gen_trunc_tl_i32(t3, t1); 3288 tcg_gen_muls2_i32(t2, t3, t2, t3); 3289 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3290 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3291 } 3292 break; 3293 case OPC_MULTU: 3294 { 3295 TCGv_i32 t2 = tcg_temp_new_i32(); 3296 TCGv_i32 t3 = tcg_temp_new_i32(); 3297 tcg_gen_trunc_tl_i32(t2, t0); 3298 tcg_gen_trunc_tl_i32(t3, t1); 3299 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3300 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3301 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3302 } 3303 break; 3304 #if defined(TARGET_MIPS64) 3305 case OPC_DDIV: 3306 { 3307 TCGv t2 = tcg_temp_new(); 3308 TCGv t3 = tcg_temp_new(); 3309 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3310 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3311 tcg_gen_and_tl(t2, t2, t3); 3312 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3313 tcg_gen_or_tl(t2, t2, t3); 3314 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3315 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3316 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3317 } 3318 break; 3319 case OPC_DDIVU: 3320 { 3321 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3322 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3323 tcg_gen_divu_i64(cpu_LO[acc], t0, t1); 3324 tcg_gen_remu_i64(cpu_HI[acc], t0, t1); 3325 } 3326 break; 3327 case OPC_DMULT: 3328 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3329 break; 3330 case OPC_DMULTU: 3331 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3332 break; 3333 #endif 3334 case OPC_MADD: 3335 { 3336 TCGv_i64 t2 = tcg_temp_new_i64(); 3337 TCGv_i64 t3 = tcg_temp_new_i64(); 3338 3339 tcg_gen_ext_tl_i64(t2, t0); 3340 tcg_gen_ext_tl_i64(t3, t1); 3341 tcg_gen_mul_i64(t2, t2, t3); 3342 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3343 tcg_gen_add_i64(t2, t2, t3); 3344 gen_move_low32(cpu_LO[acc], t2); 3345 gen_move_high32(cpu_HI[acc], t2); 3346 } 3347 break; 3348 case OPC_MADDU: 3349 { 3350 TCGv_i64 t2 = tcg_temp_new_i64(); 3351 TCGv_i64 t3 = tcg_temp_new_i64(); 3352 3353 tcg_gen_ext32u_tl(t0, t0); 3354 tcg_gen_ext32u_tl(t1, t1); 3355 tcg_gen_extu_tl_i64(t2, t0); 3356 tcg_gen_extu_tl_i64(t3, t1); 3357 tcg_gen_mul_i64(t2, t2, t3); 3358 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3359 tcg_gen_add_i64(t2, t2, t3); 3360 gen_move_low32(cpu_LO[acc], t2); 3361 gen_move_high32(cpu_HI[acc], t2); 3362 } 3363 break; 3364 case OPC_MSUB: 3365 { 3366 TCGv_i64 t2 = tcg_temp_new_i64(); 3367 TCGv_i64 t3 = tcg_temp_new_i64(); 3368 3369 tcg_gen_ext_tl_i64(t2, t0); 3370 tcg_gen_ext_tl_i64(t3, t1); 3371 tcg_gen_mul_i64(t2, t2, t3); 3372 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3373 tcg_gen_sub_i64(t2, t3, t2); 3374 gen_move_low32(cpu_LO[acc], t2); 3375 gen_move_high32(cpu_HI[acc], t2); 3376 } 3377 break; 3378 case OPC_MSUBU: 3379 { 3380 TCGv_i64 t2 = tcg_temp_new_i64(); 3381 TCGv_i64 t3 = tcg_temp_new_i64(); 3382 3383 tcg_gen_ext32u_tl(t0, t0); 3384 tcg_gen_ext32u_tl(t1, t1); 3385 tcg_gen_extu_tl_i64(t2, t0); 3386 tcg_gen_extu_tl_i64(t3, t1); 3387 tcg_gen_mul_i64(t2, t2, t3); 3388 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3389 tcg_gen_sub_i64(t2, t3, t2); 3390 gen_move_low32(cpu_LO[acc], t2); 3391 gen_move_high32(cpu_HI[acc], t2); 3392 } 3393 break; 3394 default: 3395 MIPS_INVAL("mul/div"); 3396 gen_reserved_instruction(ctx); 3397 break; 3398 } 3399 } 3400 3401 /* 3402 * These MULT[U] and MADD[U] instructions implemented in for example 3403 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core 3404 * architectures are special three-operand variants with the syntax 3405 * 3406 * MULT[U][1] rd, rs, rt 3407 * 3408 * such that 3409 * 3410 * (rd, LO, HI) <- rs * rt 3411 * 3412 * and 3413 * 3414 * MADD[U][1] rd, rs, rt 3415 * 3416 * such that 3417 * 3418 * (rd, LO, HI) <- (LO, HI) + rs * rt 3419 * 3420 * where the low-order 32-bits of the result is placed into both the 3421 * GPR rd and the special register LO. The high-order 32-bits of the 3422 * result is placed into the special register HI. 3423 * 3424 * If the GPR rd is omitted in assembly language, it is taken to be 0, 3425 * which is the zero register that always reads as 0. 3426 */ 3427 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, 3428 int rd, int rs, int rt) 3429 { 3430 TCGv t0 = tcg_temp_new(); 3431 TCGv t1 = tcg_temp_new(); 3432 int acc = 0; 3433 3434 gen_load_gpr(t0, rs); 3435 gen_load_gpr(t1, rt); 3436 3437 switch (opc) { 3438 case MMI_OPC_MULT1: 3439 acc = 1; 3440 /* Fall through */ 3441 case OPC_MULT: 3442 { 3443 TCGv_i32 t2 = tcg_temp_new_i32(); 3444 TCGv_i32 t3 = tcg_temp_new_i32(); 3445 tcg_gen_trunc_tl_i32(t2, t0); 3446 tcg_gen_trunc_tl_i32(t3, t1); 3447 tcg_gen_muls2_i32(t2, t3, t2, t3); 3448 if (rd) { 3449 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3450 } 3451 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3452 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3453 } 3454 break; 3455 case MMI_OPC_MULTU1: 3456 acc = 1; 3457 /* Fall through */ 3458 case OPC_MULTU: 3459 { 3460 TCGv_i32 t2 = tcg_temp_new_i32(); 3461 TCGv_i32 t3 = tcg_temp_new_i32(); 3462 tcg_gen_trunc_tl_i32(t2, t0); 3463 tcg_gen_trunc_tl_i32(t3, t1); 3464 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3465 if (rd) { 3466 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3467 } 3468 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3469 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3470 } 3471 break; 3472 case MMI_OPC_MADD1: 3473 acc = 1; 3474 /* Fall through */ 3475 case MMI_OPC_MADD: 3476 { 3477 TCGv_i64 t2 = tcg_temp_new_i64(); 3478 TCGv_i64 t3 = tcg_temp_new_i64(); 3479 3480 tcg_gen_ext_tl_i64(t2, t0); 3481 tcg_gen_ext_tl_i64(t3, t1); 3482 tcg_gen_mul_i64(t2, t2, t3); 3483 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3484 tcg_gen_add_i64(t2, t2, t3); 3485 gen_move_low32(cpu_LO[acc], t2); 3486 gen_move_high32(cpu_HI[acc], t2); 3487 if (rd) { 3488 gen_move_low32(cpu_gpr[rd], t2); 3489 } 3490 } 3491 break; 3492 case MMI_OPC_MADDU1: 3493 acc = 1; 3494 /* Fall through */ 3495 case MMI_OPC_MADDU: 3496 { 3497 TCGv_i64 t2 = tcg_temp_new_i64(); 3498 TCGv_i64 t3 = tcg_temp_new_i64(); 3499 3500 tcg_gen_ext32u_tl(t0, t0); 3501 tcg_gen_ext32u_tl(t1, t1); 3502 tcg_gen_extu_tl_i64(t2, t0); 3503 tcg_gen_extu_tl_i64(t3, t1); 3504 tcg_gen_mul_i64(t2, t2, t3); 3505 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3506 tcg_gen_add_i64(t2, t2, t3); 3507 gen_move_low32(cpu_LO[acc], t2); 3508 gen_move_high32(cpu_HI[acc], t2); 3509 if (rd) { 3510 gen_move_low32(cpu_gpr[rd], t2); 3511 } 3512 } 3513 break; 3514 default: 3515 MIPS_INVAL("mul/madd TXx9"); 3516 gen_reserved_instruction(ctx); 3517 break; 3518 } 3519 } 3520 3521 static void gen_cl(DisasContext *ctx, uint32_t opc, 3522 int rd, int rs) 3523 { 3524 TCGv t0; 3525 3526 if (rd == 0) { 3527 /* Treat as NOP. */ 3528 return; 3529 } 3530 t0 = cpu_gpr[rd]; 3531 gen_load_gpr(t0, rs); 3532 3533 switch (opc) { 3534 case OPC_CLO: 3535 case R6_OPC_CLO: 3536 #if defined(TARGET_MIPS64) 3537 case OPC_DCLO: 3538 case R6_OPC_DCLO: 3539 #endif 3540 tcg_gen_not_tl(t0, t0); 3541 break; 3542 } 3543 3544 switch (opc) { 3545 case OPC_CLO: 3546 case R6_OPC_CLO: 3547 case OPC_CLZ: 3548 case R6_OPC_CLZ: 3549 tcg_gen_ext32u_tl(t0, t0); 3550 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); 3551 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); 3552 break; 3553 #if defined(TARGET_MIPS64) 3554 case OPC_DCLO: 3555 case R6_OPC_DCLO: 3556 case OPC_DCLZ: 3557 case R6_OPC_DCLZ: 3558 tcg_gen_clzi_i64(t0, t0, 64); 3559 break; 3560 #endif 3561 } 3562 } 3563 3564 /* Loongson multimedia instructions */ 3565 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) 3566 { 3567 uint32_t opc, shift_max; 3568 TCGv_i64 t0, t1; 3569 TCGCond cond; 3570 3571 opc = MASK_LMMI(ctx->opcode); 3572 check_cp1_enabled(ctx); 3573 3574 t0 = tcg_temp_new_i64(); 3575 t1 = tcg_temp_new_i64(); 3576 gen_load_fpr64(ctx, t0, rs); 3577 gen_load_fpr64(ctx, t1, rt); 3578 3579 switch (opc) { 3580 case OPC_PADDSH: 3581 gen_helper_paddsh(t0, t0, t1); 3582 break; 3583 case OPC_PADDUSH: 3584 gen_helper_paddush(t0, t0, t1); 3585 break; 3586 case OPC_PADDH: 3587 gen_helper_paddh(t0, t0, t1); 3588 break; 3589 case OPC_PADDW: 3590 gen_helper_paddw(t0, t0, t1); 3591 break; 3592 case OPC_PADDSB: 3593 gen_helper_paddsb(t0, t0, t1); 3594 break; 3595 case OPC_PADDUSB: 3596 gen_helper_paddusb(t0, t0, t1); 3597 break; 3598 case OPC_PADDB: 3599 gen_helper_paddb(t0, t0, t1); 3600 break; 3601 3602 case OPC_PSUBSH: 3603 gen_helper_psubsh(t0, t0, t1); 3604 break; 3605 case OPC_PSUBUSH: 3606 gen_helper_psubush(t0, t0, t1); 3607 break; 3608 case OPC_PSUBH: 3609 gen_helper_psubh(t0, t0, t1); 3610 break; 3611 case OPC_PSUBW: 3612 gen_helper_psubw(t0, t0, t1); 3613 break; 3614 case OPC_PSUBSB: 3615 gen_helper_psubsb(t0, t0, t1); 3616 break; 3617 case OPC_PSUBUSB: 3618 gen_helper_psubusb(t0, t0, t1); 3619 break; 3620 case OPC_PSUBB: 3621 gen_helper_psubb(t0, t0, t1); 3622 break; 3623 3624 case OPC_PSHUFH: 3625 gen_helper_pshufh(t0, t0, t1); 3626 break; 3627 case OPC_PACKSSWH: 3628 gen_helper_packsswh(t0, t0, t1); 3629 break; 3630 case OPC_PACKSSHB: 3631 gen_helper_packsshb(t0, t0, t1); 3632 break; 3633 case OPC_PACKUSHB: 3634 gen_helper_packushb(t0, t0, t1); 3635 break; 3636 3637 case OPC_PUNPCKLHW: 3638 gen_helper_punpcklhw(t0, t0, t1); 3639 break; 3640 case OPC_PUNPCKHHW: 3641 gen_helper_punpckhhw(t0, t0, t1); 3642 break; 3643 case OPC_PUNPCKLBH: 3644 gen_helper_punpcklbh(t0, t0, t1); 3645 break; 3646 case OPC_PUNPCKHBH: 3647 gen_helper_punpckhbh(t0, t0, t1); 3648 break; 3649 case OPC_PUNPCKLWD: 3650 gen_helper_punpcklwd(t0, t0, t1); 3651 break; 3652 case OPC_PUNPCKHWD: 3653 gen_helper_punpckhwd(t0, t0, t1); 3654 break; 3655 3656 case OPC_PAVGH: 3657 gen_helper_pavgh(t0, t0, t1); 3658 break; 3659 case OPC_PAVGB: 3660 gen_helper_pavgb(t0, t0, t1); 3661 break; 3662 case OPC_PMAXSH: 3663 gen_helper_pmaxsh(t0, t0, t1); 3664 break; 3665 case OPC_PMINSH: 3666 gen_helper_pminsh(t0, t0, t1); 3667 break; 3668 case OPC_PMAXUB: 3669 gen_helper_pmaxub(t0, t0, t1); 3670 break; 3671 case OPC_PMINUB: 3672 gen_helper_pminub(t0, t0, t1); 3673 break; 3674 3675 case OPC_PCMPEQW: 3676 gen_helper_pcmpeqw(t0, t0, t1); 3677 break; 3678 case OPC_PCMPGTW: 3679 gen_helper_pcmpgtw(t0, t0, t1); 3680 break; 3681 case OPC_PCMPEQH: 3682 gen_helper_pcmpeqh(t0, t0, t1); 3683 break; 3684 case OPC_PCMPGTH: 3685 gen_helper_pcmpgth(t0, t0, t1); 3686 break; 3687 case OPC_PCMPEQB: 3688 gen_helper_pcmpeqb(t0, t0, t1); 3689 break; 3690 case OPC_PCMPGTB: 3691 gen_helper_pcmpgtb(t0, t0, t1); 3692 break; 3693 3694 case OPC_PSLLW: 3695 gen_helper_psllw(t0, t0, t1); 3696 break; 3697 case OPC_PSLLH: 3698 gen_helper_psllh(t0, t0, t1); 3699 break; 3700 case OPC_PSRLW: 3701 gen_helper_psrlw(t0, t0, t1); 3702 break; 3703 case OPC_PSRLH: 3704 gen_helper_psrlh(t0, t0, t1); 3705 break; 3706 case OPC_PSRAW: 3707 gen_helper_psraw(t0, t0, t1); 3708 break; 3709 case OPC_PSRAH: 3710 gen_helper_psrah(t0, t0, t1); 3711 break; 3712 3713 case OPC_PMULLH: 3714 gen_helper_pmullh(t0, t0, t1); 3715 break; 3716 case OPC_PMULHH: 3717 gen_helper_pmulhh(t0, t0, t1); 3718 break; 3719 case OPC_PMULHUH: 3720 gen_helper_pmulhuh(t0, t0, t1); 3721 break; 3722 case OPC_PMADDHW: 3723 gen_helper_pmaddhw(t0, t0, t1); 3724 break; 3725 3726 case OPC_PASUBUB: 3727 gen_helper_pasubub(t0, t0, t1); 3728 break; 3729 case OPC_BIADD: 3730 gen_helper_biadd(t0, t0); 3731 break; 3732 case OPC_PMOVMSKB: 3733 gen_helper_pmovmskb(t0, t0); 3734 break; 3735 3736 case OPC_PADDD: 3737 tcg_gen_add_i64(t0, t0, t1); 3738 break; 3739 case OPC_PSUBD: 3740 tcg_gen_sub_i64(t0, t0, t1); 3741 break; 3742 case OPC_XOR_CP2: 3743 tcg_gen_xor_i64(t0, t0, t1); 3744 break; 3745 case OPC_NOR_CP2: 3746 tcg_gen_nor_i64(t0, t0, t1); 3747 break; 3748 case OPC_AND_CP2: 3749 tcg_gen_and_i64(t0, t0, t1); 3750 break; 3751 case OPC_OR_CP2: 3752 tcg_gen_or_i64(t0, t0, t1); 3753 break; 3754 3755 case OPC_PANDN: 3756 tcg_gen_andc_i64(t0, t1, t0); 3757 break; 3758 3759 case OPC_PINSRH_0: 3760 tcg_gen_deposit_i64(t0, t0, t1, 0, 16); 3761 break; 3762 case OPC_PINSRH_1: 3763 tcg_gen_deposit_i64(t0, t0, t1, 16, 16); 3764 break; 3765 case OPC_PINSRH_2: 3766 tcg_gen_deposit_i64(t0, t0, t1, 32, 16); 3767 break; 3768 case OPC_PINSRH_3: 3769 tcg_gen_deposit_i64(t0, t0, t1, 48, 16); 3770 break; 3771 3772 case OPC_PEXTRH: 3773 tcg_gen_andi_i64(t1, t1, 3); 3774 tcg_gen_shli_i64(t1, t1, 4); 3775 tcg_gen_shr_i64(t0, t0, t1); 3776 tcg_gen_ext16u_i64(t0, t0); 3777 break; 3778 3779 case OPC_ADDU_CP2: 3780 tcg_gen_add_i64(t0, t0, t1); 3781 tcg_gen_ext32s_i64(t0, t0); 3782 break; 3783 case OPC_SUBU_CP2: 3784 tcg_gen_sub_i64(t0, t0, t1); 3785 tcg_gen_ext32s_i64(t0, t0); 3786 break; 3787 3788 case OPC_SLL_CP2: 3789 shift_max = 32; 3790 goto do_shift; 3791 case OPC_SRL_CP2: 3792 shift_max = 32; 3793 goto do_shift; 3794 case OPC_SRA_CP2: 3795 shift_max = 32; 3796 goto do_shift; 3797 case OPC_DSLL_CP2: 3798 shift_max = 64; 3799 goto do_shift; 3800 case OPC_DSRL_CP2: 3801 shift_max = 64; 3802 goto do_shift; 3803 case OPC_DSRA_CP2: 3804 shift_max = 64; 3805 goto do_shift; 3806 do_shift: 3807 /* Make sure shift count isn't TCG undefined behaviour. */ 3808 tcg_gen_andi_i64(t1, t1, shift_max - 1); 3809 3810 switch (opc) { 3811 case OPC_SLL_CP2: 3812 case OPC_DSLL_CP2: 3813 tcg_gen_shl_i64(t0, t0, t1); 3814 break; 3815 case OPC_SRA_CP2: 3816 case OPC_DSRA_CP2: 3817 /* 3818 * Since SRA is UndefinedResult without sign-extended inputs, 3819 * we can treat SRA and DSRA the same. 3820 */ 3821 tcg_gen_sar_i64(t0, t0, t1); 3822 break; 3823 case OPC_SRL_CP2: 3824 /* We want to shift in zeros for SRL; zero-extend first. */ 3825 tcg_gen_ext32u_i64(t0, t0); 3826 /* FALLTHRU */ 3827 case OPC_DSRL_CP2: 3828 tcg_gen_shr_i64(t0, t0, t1); 3829 break; 3830 } 3831 3832 if (shift_max == 32) { 3833 tcg_gen_ext32s_i64(t0, t0); 3834 } 3835 3836 /* Shifts larger than MAX produce zero. */ 3837 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); 3838 tcg_gen_neg_i64(t1, t1); 3839 tcg_gen_and_i64(t0, t0, t1); 3840 break; 3841 3842 case OPC_ADD_CP2: 3843 case OPC_DADD_CP2: 3844 { 3845 TCGv_i64 t2 = tcg_temp_new_i64(); 3846 TCGLabel *lab = gen_new_label(); 3847 3848 tcg_gen_mov_i64(t2, t0); 3849 tcg_gen_add_i64(t0, t1, t2); 3850 if (opc == OPC_ADD_CP2) { 3851 tcg_gen_ext32s_i64(t0, t0); 3852 } 3853 tcg_gen_xor_i64(t1, t1, t2); 3854 tcg_gen_xor_i64(t2, t2, t0); 3855 tcg_gen_andc_i64(t1, t2, t1); 3856 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 3857 generate_exception(ctx, EXCP_OVERFLOW); 3858 gen_set_label(lab); 3859 break; 3860 } 3861 3862 case OPC_SUB_CP2: 3863 case OPC_DSUB_CP2: 3864 { 3865 TCGv_i64 t2 = tcg_temp_new_i64(); 3866 TCGLabel *lab = gen_new_label(); 3867 3868 tcg_gen_mov_i64(t2, t0); 3869 tcg_gen_sub_i64(t0, t1, t2); 3870 if (opc == OPC_SUB_CP2) { 3871 tcg_gen_ext32s_i64(t0, t0); 3872 } 3873 tcg_gen_xor_i64(t1, t1, t2); 3874 tcg_gen_xor_i64(t2, t2, t0); 3875 tcg_gen_and_i64(t1, t1, t2); 3876 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 3877 generate_exception(ctx, EXCP_OVERFLOW); 3878 gen_set_label(lab); 3879 break; 3880 } 3881 3882 case OPC_PMULUW: 3883 tcg_gen_ext32u_i64(t0, t0); 3884 tcg_gen_ext32u_i64(t1, t1); 3885 tcg_gen_mul_i64(t0, t0, t1); 3886 break; 3887 3888 case OPC_SEQU_CP2: 3889 case OPC_SEQ_CP2: 3890 cond = TCG_COND_EQ; 3891 goto do_cc_cond; 3892 break; 3893 case OPC_SLTU_CP2: 3894 cond = TCG_COND_LTU; 3895 goto do_cc_cond; 3896 break; 3897 case OPC_SLT_CP2: 3898 cond = TCG_COND_LT; 3899 goto do_cc_cond; 3900 break; 3901 case OPC_SLEU_CP2: 3902 cond = TCG_COND_LEU; 3903 goto do_cc_cond; 3904 break; 3905 case OPC_SLE_CP2: 3906 cond = TCG_COND_LE; 3907 do_cc_cond: 3908 { 3909 int cc = (ctx->opcode >> 8) & 0x7; 3910 TCGv_i64 t64 = tcg_temp_new_i64(); 3911 TCGv_i32 t32 = tcg_temp_new_i32(); 3912 3913 tcg_gen_setcond_i64(cond, t64, t0, t1); 3914 tcg_gen_extrl_i64_i32(t32, t64); 3915 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, 3916 get_fp_bit(cc), 1); 3917 } 3918 return; 3919 default: 3920 MIPS_INVAL("loongson_cp2"); 3921 gen_reserved_instruction(ctx); 3922 return; 3923 } 3924 3925 gen_store_fpr64(ctx, t0, rd); 3926 } 3927 3928 static void gen_loongson_lswc2(DisasContext *ctx, int rt, 3929 int rs, int rd) 3930 { 3931 TCGv t0, t1; 3932 TCGv_i32 fp0; 3933 #if defined(TARGET_MIPS64) 3934 int lsq_rt1 = ctx->opcode & 0x1f; 3935 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4; 3936 #endif 3937 int shf_offset = sextract32(ctx->opcode, 6, 8); 3938 3939 t0 = tcg_temp_new(); 3940 3941 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { 3942 #if defined(TARGET_MIPS64) 3943 case OPC_GSLQ: 3944 t1 = tcg_temp_new(); 3945 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3946 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3947 ctx->default_tcg_memop_mask); 3948 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 3949 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3950 ctx->default_tcg_memop_mask); 3951 gen_store_gpr(t1, rt); 3952 gen_store_gpr(t0, lsq_rt1); 3953 break; 3954 case OPC_GSLQC1: 3955 check_cp1_enabled(ctx); 3956 t1 = tcg_temp_new(); 3957 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3958 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3959 ctx->default_tcg_memop_mask); 3960 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 3961 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3962 ctx->default_tcg_memop_mask); 3963 gen_store_fpr64(ctx, t1, rt); 3964 gen_store_fpr64(ctx, t0, lsq_rt1); 3965 break; 3966 case OPC_GSSQ: 3967 t1 = tcg_temp_new(); 3968 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3969 gen_load_gpr(t1, rt); 3970 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3971 ctx->default_tcg_memop_mask); 3972 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 3973 gen_load_gpr(t1, lsq_rt1); 3974 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3975 ctx->default_tcg_memop_mask); 3976 break; 3977 case OPC_GSSQC1: 3978 check_cp1_enabled(ctx); 3979 t1 = tcg_temp_new(); 3980 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3981 gen_load_fpr64(ctx, t1, rt); 3982 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3983 ctx->default_tcg_memop_mask); 3984 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 3985 gen_load_fpr64(ctx, t1, lsq_rt1); 3986 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3987 ctx->default_tcg_memop_mask); 3988 break; 3989 #endif 3990 case OPC_GSSHFL: 3991 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 3992 case OPC_GSLWLC1: 3993 check_cp1_enabled(ctx); 3994 gen_base_offset_addr(ctx, t0, rs, shf_offset); 3995 fp0 = tcg_temp_new_i32(); 3996 gen_load_fpr32(ctx, fp0, rt); 3997 t1 = tcg_temp_new(); 3998 tcg_gen_ext_i32_tl(t1, fp0); 3999 gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 4000 tcg_gen_trunc_tl_i32(fp0, t1); 4001 gen_store_fpr32(ctx, fp0, rt); 4002 break; 4003 case OPC_GSLWRC1: 4004 check_cp1_enabled(ctx); 4005 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4006 fp0 = tcg_temp_new_i32(); 4007 gen_load_fpr32(ctx, fp0, rt); 4008 t1 = tcg_temp_new(); 4009 tcg_gen_ext_i32_tl(t1, fp0); 4010 gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 4011 tcg_gen_trunc_tl_i32(fp0, t1); 4012 gen_store_fpr32(ctx, fp0, rt); 4013 break; 4014 #if defined(TARGET_MIPS64) 4015 case OPC_GSLDLC1: 4016 check_cp1_enabled(ctx); 4017 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4018 t1 = tcg_temp_new(); 4019 gen_load_fpr64(ctx, t1, rt); 4020 gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 4021 gen_store_fpr64(ctx, t1, rt); 4022 break; 4023 case OPC_GSLDRC1: 4024 check_cp1_enabled(ctx); 4025 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4026 t1 = tcg_temp_new(); 4027 gen_load_fpr64(ctx, t1, rt); 4028 gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 4029 gen_store_fpr64(ctx, t1, rt); 4030 break; 4031 #endif 4032 default: 4033 MIPS_INVAL("loongson_gsshfl"); 4034 gen_reserved_instruction(ctx); 4035 break; 4036 } 4037 break; 4038 case OPC_GSSHFS: 4039 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4040 case OPC_GSSWLC1: 4041 check_cp1_enabled(ctx); 4042 t1 = tcg_temp_new(); 4043 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4044 fp0 = tcg_temp_new_i32(); 4045 gen_load_fpr32(ctx, fp0, rt); 4046 tcg_gen_ext_i32_tl(t1, fp0); 4047 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); 4048 break; 4049 case OPC_GSSWRC1: 4050 check_cp1_enabled(ctx); 4051 t1 = tcg_temp_new(); 4052 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4053 fp0 = tcg_temp_new_i32(); 4054 gen_load_fpr32(ctx, fp0, rt); 4055 tcg_gen_ext_i32_tl(t1, fp0); 4056 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); 4057 break; 4058 #if defined(TARGET_MIPS64) 4059 case OPC_GSSDLC1: 4060 check_cp1_enabled(ctx); 4061 t1 = tcg_temp_new(); 4062 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4063 gen_load_fpr64(ctx, t1, rt); 4064 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); 4065 break; 4066 case OPC_GSSDRC1: 4067 check_cp1_enabled(ctx); 4068 t1 = tcg_temp_new(); 4069 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4070 gen_load_fpr64(ctx, t1, rt); 4071 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); 4072 break; 4073 #endif 4074 default: 4075 MIPS_INVAL("loongson_gsshfs"); 4076 gen_reserved_instruction(ctx); 4077 break; 4078 } 4079 break; 4080 default: 4081 MIPS_INVAL("loongson_gslsq"); 4082 gen_reserved_instruction(ctx); 4083 break; 4084 } 4085 } 4086 4087 /* Loongson EXT LDC2/SDC2 */ 4088 static void gen_loongson_lsdc2(DisasContext *ctx, int rt, 4089 int rs, int rd) 4090 { 4091 int offset = sextract32(ctx->opcode, 3, 8); 4092 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode); 4093 TCGv t0, t1; 4094 TCGv_i32 fp0; 4095 4096 /* Pre-conditions */ 4097 switch (opc) { 4098 case OPC_GSLBX: 4099 case OPC_GSLHX: 4100 case OPC_GSLWX: 4101 case OPC_GSLDX: 4102 /* prefetch, implement as NOP */ 4103 if (rt == 0) { 4104 return; 4105 } 4106 break; 4107 case OPC_GSSBX: 4108 case OPC_GSSHX: 4109 case OPC_GSSWX: 4110 case OPC_GSSDX: 4111 break; 4112 case OPC_GSLWXC1: 4113 #if defined(TARGET_MIPS64) 4114 case OPC_GSLDXC1: 4115 #endif 4116 check_cp1_enabled(ctx); 4117 /* prefetch, implement as NOP */ 4118 if (rt == 0) { 4119 return; 4120 } 4121 break; 4122 case OPC_GSSWXC1: 4123 #if defined(TARGET_MIPS64) 4124 case OPC_GSSDXC1: 4125 #endif 4126 check_cp1_enabled(ctx); 4127 break; 4128 default: 4129 MIPS_INVAL("loongson_lsdc2"); 4130 gen_reserved_instruction(ctx); 4131 return; 4132 break; 4133 } 4134 4135 t0 = tcg_temp_new(); 4136 4137 gen_base_offset_addr(ctx, t0, rs, offset); 4138 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4139 4140 switch (opc) { 4141 case OPC_GSLBX: 4142 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); 4143 gen_store_gpr(t0, rt); 4144 break; 4145 case OPC_GSLHX: 4146 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW | 4147 ctx->default_tcg_memop_mask); 4148 gen_store_gpr(t0, rt); 4149 break; 4150 case OPC_GSLWX: 4151 gen_base_offset_addr(ctx, t0, rs, offset); 4152 if (rd) { 4153 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4154 } 4155 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 4156 ctx->default_tcg_memop_mask); 4157 gen_store_gpr(t0, rt); 4158 break; 4159 #if defined(TARGET_MIPS64) 4160 case OPC_GSLDX: 4161 gen_base_offset_addr(ctx, t0, rs, offset); 4162 if (rd) { 4163 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4164 } 4165 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4166 ctx->default_tcg_memop_mask); 4167 gen_store_gpr(t0, rt); 4168 break; 4169 #endif 4170 case OPC_GSLWXC1: 4171 gen_base_offset_addr(ctx, t0, rs, offset); 4172 if (rd) { 4173 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4174 } 4175 fp0 = tcg_temp_new_i32(); 4176 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 4177 ctx->default_tcg_memop_mask); 4178 gen_store_fpr32(ctx, fp0, rt); 4179 break; 4180 #if defined(TARGET_MIPS64) 4181 case OPC_GSLDXC1: 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_fpr64(ctx, t0, rt); 4189 break; 4190 #endif 4191 case OPC_GSSBX: 4192 t1 = tcg_temp_new(); 4193 gen_load_gpr(t1, rt); 4194 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); 4195 break; 4196 case OPC_GSSHX: 4197 t1 = tcg_temp_new(); 4198 gen_load_gpr(t1, rt); 4199 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UW | 4200 ctx->default_tcg_memop_mask); 4201 break; 4202 case OPC_GSSWX: 4203 t1 = tcg_temp_new(); 4204 gen_load_gpr(t1, rt); 4205 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 4206 ctx->default_tcg_memop_mask); 4207 break; 4208 #if defined(TARGET_MIPS64) 4209 case OPC_GSSDX: 4210 t1 = tcg_temp_new(); 4211 gen_load_gpr(t1, rt); 4212 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4213 ctx->default_tcg_memop_mask); 4214 break; 4215 #endif 4216 case OPC_GSSWXC1: 4217 fp0 = tcg_temp_new_i32(); 4218 gen_load_fpr32(ctx, fp0, rt); 4219 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 4220 ctx->default_tcg_memop_mask); 4221 break; 4222 #if defined(TARGET_MIPS64) 4223 case OPC_GSSDXC1: 4224 t1 = tcg_temp_new(); 4225 gen_load_fpr64(ctx, t1, rt); 4226 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4227 ctx->default_tcg_memop_mask); 4228 break; 4229 #endif 4230 default: 4231 break; 4232 } 4233 } 4234 4235 /* Traps */ 4236 static void gen_trap(DisasContext *ctx, uint32_t opc, 4237 int rs, int rt, int16_t imm, int code) 4238 { 4239 int cond; 4240 TCGv t0 = tcg_temp_new(); 4241 TCGv t1 = tcg_temp_new(); 4242 4243 cond = 0; 4244 /* Load needed operands */ 4245 switch (opc) { 4246 case OPC_TEQ: 4247 case OPC_TGE: 4248 case OPC_TGEU: 4249 case OPC_TLT: 4250 case OPC_TLTU: 4251 case OPC_TNE: 4252 /* Compare two registers */ 4253 if (rs != rt) { 4254 gen_load_gpr(t0, rs); 4255 gen_load_gpr(t1, rt); 4256 cond = 1; 4257 } 4258 break; 4259 case OPC_TEQI: 4260 case OPC_TGEI: 4261 case OPC_TGEIU: 4262 case OPC_TLTI: 4263 case OPC_TLTIU: 4264 case OPC_TNEI: 4265 /* Compare register to immediate */ 4266 if (rs != 0 || imm != 0) { 4267 gen_load_gpr(t0, rs); 4268 tcg_gen_movi_tl(t1, (int32_t)imm); 4269 cond = 1; 4270 } 4271 break; 4272 } 4273 if (cond == 0) { 4274 switch (opc) { 4275 case OPC_TEQ: /* rs == rs */ 4276 case OPC_TEQI: /* r0 == 0 */ 4277 case OPC_TGE: /* rs >= rs */ 4278 case OPC_TGEI: /* r0 >= 0 */ 4279 case OPC_TGEU: /* rs >= rs unsigned */ 4280 case OPC_TGEIU: /* r0 >= 0 unsigned */ 4281 /* Always trap */ 4282 #ifdef CONFIG_USER_ONLY 4283 /* Pass the break code along to cpu_loop. */ 4284 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 4285 offsetof(CPUMIPSState, error_code)); 4286 #endif 4287 generate_exception_end(ctx, EXCP_TRAP); 4288 break; 4289 case OPC_TLT: /* rs < rs */ 4290 case OPC_TLTI: /* r0 < 0 */ 4291 case OPC_TLTU: /* rs < rs unsigned */ 4292 case OPC_TLTIU: /* r0 < 0 unsigned */ 4293 case OPC_TNE: /* rs != rs */ 4294 case OPC_TNEI: /* r0 != 0 */ 4295 /* Never trap: treat as NOP. */ 4296 break; 4297 } 4298 } else { 4299 TCGLabel *l1 = gen_new_label(); 4300 4301 switch (opc) { 4302 case OPC_TEQ: 4303 case OPC_TEQI: 4304 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 4305 break; 4306 case OPC_TGE: 4307 case OPC_TGEI: 4308 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 4309 break; 4310 case OPC_TGEU: 4311 case OPC_TGEIU: 4312 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 4313 break; 4314 case OPC_TLT: 4315 case OPC_TLTI: 4316 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 4317 break; 4318 case OPC_TLTU: 4319 case OPC_TLTIU: 4320 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 4321 break; 4322 case OPC_TNE: 4323 case OPC_TNEI: 4324 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 4325 break; 4326 } 4327 #ifdef CONFIG_USER_ONLY 4328 /* Pass the break code along to cpu_loop. */ 4329 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 4330 offsetof(CPUMIPSState, error_code)); 4331 #endif 4332 /* Like save_cpu_state, only don't update saved values. */ 4333 if (ctx->base.pc_next != ctx->saved_pc) { 4334 gen_save_pc(ctx->base.pc_next); 4335 } 4336 if (ctx->hflags != ctx->saved_hflags) { 4337 tcg_gen_movi_i32(hflags, ctx->hflags); 4338 } 4339 generate_exception(ctx, EXCP_TRAP); 4340 gen_set_label(l1); 4341 } 4342 } 4343 4344 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 4345 { 4346 if (translator_use_goto_tb(&ctx->base, dest)) { 4347 tcg_gen_goto_tb(n); 4348 gen_save_pc(dest); 4349 tcg_gen_exit_tb(ctx->base.tb, n); 4350 } else { 4351 gen_save_pc(dest); 4352 tcg_gen_lookup_and_goto_ptr(); 4353 } 4354 } 4355 4356 /* Branches (before delay slot) */ 4357 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, 4358 int insn_bytes, 4359 int rs, int rt, int32_t offset, 4360 int delayslot_size) 4361 { 4362 target_ulong btgt = -1; 4363 int blink = 0; 4364 int bcond_compute = 0; 4365 TCGv t0 = tcg_temp_new(); 4366 TCGv t1 = tcg_temp_new(); 4367 4368 if (ctx->hflags & MIPS_HFLAG_BMASK) { 4369 #ifdef MIPS_DEBUG_DISAS 4370 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 4371 VADDR_PRIx "\n", ctx->base.pc_next); 4372 #endif 4373 gen_reserved_instruction(ctx); 4374 goto out; 4375 } 4376 4377 /* Load needed operands */ 4378 switch (opc) { 4379 case OPC_BEQ: 4380 case OPC_BEQL: 4381 case OPC_BNE: 4382 case OPC_BNEL: 4383 /* Compare two registers */ 4384 if (rs != rt) { 4385 gen_load_gpr(t0, rs); 4386 gen_load_gpr(t1, rt); 4387 bcond_compute = 1; 4388 } 4389 btgt = ctx->base.pc_next + insn_bytes + offset; 4390 break; 4391 case OPC_BGEZ: 4392 case OPC_BGEZAL: 4393 case OPC_BGEZALL: 4394 case OPC_BGEZL: 4395 case OPC_BGTZ: 4396 case OPC_BGTZL: 4397 case OPC_BLEZ: 4398 case OPC_BLEZL: 4399 case OPC_BLTZ: 4400 case OPC_BLTZAL: 4401 case OPC_BLTZALL: 4402 case OPC_BLTZL: 4403 /* Compare to zero */ 4404 if (rs != 0) { 4405 gen_load_gpr(t0, rs); 4406 bcond_compute = 1; 4407 } 4408 btgt = ctx->base.pc_next + insn_bytes + offset; 4409 break; 4410 case OPC_BPOSGE32: 4411 #if defined(TARGET_MIPS64) 4412 case OPC_BPOSGE64: 4413 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F); 4414 #else 4415 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 4416 #endif 4417 bcond_compute = 1; 4418 btgt = ctx->base.pc_next + insn_bytes + offset; 4419 break; 4420 case OPC_J: 4421 case OPC_JAL: 4422 { 4423 /* Jump to immediate */ 4424 int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000 4425 : 0xF0000000; 4426 btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask) 4427 | (uint32_t)offset; 4428 break; 4429 } 4430 case OPC_JALX: 4431 /* Jump to immediate */ 4432 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) | 4433 (uint32_t)offset; 4434 break; 4435 case OPC_JR: 4436 case OPC_JALR: 4437 /* Jump to register */ 4438 if (offset != 0 && offset != 16) { 4439 /* 4440 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 4441 * others are reserved. 4442 */ 4443 MIPS_INVAL("jump hint"); 4444 gen_reserved_instruction(ctx); 4445 goto out; 4446 } 4447 gen_load_gpr(btarget, rs); 4448 break; 4449 default: 4450 MIPS_INVAL("branch/jump"); 4451 gen_reserved_instruction(ctx); 4452 goto out; 4453 } 4454 if (bcond_compute == 0) { 4455 /* No condition to be computed */ 4456 switch (opc) { 4457 case OPC_BEQ: /* rx == rx */ 4458 case OPC_BEQL: /* rx == rx likely */ 4459 case OPC_BGEZ: /* 0 >= 0 */ 4460 case OPC_BGEZL: /* 0 >= 0 likely */ 4461 case OPC_BLEZ: /* 0 <= 0 */ 4462 case OPC_BLEZL: /* 0 <= 0 likely */ 4463 /* Always take */ 4464 ctx->hflags |= MIPS_HFLAG_B; 4465 break; 4466 case OPC_BGEZAL: /* 0 >= 0 */ 4467 case OPC_BGEZALL: /* 0 >= 0 likely */ 4468 /* Always take and link */ 4469 blink = 31; 4470 ctx->hflags |= MIPS_HFLAG_B; 4471 break; 4472 case OPC_BNE: /* rx != rx */ 4473 case OPC_BGTZ: /* 0 > 0 */ 4474 case OPC_BLTZ: /* 0 < 0 */ 4475 /* Treat as NOP. */ 4476 goto out; 4477 case OPC_BLTZAL: /* 0 < 0 */ 4478 /* 4479 * Handle as an unconditional branch to get correct delay 4480 * slot checking. 4481 */ 4482 blink = 31; 4483 btgt = ctx->base.pc_next + insn_bytes + delayslot_size; 4484 ctx->hflags |= MIPS_HFLAG_B; 4485 break; 4486 case OPC_BLTZALL: /* 0 < 0 likely */ 4487 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 4488 /* Skip the instruction in the delay slot */ 4489 ctx->base.pc_next += 4; 4490 goto out; 4491 case OPC_BNEL: /* rx != rx likely */ 4492 case OPC_BGTZL: /* 0 > 0 likely */ 4493 case OPC_BLTZL: /* 0 < 0 likely */ 4494 /* Skip the instruction in the delay slot */ 4495 ctx->base.pc_next += 4; 4496 goto out; 4497 case OPC_J: 4498 ctx->hflags |= MIPS_HFLAG_B; 4499 break; 4500 case OPC_JALX: 4501 ctx->hflags |= MIPS_HFLAG_BX; 4502 /* Fallthrough */ 4503 case OPC_JAL: 4504 blink = 31; 4505 ctx->hflags |= MIPS_HFLAG_B; 4506 break; 4507 case OPC_JR: 4508 ctx->hflags |= MIPS_HFLAG_BR; 4509 break; 4510 case OPC_JALR: 4511 blink = rt; 4512 ctx->hflags |= MIPS_HFLAG_BR; 4513 break; 4514 default: 4515 MIPS_INVAL("branch/jump"); 4516 gen_reserved_instruction(ctx); 4517 goto out; 4518 } 4519 } else { 4520 switch (opc) { 4521 case OPC_BEQ: 4522 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 4523 goto not_likely; 4524 case OPC_BEQL: 4525 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 4526 goto likely; 4527 case OPC_BNE: 4528 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 4529 goto not_likely; 4530 case OPC_BNEL: 4531 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 4532 goto likely; 4533 case OPC_BGEZ: 4534 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4535 goto not_likely; 4536 case OPC_BGEZL: 4537 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4538 goto likely; 4539 case OPC_BGEZAL: 4540 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4541 blink = 31; 4542 goto not_likely; 4543 case OPC_BGEZALL: 4544 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4545 blink = 31; 4546 goto likely; 4547 case OPC_BGTZ: 4548 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 4549 goto not_likely; 4550 case OPC_BGTZL: 4551 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 4552 goto likely; 4553 case OPC_BLEZ: 4554 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 4555 goto not_likely; 4556 case OPC_BLEZL: 4557 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 4558 goto likely; 4559 case OPC_BLTZ: 4560 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4561 goto not_likely; 4562 case OPC_BLTZL: 4563 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4564 goto likely; 4565 case OPC_BPOSGE32: 4566 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 4567 goto not_likely; 4568 #if defined(TARGET_MIPS64) 4569 case OPC_BPOSGE64: 4570 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64); 4571 goto not_likely; 4572 #endif 4573 case OPC_BLTZAL: 4574 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4575 blink = 31; 4576 not_likely: 4577 ctx->hflags |= MIPS_HFLAG_BC; 4578 break; 4579 case OPC_BLTZALL: 4580 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4581 blink = 31; 4582 likely: 4583 ctx->hflags |= MIPS_HFLAG_BL; 4584 break; 4585 default: 4586 MIPS_INVAL("conditional branch/jump"); 4587 gen_reserved_instruction(ctx); 4588 goto out; 4589 } 4590 } 4591 4592 ctx->btarget = btgt; 4593 4594 switch (delayslot_size) { 4595 case 2: 4596 ctx->hflags |= MIPS_HFLAG_BDS16; 4597 break; 4598 case 4: 4599 ctx->hflags |= MIPS_HFLAG_BDS32; 4600 break; 4601 } 4602 4603 if (blink > 0) { 4604 int post_delay = insn_bytes + delayslot_size; 4605 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); 4606 4607 tcg_gen_movi_tl(cpu_gpr[blink], 4608 ctx->base.pc_next + post_delay + lowbit); 4609 } 4610 4611 out: 4612 if (insn_bytes == 2) { 4613 ctx->hflags |= MIPS_HFLAG_B16; 4614 } 4615 } 4616 4617 4618 /* special3 bitfield operations */ 4619 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, 4620 int rs, int lsb, int msb) 4621 { 4622 TCGv t0 = tcg_temp_new(); 4623 TCGv t1 = tcg_temp_new(); 4624 4625 gen_load_gpr(t1, rs); 4626 switch (opc) { 4627 case OPC_EXT: 4628 if (lsb + msb > 31) { 4629 goto fail; 4630 } 4631 if (msb != 31) { 4632 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 4633 } else { 4634 /* 4635 * The two checks together imply that lsb == 0, 4636 * so this is a simple sign-extension. 4637 */ 4638 tcg_gen_ext32s_tl(t0, t1); 4639 } 4640 break; 4641 #if defined(TARGET_MIPS64) 4642 case OPC_DEXTU: 4643 lsb += 32; 4644 goto do_dext; 4645 case OPC_DEXTM: 4646 msb += 32; 4647 goto do_dext; 4648 case OPC_DEXT: 4649 do_dext: 4650 if (lsb + msb > 63) { 4651 goto fail; 4652 } 4653 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 4654 break; 4655 #endif 4656 case OPC_INS: 4657 if (lsb > msb) { 4658 goto fail; 4659 } 4660 gen_load_gpr(t0, rt); 4661 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 4662 tcg_gen_ext32s_tl(t0, t0); 4663 break; 4664 #if defined(TARGET_MIPS64) 4665 case OPC_DINSU: 4666 lsb += 32; 4667 /* FALLTHRU */ 4668 case OPC_DINSM: 4669 msb += 32; 4670 /* FALLTHRU */ 4671 case OPC_DINS: 4672 if (lsb > msb) { 4673 goto fail; 4674 } 4675 gen_load_gpr(t0, rt); 4676 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 4677 break; 4678 #endif 4679 default: 4680 fail: 4681 MIPS_INVAL("bitops"); 4682 gen_reserved_instruction(ctx); 4683 return; 4684 } 4685 gen_store_gpr(t0, rt); 4686 } 4687 4688 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) 4689 { 4690 TCGv t0; 4691 4692 if (rd == 0) { 4693 /* If no destination, treat it as a NOP. */ 4694 return; 4695 } 4696 4697 t0 = tcg_temp_new(); 4698 gen_load_gpr(t0, rt); 4699 switch (op2) { 4700 case OPC_WSBH: 4701 { 4702 TCGv t1 = tcg_temp_new(); 4703 TCGv t2 = tcg_constant_tl(0x00FF00FF); 4704 4705 tcg_gen_shri_tl(t1, t0, 8); 4706 tcg_gen_and_tl(t1, t1, t2); 4707 tcg_gen_and_tl(t0, t0, t2); 4708 tcg_gen_shli_tl(t0, t0, 8); 4709 tcg_gen_or_tl(t0, t0, t1); 4710 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 4711 } 4712 break; 4713 case OPC_SEB: 4714 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 4715 break; 4716 case OPC_SEH: 4717 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 4718 break; 4719 #if defined(TARGET_MIPS64) 4720 case OPC_DSBH: 4721 { 4722 TCGv t1 = tcg_temp_new(); 4723 TCGv t2 = tcg_constant_tl(0x00FF00FF00FF00FFULL); 4724 4725 tcg_gen_shri_tl(t1, t0, 8); 4726 tcg_gen_and_tl(t1, t1, t2); 4727 tcg_gen_and_tl(t0, t0, t2); 4728 tcg_gen_shli_tl(t0, t0, 8); 4729 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 4730 } 4731 break; 4732 case OPC_DSHD: 4733 { 4734 TCGv t1 = tcg_temp_new(); 4735 TCGv t2 = tcg_constant_tl(0x0000FFFF0000FFFFULL); 4736 4737 tcg_gen_shri_tl(t1, t0, 16); 4738 tcg_gen_and_tl(t1, t1, t2); 4739 tcg_gen_and_tl(t0, t0, t2); 4740 tcg_gen_shli_tl(t0, t0, 16); 4741 tcg_gen_or_tl(t0, t0, t1); 4742 tcg_gen_shri_tl(t1, t0, 32); 4743 tcg_gen_shli_tl(t0, t0, 32); 4744 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 4745 } 4746 break; 4747 #endif 4748 default: 4749 MIPS_INVAL("bsfhl"); 4750 gen_reserved_instruction(ctx); 4751 return; 4752 } 4753 } 4754 4755 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, 4756 int rt, int bits) 4757 { 4758 TCGv t0; 4759 if (rd == 0) { 4760 /* Treat as NOP. */ 4761 return; 4762 } 4763 t0 = tcg_temp_new(); 4764 if (bits == 0 || bits == wordsz) { 4765 if (bits == 0) { 4766 gen_load_gpr(t0, rt); 4767 } else { 4768 gen_load_gpr(t0, rs); 4769 } 4770 switch (wordsz) { 4771 case 32: 4772 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 4773 break; 4774 #if defined(TARGET_MIPS64) 4775 case 64: 4776 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4777 break; 4778 #endif 4779 } 4780 } else { 4781 TCGv t1 = tcg_temp_new(); 4782 gen_load_gpr(t0, rt); 4783 gen_load_gpr(t1, rs); 4784 switch (wordsz) { 4785 case 32: 4786 { 4787 TCGv_i64 t2 = tcg_temp_new_i64(); 4788 tcg_gen_concat_tl_i64(t2, t1, t0); 4789 tcg_gen_shri_i64(t2, t2, 32 - bits); 4790 gen_move_low32(cpu_gpr[rd], t2); 4791 } 4792 break; 4793 #if defined(TARGET_MIPS64) 4794 case 64: 4795 tcg_gen_shli_tl(t0, t0, bits); 4796 tcg_gen_shri_tl(t1, t1, 64 - bits); 4797 tcg_gen_or_tl(cpu_gpr[rd], t1, t0); 4798 break; 4799 #endif 4800 } 4801 } 4802 } 4803 4804 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp) 4805 { 4806 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); 4807 } 4808 4809 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) 4810 { 4811 TCGv t0; 4812 if (rd == 0) { 4813 /* Treat as NOP. */ 4814 return; 4815 } 4816 t0 = tcg_temp_new(); 4817 gen_load_gpr(t0, rt); 4818 switch (opc) { 4819 case OPC_BITSWAP: 4820 gen_helper_bitswap(cpu_gpr[rd], t0); 4821 break; 4822 #if defined(TARGET_MIPS64) 4823 case OPC_DBITSWAP: 4824 gen_helper_dbitswap(cpu_gpr[rd], t0); 4825 break; 4826 #endif 4827 } 4828 } 4829 4830 #ifndef CONFIG_USER_ONLY 4831 /* CP0 (MMU and control) */ 4832 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off) 4833 { 4834 TCGv_i64 t0 = tcg_temp_new_i64(); 4835 TCGv_i64 t1 = tcg_temp_new_i64(); 4836 4837 tcg_gen_ext_tl_i64(t0, arg); 4838 tcg_gen_ld_i64(t1, tcg_env, off); 4839 #if defined(TARGET_MIPS64) 4840 tcg_gen_deposit_i64(t1, t1, t0, 30, 32); 4841 #else 4842 tcg_gen_concat32_i64(t1, t1, t0); 4843 #endif 4844 tcg_gen_st_i64(t1, tcg_env, off); 4845 } 4846 4847 static inline void gen_mthc0_store64(TCGv arg, target_ulong off) 4848 { 4849 TCGv_i64 t0 = tcg_temp_new_i64(); 4850 TCGv_i64 t1 = tcg_temp_new_i64(); 4851 4852 tcg_gen_ext_tl_i64(t0, arg); 4853 tcg_gen_ld_i64(t1, tcg_env, off); 4854 tcg_gen_concat32_i64(t1, t1, t0); 4855 tcg_gen_st_i64(t1, tcg_env, off); 4856 } 4857 4858 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off) 4859 { 4860 TCGv_i64 t0 = tcg_temp_new_i64(); 4861 4862 tcg_gen_ld_i64(t0, tcg_env, off); 4863 #if defined(TARGET_MIPS64) 4864 tcg_gen_shri_i64(t0, t0, 30); 4865 #else 4866 tcg_gen_shri_i64(t0, t0, 32); 4867 #endif 4868 gen_move_low32(arg, t0); 4869 } 4870 4871 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift) 4872 { 4873 TCGv_i64 t0 = tcg_temp_new_i64(); 4874 4875 tcg_gen_ld_i64(t0, tcg_env, off); 4876 tcg_gen_shri_i64(t0, t0, 32 + shift); 4877 gen_move_low32(arg, t0); 4878 } 4879 4880 static inline void gen_mfc0_load32(TCGv arg, target_ulong off) 4881 { 4882 TCGv_i32 t0 = tcg_temp_new_i32(); 4883 4884 tcg_gen_ld_i32(t0, tcg_env, off); 4885 tcg_gen_ext_i32_tl(arg, t0); 4886 } 4887 4888 static inline void gen_mfc0_load64(TCGv arg, target_ulong off) 4889 { 4890 tcg_gen_ld_tl(arg, tcg_env, off); 4891 tcg_gen_ext32s_tl(arg, arg); 4892 } 4893 4894 static inline void gen_mtc0_store32(TCGv arg, target_ulong off) 4895 { 4896 TCGv_i32 t0 = tcg_temp_new_i32(); 4897 4898 tcg_gen_trunc_tl_i32(t0, arg); 4899 tcg_gen_st_i32(t0, tcg_env, off); 4900 } 4901 4902 #define CP0_CHECK(c) \ 4903 do { \ 4904 if (!(c)) { \ 4905 goto cp0_unimplemented; \ 4906 } \ 4907 } while (0) 4908 4909 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) 4910 { 4911 const char *register_name = "invalid"; 4912 4913 switch (reg) { 4914 case CP0_REGISTER_02: 4915 switch (sel) { 4916 case 0: 4917 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 4918 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 4919 register_name = "EntryLo0"; 4920 break; 4921 default: 4922 goto cp0_unimplemented; 4923 } 4924 break; 4925 case CP0_REGISTER_03: 4926 switch (sel) { 4927 case CP0_REG03__ENTRYLO1: 4928 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 4929 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 4930 register_name = "EntryLo1"; 4931 break; 4932 default: 4933 goto cp0_unimplemented; 4934 } 4935 break; 4936 case CP0_REGISTER_17: 4937 switch (sel) { 4938 case CP0_REG17__LLADDR: 4939 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr), 4940 ctx->CP0_LLAddr_shift); 4941 register_name = "LLAddr"; 4942 break; 4943 case CP0_REG17__MAAR: 4944 CP0_CHECK(ctx->mrp); 4945 gen_helper_mfhc0_maar(arg, tcg_env); 4946 register_name = "MAAR"; 4947 break; 4948 default: 4949 goto cp0_unimplemented; 4950 } 4951 break; 4952 case CP0_REGISTER_19: 4953 switch (sel) { 4954 case CP0_REG19__WATCHHI0: 4955 case CP0_REG19__WATCHHI1: 4956 case CP0_REG19__WATCHHI2: 4957 case CP0_REG19__WATCHHI3: 4958 case CP0_REG19__WATCHHI4: 4959 case CP0_REG19__WATCHHI5: 4960 case CP0_REG19__WATCHHI6: 4961 case CP0_REG19__WATCHHI7: 4962 /* upper 32 bits are only available when Config5MI != 0 */ 4963 CP0_CHECK(ctx->mi); 4964 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0); 4965 register_name = "WatchHi"; 4966 break; 4967 default: 4968 goto cp0_unimplemented; 4969 } 4970 break; 4971 case CP0_REGISTER_28: 4972 switch (sel) { 4973 case 0: 4974 case 2: 4975 case 4: 4976 case 6: 4977 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0); 4978 register_name = "TagLo"; 4979 break; 4980 default: 4981 goto cp0_unimplemented; 4982 } 4983 break; 4984 default: 4985 goto cp0_unimplemented; 4986 } 4987 trace_mips_translate_c0("mfhc0", register_name, reg, sel); 4988 return; 4989 4990 cp0_unimplemented: 4991 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", 4992 register_name, reg, sel); 4993 tcg_gen_movi_tl(arg, 0); 4994 } 4995 4996 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) 4997 { 4998 const char *register_name = "invalid"; 4999 uint64_t mask = ctx->PAMask >> 36; 5000 5001 switch (reg) { 5002 case CP0_REGISTER_02: 5003 switch (sel) { 5004 case 0: 5005 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5006 tcg_gen_andi_tl(arg, arg, mask); 5007 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5008 register_name = "EntryLo0"; 5009 break; 5010 default: 5011 goto cp0_unimplemented; 5012 } 5013 break; 5014 case CP0_REGISTER_03: 5015 switch (sel) { 5016 case CP0_REG03__ENTRYLO1: 5017 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5018 tcg_gen_andi_tl(arg, arg, mask); 5019 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5020 register_name = "EntryLo1"; 5021 break; 5022 default: 5023 goto cp0_unimplemented; 5024 } 5025 break; 5026 case CP0_REGISTER_17: 5027 switch (sel) { 5028 case CP0_REG17__LLADDR: 5029 /* 5030 * LLAddr is read-only (the only exception is bit 0 if LLB is 5031 * supported); the CP0_LLAddr_rw_bitmask does not seem to be 5032 * relevant for modern MIPS cores supporting MTHC0, therefore 5033 * treating MTHC0 to LLAddr as NOP. 5034 */ 5035 register_name = "LLAddr"; 5036 break; 5037 case CP0_REG17__MAAR: 5038 CP0_CHECK(ctx->mrp); 5039 gen_helper_mthc0_maar(tcg_env, arg); 5040 register_name = "MAAR"; 5041 break; 5042 default: 5043 goto cp0_unimplemented; 5044 } 5045 break; 5046 case CP0_REGISTER_19: 5047 switch (sel) { 5048 case CP0_REG19__WATCHHI0: 5049 case CP0_REG19__WATCHHI1: 5050 case CP0_REG19__WATCHHI2: 5051 case CP0_REG19__WATCHHI3: 5052 case CP0_REG19__WATCHHI4: 5053 case CP0_REG19__WATCHHI5: 5054 case CP0_REG19__WATCHHI6: 5055 case CP0_REG19__WATCHHI7: 5056 /* upper 32 bits are only available when Config5MI != 0 */ 5057 CP0_CHECK(ctx->mi); 5058 gen_helper_0e1i(mthc0_watchhi, arg, sel); 5059 register_name = "WatchHi"; 5060 break; 5061 default: 5062 goto cp0_unimplemented; 5063 } 5064 break; 5065 case CP0_REGISTER_28: 5066 switch (sel) { 5067 case 0: 5068 case 2: 5069 case 4: 5070 case 6: 5071 tcg_gen_andi_tl(arg, arg, mask); 5072 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo)); 5073 register_name = "TagLo"; 5074 break; 5075 default: 5076 goto cp0_unimplemented; 5077 } 5078 break; 5079 default: 5080 goto cp0_unimplemented; 5081 } 5082 trace_mips_translate_c0("mthc0", register_name, reg, sel); 5083 return; 5084 5085 cp0_unimplemented: 5086 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", 5087 register_name, reg, sel); 5088 } 5089 5090 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg) 5091 { 5092 if (ctx->insn_flags & ISA_MIPS_R6) { 5093 tcg_gen_movi_tl(arg, 0); 5094 } else { 5095 tcg_gen_movi_tl(arg, ~0); 5096 } 5097 } 5098 5099 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5100 { 5101 const char *register_name = "invalid"; 5102 5103 if (sel != 0) { 5104 check_insn(ctx, ISA_MIPS_R1); 5105 } 5106 5107 switch (reg) { 5108 case CP0_REGISTER_00: 5109 switch (sel) { 5110 case CP0_REG00__INDEX: 5111 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 5112 register_name = "Index"; 5113 break; 5114 case CP0_REG00__MVPCONTROL: 5115 CP0_CHECK(disas_mt_available(ctx)); 5116 gen_helper_mfc0_mvpcontrol(arg, tcg_env); 5117 register_name = "MVPControl"; 5118 break; 5119 case CP0_REG00__MVPCONF0: 5120 CP0_CHECK(disas_mt_available(ctx)); 5121 gen_helper_mfc0_mvpconf0(arg, tcg_env); 5122 register_name = "MVPConf0"; 5123 break; 5124 case CP0_REG00__MVPCONF1: 5125 CP0_CHECK(disas_mt_available(ctx)); 5126 gen_helper_mfc0_mvpconf1(arg, tcg_env); 5127 register_name = "MVPConf1"; 5128 break; 5129 case CP0_REG00__VPCONTROL: 5130 CP0_CHECK(ctx->vp); 5131 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 5132 register_name = "VPControl"; 5133 break; 5134 default: 5135 goto cp0_unimplemented; 5136 } 5137 break; 5138 case CP0_REGISTER_01: 5139 switch (sel) { 5140 case CP0_REG01__RANDOM: 5141 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5142 gen_helper_mfc0_random(arg, tcg_env); 5143 register_name = "Random"; 5144 break; 5145 case CP0_REG01__VPECONTROL: 5146 CP0_CHECK(disas_mt_available(ctx)); 5147 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 5148 register_name = "VPEControl"; 5149 break; 5150 case CP0_REG01__VPECONF0: 5151 CP0_CHECK(disas_mt_available(ctx)); 5152 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 5153 register_name = "VPEConf0"; 5154 break; 5155 case CP0_REG01__VPECONF1: 5156 CP0_CHECK(disas_mt_available(ctx)); 5157 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 5158 register_name = "VPEConf1"; 5159 break; 5160 case CP0_REG01__YQMASK: 5161 CP0_CHECK(disas_mt_available(ctx)); 5162 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 5163 register_name = "YQMask"; 5164 break; 5165 case CP0_REG01__VPESCHEDULE: 5166 CP0_CHECK(disas_mt_available(ctx)); 5167 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 5168 register_name = "VPESchedule"; 5169 break; 5170 case CP0_REG01__VPESCHEFBACK: 5171 CP0_CHECK(disas_mt_available(ctx)); 5172 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5173 register_name = "VPEScheFBack"; 5174 break; 5175 case CP0_REG01__VPEOPT: 5176 CP0_CHECK(disas_mt_available(ctx)); 5177 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 5178 register_name = "VPEOpt"; 5179 break; 5180 default: 5181 goto cp0_unimplemented; 5182 } 5183 break; 5184 case CP0_REGISTER_02: 5185 switch (sel) { 5186 case CP0_REG02__ENTRYLO0: 5187 { 5188 TCGv_i64 tmp = tcg_temp_new_i64(); 5189 tcg_gen_ld_i64(tmp, tcg_env, 5190 offsetof(CPUMIPSState, CP0_EntryLo0)); 5191 #if defined(TARGET_MIPS64) 5192 if (ctx->rxi) { 5193 /* Move RI/XI fields to bits 31:30 */ 5194 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5195 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5196 } 5197 #endif 5198 gen_move_low32(arg, tmp); 5199 } 5200 register_name = "EntryLo0"; 5201 break; 5202 case CP0_REG02__TCSTATUS: 5203 CP0_CHECK(disas_mt_available(ctx)); 5204 gen_helper_mfc0_tcstatus(arg, tcg_env); 5205 register_name = "TCStatus"; 5206 break; 5207 case CP0_REG02__TCBIND: 5208 CP0_CHECK(disas_mt_available(ctx)); 5209 gen_helper_mfc0_tcbind(arg, tcg_env); 5210 register_name = "TCBind"; 5211 break; 5212 case CP0_REG02__TCRESTART: 5213 CP0_CHECK(disas_mt_available(ctx)); 5214 gen_helper_mfc0_tcrestart(arg, tcg_env); 5215 register_name = "TCRestart"; 5216 break; 5217 case CP0_REG02__TCHALT: 5218 CP0_CHECK(disas_mt_available(ctx)); 5219 gen_helper_mfc0_tchalt(arg, tcg_env); 5220 register_name = "TCHalt"; 5221 break; 5222 case CP0_REG02__TCCONTEXT: 5223 CP0_CHECK(disas_mt_available(ctx)); 5224 gen_helper_mfc0_tccontext(arg, tcg_env); 5225 register_name = "TCContext"; 5226 break; 5227 case CP0_REG02__TCSCHEDULE: 5228 CP0_CHECK(disas_mt_available(ctx)); 5229 gen_helper_mfc0_tcschedule(arg, tcg_env); 5230 register_name = "TCSchedule"; 5231 break; 5232 case CP0_REG02__TCSCHEFBACK: 5233 CP0_CHECK(disas_mt_available(ctx)); 5234 gen_helper_mfc0_tcschefback(arg, tcg_env); 5235 register_name = "TCScheFBack"; 5236 break; 5237 default: 5238 goto cp0_unimplemented; 5239 } 5240 break; 5241 case CP0_REGISTER_03: 5242 switch (sel) { 5243 case CP0_REG03__ENTRYLO1: 5244 { 5245 TCGv_i64 tmp = tcg_temp_new_i64(); 5246 tcg_gen_ld_i64(tmp, tcg_env, 5247 offsetof(CPUMIPSState, CP0_EntryLo1)); 5248 #if defined(TARGET_MIPS64) 5249 if (ctx->rxi) { 5250 /* Move RI/XI fields to bits 31:30 */ 5251 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5252 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5253 } 5254 #endif 5255 gen_move_low32(arg, tmp); 5256 } 5257 register_name = "EntryLo1"; 5258 break; 5259 case CP0_REG03__GLOBALNUM: 5260 CP0_CHECK(ctx->vp); 5261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 5262 register_name = "GlobalNumber"; 5263 break; 5264 default: 5265 goto cp0_unimplemented; 5266 } 5267 break; 5268 case CP0_REGISTER_04: 5269 switch (sel) { 5270 case CP0_REG04__CONTEXT: 5271 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context)); 5272 tcg_gen_ext32s_tl(arg, arg); 5273 register_name = "Context"; 5274 break; 5275 case CP0_REG04__CONTEXTCONFIG: 5276 /* SmartMIPS ASE */ 5277 /* gen_helper_mfc0_contextconfig(arg); */ 5278 register_name = "ContextConfig"; 5279 goto cp0_unimplemented; 5280 case CP0_REG04__USERLOCAL: 5281 CP0_CHECK(ctx->ulri); 5282 tcg_gen_ld_tl(arg, tcg_env, 5283 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 5284 tcg_gen_ext32s_tl(arg, arg); 5285 register_name = "UserLocal"; 5286 break; 5287 case CP0_REG04__MMID: 5288 CP0_CHECK(ctx->mi); 5289 gen_helper_mtc0_memorymapid(tcg_env, arg); 5290 register_name = "MMID"; 5291 break; 5292 default: 5293 goto cp0_unimplemented; 5294 } 5295 break; 5296 case CP0_REGISTER_05: 5297 switch (sel) { 5298 case CP0_REG05__PAGEMASK: 5299 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 5300 register_name = "PageMask"; 5301 break; 5302 case CP0_REG05__PAGEGRAIN: 5303 check_insn(ctx, ISA_MIPS_R2); 5304 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 5305 register_name = "PageGrain"; 5306 break; 5307 case CP0_REG05__SEGCTL0: 5308 CP0_CHECK(ctx->sc); 5309 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 5310 tcg_gen_ext32s_tl(arg, arg); 5311 register_name = "SegCtl0"; 5312 break; 5313 case CP0_REG05__SEGCTL1: 5314 CP0_CHECK(ctx->sc); 5315 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 5316 tcg_gen_ext32s_tl(arg, arg); 5317 register_name = "SegCtl1"; 5318 break; 5319 case CP0_REG05__SEGCTL2: 5320 CP0_CHECK(ctx->sc); 5321 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 5322 tcg_gen_ext32s_tl(arg, arg); 5323 register_name = "SegCtl2"; 5324 break; 5325 case CP0_REG05__PWBASE: 5326 check_pw(ctx); 5327 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 5328 register_name = "PWBase"; 5329 break; 5330 case CP0_REG05__PWFIELD: 5331 check_pw(ctx); 5332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField)); 5333 register_name = "PWField"; 5334 break; 5335 case CP0_REG05__PWSIZE: 5336 check_pw(ctx); 5337 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize)); 5338 register_name = "PWSize"; 5339 break; 5340 default: 5341 goto cp0_unimplemented; 5342 } 5343 break; 5344 case CP0_REGISTER_06: 5345 switch (sel) { 5346 case CP0_REG06__WIRED: 5347 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 5348 register_name = "Wired"; 5349 break; 5350 case CP0_REG06__SRSCONF0: 5351 check_insn(ctx, ISA_MIPS_R2); 5352 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 5353 register_name = "SRSConf0"; 5354 break; 5355 case CP0_REG06__SRSCONF1: 5356 check_insn(ctx, ISA_MIPS_R2); 5357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 5358 register_name = "SRSConf1"; 5359 break; 5360 case CP0_REG06__SRSCONF2: 5361 check_insn(ctx, ISA_MIPS_R2); 5362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 5363 register_name = "SRSConf2"; 5364 break; 5365 case CP0_REG06__SRSCONF3: 5366 check_insn(ctx, ISA_MIPS_R2); 5367 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 5368 register_name = "SRSConf3"; 5369 break; 5370 case CP0_REG06__SRSCONF4: 5371 check_insn(ctx, ISA_MIPS_R2); 5372 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 5373 register_name = "SRSConf4"; 5374 break; 5375 case CP0_REG06__PWCTL: 5376 check_pw(ctx); 5377 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 5378 register_name = "PWCtl"; 5379 break; 5380 default: 5381 goto cp0_unimplemented; 5382 } 5383 break; 5384 case CP0_REGISTER_07: 5385 switch (sel) { 5386 case CP0_REG07__HWRENA: 5387 check_insn(ctx, ISA_MIPS_R2); 5388 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 5389 register_name = "HWREna"; 5390 break; 5391 default: 5392 goto cp0_unimplemented; 5393 } 5394 break; 5395 case CP0_REGISTER_08: 5396 switch (sel) { 5397 case CP0_REG08__BADVADDR: 5398 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 5399 tcg_gen_ext32s_tl(arg, arg); 5400 register_name = "BadVAddr"; 5401 break; 5402 case CP0_REG08__BADINSTR: 5403 CP0_CHECK(ctx->bi); 5404 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 5405 register_name = "BadInstr"; 5406 break; 5407 case CP0_REG08__BADINSTRP: 5408 CP0_CHECK(ctx->bp); 5409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 5410 register_name = "BadInstrP"; 5411 break; 5412 case CP0_REG08__BADINSTRX: 5413 CP0_CHECK(ctx->bi); 5414 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 5415 tcg_gen_andi_tl(arg, arg, ~0xffff); 5416 register_name = "BadInstrX"; 5417 break; 5418 default: 5419 goto cp0_unimplemented; 5420 } 5421 break; 5422 case CP0_REGISTER_09: 5423 switch (sel) { 5424 case CP0_REG09__COUNT: 5425 /* Mark as an IO operation because we read the time. */ 5426 translator_io_start(&ctx->base); 5427 5428 gen_helper_mfc0_count(arg, tcg_env); 5429 /* 5430 * Break the TB to be able to take timer interrupts immediately 5431 * after reading count. DISAS_STOP isn't sufficient, we need to 5432 * ensure we break completely out of translated code. 5433 */ 5434 gen_save_pc(ctx->base.pc_next + 4); 5435 ctx->base.is_jmp = DISAS_EXIT; 5436 register_name = "Count"; 5437 break; 5438 default: 5439 goto cp0_unimplemented; 5440 } 5441 break; 5442 case CP0_REGISTER_10: 5443 switch (sel) { 5444 case CP0_REG10__ENTRYHI: 5445 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi)); 5446 tcg_gen_ext32s_tl(arg, arg); 5447 register_name = "EntryHi"; 5448 break; 5449 default: 5450 goto cp0_unimplemented; 5451 } 5452 break; 5453 case CP0_REGISTER_11: 5454 switch (sel) { 5455 case CP0_REG11__COMPARE: 5456 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 5457 register_name = "Compare"; 5458 break; 5459 /* 6,7 are implementation dependent */ 5460 default: 5461 goto cp0_unimplemented; 5462 } 5463 break; 5464 case CP0_REGISTER_12: 5465 switch (sel) { 5466 case CP0_REG12__STATUS: 5467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 5468 register_name = "Status"; 5469 break; 5470 case CP0_REG12__INTCTL: 5471 check_insn(ctx, ISA_MIPS_R2); 5472 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 5473 register_name = "IntCtl"; 5474 break; 5475 case CP0_REG12__SRSCTL: 5476 check_insn(ctx, ISA_MIPS_R2); 5477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 5478 register_name = "SRSCtl"; 5479 break; 5480 case CP0_REG12__SRSMAP: 5481 check_insn(ctx, ISA_MIPS_R2); 5482 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 5483 register_name = "SRSMap"; 5484 break; 5485 default: 5486 goto cp0_unimplemented; 5487 } 5488 break; 5489 case CP0_REGISTER_13: 5490 switch (sel) { 5491 case CP0_REG13__CAUSE: 5492 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 5493 register_name = "Cause"; 5494 break; 5495 default: 5496 goto cp0_unimplemented; 5497 } 5498 break; 5499 case CP0_REGISTER_14: 5500 switch (sel) { 5501 case CP0_REG14__EPC: 5502 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 5503 tcg_gen_ext32s_tl(arg, arg); 5504 register_name = "EPC"; 5505 break; 5506 default: 5507 goto cp0_unimplemented; 5508 } 5509 break; 5510 case CP0_REGISTER_15: 5511 switch (sel) { 5512 case CP0_REG15__PRID: 5513 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 5514 register_name = "PRid"; 5515 break; 5516 case CP0_REG15__EBASE: 5517 check_insn(ctx, ISA_MIPS_R2); 5518 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase)); 5519 tcg_gen_ext32s_tl(arg, arg); 5520 register_name = "EBase"; 5521 break; 5522 case CP0_REG15__CMGCRBASE: 5523 check_insn(ctx, ISA_MIPS_R2); 5524 CP0_CHECK(ctx->cmgcr); 5525 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 5526 tcg_gen_ext32s_tl(arg, arg); 5527 register_name = "CMGCRBase"; 5528 break; 5529 default: 5530 goto cp0_unimplemented; 5531 } 5532 break; 5533 case CP0_REGISTER_16: 5534 switch (sel) { 5535 case CP0_REG16__CONFIG: 5536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 5537 register_name = "Config"; 5538 break; 5539 case CP0_REG16__CONFIG1: 5540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 5541 register_name = "Config1"; 5542 break; 5543 case CP0_REG16__CONFIG2: 5544 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 5545 register_name = "Config2"; 5546 break; 5547 case CP0_REG16__CONFIG3: 5548 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 5549 register_name = "Config3"; 5550 break; 5551 case CP0_REG16__CONFIG4: 5552 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 5553 register_name = "Config4"; 5554 break; 5555 case CP0_REG16__CONFIG5: 5556 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 5557 register_name = "Config5"; 5558 break; 5559 /* 6,7 are implementation dependent */ 5560 case CP0_REG16__CONFIG6: 5561 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 5562 register_name = "Config6"; 5563 break; 5564 case CP0_REG16__CONFIG7: 5565 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 5566 register_name = "Config7"; 5567 break; 5568 default: 5569 goto cp0_unimplemented; 5570 } 5571 break; 5572 case CP0_REGISTER_17: 5573 switch (sel) { 5574 case CP0_REG17__LLADDR: 5575 gen_helper_mfc0_lladdr(arg, tcg_env); 5576 register_name = "LLAddr"; 5577 break; 5578 case CP0_REG17__MAAR: 5579 CP0_CHECK(ctx->mrp); 5580 gen_helper_mfc0_maar(arg, tcg_env); 5581 register_name = "MAAR"; 5582 break; 5583 case CP0_REG17__MAARI: 5584 CP0_CHECK(ctx->mrp); 5585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 5586 register_name = "MAARI"; 5587 break; 5588 default: 5589 goto cp0_unimplemented; 5590 } 5591 break; 5592 case CP0_REGISTER_18: 5593 switch (sel) { 5594 case CP0_REG18__WATCHLO0: 5595 case CP0_REG18__WATCHLO1: 5596 case CP0_REG18__WATCHLO2: 5597 case CP0_REG18__WATCHLO3: 5598 case CP0_REG18__WATCHLO4: 5599 case CP0_REG18__WATCHLO5: 5600 case CP0_REG18__WATCHLO6: 5601 case CP0_REG18__WATCHLO7: 5602 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 5603 gen_helper_1e0i(mfc0_watchlo, arg, sel); 5604 register_name = "WatchLo"; 5605 break; 5606 default: 5607 goto cp0_unimplemented; 5608 } 5609 break; 5610 case CP0_REGISTER_19: 5611 switch (sel) { 5612 case CP0_REG19__WATCHHI0: 5613 case CP0_REG19__WATCHHI1: 5614 case CP0_REG19__WATCHHI2: 5615 case CP0_REG19__WATCHHI3: 5616 case CP0_REG19__WATCHHI4: 5617 case CP0_REG19__WATCHHI5: 5618 case CP0_REG19__WATCHHI6: 5619 case CP0_REG19__WATCHHI7: 5620 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 5621 gen_helper_1e0i(mfc0_watchhi, arg, sel); 5622 register_name = "WatchHi"; 5623 break; 5624 default: 5625 goto cp0_unimplemented; 5626 } 5627 break; 5628 case CP0_REGISTER_20: 5629 switch (sel) { 5630 case CP0_REG20__XCONTEXT: 5631 #if defined(TARGET_MIPS64) 5632 check_insn(ctx, ISA_MIPS3); 5633 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext)); 5634 tcg_gen_ext32s_tl(arg, arg); 5635 register_name = "XContext"; 5636 break; 5637 #endif 5638 default: 5639 goto cp0_unimplemented; 5640 } 5641 break; 5642 case CP0_REGISTER_21: 5643 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 5644 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5645 switch (sel) { 5646 case 0: 5647 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 5648 register_name = "Framemask"; 5649 break; 5650 default: 5651 goto cp0_unimplemented; 5652 } 5653 break; 5654 case CP0_REGISTER_22: 5655 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 5656 register_name = "'Diagnostic"; /* implementation dependent */ 5657 break; 5658 case CP0_REGISTER_23: 5659 switch (sel) { 5660 case CP0_REG23__DEBUG: 5661 gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */ 5662 register_name = "Debug"; 5663 break; 5664 case CP0_REG23__TRACECONTROL: 5665 /* PDtrace support */ 5666 /* gen_helper_mfc0_tracecontrol(arg); */ 5667 register_name = "TraceControl"; 5668 goto cp0_unimplemented; 5669 case CP0_REG23__TRACECONTROL2: 5670 /* PDtrace support */ 5671 /* gen_helper_mfc0_tracecontrol2(arg); */ 5672 register_name = "TraceControl2"; 5673 goto cp0_unimplemented; 5674 case CP0_REG23__USERTRACEDATA1: 5675 /* PDtrace support */ 5676 /* gen_helper_mfc0_usertracedata1(arg);*/ 5677 register_name = "UserTraceData1"; 5678 goto cp0_unimplemented; 5679 case CP0_REG23__TRACEIBPC: 5680 /* PDtrace support */ 5681 /* gen_helper_mfc0_traceibpc(arg); */ 5682 register_name = "TraceIBPC"; 5683 goto cp0_unimplemented; 5684 case CP0_REG23__TRACEDBPC: 5685 /* PDtrace support */ 5686 /* gen_helper_mfc0_tracedbpc(arg); */ 5687 register_name = "TraceDBPC"; 5688 goto cp0_unimplemented; 5689 default: 5690 goto cp0_unimplemented; 5691 } 5692 break; 5693 case CP0_REGISTER_24: 5694 switch (sel) { 5695 case CP0_REG24__DEPC: 5696 /* EJTAG support */ 5697 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 5698 tcg_gen_ext32s_tl(arg, arg); 5699 register_name = "DEPC"; 5700 break; 5701 default: 5702 goto cp0_unimplemented; 5703 } 5704 break; 5705 case CP0_REGISTER_25: 5706 switch (sel) { 5707 case CP0_REG25__PERFCTL0: 5708 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 5709 register_name = "Performance0"; 5710 break; 5711 case CP0_REG25__PERFCNT0: 5712 /* gen_helper_mfc0_performance1(arg); */ 5713 register_name = "Performance1"; 5714 goto cp0_unimplemented; 5715 case CP0_REG25__PERFCTL1: 5716 /* gen_helper_mfc0_performance2(arg); */ 5717 register_name = "Performance2"; 5718 goto cp0_unimplemented; 5719 case CP0_REG25__PERFCNT1: 5720 /* gen_helper_mfc0_performance3(arg); */ 5721 register_name = "Performance3"; 5722 goto cp0_unimplemented; 5723 case CP0_REG25__PERFCTL2: 5724 /* gen_helper_mfc0_performance4(arg); */ 5725 register_name = "Performance4"; 5726 goto cp0_unimplemented; 5727 case CP0_REG25__PERFCNT2: 5728 /* gen_helper_mfc0_performance5(arg); */ 5729 register_name = "Performance5"; 5730 goto cp0_unimplemented; 5731 case CP0_REG25__PERFCTL3: 5732 /* gen_helper_mfc0_performance6(arg); */ 5733 register_name = "Performance6"; 5734 goto cp0_unimplemented; 5735 case CP0_REG25__PERFCNT3: 5736 /* gen_helper_mfc0_performance7(arg); */ 5737 register_name = "Performance7"; 5738 goto cp0_unimplemented; 5739 default: 5740 goto cp0_unimplemented; 5741 } 5742 break; 5743 case CP0_REGISTER_26: 5744 switch (sel) { 5745 case CP0_REG26__ERRCTL: 5746 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 5747 register_name = "ErrCtl"; 5748 break; 5749 default: 5750 goto cp0_unimplemented; 5751 } 5752 break; 5753 case CP0_REGISTER_27: 5754 switch (sel) { 5755 case CP0_REG27__CACHERR: 5756 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 5757 register_name = "CacheErr"; 5758 break; 5759 default: 5760 goto cp0_unimplemented; 5761 } 5762 break; 5763 case CP0_REGISTER_28: 5764 switch (sel) { 5765 case CP0_REG28__TAGLO: 5766 case CP0_REG28__TAGLO1: 5767 case CP0_REG28__TAGLO2: 5768 case CP0_REG28__TAGLO3: 5769 { 5770 TCGv_i64 tmp = tcg_temp_new_i64(); 5771 tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPUMIPSState, CP0_TagLo)); 5772 gen_move_low32(arg, tmp); 5773 } 5774 register_name = "TagLo"; 5775 break; 5776 case CP0_REG28__DATALO: 5777 case CP0_REG28__DATALO1: 5778 case CP0_REG28__DATALO2: 5779 case CP0_REG28__DATALO3: 5780 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 5781 register_name = "DataLo"; 5782 break; 5783 default: 5784 goto cp0_unimplemented; 5785 } 5786 break; 5787 case CP0_REGISTER_29: 5788 switch (sel) { 5789 case CP0_REG29__TAGHI: 5790 case CP0_REG29__TAGHI1: 5791 case CP0_REG29__TAGHI2: 5792 case CP0_REG29__TAGHI3: 5793 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 5794 register_name = "TagHi"; 5795 break; 5796 case CP0_REG29__DATAHI: 5797 case CP0_REG29__DATAHI1: 5798 case CP0_REG29__DATAHI2: 5799 case CP0_REG29__DATAHI3: 5800 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 5801 register_name = "DataHi"; 5802 break; 5803 default: 5804 goto cp0_unimplemented; 5805 } 5806 break; 5807 case CP0_REGISTER_30: 5808 switch (sel) { 5809 case CP0_REG30__ERROREPC: 5810 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 5811 tcg_gen_ext32s_tl(arg, arg); 5812 register_name = "ErrorEPC"; 5813 break; 5814 default: 5815 goto cp0_unimplemented; 5816 } 5817 break; 5818 case CP0_REGISTER_31: 5819 switch (sel) { 5820 case CP0_REG31__DESAVE: 5821 /* EJTAG support */ 5822 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 5823 register_name = "DESAVE"; 5824 break; 5825 case CP0_REG31__KSCRATCH1: 5826 case CP0_REG31__KSCRATCH2: 5827 case CP0_REG31__KSCRATCH3: 5828 case CP0_REG31__KSCRATCH4: 5829 case CP0_REG31__KSCRATCH5: 5830 case CP0_REG31__KSCRATCH6: 5831 CP0_CHECK(ctx->kscrexist & (1 << sel)); 5832 tcg_gen_ld_tl(arg, tcg_env, 5833 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 5834 tcg_gen_ext32s_tl(arg, arg); 5835 register_name = "KScratch"; 5836 break; 5837 default: 5838 goto cp0_unimplemented; 5839 } 5840 break; 5841 default: 5842 goto cp0_unimplemented; 5843 } 5844 trace_mips_translate_c0("mfc0", register_name, reg, sel); 5845 return; 5846 5847 cp0_unimplemented: 5848 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", 5849 register_name, reg, sel); 5850 gen_mfc0_unimplemented(ctx, arg); 5851 } 5852 5853 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5854 { 5855 const char *register_name = "invalid"; 5856 bool icount; 5857 5858 if (sel != 0) { 5859 check_insn(ctx, ISA_MIPS_R1); 5860 } 5861 5862 icount = translator_io_start(&ctx->base); 5863 5864 switch (reg) { 5865 case CP0_REGISTER_00: 5866 switch (sel) { 5867 case CP0_REG00__INDEX: 5868 gen_helper_mtc0_index(tcg_env, arg); 5869 register_name = "Index"; 5870 break; 5871 case CP0_REG00__MVPCONTROL: 5872 CP0_CHECK(disas_mt_available(ctx)); 5873 gen_helper_mtc0_mvpcontrol(tcg_env, arg); 5874 register_name = "MVPControl"; 5875 break; 5876 case CP0_REG00__MVPCONF0: 5877 CP0_CHECK(disas_mt_available(ctx)); 5878 /* ignored */ 5879 register_name = "MVPConf0"; 5880 break; 5881 case CP0_REG00__MVPCONF1: 5882 CP0_CHECK(disas_mt_available(ctx)); 5883 /* ignored */ 5884 register_name = "MVPConf1"; 5885 break; 5886 case CP0_REG00__VPCONTROL: 5887 CP0_CHECK(ctx->vp); 5888 /* ignored */ 5889 register_name = "VPControl"; 5890 break; 5891 default: 5892 goto cp0_unimplemented; 5893 } 5894 break; 5895 case CP0_REGISTER_01: 5896 switch (sel) { 5897 case CP0_REG01__RANDOM: 5898 /* ignored */ 5899 register_name = "Random"; 5900 break; 5901 case CP0_REG01__VPECONTROL: 5902 CP0_CHECK(disas_mt_available(ctx)); 5903 gen_helper_mtc0_vpecontrol(tcg_env, arg); 5904 register_name = "VPEControl"; 5905 break; 5906 case CP0_REG01__VPECONF0: 5907 CP0_CHECK(disas_mt_available(ctx)); 5908 gen_helper_mtc0_vpeconf0(tcg_env, arg); 5909 register_name = "VPEConf0"; 5910 break; 5911 case CP0_REG01__VPECONF1: 5912 CP0_CHECK(disas_mt_available(ctx)); 5913 gen_helper_mtc0_vpeconf1(tcg_env, arg); 5914 register_name = "VPEConf1"; 5915 break; 5916 case CP0_REG01__YQMASK: 5917 CP0_CHECK(disas_mt_available(ctx)); 5918 gen_helper_mtc0_yqmask(tcg_env, arg); 5919 register_name = "YQMask"; 5920 break; 5921 case CP0_REG01__VPESCHEDULE: 5922 CP0_CHECK(disas_mt_available(ctx)); 5923 tcg_gen_st_tl(arg, tcg_env, 5924 offsetof(CPUMIPSState, CP0_VPESchedule)); 5925 register_name = "VPESchedule"; 5926 break; 5927 case CP0_REG01__VPESCHEFBACK: 5928 CP0_CHECK(disas_mt_available(ctx)); 5929 tcg_gen_st_tl(arg, tcg_env, 5930 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5931 register_name = "VPEScheFBack"; 5932 break; 5933 case CP0_REG01__VPEOPT: 5934 CP0_CHECK(disas_mt_available(ctx)); 5935 gen_helper_mtc0_vpeopt(tcg_env, arg); 5936 register_name = "VPEOpt"; 5937 break; 5938 default: 5939 goto cp0_unimplemented; 5940 } 5941 break; 5942 case CP0_REGISTER_02: 5943 switch (sel) { 5944 case CP0_REG02__ENTRYLO0: 5945 gen_helper_mtc0_entrylo0(tcg_env, arg); 5946 register_name = "EntryLo0"; 5947 break; 5948 case CP0_REG02__TCSTATUS: 5949 CP0_CHECK(disas_mt_available(ctx)); 5950 gen_helper_mtc0_tcstatus(tcg_env, arg); 5951 register_name = "TCStatus"; 5952 break; 5953 case CP0_REG02__TCBIND: 5954 CP0_CHECK(disas_mt_available(ctx)); 5955 gen_helper_mtc0_tcbind(tcg_env, arg); 5956 register_name = "TCBind"; 5957 break; 5958 case CP0_REG02__TCRESTART: 5959 CP0_CHECK(disas_mt_available(ctx)); 5960 gen_helper_mtc0_tcrestart(tcg_env, arg); 5961 register_name = "TCRestart"; 5962 break; 5963 case CP0_REG02__TCHALT: 5964 CP0_CHECK(disas_mt_available(ctx)); 5965 gen_helper_mtc0_tchalt(tcg_env, arg); 5966 register_name = "TCHalt"; 5967 break; 5968 case CP0_REG02__TCCONTEXT: 5969 CP0_CHECK(disas_mt_available(ctx)); 5970 gen_helper_mtc0_tccontext(tcg_env, arg); 5971 register_name = "TCContext"; 5972 break; 5973 case CP0_REG02__TCSCHEDULE: 5974 CP0_CHECK(disas_mt_available(ctx)); 5975 gen_helper_mtc0_tcschedule(tcg_env, arg); 5976 register_name = "TCSchedule"; 5977 break; 5978 case CP0_REG02__TCSCHEFBACK: 5979 CP0_CHECK(disas_mt_available(ctx)); 5980 gen_helper_mtc0_tcschefback(tcg_env, arg); 5981 register_name = "TCScheFBack"; 5982 break; 5983 default: 5984 goto cp0_unimplemented; 5985 } 5986 break; 5987 case CP0_REGISTER_03: 5988 switch (sel) { 5989 case CP0_REG03__ENTRYLO1: 5990 gen_helper_mtc0_entrylo1(tcg_env, arg); 5991 register_name = "EntryLo1"; 5992 break; 5993 case CP0_REG03__GLOBALNUM: 5994 CP0_CHECK(ctx->vp); 5995 /* ignored */ 5996 register_name = "GlobalNumber"; 5997 break; 5998 default: 5999 goto cp0_unimplemented; 6000 } 6001 break; 6002 case CP0_REGISTER_04: 6003 switch (sel) { 6004 case CP0_REG04__CONTEXT: 6005 gen_helper_mtc0_context(tcg_env, arg); 6006 register_name = "Context"; 6007 break; 6008 case CP0_REG04__CONTEXTCONFIG: 6009 /* SmartMIPS ASE */ 6010 /* gen_helper_mtc0_contextconfig(arg); */ 6011 register_name = "ContextConfig"; 6012 goto cp0_unimplemented; 6013 case CP0_REG04__USERLOCAL: 6014 CP0_CHECK(ctx->ulri); 6015 tcg_gen_st_tl(arg, tcg_env, 6016 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6017 register_name = "UserLocal"; 6018 break; 6019 case CP0_REG04__MMID: 6020 CP0_CHECK(ctx->mi); 6021 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 6022 register_name = "MMID"; 6023 break; 6024 default: 6025 goto cp0_unimplemented; 6026 } 6027 break; 6028 case CP0_REGISTER_05: 6029 switch (sel) { 6030 case CP0_REG05__PAGEMASK: 6031 gen_helper_mtc0_pagemask(tcg_env, arg); 6032 register_name = "PageMask"; 6033 break; 6034 case CP0_REG05__PAGEGRAIN: 6035 check_insn(ctx, ISA_MIPS_R2); 6036 gen_helper_mtc0_pagegrain(tcg_env, arg); 6037 register_name = "PageGrain"; 6038 ctx->base.is_jmp = DISAS_STOP; 6039 break; 6040 case CP0_REG05__SEGCTL0: 6041 CP0_CHECK(ctx->sc); 6042 gen_helper_mtc0_segctl0(tcg_env, arg); 6043 register_name = "SegCtl0"; 6044 break; 6045 case CP0_REG05__SEGCTL1: 6046 CP0_CHECK(ctx->sc); 6047 gen_helper_mtc0_segctl1(tcg_env, arg); 6048 register_name = "SegCtl1"; 6049 break; 6050 case CP0_REG05__SEGCTL2: 6051 CP0_CHECK(ctx->sc); 6052 gen_helper_mtc0_segctl2(tcg_env, arg); 6053 register_name = "SegCtl2"; 6054 break; 6055 case CP0_REG05__PWBASE: 6056 check_pw(ctx); 6057 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 6058 register_name = "PWBase"; 6059 break; 6060 case CP0_REG05__PWFIELD: 6061 check_pw(ctx); 6062 gen_helper_mtc0_pwfield(tcg_env, arg); 6063 register_name = "PWField"; 6064 break; 6065 case CP0_REG05__PWSIZE: 6066 check_pw(ctx); 6067 gen_helper_mtc0_pwsize(tcg_env, arg); 6068 register_name = "PWSize"; 6069 break; 6070 default: 6071 goto cp0_unimplemented; 6072 } 6073 break; 6074 case CP0_REGISTER_06: 6075 switch (sel) { 6076 case CP0_REG06__WIRED: 6077 gen_helper_mtc0_wired(tcg_env, arg); 6078 register_name = "Wired"; 6079 break; 6080 case CP0_REG06__SRSCONF0: 6081 check_insn(ctx, ISA_MIPS_R2); 6082 gen_helper_mtc0_srsconf0(tcg_env, arg); 6083 register_name = "SRSConf0"; 6084 break; 6085 case CP0_REG06__SRSCONF1: 6086 check_insn(ctx, ISA_MIPS_R2); 6087 gen_helper_mtc0_srsconf1(tcg_env, arg); 6088 register_name = "SRSConf1"; 6089 break; 6090 case CP0_REG06__SRSCONF2: 6091 check_insn(ctx, ISA_MIPS_R2); 6092 gen_helper_mtc0_srsconf2(tcg_env, arg); 6093 register_name = "SRSConf2"; 6094 break; 6095 case CP0_REG06__SRSCONF3: 6096 check_insn(ctx, ISA_MIPS_R2); 6097 gen_helper_mtc0_srsconf3(tcg_env, arg); 6098 register_name = "SRSConf3"; 6099 break; 6100 case CP0_REG06__SRSCONF4: 6101 check_insn(ctx, ISA_MIPS_R2); 6102 gen_helper_mtc0_srsconf4(tcg_env, arg); 6103 register_name = "SRSConf4"; 6104 break; 6105 case CP0_REG06__PWCTL: 6106 check_pw(ctx); 6107 gen_helper_mtc0_pwctl(tcg_env, arg); 6108 register_name = "PWCtl"; 6109 break; 6110 default: 6111 goto cp0_unimplemented; 6112 } 6113 break; 6114 case CP0_REGISTER_07: 6115 switch (sel) { 6116 case CP0_REG07__HWRENA: 6117 check_insn(ctx, ISA_MIPS_R2); 6118 gen_helper_mtc0_hwrena(tcg_env, arg); 6119 ctx->base.is_jmp = DISAS_STOP; 6120 register_name = "HWREna"; 6121 break; 6122 default: 6123 goto cp0_unimplemented; 6124 } 6125 break; 6126 case CP0_REGISTER_08: 6127 switch (sel) { 6128 case CP0_REG08__BADVADDR: 6129 /* ignored */ 6130 register_name = "BadVAddr"; 6131 break; 6132 case CP0_REG08__BADINSTR: 6133 /* ignored */ 6134 register_name = "BadInstr"; 6135 break; 6136 case CP0_REG08__BADINSTRP: 6137 /* ignored */ 6138 register_name = "BadInstrP"; 6139 break; 6140 case CP0_REG08__BADINSTRX: 6141 /* ignored */ 6142 register_name = "BadInstrX"; 6143 break; 6144 default: 6145 goto cp0_unimplemented; 6146 } 6147 break; 6148 case CP0_REGISTER_09: 6149 switch (sel) { 6150 case CP0_REG09__COUNT: 6151 gen_helper_mtc0_count(tcg_env, arg); 6152 register_name = "Count"; 6153 break; 6154 default: 6155 goto cp0_unimplemented; 6156 } 6157 break; 6158 case CP0_REGISTER_10: 6159 switch (sel) { 6160 case CP0_REG10__ENTRYHI: 6161 gen_helper_mtc0_entryhi(tcg_env, arg); 6162 register_name = "EntryHi"; 6163 break; 6164 default: 6165 goto cp0_unimplemented; 6166 } 6167 break; 6168 case CP0_REGISTER_11: 6169 switch (sel) { 6170 case CP0_REG11__COMPARE: 6171 gen_helper_mtc0_compare(tcg_env, arg); 6172 register_name = "Compare"; 6173 break; 6174 /* 6,7 are implementation dependent */ 6175 default: 6176 goto cp0_unimplemented; 6177 } 6178 break; 6179 case CP0_REGISTER_12: 6180 switch (sel) { 6181 case CP0_REG12__STATUS: 6182 save_cpu_state(ctx, 1); 6183 gen_helper_mtc0_status(tcg_env, arg); 6184 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6185 gen_save_pc(ctx->base.pc_next + 4); 6186 ctx->base.is_jmp = DISAS_EXIT; 6187 register_name = "Status"; 6188 break; 6189 case CP0_REG12__INTCTL: 6190 check_insn(ctx, ISA_MIPS_R2); 6191 gen_helper_mtc0_intctl(tcg_env, arg); 6192 /* Stop translation as we may have switched the execution mode */ 6193 ctx->base.is_jmp = DISAS_STOP; 6194 register_name = "IntCtl"; 6195 break; 6196 case CP0_REG12__SRSCTL: 6197 check_insn(ctx, ISA_MIPS_R2); 6198 gen_helper_mtc0_srsctl(tcg_env, arg); 6199 /* Stop translation as we may have switched the execution mode */ 6200 ctx->base.is_jmp = DISAS_STOP; 6201 register_name = "SRSCtl"; 6202 break; 6203 case CP0_REG12__SRSMAP: 6204 check_insn(ctx, ISA_MIPS_R2); 6205 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6206 /* Stop translation as we may have switched the execution mode */ 6207 ctx->base.is_jmp = DISAS_STOP; 6208 register_name = "SRSMap"; 6209 break; 6210 default: 6211 goto cp0_unimplemented; 6212 } 6213 break; 6214 case CP0_REGISTER_13: 6215 switch (sel) { 6216 case CP0_REG13__CAUSE: 6217 save_cpu_state(ctx, 1); 6218 gen_helper_mtc0_cause(tcg_env, arg); 6219 /* 6220 * Stop translation as we may have triggered an interrupt. 6221 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6222 * translated code to check for pending interrupts. 6223 */ 6224 gen_save_pc(ctx->base.pc_next + 4); 6225 ctx->base.is_jmp = DISAS_EXIT; 6226 register_name = "Cause"; 6227 break; 6228 default: 6229 goto cp0_unimplemented; 6230 } 6231 break; 6232 case CP0_REGISTER_14: 6233 switch (sel) { 6234 case CP0_REG14__EPC: 6235 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 6236 register_name = "EPC"; 6237 break; 6238 default: 6239 goto cp0_unimplemented; 6240 } 6241 break; 6242 case CP0_REGISTER_15: 6243 switch (sel) { 6244 case CP0_REG15__PRID: 6245 /* ignored */ 6246 register_name = "PRid"; 6247 break; 6248 case CP0_REG15__EBASE: 6249 check_insn(ctx, ISA_MIPS_R2); 6250 gen_helper_mtc0_ebase(tcg_env, arg); 6251 register_name = "EBase"; 6252 break; 6253 default: 6254 goto cp0_unimplemented; 6255 } 6256 break; 6257 case CP0_REGISTER_16: 6258 switch (sel) { 6259 case CP0_REG16__CONFIG: 6260 gen_helper_mtc0_config0(tcg_env, arg); 6261 register_name = "Config"; 6262 /* Stop translation as we may have switched the execution mode */ 6263 ctx->base.is_jmp = DISAS_STOP; 6264 break; 6265 case CP0_REG16__CONFIG1: 6266 /* ignored, read only */ 6267 register_name = "Config1"; 6268 break; 6269 case CP0_REG16__CONFIG2: 6270 gen_helper_mtc0_config2(tcg_env, arg); 6271 register_name = "Config2"; 6272 /* Stop translation as we may have switched the execution mode */ 6273 ctx->base.is_jmp = DISAS_STOP; 6274 break; 6275 case CP0_REG16__CONFIG3: 6276 gen_helper_mtc0_config3(tcg_env, arg); 6277 register_name = "Config3"; 6278 /* Stop translation as we may have switched the execution mode */ 6279 ctx->base.is_jmp = DISAS_STOP; 6280 break; 6281 case CP0_REG16__CONFIG4: 6282 gen_helper_mtc0_config4(tcg_env, arg); 6283 register_name = "Config4"; 6284 ctx->base.is_jmp = DISAS_STOP; 6285 break; 6286 case CP0_REG16__CONFIG5: 6287 gen_helper_mtc0_config5(tcg_env, arg); 6288 register_name = "Config5"; 6289 /* Stop translation as we may have switched the execution mode */ 6290 ctx->base.is_jmp = DISAS_STOP; 6291 break; 6292 /* 6,7 are implementation dependent */ 6293 case CP0_REG16__CONFIG6: 6294 /* ignored */ 6295 register_name = "Config6"; 6296 break; 6297 case CP0_REG16__CONFIG7: 6298 /* ignored */ 6299 register_name = "Config7"; 6300 break; 6301 default: 6302 register_name = "Invalid config selector"; 6303 goto cp0_unimplemented; 6304 } 6305 break; 6306 case CP0_REGISTER_17: 6307 switch (sel) { 6308 case CP0_REG17__LLADDR: 6309 gen_helper_mtc0_lladdr(tcg_env, arg); 6310 register_name = "LLAddr"; 6311 break; 6312 case CP0_REG17__MAAR: 6313 CP0_CHECK(ctx->mrp); 6314 gen_helper_mtc0_maar(tcg_env, arg); 6315 register_name = "MAAR"; 6316 break; 6317 case CP0_REG17__MAARI: 6318 CP0_CHECK(ctx->mrp); 6319 gen_helper_mtc0_maari(tcg_env, arg); 6320 register_name = "MAARI"; 6321 break; 6322 default: 6323 goto cp0_unimplemented; 6324 } 6325 break; 6326 case CP0_REGISTER_18: 6327 switch (sel) { 6328 case CP0_REG18__WATCHLO0: 6329 case CP0_REG18__WATCHLO1: 6330 case CP0_REG18__WATCHLO2: 6331 case CP0_REG18__WATCHLO3: 6332 case CP0_REG18__WATCHLO4: 6333 case CP0_REG18__WATCHLO5: 6334 case CP0_REG18__WATCHLO6: 6335 case CP0_REG18__WATCHLO7: 6336 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6337 gen_helper_0e1i(mtc0_watchlo, arg, sel); 6338 register_name = "WatchLo"; 6339 break; 6340 default: 6341 goto cp0_unimplemented; 6342 } 6343 break; 6344 case CP0_REGISTER_19: 6345 switch (sel) { 6346 case CP0_REG19__WATCHHI0: 6347 case CP0_REG19__WATCHHI1: 6348 case CP0_REG19__WATCHHI2: 6349 case CP0_REG19__WATCHHI3: 6350 case CP0_REG19__WATCHHI4: 6351 case CP0_REG19__WATCHHI5: 6352 case CP0_REG19__WATCHHI6: 6353 case CP0_REG19__WATCHHI7: 6354 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6355 gen_helper_0e1i(mtc0_watchhi, arg, sel); 6356 register_name = "WatchHi"; 6357 break; 6358 default: 6359 goto cp0_unimplemented; 6360 } 6361 break; 6362 case CP0_REGISTER_20: 6363 switch (sel) { 6364 case CP0_REG20__XCONTEXT: 6365 #if defined(TARGET_MIPS64) 6366 check_insn(ctx, ISA_MIPS3); 6367 gen_helper_mtc0_xcontext(tcg_env, arg); 6368 register_name = "XContext"; 6369 break; 6370 #endif 6371 default: 6372 goto cp0_unimplemented; 6373 } 6374 break; 6375 case CP0_REGISTER_21: 6376 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6377 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6378 switch (sel) { 6379 case 0: 6380 gen_helper_mtc0_framemask(tcg_env, arg); 6381 register_name = "Framemask"; 6382 break; 6383 default: 6384 goto cp0_unimplemented; 6385 } 6386 break; 6387 case CP0_REGISTER_22: 6388 /* ignored */ 6389 register_name = "Diagnostic"; /* implementation dependent */ 6390 break; 6391 case CP0_REGISTER_23: 6392 switch (sel) { 6393 case CP0_REG23__DEBUG: 6394 gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */ 6395 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6396 gen_save_pc(ctx->base.pc_next + 4); 6397 ctx->base.is_jmp = DISAS_EXIT; 6398 register_name = "Debug"; 6399 break; 6400 case CP0_REG23__TRACECONTROL: 6401 /* PDtrace support */ 6402 /* gen_helper_mtc0_tracecontrol(tcg_env, arg); */ 6403 register_name = "TraceControl"; 6404 /* Stop translation as we may have switched the execution mode */ 6405 ctx->base.is_jmp = DISAS_STOP; 6406 goto cp0_unimplemented; 6407 case CP0_REG23__TRACECONTROL2: 6408 /* PDtrace support */ 6409 /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */ 6410 register_name = "TraceControl2"; 6411 /* Stop translation as we may have switched the execution mode */ 6412 ctx->base.is_jmp = DISAS_STOP; 6413 goto cp0_unimplemented; 6414 case CP0_REG23__USERTRACEDATA1: 6415 /* Stop translation as we may have switched the execution mode */ 6416 ctx->base.is_jmp = DISAS_STOP; 6417 /* PDtrace support */ 6418 /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/ 6419 register_name = "UserTraceData"; 6420 /* Stop translation as we may have switched the execution mode */ 6421 ctx->base.is_jmp = DISAS_STOP; 6422 goto cp0_unimplemented; 6423 case CP0_REG23__TRACEIBPC: 6424 /* PDtrace support */ 6425 /* gen_helper_mtc0_traceibpc(tcg_env, arg); */ 6426 /* Stop translation as we may have switched the execution mode */ 6427 ctx->base.is_jmp = DISAS_STOP; 6428 register_name = "TraceIBPC"; 6429 goto cp0_unimplemented; 6430 case CP0_REG23__TRACEDBPC: 6431 /* PDtrace support */ 6432 /* gen_helper_mtc0_tracedbpc(tcg_env, arg); */ 6433 /* Stop translation as we may have switched the execution mode */ 6434 ctx->base.is_jmp = DISAS_STOP; 6435 register_name = "TraceDBPC"; 6436 goto cp0_unimplemented; 6437 default: 6438 goto cp0_unimplemented; 6439 } 6440 break; 6441 case CP0_REGISTER_24: 6442 switch (sel) { 6443 case CP0_REG24__DEPC: 6444 /* EJTAG support */ 6445 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 6446 register_name = "DEPC"; 6447 break; 6448 default: 6449 goto cp0_unimplemented; 6450 } 6451 break; 6452 case CP0_REGISTER_25: 6453 switch (sel) { 6454 case CP0_REG25__PERFCTL0: 6455 gen_helper_mtc0_performance0(tcg_env, arg); 6456 register_name = "Performance0"; 6457 break; 6458 case CP0_REG25__PERFCNT0: 6459 /* gen_helper_mtc0_performance1(arg); */ 6460 register_name = "Performance1"; 6461 goto cp0_unimplemented; 6462 case CP0_REG25__PERFCTL1: 6463 /* gen_helper_mtc0_performance2(arg); */ 6464 register_name = "Performance2"; 6465 goto cp0_unimplemented; 6466 case CP0_REG25__PERFCNT1: 6467 /* gen_helper_mtc0_performance3(arg); */ 6468 register_name = "Performance3"; 6469 goto cp0_unimplemented; 6470 case CP0_REG25__PERFCTL2: 6471 /* gen_helper_mtc0_performance4(arg); */ 6472 register_name = "Performance4"; 6473 goto cp0_unimplemented; 6474 case CP0_REG25__PERFCNT2: 6475 /* gen_helper_mtc0_performance5(arg); */ 6476 register_name = "Performance5"; 6477 goto cp0_unimplemented; 6478 case CP0_REG25__PERFCTL3: 6479 /* gen_helper_mtc0_performance6(arg); */ 6480 register_name = "Performance6"; 6481 goto cp0_unimplemented; 6482 case CP0_REG25__PERFCNT3: 6483 /* gen_helper_mtc0_performance7(arg); */ 6484 register_name = "Performance7"; 6485 goto cp0_unimplemented; 6486 default: 6487 goto cp0_unimplemented; 6488 } 6489 break; 6490 case CP0_REGISTER_26: 6491 switch (sel) { 6492 case CP0_REG26__ERRCTL: 6493 gen_helper_mtc0_errctl(tcg_env, arg); 6494 ctx->base.is_jmp = DISAS_STOP; 6495 register_name = "ErrCtl"; 6496 break; 6497 default: 6498 goto cp0_unimplemented; 6499 } 6500 break; 6501 case CP0_REGISTER_27: 6502 switch (sel) { 6503 case CP0_REG27__CACHERR: 6504 /* ignored */ 6505 register_name = "CacheErr"; 6506 break; 6507 default: 6508 goto cp0_unimplemented; 6509 } 6510 break; 6511 case CP0_REGISTER_28: 6512 switch (sel) { 6513 case CP0_REG28__TAGLO: 6514 case CP0_REG28__TAGLO1: 6515 case CP0_REG28__TAGLO2: 6516 case CP0_REG28__TAGLO3: 6517 gen_helper_mtc0_taglo(tcg_env, arg); 6518 register_name = "TagLo"; 6519 break; 6520 case CP0_REG28__DATALO: 6521 case CP0_REG28__DATALO1: 6522 case CP0_REG28__DATALO2: 6523 case CP0_REG28__DATALO3: 6524 gen_helper_mtc0_datalo(tcg_env, arg); 6525 register_name = "DataLo"; 6526 break; 6527 default: 6528 goto cp0_unimplemented; 6529 } 6530 break; 6531 case CP0_REGISTER_29: 6532 switch (sel) { 6533 case CP0_REG29__TAGHI: 6534 case CP0_REG29__TAGHI1: 6535 case CP0_REG29__TAGHI2: 6536 case CP0_REG29__TAGHI3: 6537 gen_helper_mtc0_taghi(tcg_env, arg); 6538 register_name = "TagHi"; 6539 break; 6540 case CP0_REG29__DATAHI: 6541 case CP0_REG29__DATAHI1: 6542 case CP0_REG29__DATAHI2: 6543 case CP0_REG29__DATAHI3: 6544 gen_helper_mtc0_datahi(tcg_env, arg); 6545 register_name = "DataHi"; 6546 break; 6547 default: 6548 register_name = "invalid sel"; 6549 goto cp0_unimplemented; 6550 } 6551 break; 6552 case CP0_REGISTER_30: 6553 switch (sel) { 6554 case CP0_REG30__ERROREPC: 6555 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 6556 register_name = "ErrorEPC"; 6557 break; 6558 default: 6559 goto cp0_unimplemented; 6560 } 6561 break; 6562 case CP0_REGISTER_31: 6563 switch (sel) { 6564 case CP0_REG31__DESAVE: 6565 /* EJTAG support */ 6566 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 6567 register_name = "DESAVE"; 6568 break; 6569 case CP0_REG31__KSCRATCH1: 6570 case CP0_REG31__KSCRATCH2: 6571 case CP0_REG31__KSCRATCH3: 6572 case CP0_REG31__KSCRATCH4: 6573 case CP0_REG31__KSCRATCH5: 6574 case CP0_REG31__KSCRATCH6: 6575 CP0_CHECK(ctx->kscrexist & (1 << sel)); 6576 tcg_gen_st_tl(arg, tcg_env, 6577 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 6578 register_name = "KScratch"; 6579 break; 6580 default: 6581 goto cp0_unimplemented; 6582 } 6583 break; 6584 default: 6585 goto cp0_unimplemented; 6586 } 6587 trace_mips_translate_c0("mtc0", register_name, reg, sel); 6588 6589 /* For simplicity assume that all writes can cause interrupts. */ 6590 if (icount) { 6591 /* 6592 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6593 * translated code to check for pending interrupts. 6594 */ 6595 gen_save_pc(ctx->base.pc_next + 4); 6596 ctx->base.is_jmp = DISAS_EXIT; 6597 } 6598 return; 6599 6600 cp0_unimplemented: 6601 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", 6602 register_name, reg, sel); 6603 } 6604 6605 #if defined(TARGET_MIPS64) 6606 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 6607 { 6608 const char *register_name = "invalid"; 6609 6610 if (sel != 0) { 6611 check_insn(ctx, ISA_MIPS_R1); 6612 } 6613 6614 switch (reg) { 6615 case CP0_REGISTER_00: 6616 switch (sel) { 6617 case CP0_REG00__INDEX: 6618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 6619 register_name = "Index"; 6620 break; 6621 case CP0_REG00__MVPCONTROL: 6622 CP0_CHECK(disas_mt_available(ctx)); 6623 gen_helper_mfc0_mvpcontrol(arg, tcg_env); 6624 register_name = "MVPControl"; 6625 break; 6626 case CP0_REG00__MVPCONF0: 6627 CP0_CHECK(disas_mt_available(ctx)); 6628 gen_helper_mfc0_mvpconf0(arg, tcg_env); 6629 register_name = "MVPConf0"; 6630 break; 6631 case CP0_REG00__MVPCONF1: 6632 CP0_CHECK(disas_mt_available(ctx)); 6633 gen_helper_mfc0_mvpconf1(arg, tcg_env); 6634 register_name = "MVPConf1"; 6635 break; 6636 case CP0_REG00__VPCONTROL: 6637 CP0_CHECK(ctx->vp); 6638 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 6639 register_name = "VPControl"; 6640 break; 6641 default: 6642 goto cp0_unimplemented; 6643 } 6644 break; 6645 case CP0_REGISTER_01: 6646 switch (sel) { 6647 case CP0_REG01__RANDOM: 6648 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6649 gen_helper_mfc0_random(arg, tcg_env); 6650 register_name = "Random"; 6651 break; 6652 case CP0_REG01__VPECONTROL: 6653 CP0_CHECK(disas_mt_available(ctx)); 6654 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 6655 register_name = "VPEControl"; 6656 break; 6657 case CP0_REG01__VPECONF0: 6658 CP0_CHECK(disas_mt_available(ctx)); 6659 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 6660 register_name = "VPEConf0"; 6661 break; 6662 case CP0_REG01__VPECONF1: 6663 CP0_CHECK(disas_mt_available(ctx)); 6664 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 6665 register_name = "VPEConf1"; 6666 break; 6667 case CP0_REG01__YQMASK: 6668 CP0_CHECK(disas_mt_available(ctx)); 6669 tcg_gen_ld_tl(arg, tcg_env, 6670 offsetof(CPUMIPSState, CP0_YQMask)); 6671 register_name = "YQMask"; 6672 break; 6673 case CP0_REG01__VPESCHEDULE: 6674 CP0_CHECK(disas_mt_available(ctx)); 6675 tcg_gen_ld_tl(arg, tcg_env, 6676 offsetof(CPUMIPSState, CP0_VPESchedule)); 6677 register_name = "VPESchedule"; 6678 break; 6679 case CP0_REG01__VPESCHEFBACK: 6680 CP0_CHECK(disas_mt_available(ctx)); 6681 tcg_gen_ld_tl(arg, tcg_env, 6682 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6683 register_name = "VPEScheFBack"; 6684 break; 6685 case CP0_REG01__VPEOPT: 6686 CP0_CHECK(disas_mt_available(ctx)); 6687 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 6688 register_name = "VPEOpt"; 6689 break; 6690 default: 6691 goto cp0_unimplemented; 6692 } 6693 break; 6694 case CP0_REGISTER_02: 6695 switch (sel) { 6696 case CP0_REG02__ENTRYLO0: 6697 tcg_gen_ld_tl(arg, tcg_env, 6698 offsetof(CPUMIPSState, CP0_EntryLo0)); 6699 register_name = "EntryLo0"; 6700 break; 6701 case CP0_REG02__TCSTATUS: 6702 CP0_CHECK(disas_mt_available(ctx)); 6703 gen_helper_mfc0_tcstatus(arg, tcg_env); 6704 register_name = "TCStatus"; 6705 break; 6706 case CP0_REG02__TCBIND: 6707 CP0_CHECK(disas_mt_available(ctx)); 6708 gen_helper_mfc0_tcbind(arg, tcg_env); 6709 register_name = "TCBind"; 6710 break; 6711 case CP0_REG02__TCRESTART: 6712 CP0_CHECK(disas_mt_available(ctx)); 6713 gen_helper_dmfc0_tcrestart(arg, tcg_env); 6714 register_name = "TCRestart"; 6715 break; 6716 case CP0_REG02__TCHALT: 6717 CP0_CHECK(disas_mt_available(ctx)); 6718 gen_helper_dmfc0_tchalt(arg, tcg_env); 6719 register_name = "TCHalt"; 6720 break; 6721 case CP0_REG02__TCCONTEXT: 6722 CP0_CHECK(disas_mt_available(ctx)); 6723 gen_helper_dmfc0_tccontext(arg, tcg_env); 6724 register_name = "TCContext"; 6725 break; 6726 case CP0_REG02__TCSCHEDULE: 6727 CP0_CHECK(disas_mt_available(ctx)); 6728 gen_helper_dmfc0_tcschedule(arg, tcg_env); 6729 register_name = "TCSchedule"; 6730 break; 6731 case CP0_REG02__TCSCHEFBACK: 6732 CP0_CHECK(disas_mt_available(ctx)); 6733 gen_helper_dmfc0_tcschefback(arg, tcg_env); 6734 register_name = "TCScheFBack"; 6735 break; 6736 default: 6737 goto cp0_unimplemented; 6738 } 6739 break; 6740 case CP0_REGISTER_03: 6741 switch (sel) { 6742 case CP0_REG03__ENTRYLO1: 6743 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 6744 register_name = "EntryLo1"; 6745 break; 6746 case CP0_REG03__GLOBALNUM: 6747 CP0_CHECK(ctx->vp); 6748 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 6749 register_name = "GlobalNumber"; 6750 break; 6751 default: 6752 goto cp0_unimplemented; 6753 } 6754 break; 6755 case CP0_REGISTER_04: 6756 switch (sel) { 6757 case CP0_REG04__CONTEXT: 6758 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context)); 6759 register_name = "Context"; 6760 break; 6761 case CP0_REG04__CONTEXTCONFIG: 6762 /* SmartMIPS ASE */ 6763 /* gen_helper_dmfc0_contextconfig(arg); */ 6764 register_name = "ContextConfig"; 6765 goto cp0_unimplemented; 6766 case CP0_REG04__USERLOCAL: 6767 CP0_CHECK(ctx->ulri); 6768 tcg_gen_ld_tl(arg, tcg_env, 6769 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6770 register_name = "UserLocal"; 6771 break; 6772 case CP0_REG04__MMID: 6773 CP0_CHECK(ctx->mi); 6774 gen_helper_mtc0_memorymapid(tcg_env, arg); 6775 register_name = "MMID"; 6776 break; 6777 default: 6778 goto cp0_unimplemented; 6779 } 6780 break; 6781 case CP0_REGISTER_05: 6782 switch (sel) { 6783 case CP0_REG05__PAGEMASK: 6784 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 6785 register_name = "PageMask"; 6786 break; 6787 case CP0_REG05__PAGEGRAIN: 6788 check_insn(ctx, ISA_MIPS_R2); 6789 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 6790 register_name = "PageGrain"; 6791 break; 6792 case CP0_REG05__SEGCTL0: 6793 CP0_CHECK(ctx->sc); 6794 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 6795 register_name = "SegCtl0"; 6796 break; 6797 case CP0_REG05__SEGCTL1: 6798 CP0_CHECK(ctx->sc); 6799 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 6800 register_name = "SegCtl1"; 6801 break; 6802 case CP0_REG05__SEGCTL2: 6803 CP0_CHECK(ctx->sc); 6804 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 6805 register_name = "SegCtl2"; 6806 break; 6807 case CP0_REG05__PWBASE: 6808 check_pw(ctx); 6809 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase)); 6810 register_name = "PWBase"; 6811 break; 6812 case CP0_REG05__PWFIELD: 6813 check_pw(ctx); 6814 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWField)); 6815 register_name = "PWField"; 6816 break; 6817 case CP0_REG05__PWSIZE: 6818 check_pw(ctx); 6819 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWSize)); 6820 register_name = "PWSize"; 6821 break; 6822 default: 6823 goto cp0_unimplemented; 6824 } 6825 break; 6826 case CP0_REGISTER_06: 6827 switch (sel) { 6828 case CP0_REG06__WIRED: 6829 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 6830 register_name = "Wired"; 6831 break; 6832 case CP0_REG06__SRSCONF0: 6833 check_insn(ctx, ISA_MIPS_R2); 6834 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 6835 register_name = "SRSConf0"; 6836 break; 6837 case CP0_REG06__SRSCONF1: 6838 check_insn(ctx, ISA_MIPS_R2); 6839 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 6840 register_name = "SRSConf1"; 6841 break; 6842 case CP0_REG06__SRSCONF2: 6843 check_insn(ctx, ISA_MIPS_R2); 6844 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 6845 register_name = "SRSConf2"; 6846 break; 6847 case CP0_REG06__SRSCONF3: 6848 check_insn(ctx, ISA_MIPS_R2); 6849 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 6850 register_name = "SRSConf3"; 6851 break; 6852 case CP0_REG06__SRSCONF4: 6853 check_insn(ctx, ISA_MIPS_R2); 6854 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 6855 register_name = "SRSConf4"; 6856 break; 6857 case CP0_REG06__PWCTL: 6858 check_pw(ctx); 6859 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 6860 register_name = "PWCtl"; 6861 break; 6862 default: 6863 goto cp0_unimplemented; 6864 } 6865 break; 6866 case CP0_REGISTER_07: 6867 switch (sel) { 6868 case CP0_REG07__HWRENA: 6869 check_insn(ctx, ISA_MIPS_R2); 6870 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 6871 register_name = "HWREna"; 6872 break; 6873 default: 6874 goto cp0_unimplemented; 6875 } 6876 break; 6877 case CP0_REGISTER_08: 6878 switch (sel) { 6879 case CP0_REG08__BADVADDR: 6880 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 6881 register_name = "BadVAddr"; 6882 break; 6883 case CP0_REG08__BADINSTR: 6884 CP0_CHECK(ctx->bi); 6885 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 6886 register_name = "BadInstr"; 6887 break; 6888 case CP0_REG08__BADINSTRP: 6889 CP0_CHECK(ctx->bp); 6890 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 6891 register_name = "BadInstrP"; 6892 break; 6893 case CP0_REG08__BADINSTRX: 6894 CP0_CHECK(ctx->bi); 6895 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 6896 tcg_gen_andi_tl(arg, arg, ~0xffff); 6897 register_name = "BadInstrX"; 6898 break; 6899 default: 6900 goto cp0_unimplemented; 6901 } 6902 break; 6903 case CP0_REGISTER_09: 6904 switch (sel) { 6905 case CP0_REG09__COUNT: 6906 /* Mark as an IO operation because we read the time. */ 6907 translator_io_start(&ctx->base); 6908 gen_helper_mfc0_count(arg, tcg_env); 6909 /* 6910 * Break the TB to be able to take timer interrupts immediately 6911 * after reading count. DISAS_STOP isn't sufficient, we need to 6912 * ensure we break completely out of translated code. 6913 */ 6914 gen_save_pc(ctx->base.pc_next + 4); 6915 ctx->base.is_jmp = DISAS_EXIT; 6916 register_name = "Count"; 6917 break; 6918 default: 6919 goto cp0_unimplemented; 6920 } 6921 break; 6922 case CP0_REGISTER_10: 6923 switch (sel) { 6924 case CP0_REG10__ENTRYHI: 6925 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi)); 6926 register_name = "EntryHi"; 6927 break; 6928 default: 6929 goto cp0_unimplemented; 6930 } 6931 break; 6932 case CP0_REGISTER_11: 6933 switch (sel) { 6934 case CP0_REG11__COMPARE: 6935 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 6936 register_name = "Compare"; 6937 break; 6938 /* 6,7 are implementation dependent */ 6939 default: 6940 goto cp0_unimplemented; 6941 } 6942 break; 6943 case CP0_REGISTER_12: 6944 switch (sel) { 6945 case CP0_REG12__STATUS: 6946 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 6947 register_name = "Status"; 6948 break; 6949 case CP0_REG12__INTCTL: 6950 check_insn(ctx, ISA_MIPS_R2); 6951 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 6952 register_name = "IntCtl"; 6953 break; 6954 case CP0_REG12__SRSCTL: 6955 check_insn(ctx, ISA_MIPS_R2); 6956 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 6957 register_name = "SRSCtl"; 6958 break; 6959 case CP0_REG12__SRSMAP: 6960 check_insn(ctx, ISA_MIPS_R2); 6961 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6962 register_name = "SRSMap"; 6963 break; 6964 default: 6965 goto cp0_unimplemented; 6966 } 6967 break; 6968 case CP0_REGISTER_13: 6969 switch (sel) { 6970 case CP0_REG13__CAUSE: 6971 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 6972 register_name = "Cause"; 6973 break; 6974 default: 6975 goto cp0_unimplemented; 6976 } 6977 break; 6978 case CP0_REGISTER_14: 6979 switch (sel) { 6980 case CP0_REG14__EPC: 6981 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 6982 register_name = "EPC"; 6983 break; 6984 default: 6985 goto cp0_unimplemented; 6986 } 6987 break; 6988 case CP0_REGISTER_15: 6989 switch (sel) { 6990 case CP0_REG15__PRID: 6991 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 6992 register_name = "PRid"; 6993 break; 6994 case CP0_REG15__EBASE: 6995 check_insn(ctx, ISA_MIPS_R2); 6996 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase)); 6997 register_name = "EBase"; 6998 break; 6999 case CP0_REG15__CMGCRBASE: 7000 check_insn(ctx, ISA_MIPS_R2); 7001 CP0_CHECK(ctx->cmgcr); 7002 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 7003 register_name = "CMGCRBase"; 7004 break; 7005 default: 7006 goto cp0_unimplemented; 7007 } 7008 break; 7009 case CP0_REGISTER_16: 7010 switch (sel) { 7011 case CP0_REG16__CONFIG: 7012 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 7013 register_name = "Config"; 7014 break; 7015 case CP0_REG16__CONFIG1: 7016 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 7017 register_name = "Config1"; 7018 break; 7019 case CP0_REG16__CONFIG2: 7020 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 7021 register_name = "Config2"; 7022 break; 7023 case CP0_REG16__CONFIG3: 7024 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 7025 register_name = "Config3"; 7026 break; 7027 case CP0_REG16__CONFIG4: 7028 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 7029 register_name = "Config4"; 7030 break; 7031 case CP0_REG16__CONFIG5: 7032 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 7033 register_name = "Config5"; 7034 break; 7035 /* 6,7 are implementation dependent */ 7036 case CP0_REG16__CONFIG6: 7037 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 7038 register_name = "Config6"; 7039 break; 7040 case CP0_REG16__CONFIG7: 7041 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 7042 register_name = "Config7"; 7043 break; 7044 default: 7045 goto cp0_unimplemented; 7046 } 7047 break; 7048 case CP0_REGISTER_17: 7049 switch (sel) { 7050 case CP0_REG17__LLADDR: 7051 gen_helper_dmfc0_lladdr(arg, tcg_env); 7052 register_name = "LLAddr"; 7053 break; 7054 case CP0_REG17__MAAR: 7055 CP0_CHECK(ctx->mrp); 7056 gen_helper_dmfc0_maar(arg, tcg_env); 7057 register_name = "MAAR"; 7058 break; 7059 case CP0_REG17__MAARI: 7060 CP0_CHECK(ctx->mrp); 7061 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 7062 register_name = "MAARI"; 7063 break; 7064 default: 7065 goto cp0_unimplemented; 7066 } 7067 break; 7068 case CP0_REGISTER_18: 7069 switch (sel) { 7070 case CP0_REG18__WATCHLO0: 7071 case CP0_REG18__WATCHLO1: 7072 case CP0_REG18__WATCHLO2: 7073 case CP0_REG18__WATCHLO3: 7074 case CP0_REG18__WATCHLO4: 7075 case CP0_REG18__WATCHLO5: 7076 case CP0_REG18__WATCHLO6: 7077 case CP0_REG18__WATCHLO7: 7078 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7079 gen_helper_1e0i(dmfc0_watchlo, arg, sel); 7080 register_name = "WatchLo"; 7081 break; 7082 default: 7083 goto cp0_unimplemented; 7084 } 7085 break; 7086 case CP0_REGISTER_19: 7087 switch (sel) { 7088 case CP0_REG19__WATCHHI0: 7089 case CP0_REG19__WATCHHI1: 7090 case CP0_REG19__WATCHHI2: 7091 case CP0_REG19__WATCHHI3: 7092 case CP0_REG19__WATCHHI4: 7093 case CP0_REG19__WATCHHI5: 7094 case CP0_REG19__WATCHHI6: 7095 case CP0_REG19__WATCHHI7: 7096 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7097 gen_helper_1e0i(dmfc0_watchhi, arg, sel); 7098 register_name = "WatchHi"; 7099 break; 7100 default: 7101 goto cp0_unimplemented; 7102 } 7103 break; 7104 case CP0_REGISTER_20: 7105 switch (sel) { 7106 case CP0_REG20__XCONTEXT: 7107 check_insn(ctx, ISA_MIPS3); 7108 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext)); 7109 register_name = "XContext"; 7110 break; 7111 default: 7112 goto cp0_unimplemented; 7113 } 7114 break; 7115 case CP0_REGISTER_21: 7116 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7117 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7118 switch (sel) { 7119 case 0: 7120 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 7121 register_name = "Framemask"; 7122 break; 7123 default: 7124 goto cp0_unimplemented; 7125 } 7126 break; 7127 case CP0_REGISTER_22: 7128 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7129 register_name = "'Diagnostic"; /* implementation dependent */ 7130 break; 7131 case CP0_REGISTER_23: 7132 switch (sel) { 7133 case CP0_REG23__DEBUG: 7134 gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */ 7135 register_name = "Debug"; 7136 break; 7137 case CP0_REG23__TRACECONTROL: 7138 /* PDtrace support */ 7139 /* gen_helper_dmfc0_tracecontrol(arg, tcg_env); */ 7140 register_name = "TraceControl"; 7141 goto cp0_unimplemented; 7142 case CP0_REG23__TRACECONTROL2: 7143 /* PDtrace support */ 7144 /* gen_helper_dmfc0_tracecontrol2(arg, tcg_env); */ 7145 register_name = "TraceControl2"; 7146 goto cp0_unimplemented; 7147 case CP0_REG23__USERTRACEDATA1: 7148 /* PDtrace support */ 7149 /* gen_helper_dmfc0_usertracedata1(arg, tcg_env);*/ 7150 register_name = "UserTraceData1"; 7151 goto cp0_unimplemented; 7152 case CP0_REG23__TRACEIBPC: 7153 /* PDtrace support */ 7154 /* gen_helper_dmfc0_traceibpc(arg, tcg_env); */ 7155 register_name = "TraceIBPC"; 7156 goto cp0_unimplemented; 7157 case CP0_REG23__TRACEDBPC: 7158 /* PDtrace support */ 7159 /* gen_helper_dmfc0_tracedbpc(arg, tcg_env); */ 7160 register_name = "TraceDBPC"; 7161 goto cp0_unimplemented; 7162 default: 7163 goto cp0_unimplemented; 7164 } 7165 break; 7166 case CP0_REGISTER_24: 7167 switch (sel) { 7168 case CP0_REG24__DEPC: 7169 /* EJTAG support */ 7170 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 7171 register_name = "DEPC"; 7172 break; 7173 default: 7174 goto cp0_unimplemented; 7175 } 7176 break; 7177 case CP0_REGISTER_25: 7178 switch (sel) { 7179 case CP0_REG25__PERFCTL0: 7180 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 7181 register_name = "Performance0"; 7182 break; 7183 case CP0_REG25__PERFCNT0: 7184 /* gen_helper_dmfc0_performance1(arg); */ 7185 register_name = "Performance1"; 7186 goto cp0_unimplemented; 7187 case CP0_REG25__PERFCTL1: 7188 /* gen_helper_dmfc0_performance2(arg); */ 7189 register_name = "Performance2"; 7190 goto cp0_unimplemented; 7191 case CP0_REG25__PERFCNT1: 7192 /* gen_helper_dmfc0_performance3(arg); */ 7193 register_name = "Performance3"; 7194 goto cp0_unimplemented; 7195 case CP0_REG25__PERFCTL2: 7196 /* gen_helper_dmfc0_performance4(arg); */ 7197 register_name = "Performance4"; 7198 goto cp0_unimplemented; 7199 case CP0_REG25__PERFCNT2: 7200 /* gen_helper_dmfc0_performance5(arg); */ 7201 register_name = "Performance5"; 7202 goto cp0_unimplemented; 7203 case CP0_REG25__PERFCTL3: 7204 /* gen_helper_dmfc0_performance6(arg); */ 7205 register_name = "Performance6"; 7206 goto cp0_unimplemented; 7207 case CP0_REG25__PERFCNT3: 7208 /* gen_helper_dmfc0_performance7(arg); */ 7209 register_name = "Performance7"; 7210 goto cp0_unimplemented; 7211 default: 7212 goto cp0_unimplemented; 7213 } 7214 break; 7215 case CP0_REGISTER_26: 7216 switch (sel) { 7217 case CP0_REG26__ERRCTL: 7218 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 7219 register_name = "ErrCtl"; 7220 break; 7221 default: 7222 goto cp0_unimplemented; 7223 } 7224 break; 7225 case CP0_REGISTER_27: 7226 switch (sel) { 7227 /* ignored */ 7228 case CP0_REG27__CACHERR: 7229 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7230 register_name = "CacheErr"; 7231 break; 7232 default: 7233 goto cp0_unimplemented; 7234 } 7235 break; 7236 case CP0_REGISTER_28: 7237 switch (sel) { 7238 case CP0_REG28__TAGLO: 7239 case CP0_REG28__TAGLO1: 7240 case CP0_REG28__TAGLO2: 7241 case CP0_REG28__TAGLO3: 7242 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 7243 register_name = "TagLo"; 7244 break; 7245 case CP0_REG28__DATALO: 7246 case CP0_REG28__DATALO1: 7247 case CP0_REG28__DATALO2: 7248 case CP0_REG28__DATALO3: 7249 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 7250 register_name = "DataLo"; 7251 break; 7252 default: 7253 goto cp0_unimplemented; 7254 } 7255 break; 7256 case CP0_REGISTER_29: 7257 switch (sel) { 7258 case CP0_REG29__TAGHI: 7259 case CP0_REG29__TAGHI1: 7260 case CP0_REG29__TAGHI2: 7261 case CP0_REG29__TAGHI3: 7262 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 7263 register_name = "TagHi"; 7264 break; 7265 case CP0_REG29__DATAHI: 7266 case CP0_REG29__DATAHI1: 7267 case CP0_REG29__DATAHI2: 7268 case CP0_REG29__DATAHI3: 7269 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 7270 register_name = "DataHi"; 7271 break; 7272 default: 7273 goto cp0_unimplemented; 7274 } 7275 break; 7276 case CP0_REGISTER_30: 7277 switch (sel) { 7278 case CP0_REG30__ERROREPC: 7279 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7280 register_name = "ErrorEPC"; 7281 break; 7282 default: 7283 goto cp0_unimplemented; 7284 } 7285 break; 7286 case CP0_REGISTER_31: 7287 switch (sel) { 7288 case CP0_REG31__DESAVE: 7289 /* EJTAG support */ 7290 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7291 register_name = "DESAVE"; 7292 break; 7293 case CP0_REG31__KSCRATCH1: 7294 case CP0_REG31__KSCRATCH2: 7295 case CP0_REG31__KSCRATCH3: 7296 case CP0_REG31__KSCRATCH4: 7297 case CP0_REG31__KSCRATCH5: 7298 case CP0_REG31__KSCRATCH6: 7299 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7300 tcg_gen_ld_tl(arg, tcg_env, 7301 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7302 register_name = "KScratch"; 7303 break; 7304 default: 7305 goto cp0_unimplemented; 7306 } 7307 break; 7308 default: 7309 goto cp0_unimplemented; 7310 } 7311 trace_mips_translate_c0("dmfc0", register_name, reg, sel); 7312 return; 7313 7314 cp0_unimplemented: 7315 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", 7316 register_name, reg, sel); 7317 gen_mfc0_unimplemented(ctx, arg); 7318 } 7319 7320 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7321 { 7322 const char *register_name = "invalid"; 7323 bool icount; 7324 7325 if (sel != 0) { 7326 check_insn(ctx, ISA_MIPS_R1); 7327 } 7328 7329 icount = translator_io_start(&ctx->base); 7330 7331 switch (reg) { 7332 case CP0_REGISTER_00: 7333 switch (sel) { 7334 case CP0_REG00__INDEX: 7335 gen_helper_mtc0_index(tcg_env, arg); 7336 register_name = "Index"; 7337 break; 7338 case CP0_REG00__MVPCONTROL: 7339 CP0_CHECK(disas_mt_available(ctx)); 7340 gen_helper_mtc0_mvpcontrol(tcg_env, arg); 7341 register_name = "MVPControl"; 7342 break; 7343 case CP0_REG00__MVPCONF0: 7344 CP0_CHECK(disas_mt_available(ctx)); 7345 /* ignored */ 7346 register_name = "MVPConf0"; 7347 break; 7348 case CP0_REG00__MVPCONF1: 7349 CP0_CHECK(disas_mt_available(ctx)); 7350 /* ignored */ 7351 register_name = "MVPConf1"; 7352 break; 7353 case CP0_REG00__VPCONTROL: 7354 CP0_CHECK(ctx->vp); 7355 /* ignored */ 7356 register_name = "VPControl"; 7357 break; 7358 default: 7359 goto cp0_unimplemented; 7360 } 7361 break; 7362 case CP0_REGISTER_01: 7363 switch (sel) { 7364 case CP0_REG01__RANDOM: 7365 /* ignored */ 7366 register_name = "Random"; 7367 break; 7368 case CP0_REG01__VPECONTROL: 7369 CP0_CHECK(disas_mt_available(ctx)); 7370 gen_helper_mtc0_vpecontrol(tcg_env, arg); 7371 register_name = "VPEControl"; 7372 break; 7373 case CP0_REG01__VPECONF0: 7374 CP0_CHECK(disas_mt_available(ctx)); 7375 gen_helper_mtc0_vpeconf0(tcg_env, arg); 7376 register_name = "VPEConf0"; 7377 break; 7378 case CP0_REG01__VPECONF1: 7379 CP0_CHECK(disas_mt_available(ctx)); 7380 gen_helper_mtc0_vpeconf1(tcg_env, arg); 7381 register_name = "VPEConf1"; 7382 break; 7383 case CP0_REG01__YQMASK: 7384 CP0_CHECK(disas_mt_available(ctx)); 7385 gen_helper_mtc0_yqmask(tcg_env, arg); 7386 register_name = "YQMask"; 7387 break; 7388 case CP0_REG01__VPESCHEDULE: 7389 CP0_CHECK(disas_mt_available(ctx)); 7390 tcg_gen_st_tl(arg, tcg_env, 7391 offsetof(CPUMIPSState, CP0_VPESchedule)); 7392 register_name = "VPESchedule"; 7393 break; 7394 case CP0_REG01__VPESCHEFBACK: 7395 CP0_CHECK(disas_mt_available(ctx)); 7396 tcg_gen_st_tl(arg, tcg_env, 7397 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7398 register_name = "VPEScheFBack"; 7399 break; 7400 case CP0_REG01__VPEOPT: 7401 CP0_CHECK(disas_mt_available(ctx)); 7402 gen_helper_mtc0_vpeopt(tcg_env, arg); 7403 register_name = "VPEOpt"; 7404 break; 7405 default: 7406 goto cp0_unimplemented; 7407 } 7408 break; 7409 case CP0_REGISTER_02: 7410 switch (sel) { 7411 case CP0_REG02__ENTRYLO0: 7412 gen_helper_dmtc0_entrylo0(tcg_env, arg); 7413 register_name = "EntryLo0"; 7414 break; 7415 case CP0_REG02__TCSTATUS: 7416 CP0_CHECK(disas_mt_available(ctx)); 7417 gen_helper_mtc0_tcstatus(tcg_env, arg); 7418 register_name = "TCStatus"; 7419 break; 7420 case CP0_REG02__TCBIND: 7421 CP0_CHECK(disas_mt_available(ctx)); 7422 gen_helper_mtc0_tcbind(tcg_env, arg); 7423 register_name = "TCBind"; 7424 break; 7425 case CP0_REG02__TCRESTART: 7426 CP0_CHECK(disas_mt_available(ctx)); 7427 gen_helper_mtc0_tcrestart(tcg_env, arg); 7428 register_name = "TCRestart"; 7429 break; 7430 case CP0_REG02__TCHALT: 7431 CP0_CHECK(disas_mt_available(ctx)); 7432 gen_helper_mtc0_tchalt(tcg_env, arg); 7433 register_name = "TCHalt"; 7434 break; 7435 case CP0_REG02__TCCONTEXT: 7436 CP0_CHECK(disas_mt_available(ctx)); 7437 gen_helper_mtc0_tccontext(tcg_env, arg); 7438 register_name = "TCContext"; 7439 break; 7440 case CP0_REG02__TCSCHEDULE: 7441 CP0_CHECK(disas_mt_available(ctx)); 7442 gen_helper_mtc0_tcschedule(tcg_env, arg); 7443 register_name = "TCSchedule"; 7444 break; 7445 case CP0_REG02__TCSCHEFBACK: 7446 CP0_CHECK(disas_mt_available(ctx)); 7447 gen_helper_mtc0_tcschefback(tcg_env, arg); 7448 register_name = "TCScheFBack"; 7449 break; 7450 default: 7451 goto cp0_unimplemented; 7452 } 7453 break; 7454 case CP0_REGISTER_03: 7455 switch (sel) { 7456 case CP0_REG03__ENTRYLO1: 7457 gen_helper_dmtc0_entrylo1(tcg_env, arg); 7458 register_name = "EntryLo1"; 7459 break; 7460 case CP0_REG03__GLOBALNUM: 7461 CP0_CHECK(ctx->vp); 7462 /* ignored */ 7463 register_name = "GlobalNumber"; 7464 break; 7465 default: 7466 goto cp0_unimplemented; 7467 } 7468 break; 7469 case CP0_REGISTER_04: 7470 switch (sel) { 7471 case CP0_REG04__CONTEXT: 7472 gen_helper_mtc0_context(tcg_env, arg); 7473 register_name = "Context"; 7474 break; 7475 case CP0_REG04__CONTEXTCONFIG: 7476 /* SmartMIPS ASE */ 7477 /* gen_helper_dmtc0_contextconfig(arg); */ 7478 register_name = "ContextConfig"; 7479 goto cp0_unimplemented; 7480 case CP0_REG04__USERLOCAL: 7481 CP0_CHECK(ctx->ulri); 7482 tcg_gen_st_tl(arg, tcg_env, 7483 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 7484 register_name = "UserLocal"; 7485 break; 7486 case CP0_REG04__MMID: 7487 CP0_CHECK(ctx->mi); 7488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 7489 register_name = "MMID"; 7490 break; 7491 default: 7492 goto cp0_unimplemented; 7493 } 7494 break; 7495 case CP0_REGISTER_05: 7496 switch (sel) { 7497 case CP0_REG05__PAGEMASK: 7498 gen_helper_mtc0_pagemask(tcg_env, arg); 7499 register_name = "PageMask"; 7500 break; 7501 case CP0_REG05__PAGEGRAIN: 7502 check_insn(ctx, ISA_MIPS_R2); 7503 gen_helper_mtc0_pagegrain(tcg_env, arg); 7504 register_name = "PageGrain"; 7505 break; 7506 case CP0_REG05__SEGCTL0: 7507 CP0_CHECK(ctx->sc); 7508 gen_helper_mtc0_segctl0(tcg_env, arg); 7509 register_name = "SegCtl0"; 7510 break; 7511 case CP0_REG05__SEGCTL1: 7512 CP0_CHECK(ctx->sc); 7513 gen_helper_mtc0_segctl1(tcg_env, arg); 7514 register_name = "SegCtl1"; 7515 break; 7516 case CP0_REG05__SEGCTL2: 7517 CP0_CHECK(ctx->sc); 7518 gen_helper_mtc0_segctl2(tcg_env, arg); 7519 register_name = "SegCtl2"; 7520 break; 7521 case CP0_REG05__PWBASE: 7522 check_pw(ctx); 7523 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase)); 7524 register_name = "PWBase"; 7525 break; 7526 case CP0_REG05__PWFIELD: 7527 check_pw(ctx); 7528 gen_helper_mtc0_pwfield(tcg_env, arg); 7529 register_name = "PWField"; 7530 break; 7531 case CP0_REG05__PWSIZE: 7532 check_pw(ctx); 7533 gen_helper_mtc0_pwsize(tcg_env, arg); 7534 register_name = "PWSize"; 7535 break; 7536 default: 7537 goto cp0_unimplemented; 7538 } 7539 break; 7540 case CP0_REGISTER_06: 7541 switch (sel) { 7542 case CP0_REG06__WIRED: 7543 gen_helper_mtc0_wired(tcg_env, arg); 7544 register_name = "Wired"; 7545 break; 7546 case CP0_REG06__SRSCONF0: 7547 check_insn(ctx, ISA_MIPS_R2); 7548 gen_helper_mtc0_srsconf0(tcg_env, arg); 7549 register_name = "SRSConf0"; 7550 break; 7551 case CP0_REG06__SRSCONF1: 7552 check_insn(ctx, ISA_MIPS_R2); 7553 gen_helper_mtc0_srsconf1(tcg_env, arg); 7554 register_name = "SRSConf1"; 7555 break; 7556 case CP0_REG06__SRSCONF2: 7557 check_insn(ctx, ISA_MIPS_R2); 7558 gen_helper_mtc0_srsconf2(tcg_env, arg); 7559 register_name = "SRSConf2"; 7560 break; 7561 case CP0_REG06__SRSCONF3: 7562 check_insn(ctx, ISA_MIPS_R2); 7563 gen_helper_mtc0_srsconf3(tcg_env, arg); 7564 register_name = "SRSConf3"; 7565 break; 7566 case CP0_REG06__SRSCONF4: 7567 check_insn(ctx, ISA_MIPS_R2); 7568 gen_helper_mtc0_srsconf4(tcg_env, arg); 7569 register_name = "SRSConf4"; 7570 break; 7571 case CP0_REG06__PWCTL: 7572 check_pw(ctx); 7573 gen_helper_mtc0_pwctl(tcg_env, arg); 7574 register_name = "PWCtl"; 7575 break; 7576 default: 7577 goto cp0_unimplemented; 7578 } 7579 break; 7580 case CP0_REGISTER_07: 7581 switch (sel) { 7582 case CP0_REG07__HWRENA: 7583 check_insn(ctx, ISA_MIPS_R2); 7584 gen_helper_mtc0_hwrena(tcg_env, arg); 7585 ctx->base.is_jmp = DISAS_STOP; 7586 register_name = "HWREna"; 7587 break; 7588 default: 7589 goto cp0_unimplemented; 7590 } 7591 break; 7592 case CP0_REGISTER_08: 7593 switch (sel) { 7594 case CP0_REG08__BADVADDR: 7595 /* ignored */ 7596 register_name = "BadVAddr"; 7597 break; 7598 case CP0_REG08__BADINSTR: 7599 /* ignored */ 7600 register_name = "BadInstr"; 7601 break; 7602 case CP0_REG08__BADINSTRP: 7603 /* ignored */ 7604 register_name = "BadInstrP"; 7605 break; 7606 case CP0_REG08__BADINSTRX: 7607 /* ignored */ 7608 register_name = "BadInstrX"; 7609 break; 7610 default: 7611 goto cp0_unimplemented; 7612 } 7613 break; 7614 case CP0_REGISTER_09: 7615 switch (sel) { 7616 case CP0_REG09__COUNT: 7617 gen_helper_mtc0_count(tcg_env, arg); 7618 register_name = "Count"; 7619 break; 7620 default: 7621 goto cp0_unimplemented; 7622 } 7623 /* Stop translation as we may have switched the execution mode */ 7624 ctx->base.is_jmp = DISAS_STOP; 7625 break; 7626 case CP0_REGISTER_10: 7627 switch (sel) { 7628 case CP0_REG10__ENTRYHI: 7629 gen_helper_mtc0_entryhi(tcg_env, arg); 7630 register_name = "EntryHi"; 7631 break; 7632 default: 7633 goto cp0_unimplemented; 7634 } 7635 break; 7636 case CP0_REGISTER_11: 7637 switch (sel) { 7638 case CP0_REG11__COMPARE: 7639 gen_helper_mtc0_compare(tcg_env, arg); 7640 register_name = "Compare"; 7641 break; 7642 /* 6,7 are implementation dependent */ 7643 default: 7644 goto cp0_unimplemented; 7645 } 7646 /* Stop translation as we may have switched the execution mode */ 7647 ctx->base.is_jmp = DISAS_STOP; 7648 break; 7649 case CP0_REGISTER_12: 7650 switch (sel) { 7651 case CP0_REG12__STATUS: 7652 save_cpu_state(ctx, 1); 7653 gen_helper_mtc0_status(tcg_env, arg); 7654 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7655 gen_save_pc(ctx->base.pc_next + 4); 7656 ctx->base.is_jmp = DISAS_EXIT; 7657 register_name = "Status"; 7658 break; 7659 case CP0_REG12__INTCTL: 7660 check_insn(ctx, ISA_MIPS_R2); 7661 gen_helper_mtc0_intctl(tcg_env, arg); 7662 /* Stop translation as we may have switched the execution mode */ 7663 ctx->base.is_jmp = DISAS_STOP; 7664 register_name = "IntCtl"; 7665 break; 7666 case CP0_REG12__SRSCTL: 7667 check_insn(ctx, ISA_MIPS_R2); 7668 gen_helper_mtc0_srsctl(tcg_env, arg); 7669 /* Stop translation as we may have switched the execution mode */ 7670 ctx->base.is_jmp = DISAS_STOP; 7671 register_name = "SRSCtl"; 7672 break; 7673 case CP0_REG12__SRSMAP: 7674 check_insn(ctx, ISA_MIPS_R2); 7675 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7676 /* Stop translation as we may have switched the execution mode */ 7677 ctx->base.is_jmp = DISAS_STOP; 7678 register_name = "SRSMap"; 7679 break; 7680 default: 7681 goto cp0_unimplemented; 7682 } 7683 break; 7684 case CP0_REGISTER_13: 7685 switch (sel) { 7686 case CP0_REG13__CAUSE: 7687 save_cpu_state(ctx, 1); 7688 gen_helper_mtc0_cause(tcg_env, arg); 7689 /* 7690 * Stop translation as we may have triggered an interrupt. 7691 * DISAS_STOP isn't sufficient, we need to ensure we break out of 7692 * translated code to check for pending interrupts. 7693 */ 7694 gen_save_pc(ctx->base.pc_next + 4); 7695 ctx->base.is_jmp = DISAS_EXIT; 7696 register_name = "Cause"; 7697 break; 7698 default: 7699 goto cp0_unimplemented; 7700 } 7701 break; 7702 case CP0_REGISTER_14: 7703 switch (sel) { 7704 case CP0_REG14__EPC: 7705 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 7706 register_name = "EPC"; 7707 break; 7708 default: 7709 goto cp0_unimplemented; 7710 } 7711 break; 7712 case CP0_REGISTER_15: 7713 switch (sel) { 7714 case CP0_REG15__PRID: 7715 /* ignored */ 7716 register_name = "PRid"; 7717 break; 7718 case CP0_REG15__EBASE: 7719 check_insn(ctx, ISA_MIPS_R2); 7720 gen_helper_mtc0_ebase(tcg_env, arg); 7721 register_name = "EBase"; 7722 break; 7723 default: 7724 goto cp0_unimplemented; 7725 } 7726 break; 7727 case CP0_REGISTER_16: 7728 switch (sel) { 7729 case CP0_REG16__CONFIG: 7730 gen_helper_mtc0_config0(tcg_env, arg); 7731 register_name = "Config"; 7732 /* Stop translation as we may have switched the execution mode */ 7733 ctx->base.is_jmp = DISAS_STOP; 7734 break; 7735 case CP0_REG16__CONFIG1: 7736 /* ignored, read only */ 7737 register_name = "Config1"; 7738 break; 7739 case CP0_REG16__CONFIG2: 7740 gen_helper_mtc0_config2(tcg_env, arg); 7741 register_name = "Config2"; 7742 /* Stop translation as we may have switched the execution mode */ 7743 ctx->base.is_jmp = DISAS_STOP; 7744 break; 7745 case CP0_REG16__CONFIG3: 7746 gen_helper_mtc0_config3(tcg_env, arg); 7747 register_name = "Config3"; 7748 /* Stop translation as we may have switched the execution mode */ 7749 ctx->base.is_jmp = DISAS_STOP; 7750 break; 7751 case CP0_REG16__CONFIG4: 7752 /* currently ignored */ 7753 register_name = "Config4"; 7754 break; 7755 case CP0_REG16__CONFIG5: 7756 gen_helper_mtc0_config5(tcg_env, arg); 7757 register_name = "Config5"; 7758 /* Stop translation as we may have switched the execution mode */ 7759 ctx->base.is_jmp = DISAS_STOP; 7760 break; 7761 /* 6,7 are implementation dependent */ 7762 default: 7763 register_name = "Invalid config selector"; 7764 goto cp0_unimplemented; 7765 } 7766 break; 7767 case CP0_REGISTER_17: 7768 switch (sel) { 7769 case CP0_REG17__LLADDR: 7770 gen_helper_mtc0_lladdr(tcg_env, arg); 7771 register_name = "LLAddr"; 7772 break; 7773 case CP0_REG17__MAAR: 7774 CP0_CHECK(ctx->mrp); 7775 gen_helper_mtc0_maar(tcg_env, arg); 7776 register_name = "MAAR"; 7777 break; 7778 case CP0_REG17__MAARI: 7779 CP0_CHECK(ctx->mrp); 7780 gen_helper_mtc0_maari(tcg_env, arg); 7781 register_name = "MAARI"; 7782 break; 7783 default: 7784 goto cp0_unimplemented; 7785 } 7786 break; 7787 case CP0_REGISTER_18: 7788 switch (sel) { 7789 case CP0_REG18__WATCHLO0: 7790 case CP0_REG18__WATCHLO1: 7791 case CP0_REG18__WATCHLO2: 7792 case CP0_REG18__WATCHLO3: 7793 case CP0_REG18__WATCHLO4: 7794 case CP0_REG18__WATCHLO5: 7795 case CP0_REG18__WATCHLO6: 7796 case CP0_REG18__WATCHLO7: 7797 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7798 gen_helper_0e1i(mtc0_watchlo, arg, sel); 7799 register_name = "WatchLo"; 7800 break; 7801 default: 7802 goto cp0_unimplemented; 7803 } 7804 break; 7805 case CP0_REGISTER_19: 7806 switch (sel) { 7807 case CP0_REG19__WATCHHI0: 7808 case CP0_REG19__WATCHHI1: 7809 case CP0_REG19__WATCHHI2: 7810 case CP0_REG19__WATCHHI3: 7811 case CP0_REG19__WATCHHI4: 7812 case CP0_REG19__WATCHHI5: 7813 case CP0_REG19__WATCHHI6: 7814 case CP0_REG19__WATCHHI7: 7815 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7816 gen_helper_0e1i(mtc0_watchhi, arg, sel); 7817 register_name = "WatchHi"; 7818 break; 7819 default: 7820 goto cp0_unimplemented; 7821 } 7822 break; 7823 case CP0_REGISTER_20: 7824 switch (sel) { 7825 case CP0_REG20__XCONTEXT: 7826 check_insn(ctx, ISA_MIPS3); 7827 gen_helper_mtc0_xcontext(tcg_env, arg); 7828 register_name = "XContext"; 7829 break; 7830 default: 7831 goto cp0_unimplemented; 7832 } 7833 break; 7834 case CP0_REGISTER_21: 7835 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7836 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7837 switch (sel) { 7838 case 0: 7839 gen_helper_mtc0_framemask(tcg_env, arg); 7840 register_name = "Framemask"; 7841 break; 7842 default: 7843 goto cp0_unimplemented; 7844 } 7845 break; 7846 case CP0_REGISTER_22: 7847 /* ignored */ 7848 register_name = "Diagnostic"; /* implementation dependent */ 7849 break; 7850 case CP0_REGISTER_23: 7851 switch (sel) { 7852 case CP0_REG23__DEBUG: 7853 gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */ 7854 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7855 gen_save_pc(ctx->base.pc_next + 4); 7856 ctx->base.is_jmp = DISAS_EXIT; 7857 register_name = "Debug"; 7858 break; 7859 case CP0_REG23__TRACECONTROL: 7860 /* PDtrace support */ 7861 /* gen_helper_mtc0_tracecontrol(tcg_env, arg); */ 7862 /* Stop translation as we may have switched the execution mode */ 7863 ctx->base.is_jmp = DISAS_STOP; 7864 register_name = "TraceControl"; 7865 goto cp0_unimplemented; 7866 case CP0_REG23__TRACECONTROL2: 7867 /* PDtrace support */ 7868 /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */ 7869 /* Stop translation as we may have switched the execution mode */ 7870 ctx->base.is_jmp = DISAS_STOP; 7871 register_name = "TraceControl2"; 7872 goto cp0_unimplemented; 7873 case CP0_REG23__USERTRACEDATA1: 7874 /* PDtrace support */ 7875 /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/ 7876 /* Stop translation as we may have switched the execution mode */ 7877 ctx->base.is_jmp = DISAS_STOP; 7878 register_name = "UserTraceData1"; 7879 goto cp0_unimplemented; 7880 case CP0_REG23__TRACEIBPC: 7881 /* PDtrace support */ 7882 /* gen_helper_mtc0_traceibpc(tcg_env, arg); */ 7883 /* Stop translation as we may have switched the execution mode */ 7884 ctx->base.is_jmp = DISAS_STOP; 7885 register_name = "TraceIBPC"; 7886 goto cp0_unimplemented; 7887 case CP0_REG23__TRACEDBPC: 7888 /* PDtrace support */ 7889 /* gen_helper_mtc0_tracedbpc(tcg_env, arg); */ 7890 /* Stop translation as we may have switched the execution mode */ 7891 ctx->base.is_jmp = DISAS_STOP; 7892 register_name = "TraceDBPC"; 7893 goto cp0_unimplemented; 7894 default: 7895 goto cp0_unimplemented; 7896 } 7897 break; 7898 case CP0_REGISTER_24: 7899 switch (sel) { 7900 case CP0_REG24__DEPC: 7901 /* EJTAG support */ 7902 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 7903 register_name = "DEPC"; 7904 break; 7905 default: 7906 goto cp0_unimplemented; 7907 } 7908 break; 7909 case CP0_REGISTER_25: 7910 switch (sel) { 7911 case CP0_REG25__PERFCTL0: 7912 gen_helper_mtc0_performance0(tcg_env, arg); 7913 register_name = "Performance0"; 7914 break; 7915 case CP0_REG25__PERFCNT0: 7916 /* gen_helper_mtc0_performance1(tcg_env, arg); */ 7917 register_name = "Performance1"; 7918 goto cp0_unimplemented; 7919 case CP0_REG25__PERFCTL1: 7920 /* gen_helper_mtc0_performance2(tcg_env, arg); */ 7921 register_name = "Performance2"; 7922 goto cp0_unimplemented; 7923 case CP0_REG25__PERFCNT1: 7924 /* gen_helper_mtc0_performance3(tcg_env, arg); */ 7925 register_name = "Performance3"; 7926 goto cp0_unimplemented; 7927 case CP0_REG25__PERFCTL2: 7928 /* gen_helper_mtc0_performance4(tcg_env, arg); */ 7929 register_name = "Performance4"; 7930 goto cp0_unimplemented; 7931 case CP0_REG25__PERFCNT2: 7932 /* gen_helper_mtc0_performance5(tcg_env, arg); */ 7933 register_name = "Performance5"; 7934 goto cp0_unimplemented; 7935 case CP0_REG25__PERFCTL3: 7936 /* gen_helper_mtc0_performance6(tcg_env, arg); */ 7937 register_name = "Performance6"; 7938 goto cp0_unimplemented; 7939 case CP0_REG25__PERFCNT3: 7940 /* gen_helper_mtc0_performance7(tcg_env, arg); */ 7941 register_name = "Performance7"; 7942 goto cp0_unimplemented; 7943 default: 7944 goto cp0_unimplemented; 7945 } 7946 break; 7947 case CP0_REGISTER_26: 7948 switch (sel) { 7949 case CP0_REG26__ERRCTL: 7950 gen_helper_mtc0_errctl(tcg_env, arg); 7951 ctx->base.is_jmp = DISAS_STOP; 7952 register_name = "ErrCtl"; 7953 break; 7954 default: 7955 goto cp0_unimplemented; 7956 } 7957 break; 7958 case CP0_REGISTER_27: 7959 switch (sel) { 7960 case CP0_REG27__CACHERR: 7961 /* ignored */ 7962 register_name = "CacheErr"; 7963 break; 7964 default: 7965 goto cp0_unimplemented; 7966 } 7967 break; 7968 case CP0_REGISTER_28: 7969 switch (sel) { 7970 case CP0_REG28__TAGLO: 7971 case CP0_REG28__TAGLO1: 7972 case CP0_REG28__TAGLO2: 7973 case CP0_REG28__TAGLO3: 7974 gen_helper_mtc0_taglo(tcg_env, arg); 7975 register_name = "TagLo"; 7976 break; 7977 case CP0_REG28__DATALO: 7978 case CP0_REG28__DATALO1: 7979 case CP0_REG28__DATALO2: 7980 case CP0_REG28__DATALO3: 7981 gen_helper_mtc0_datalo(tcg_env, arg); 7982 register_name = "DataLo"; 7983 break; 7984 default: 7985 goto cp0_unimplemented; 7986 } 7987 break; 7988 case CP0_REGISTER_29: 7989 switch (sel) { 7990 case CP0_REG29__TAGHI: 7991 case CP0_REG29__TAGHI1: 7992 case CP0_REG29__TAGHI2: 7993 case CP0_REG29__TAGHI3: 7994 gen_helper_mtc0_taghi(tcg_env, arg); 7995 register_name = "TagHi"; 7996 break; 7997 case CP0_REG29__DATAHI: 7998 case CP0_REG29__DATAHI1: 7999 case CP0_REG29__DATAHI2: 8000 case CP0_REG29__DATAHI3: 8001 gen_helper_mtc0_datahi(tcg_env, arg); 8002 register_name = "DataHi"; 8003 break; 8004 default: 8005 register_name = "invalid sel"; 8006 goto cp0_unimplemented; 8007 } 8008 break; 8009 case CP0_REGISTER_30: 8010 switch (sel) { 8011 case CP0_REG30__ERROREPC: 8012 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 8013 register_name = "ErrorEPC"; 8014 break; 8015 default: 8016 goto cp0_unimplemented; 8017 } 8018 break; 8019 case CP0_REGISTER_31: 8020 switch (sel) { 8021 case CP0_REG31__DESAVE: 8022 /* EJTAG support */ 8023 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 8024 register_name = "DESAVE"; 8025 break; 8026 case CP0_REG31__KSCRATCH1: 8027 case CP0_REG31__KSCRATCH2: 8028 case CP0_REG31__KSCRATCH3: 8029 case CP0_REG31__KSCRATCH4: 8030 case CP0_REG31__KSCRATCH5: 8031 case CP0_REG31__KSCRATCH6: 8032 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8033 tcg_gen_st_tl(arg, tcg_env, 8034 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8035 register_name = "KScratch"; 8036 break; 8037 default: 8038 goto cp0_unimplemented; 8039 } 8040 break; 8041 default: 8042 goto cp0_unimplemented; 8043 } 8044 trace_mips_translate_c0("dmtc0", register_name, reg, sel); 8045 8046 /* For simplicity assume that all writes can cause interrupts. */ 8047 if (icount) { 8048 /* 8049 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8050 * translated code to check for pending interrupts. 8051 */ 8052 gen_save_pc(ctx->base.pc_next + 4); 8053 ctx->base.is_jmp = DISAS_EXIT; 8054 } 8055 return; 8056 8057 cp0_unimplemented: 8058 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", 8059 register_name, reg, sel); 8060 } 8061 #endif /* TARGET_MIPS64 */ 8062 8063 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 8064 int u, int sel, int h) 8065 { 8066 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8067 TCGv t0 = tcg_temp_new(); 8068 8069 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8070 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8071 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8072 tcg_gen_movi_tl(t0, -1); 8073 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8074 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8075 tcg_gen_movi_tl(t0, -1); 8076 } else if (u == 0) { 8077 switch (rt) { 8078 case 1: 8079 switch (sel) { 8080 case 1: 8081 gen_helper_mftc0_vpecontrol(t0, tcg_env); 8082 break; 8083 case 2: 8084 gen_helper_mftc0_vpeconf0(t0, tcg_env); 8085 break; 8086 default: 8087 goto die; 8088 break; 8089 } 8090 break; 8091 case 2: 8092 switch (sel) { 8093 case 1: 8094 gen_helper_mftc0_tcstatus(t0, tcg_env); 8095 break; 8096 case 2: 8097 gen_helper_mftc0_tcbind(t0, tcg_env); 8098 break; 8099 case 3: 8100 gen_helper_mftc0_tcrestart(t0, tcg_env); 8101 break; 8102 case 4: 8103 gen_helper_mftc0_tchalt(t0, tcg_env); 8104 break; 8105 case 5: 8106 gen_helper_mftc0_tccontext(t0, tcg_env); 8107 break; 8108 case 6: 8109 gen_helper_mftc0_tcschedule(t0, tcg_env); 8110 break; 8111 case 7: 8112 gen_helper_mftc0_tcschefback(t0, tcg_env); 8113 break; 8114 default: 8115 gen_mfc0(ctx, t0, rt, sel); 8116 break; 8117 } 8118 break; 8119 case 10: 8120 switch (sel) { 8121 case 0: 8122 gen_helper_mftc0_entryhi(t0, tcg_env); 8123 break; 8124 default: 8125 gen_mfc0(ctx, t0, rt, sel); 8126 break; 8127 } 8128 break; 8129 case 12: 8130 switch (sel) { 8131 case 0: 8132 gen_helper_mftc0_status(t0, tcg_env); 8133 break; 8134 default: 8135 gen_mfc0(ctx, t0, rt, sel); 8136 break; 8137 } 8138 break; 8139 case 13: 8140 switch (sel) { 8141 case 0: 8142 gen_helper_mftc0_cause(t0, tcg_env); 8143 break; 8144 default: 8145 goto die; 8146 break; 8147 } 8148 break; 8149 case 14: 8150 switch (sel) { 8151 case 0: 8152 gen_helper_mftc0_epc(t0, tcg_env); 8153 break; 8154 default: 8155 goto die; 8156 break; 8157 } 8158 break; 8159 case 15: 8160 switch (sel) { 8161 case 1: 8162 gen_helper_mftc0_ebase(t0, tcg_env); 8163 break; 8164 default: 8165 goto die; 8166 break; 8167 } 8168 break; 8169 case 16: 8170 switch (sel) { 8171 case 0: 8172 case 1: 8173 case 2: 8174 case 3: 8175 case 4: 8176 case 5: 8177 case 6: 8178 case 7: 8179 gen_helper_mftc0_configx(t0, tcg_env, tcg_constant_tl(sel)); 8180 break; 8181 default: 8182 goto die; 8183 break; 8184 } 8185 break; 8186 case 23: 8187 switch (sel) { 8188 case 0: 8189 gen_helper_mftc0_debug(t0, tcg_env); 8190 break; 8191 default: 8192 gen_mfc0(ctx, t0, rt, sel); 8193 break; 8194 } 8195 break; 8196 default: 8197 gen_mfc0(ctx, t0, rt, sel); 8198 } 8199 } else { 8200 switch (sel) { 8201 /* GPR registers. */ 8202 case 0: 8203 gen_helper_1e0i(mftgpr, t0, rt); 8204 break; 8205 /* Auxiliary CPU registers */ 8206 case 1: 8207 switch (rt) { 8208 case 0: 8209 gen_helper_1e0i(mftlo, t0, 0); 8210 break; 8211 case 1: 8212 gen_helper_1e0i(mfthi, t0, 0); 8213 break; 8214 case 2: 8215 gen_helper_1e0i(mftacx, t0, 0); 8216 break; 8217 case 4: 8218 gen_helper_1e0i(mftlo, t0, 1); 8219 break; 8220 case 5: 8221 gen_helper_1e0i(mfthi, t0, 1); 8222 break; 8223 case 6: 8224 gen_helper_1e0i(mftacx, t0, 1); 8225 break; 8226 case 8: 8227 gen_helper_1e0i(mftlo, t0, 2); 8228 break; 8229 case 9: 8230 gen_helper_1e0i(mfthi, t0, 2); 8231 break; 8232 case 10: 8233 gen_helper_1e0i(mftacx, t0, 2); 8234 break; 8235 case 12: 8236 gen_helper_1e0i(mftlo, t0, 3); 8237 break; 8238 case 13: 8239 gen_helper_1e0i(mfthi, t0, 3); 8240 break; 8241 case 14: 8242 gen_helper_1e0i(mftacx, t0, 3); 8243 break; 8244 case 16: 8245 gen_helper_mftdsp(t0, tcg_env); 8246 break; 8247 default: 8248 goto die; 8249 } 8250 break; 8251 /* Floating point (COP1). */ 8252 case 2: 8253 /* XXX: For now we support only a single FPU context. */ 8254 if (h == 0) { 8255 TCGv_i32 fp0 = tcg_temp_new_i32(); 8256 8257 gen_load_fpr32(ctx, fp0, rt); 8258 tcg_gen_ext_i32_tl(t0, fp0); 8259 } else { 8260 TCGv_i32 fp0 = tcg_temp_new_i32(); 8261 8262 gen_load_fpr32h(ctx, fp0, rt); 8263 tcg_gen_ext_i32_tl(t0, fp0); 8264 } 8265 break; 8266 case 3: 8267 /* XXX: For now we support only a single FPU context. */ 8268 gen_helper_1e0i(cfc1, t0, rt); 8269 break; 8270 /* COP2: Not implemented. */ 8271 case 4: 8272 case 5: 8273 /* fall through */ 8274 default: 8275 goto die; 8276 } 8277 } 8278 trace_mips_translate_tr("mftr", rt, u, sel, h); 8279 gen_store_gpr(t0, rd); 8280 return; 8281 8282 die: 8283 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 8284 gen_reserved_instruction(ctx); 8285 } 8286 8287 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 8288 int u, int sel, int h) 8289 { 8290 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8291 TCGv t0 = tcg_temp_new(); 8292 8293 gen_load_gpr(t0, rt); 8294 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8295 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8296 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8297 /* NOP */ 8298 ; 8299 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8300 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8301 /* NOP */ 8302 ; 8303 } else if (u == 0) { 8304 switch (rd) { 8305 case 1: 8306 switch (sel) { 8307 case 1: 8308 gen_helper_mttc0_vpecontrol(tcg_env, t0); 8309 break; 8310 case 2: 8311 gen_helper_mttc0_vpeconf0(tcg_env, t0); 8312 break; 8313 default: 8314 goto die; 8315 break; 8316 } 8317 break; 8318 case 2: 8319 switch (sel) { 8320 case 1: 8321 gen_helper_mttc0_tcstatus(tcg_env, t0); 8322 break; 8323 case 2: 8324 gen_helper_mttc0_tcbind(tcg_env, t0); 8325 break; 8326 case 3: 8327 gen_helper_mttc0_tcrestart(tcg_env, t0); 8328 break; 8329 case 4: 8330 gen_helper_mttc0_tchalt(tcg_env, t0); 8331 break; 8332 case 5: 8333 gen_helper_mttc0_tccontext(tcg_env, t0); 8334 break; 8335 case 6: 8336 gen_helper_mttc0_tcschedule(tcg_env, t0); 8337 break; 8338 case 7: 8339 gen_helper_mttc0_tcschefback(tcg_env, t0); 8340 break; 8341 default: 8342 gen_mtc0(ctx, t0, rd, sel); 8343 break; 8344 } 8345 break; 8346 case 10: 8347 switch (sel) { 8348 case 0: 8349 gen_helper_mttc0_entryhi(tcg_env, t0); 8350 break; 8351 default: 8352 gen_mtc0(ctx, t0, rd, sel); 8353 break; 8354 } 8355 break; 8356 case 12: 8357 switch (sel) { 8358 case 0: 8359 gen_helper_mttc0_status(tcg_env, t0); 8360 break; 8361 default: 8362 gen_mtc0(ctx, t0, rd, sel); 8363 break; 8364 } 8365 break; 8366 case 13: 8367 switch (sel) { 8368 case 0: 8369 gen_helper_mttc0_cause(tcg_env, t0); 8370 break; 8371 default: 8372 goto die; 8373 break; 8374 } 8375 break; 8376 case 15: 8377 switch (sel) { 8378 case 1: 8379 gen_helper_mttc0_ebase(tcg_env, t0); 8380 break; 8381 default: 8382 goto die; 8383 break; 8384 } 8385 break; 8386 case 23: 8387 switch (sel) { 8388 case 0: 8389 gen_helper_mttc0_debug(tcg_env, t0); 8390 break; 8391 default: 8392 gen_mtc0(ctx, t0, rd, sel); 8393 break; 8394 } 8395 break; 8396 default: 8397 gen_mtc0(ctx, t0, rd, sel); 8398 } 8399 } else { 8400 switch (sel) { 8401 /* GPR registers. */ 8402 case 0: 8403 gen_helper_0e1i(mttgpr, t0, rd); 8404 break; 8405 /* Auxiliary CPU registers */ 8406 case 1: 8407 switch (rd) { 8408 case 0: 8409 gen_helper_0e1i(mttlo, t0, 0); 8410 break; 8411 case 1: 8412 gen_helper_0e1i(mtthi, t0, 0); 8413 break; 8414 case 2: 8415 gen_helper_0e1i(mttacx, t0, 0); 8416 break; 8417 case 4: 8418 gen_helper_0e1i(mttlo, t0, 1); 8419 break; 8420 case 5: 8421 gen_helper_0e1i(mtthi, t0, 1); 8422 break; 8423 case 6: 8424 gen_helper_0e1i(mttacx, t0, 1); 8425 break; 8426 case 8: 8427 gen_helper_0e1i(mttlo, t0, 2); 8428 break; 8429 case 9: 8430 gen_helper_0e1i(mtthi, t0, 2); 8431 break; 8432 case 10: 8433 gen_helper_0e1i(mttacx, t0, 2); 8434 break; 8435 case 12: 8436 gen_helper_0e1i(mttlo, t0, 3); 8437 break; 8438 case 13: 8439 gen_helper_0e1i(mtthi, t0, 3); 8440 break; 8441 case 14: 8442 gen_helper_0e1i(mttacx, t0, 3); 8443 break; 8444 case 16: 8445 gen_helper_mttdsp(tcg_env, t0); 8446 break; 8447 default: 8448 goto die; 8449 } 8450 break; 8451 /* Floating point (COP1). */ 8452 case 2: 8453 /* XXX: For now we support only a single FPU context. */ 8454 if (h == 0) { 8455 TCGv_i32 fp0 = tcg_temp_new_i32(); 8456 8457 tcg_gen_trunc_tl_i32(fp0, t0); 8458 gen_store_fpr32(ctx, fp0, rd); 8459 } else { 8460 TCGv_i32 fp0 = tcg_temp_new_i32(); 8461 8462 tcg_gen_trunc_tl_i32(fp0, t0); 8463 gen_store_fpr32h(ctx, fp0, rd); 8464 } 8465 break; 8466 case 3: 8467 /* XXX: For now we support only a single FPU context. */ 8468 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt); 8469 /* Stop translation as we may have changed hflags */ 8470 ctx->base.is_jmp = DISAS_STOP; 8471 break; 8472 /* COP2: Not implemented. */ 8473 case 4: 8474 case 5: 8475 /* fall through */ 8476 default: 8477 goto die; 8478 } 8479 } 8480 trace_mips_translate_tr("mttr", rd, u, sel, h); 8481 return; 8482 8483 die: 8484 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 8485 gen_reserved_instruction(ctx); 8486 } 8487 8488 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 8489 int rt, int rd) 8490 { 8491 const char *opn = "ldst"; 8492 8493 check_cp0_enabled(ctx); 8494 switch (opc) { 8495 case OPC_MFC0: 8496 if (rt == 0) { 8497 /* Treat as NOP. */ 8498 return; 8499 } 8500 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8501 opn = "mfc0"; 8502 break; 8503 case OPC_MTC0: 8504 { 8505 TCGv t0 = tcg_temp_new(); 8506 8507 gen_load_gpr(t0, rt); 8508 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7); 8509 } 8510 opn = "mtc0"; 8511 break; 8512 #if defined(TARGET_MIPS64) 8513 case OPC_DMFC0: 8514 check_insn(ctx, ISA_MIPS3); 8515 if (rt == 0) { 8516 /* Treat as NOP. */ 8517 return; 8518 } 8519 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8520 opn = "dmfc0"; 8521 break; 8522 case OPC_DMTC0: 8523 check_insn(ctx, ISA_MIPS3); 8524 { 8525 TCGv t0 = tcg_temp_new(); 8526 8527 gen_load_gpr(t0, rt); 8528 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7); 8529 } 8530 opn = "dmtc0"; 8531 break; 8532 #endif 8533 case OPC_MFHC0: 8534 check_mvh(ctx); 8535 if (rt == 0) { 8536 /* Treat as NOP. */ 8537 return; 8538 } 8539 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8540 opn = "mfhc0"; 8541 break; 8542 case OPC_MTHC0: 8543 check_mvh(ctx); 8544 { 8545 TCGv t0 = tcg_temp_new(); 8546 gen_load_gpr(t0, rt); 8547 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7); 8548 } 8549 opn = "mthc0"; 8550 break; 8551 case OPC_MFTR: 8552 check_cp0_enabled(ctx); 8553 if (rd == 0) { 8554 /* Treat as NOP. */ 8555 return; 8556 } 8557 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 8558 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 8559 opn = "mftr"; 8560 break; 8561 case OPC_MTTR: 8562 check_cp0_enabled(ctx); 8563 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 8564 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 8565 opn = "mttr"; 8566 break; 8567 case OPC_TLBWI: 8568 opn = "tlbwi"; 8569 if (!env->tlb->helper_tlbwi) { 8570 goto die; 8571 } 8572 gen_helper_tlbwi(tcg_env); 8573 break; 8574 case OPC_TLBINV: 8575 opn = "tlbinv"; 8576 if (ctx->ie >= 2) { 8577 if (!env->tlb->helper_tlbinv) { 8578 goto die; 8579 } 8580 gen_helper_tlbinv(tcg_env); 8581 } /* treat as nop if TLBINV not supported */ 8582 break; 8583 case OPC_TLBINVF: 8584 opn = "tlbinvf"; 8585 if (ctx->ie >= 2) { 8586 if (!env->tlb->helper_tlbinvf) { 8587 goto die; 8588 } 8589 gen_helper_tlbinvf(tcg_env); 8590 } /* treat as nop if TLBINV not supported */ 8591 break; 8592 case OPC_TLBWR: 8593 opn = "tlbwr"; 8594 if (!env->tlb->helper_tlbwr) { 8595 goto die; 8596 } 8597 gen_helper_tlbwr(tcg_env); 8598 break; 8599 case OPC_TLBP: 8600 opn = "tlbp"; 8601 if (!env->tlb->helper_tlbp) { 8602 goto die; 8603 } 8604 gen_helper_tlbp(tcg_env); 8605 break; 8606 case OPC_TLBR: 8607 opn = "tlbr"; 8608 if (!env->tlb->helper_tlbr) { 8609 goto die; 8610 } 8611 gen_helper_tlbr(tcg_env); 8612 break; 8613 case OPC_ERET: /* OPC_ERETNC */ 8614 if ((ctx->insn_flags & ISA_MIPS_R6) && 8615 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8616 goto die; 8617 } else { 8618 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6; 8619 if (ctx->opcode & (1 << bit_shift)) { 8620 /* OPC_ERETNC */ 8621 opn = "eretnc"; 8622 check_insn(ctx, ISA_MIPS_R5); 8623 gen_helper_eretnc(tcg_env); 8624 } else { 8625 /* OPC_ERET */ 8626 opn = "eret"; 8627 check_insn(ctx, ISA_MIPS2); 8628 gen_helper_eret(tcg_env); 8629 } 8630 ctx->base.is_jmp = DISAS_EXIT; 8631 } 8632 break; 8633 case OPC_DERET: 8634 opn = "deret"; 8635 check_insn(ctx, ISA_MIPS_R1); 8636 if ((ctx->insn_flags & ISA_MIPS_R6) && 8637 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8638 goto die; 8639 } 8640 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 8641 MIPS_INVAL(opn); 8642 gen_reserved_instruction(ctx); 8643 } else { 8644 gen_helper_deret(tcg_env); 8645 ctx->base.is_jmp = DISAS_EXIT; 8646 } 8647 break; 8648 case OPC_WAIT: 8649 opn = "wait"; 8650 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 8651 if ((ctx->insn_flags & ISA_MIPS_R6) && 8652 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8653 goto die; 8654 } 8655 /* If we get an exception, we want to restart at next instruction */ 8656 ctx->base.pc_next += 4; 8657 save_cpu_state(ctx, 1); 8658 ctx->base.pc_next -= 4; 8659 gen_helper_wait(tcg_env); 8660 ctx->base.is_jmp = DISAS_NORETURN; 8661 break; 8662 default: 8663 die: 8664 MIPS_INVAL(opn); 8665 gen_reserved_instruction(ctx); 8666 return; 8667 } 8668 (void)opn; /* avoid a compiler warning */ 8669 } 8670 #endif /* !CONFIG_USER_ONLY */ 8671 8672 /* CP1 Branches (before delay slot) */ 8673 static void gen_compute_branch1(DisasContext *ctx, uint32_t op, 8674 int32_t cc, int32_t offset) 8675 { 8676 target_ulong btarget; 8677 TCGv_i32 t0 = tcg_temp_new_i32(); 8678 8679 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { 8680 gen_reserved_instruction(ctx); 8681 return; 8682 } 8683 8684 if (cc != 0) { 8685 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 8686 } 8687 8688 btarget = ctx->base.pc_next + 4 + offset; 8689 8690 switch (op) { 8691 case OPC_BC1F: 8692 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8693 tcg_gen_not_i32(t0, t0); 8694 tcg_gen_andi_i32(t0, t0, 1); 8695 tcg_gen_extu_i32_tl(bcond, t0); 8696 goto not_likely; 8697 case OPC_BC1FL: 8698 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8699 tcg_gen_not_i32(t0, t0); 8700 tcg_gen_andi_i32(t0, t0, 1); 8701 tcg_gen_extu_i32_tl(bcond, t0); 8702 goto likely; 8703 case OPC_BC1T: 8704 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8705 tcg_gen_andi_i32(t0, t0, 1); 8706 tcg_gen_extu_i32_tl(bcond, t0); 8707 goto not_likely; 8708 case OPC_BC1TL: 8709 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8710 tcg_gen_andi_i32(t0, t0, 1); 8711 tcg_gen_extu_i32_tl(bcond, t0); 8712 likely: 8713 ctx->hflags |= MIPS_HFLAG_BL; 8714 break; 8715 case OPC_BC1FANY2: 8716 { 8717 TCGv_i32 t1 = tcg_temp_new_i32(); 8718 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8719 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8720 tcg_gen_nand_i32(t0, t0, t1); 8721 tcg_gen_andi_i32(t0, t0, 1); 8722 tcg_gen_extu_i32_tl(bcond, t0); 8723 } 8724 goto not_likely; 8725 case OPC_BC1TANY2: 8726 { 8727 TCGv_i32 t1 = tcg_temp_new_i32(); 8728 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8729 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8730 tcg_gen_or_i32(t0, t0, t1); 8731 tcg_gen_andi_i32(t0, t0, 1); 8732 tcg_gen_extu_i32_tl(bcond, t0); 8733 } 8734 goto not_likely; 8735 case OPC_BC1FANY4: 8736 { 8737 TCGv_i32 t1 = tcg_temp_new_i32(); 8738 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8739 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8740 tcg_gen_and_i32(t0, t0, t1); 8741 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 8742 tcg_gen_and_i32(t0, t0, t1); 8743 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 8744 tcg_gen_nand_i32(t0, t0, t1); 8745 tcg_gen_andi_i32(t0, t0, 1); 8746 tcg_gen_extu_i32_tl(bcond, t0); 8747 } 8748 goto not_likely; 8749 case OPC_BC1TANY4: 8750 { 8751 TCGv_i32 t1 = tcg_temp_new_i32(); 8752 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8753 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8754 tcg_gen_or_i32(t0, t0, t1); 8755 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 8756 tcg_gen_or_i32(t0, t0, t1); 8757 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 8758 tcg_gen_or_i32(t0, t0, t1); 8759 tcg_gen_andi_i32(t0, t0, 1); 8760 tcg_gen_extu_i32_tl(bcond, t0); 8761 } 8762 not_likely: 8763 ctx->hflags |= MIPS_HFLAG_BC; 8764 break; 8765 default: 8766 MIPS_INVAL("cp1 cond branch"); 8767 gen_reserved_instruction(ctx); 8768 return; 8769 } 8770 ctx->btarget = btarget; 8771 ctx->hflags |= MIPS_HFLAG_BDS32; 8772 } 8773 8774 /* R6 CP1 Branches */ 8775 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, 8776 int32_t ft, int32_t offset, 8777 int delayslot_size) 8778 { 8779 target_ulong btarget; 8780 TCGv_i64 t0 = tcg_temp_new_i64(); 8781 8782 if (ctx->hflags & MIPS_HFLAG_BMASK) { 8783 #ifdef MIPS_DEBUG_DISAS 8784 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 8785 VADDR_PRIx "\n", ctx->base.pc_next); 8786 #endif 8787 gen_reserved_instruction(ctx); 8788 return; 8789 } 8790 8791 gen_load_fpr64(ctx, t0, ft); 8792 tcg_gen_andi_i64(t0, t0, 1); 8793 8794 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 8795 8796 switch (op) { 8797 case OPC_BC1EQZ: 8798 tcg_gen_xori_i64(t0, t0, 1); 8799 ctx->hflags |= MIPS_HFLAG_BC; 8800 break; 8801 case OPC_BC1NEZ: 8802 /* t0 already set */ 8803 ctx->hflags |= MIPS_HFLAG_BC; 8804 break; 8805 default: 8806 MIPS_INVAL("cp1 cond branch"); 8807 gen_reserved_instruction(ctx); 8808 return; 8809 } 8810 8811 tcg_gen_trunc_i64_tl(bcond, t0); 8812 8813 ctx->btarget = btarget; 8814 8815 switch (delayslot_size) { 8816 case 2: 8817 ctx->hflags |= MIPS_HFLAG_BDS16; 8818 break; 8819 case 4: 8820 ctx->hflags |= MIPS_HFLAG_BDS32; 8821 break; 8822 } 8823 } 8824 8825 /* Coprocessor 1 (FPU) */ 8826 8827 #define FOP(func, fmt) (((fmt) << 21) | (func)) 8828 8829 enum fopcode { 8830 OPC_ADD_S = FOP(0, FMT_S), 8831 OPC_SUB_S = FOP(1, FMT_S), 8832 OPC_MUL_S = FOP(2, FMT_S), 8833 OPC_DIV_S = FOP(3, FMT_S), 8834 OPC_SQRT_S = FOP(4, FMT_S), 8835 OPC_ABS_S = FOP(5, FMT_S), 8836 OPC_MOV_S = FOP(6, FMT_S), 8837 OPC_NEG_S = FOP(7, FMT_S), 8838 OPC_ROUND_L_S = FOP(8, FMT_S), 8839 OPC_TRUNC_L_S = FOP(9, FMT_S), 8840 OPC_CEIL_L_S = FOP(10, FMT_S), 8841 OPC_FLOOR_L_S = FOP(11, FMT_S), 8842 OPC_ROUND_W_S = FOP(12, FMT_S), 8843 OPC_TRUNC_W_S = FOP(13, FMT_S), 8844 OPC_CEIL_W_S = FOP(14, FMT_S), 8845 OPC_FLOOR_W_S = FOP(15, FMT_S), 8846 OPC_SEL_S = FOP(16, FMT_S), 8847 OPC_MOVCF_S = FOP(17, FMT_S), 8848 OPC_MOVZ_S = FOP(18, FMT_S), 8849 OPC_MOVN_S = FOP(19, FMT_S), 8850 OPC_SELEQZ_S = FOP(20, FMT_S), 8851 OPC_RECIP_S = FOP(21, FMT_S), 8852 OPC_RSQRT_S = FOP(22, FMT_S), 8853 OPC_SELNEZ_S = FOP(23, FMT_S), 8854 OPC_MADDF_S = FOP(24, FMT_S), 8855 OPC_MSUBF_S = FOP(25, FMT_S), 8856 OPC_RINT_S = FOP(26, FMT_S), 8857 OPC_CLASS_S = FOP(27, FMT_S), 8858 OPC_MIN_S = FOP(28, FMT_S), 8859 OPC_RECIP2_S = FOP(28, FMT_S), 8860 OPC_MINA_S = FOP(29, FMT_S), 8861 OPC_RECIP1_S = FOP(29, FMT_S), 8862 OPC_MAX_S = FOP(30, FMT_S), 8863 OPC_RSQRT1_S = FOP(30, FMT_S), 8864 OPC_MAXA_S = FOP(31, FMT_S), 8865 OPC_RSQRT2_S = FOP(31, FMT_S), 8866 OPC_CVT_D_S = FOP(33, FMT_S), 8867 OPC_CVT_W_S = FOP(36, FMT_S), 8868 OPC_CVT_L_S = FOP(37, FMT_S), 8869 OPC_CVT_PS_S = FOP(38, FMT_S), 8870 OPC_CMP_F_S = FOP(48, FMT_S), 8871 OPC_CMP_UN_S = FOP(49, FMT_S), 8872 OPC_CMP_EQ_S = FOP(50, FMT_S), 8873 OPC_CMP_UEQ_S = FOP(51, FMT_S), 8874 OPC_CMP_OLT_S = FOP(52, FMT_S), 8875 OPC_CMP_ULT_S = FOP(53, FMT_S), 8876 OPC_CMP_OLE_S = FOP(54, FMT_S), 8877 OPC_CMP_ULE_S = FOP(55, FMT_S), 8878 OPC_CMP_SF_S = FOP(56, FMT_S), 8879 OPC_CMP_NGLE_S = FOP(57, FMT_S), 8880 OPC_CMP_SEQ_S = FOP(58, FMT_S), 8881 OPC_CMP_NGL_S = FOP(59, FMT_S), 8882 OPC_CMP_LT_S = FOP(60, FMT_S), 8883 OPC_CMP_NGE_S = FOP(61, FMT_S), 8884 OPC_CMP_LE_S = FOP(62, FMT_S), 8885 OPC_CMP_NGT_S = FOP(63, FMT_S), 8886 8887 OPC_ADD_D = FOP(0, FMT_D), 8888 OPC_SUB_D = FOP(1, FMT_D), 8889 OPC_MUL_D = FOP(2, FMT_D), 8890 OPC_DIV_D = FOP(3, FMT_D), 8891 OPC_SQRT_D = FOP(4, FMT_D), 8892 OPC_ABS_D = FOP(5, FMT_D), 8893 OPC_MOV_D = FOP(6, FMT_D), 8894 OPC_NEG_D = FOP(7, FMT_D), 8895 OPC_ROUND_L_D = FOP(8, FMT_D), 8896 OPC_TRUNC_L_D = FOP(9, FMT_D), 8897 OPC_CEIL_L_D = FOP(10, FMT_D), 8898 OPC_FLOOR_L_D = FOP(11, FMT_D), 8899 OPC_ROUND_W_D = FOP(12, FMT_D), 8900 OPC_TRUNC_W_D = FOP(13, FMT_D), 8901 OPC_CEIL_W_D = FOP(14, FMT_D), 8902 OPC_FLOOR_W_D = FOP(15, FMT_D), 8903 OPC_SEL_D = FOP(16, FMT_D), 8904 OPC_MOVCF_D = FOP(17, FMT_D), 8905 OPC_MOVZ_D = FOP(18, FMT_D), 8906 OPC_MOVN_D = FOP(19, FMT_D), 8907 OPC_SELEQZ_D = FOP(20, FMT_D), 8908 OPC_RECIP_D = FOP(21, FMT_D), 8909 OPC_RSQRT_D = FOP(22, FMT_D), 8910 OPC_SELNEZ_D = FOP(23, FMT_D), 8911 OPC_MADDF_D = FOP(24, FMT_D), 8912 OPC_MSUBF_D = FOP(25, FMT_D), 8913 OPC_RINT_D = FOP(26, FMT_D), 8914 OPC_CLASS_D = FOP(27, FMT_D), 8915 OPC_MIN_D = FOP(28, FMT_D), 8916 OPC_RECIP2_D = FOP(28, FMT_D), 8917 OPC_MINA_D = FOP(29, FMT_D), 8918 OPC_RECIP1_D = FOP(29, FMT_D), 8919 OPC_MAX_D = FOP(30, FMT_D), 8920 OPC_RSQRT1_D = FOP(30, FMT_D), 8921 OPC_MAXA_D = FOP(31, FMT_D), 8922 OPC_RSQRT2_D = FOP(31, FMT_D), 8923 OPC_CVT_S_D = FOP(32, FMT_D), 8924 OPC_CVT_W_D = FOP(36, FMT_D), 8925 OPC_CVT_L_D = FOP(37, FMT_D), 8926 OPC_CMP_F_D = FOP(48, FMT_D), 8927 OPC_CMP_UN_D = FOP(49, FMT_D), 8928 OPC_CMP_EQ_D = FOP(50, FMT_D), 8929 OPC_CMP_UEQ_D = FOP(51, FMT_D), 8930 OPC_CMP_OLT_D = FOP(52, FMT_D), 8931 OPC_CMP_ULT_D = FOP(53, FMT_D), 8932 OPC_CMP_OLE_D = FOP(54, FMT_D), 8933 OPC_CMP_ULE_D = FOP(55, FMT_D), 8934 OPC_CMP_SF_D = FOP(56, FMT_D), 8935 OPC_CMP_NGLE_D = FOP(57, FMT_D), 8936 OPC_CMP_SEQ_D = FOP(58, FMT_D), 8937 OPC_CMP_NGL_D = FOP(59, FMT_D), 8938 OPC_CMP_LT_D = FOP(60, FMT_D), 8939 OPC_CMP_NGE_D = FOP(61, FMT_D), 8940 OPC_CMP_LE_D = FOP(62, FMT_D), 8941 OPC_CMP_NGT_D = FOP(63, FMT_D), 8942 8943 OPC_CVT_S_W = FOP(32, FMT_W), 8944 OPC_CVT_D_W = FOP(33, FMT_W), 8945 OPC_CVT_S_L = FOP(32, FMT_L), 8946 OPC_CVT_D_L = FOP(33, FMT_L), 8947 OPC_CVT_PS_PW = FOP(38, FMT_W), 8948 8949 OPC_ADD_PS = FOP(0, FMT_PS), 8950 OPC_SUB_PS = FOP(1, FMT_PS), 8951 OPC_MUL_PS = FOP(2, FMT_PS), 8952 OPC_DIV_PS = FOP(3, FMT_PS), 8953 OPC_ABS_PS = FOP(5, FMT_PS), 8954 OPC_MOV_PS = FOP(6, FMT_PS), 8955 OPC_NEG_PS = FOP(7, FMT_PS), 8956 OPC_MOVCF_PS = FOP(17, FMT_PS), 8957 OPC_MOVZ_PS = FOP(18, FMT_PS), 8958 OPC_MOVN_PS = FOP(19, FMT_PS), 8959 OPC_ADDR_PS = FOP(24, FMT_PS), 8960 OPC_MULR_PS = FOP(26, FMT_PS), 8961 OPC_RECIP2_PS = FOP(28, FMT_PS), 8962 OPC_RECIP1_PS = FOP(29, FMT_PS), 8963 OPC_RSQRT1_PS = FOP(30, FMT_PS), 8964 OPC_RSQRT2_PS = FOP(31, FMT_PS), 8965 8966 OPC_CVT_S_PU = FOP(32, FMT_PS), 8967 OPC_CVT_PW_PS = FOP(36, FMT_PS), 8968 OPC_CVT_S_PL = FOP(40, FMT_PS), 8969 OPC_PLL_PS = FOP(44, FMT_PS), 8970 OPC_PLU_PS = FOP(45, FMT_PS), 8971 OPC_PUL_PS = FOP(46, FMT_PS), 8972 OPC_PUU_PS = FOP(47, FMT_PS), 8973 OPC_CMP_F_PS = FOP(48, FMT_PS), 8974 OPC_CMP_UN_PS = FOP(49, FMT_PS), 8975 OPC_CMP_EQ_PS = FOP(50, FMT_PS), 8976 OPC_CMP_UEQ_PS = FOP(51, FMT_PS), 8977 OPC_CMP_OLT_PS = FOP(52, FMT_PS), 8978 OPC_CMP_ULT_PS = FOP(53, FMT_PS), 8979 OPC_CMP_OLE_PS = FOP(54, FMT_PS), 8980 OPC_CMP_ULE_PS = FOP(55, FMT_PS), 8981 OPC_CMP_SF_PS = FOP(56, FMT_PS), 8982 OPC_CMP_NGLE_PS = FOP(57, FMT_PS), 8983 OPC_CMP_SEQ_PS = FOP(58, FMT_PS), 8984 OPC_CMP_NGL_PS = FOP(59, FMT_PS), 8985 OPC_CMP_LT_PS = FOP(60, FMT_PS), 8986 OPC_CMP_NGE_PS = FOP(61, FMT_PS), 8987 OPC_CMP_LE_PS = FOP(62, FMT_PS), 8988 OPC_CMP_NGT_PS = FOP(63, FMT_PS), 8989 }; 8990 8991 enum r6_f_cmp_op { 8992 R6_OPC_CMP_AF_S = FOP(0, FMT_W), 8993 R6_OPC_CMP_UN_S = FOP(1, FMT_W), 8994 R6_OPC_CMP_EQ_S = FOP(2, FMT_W), 8995 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W), 8996 R6_OPC_CMP_LT_S = FOP(4, FMT_W), 8997 R6_OPC_CMP_ULT_S = FOP(5, FMT_W), 8998 R6_OPC_CMP_LE_S = FOP(6, FMT_W), 8999 R6_OPC_CMP_ULE_S = FOP(7, FMT_W), 9000 R6_OPC_CMP_SAF_S = FOP(8, FMT_W), 9001 R6_OPC_CMP_SUN_S = FOP(9, FMT_W), 9002 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W), 9003 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W), 9004 R6_OPC_CMP_SLT_S = FOP(12, FMT_W), 9005 R6_OPC_CMP_SULT_S = FOP(13, FMT_W), 9006 R6_OPC_CMP_SLE_S = FOP(14, FMT_W), 9007 R6_OPC_CMP_SULE_S = FOP(15, FMT_W), 9008 R6_OPC_CMP_OR_S = FOP(17, FMT_W), 9009 R6_OPC_CMP_UNE_S = FOP(18, FMT_W), 9010 R6_OPC_CMP_NE_S = FOP(19, FMT_W), 9011 R6_OPC_CMP_SOR_S = FOP(25, FMT_W), 9012 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W), 9013 R6_OPC_CMP_SNE_S = FOP(27, FMT_W), 9014 9015 R6_OPC_CMP_AF_D = FOP(0, FMT_L), 9016 R6_OPC_CMP_UN_D = FOP(1, FMT_L), 9017 R6_OPC_CMP_EQ_D = FOP(2, FMT_L), 9018 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L), 9019 R6_OPC_CMP_LT_D = FOP(4, FMT_L), 9020 R6_OPC_CMP_ULT_D = FOP(5, FMT_L), 9021 R6_OPC_CMP_LE_D = FOP(6, FMT_L), 9022 R6_OPC_CMP_ULE_D = FOP(7, FMT_L), 9023 R6_OPC_CMP_SAF_D = FOP(8, FMT_L), 9024 R6_OPC_CMP_SUN_D = FOP(9, FMT_L), 9025 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L), 9026 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L), 9027 R6_OPC_CMP_SLT_D = FOP(12, FMT_L), 9028 R6_OPC_CMP_SULT_D = FOP(13, FMT_L), 9029 R6_OPC_CMP_SLE_D = FOP(14, FMT_L), 9030 R6_OPC_CMP_SULE_D = FOP(15, FMT_L), 9031 R6_OPC_CMP_OR_D = FOP(17, FMT_L), 9032 R6_OPC_CMP_UNE_D = FOP(18, FMT_L), 9033 R6_OPC_CMP_NE_D = FOP(19, FMT_L), 9034 R6_OPC_CMP_SOR_D = FOP(25, FMT_L), 9035 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L), 9036 R6_OPC_CMP_SNE_D = FOP(27, FMT_L), 9037 }; 9038 9039 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) 9040 { 9041 TCGv t0 = tcg_temp_new(); 9042 9043 switch (opc) { 9044 case OPC_MFC1: 9045 { 9046 TCGv_i32 fp0 = tcg_temp_new_i32(); 9047 9048 gen_load_fpr32(ctx, fp0, fs); 9049 tcg_gen_ext_i32_tl(t0, fp0); 9050 } 9051 gen_store_gpr(t0, rt); 9052 break; 9053 case OPC_MTC1: 9054 gen_load_gpr(t0, rt); 9055 { 9056 TCGv_i32 fp0 = tcg_temp_new_i32(); 9057 9058 tcg_gen_trunc_tl_i32(fp0, t0); 9059 gen_store_fpr32(ctx, fp0, fs); 9060 } 9061 break; 9062 case OPC_CFC1: 9063 gen_helper_1e0i(cfc1, t0, fs); 9064 gen_store_gpr(t0, rt); 9065 break; 9066 case OPC_CTC1: 9067 gen_load_gpr(t0, rt); 9068 save_cpu_state(ctx, 0); 9069 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt); 9070 /* Stop translation as we may have changed hflags */ 9071 ctx->base.is_jmp = DISAS_STOP; 9072 break; 9073 #if defined(TARGET_MIPS64) 9074 case OPC_DMFC1: 9075 gen_load_fpr64(ctx, t0, fs); 9076 gen_store_gpr(t0, rt); 9077 break; 9078 case OPC_DMTC1: 9079 gen_load_gpr(t0, rt); 9080 gen_store_fpr64(ctx, t0, fs); 9081 break; 9082 #endif 9083 case OPC_MFHC1: 9084 { 9085 TCGv_i32 fp0 = tcg_temp_new_i32(); 9086 9087 gen_load_fpr32h(ctx, fp0, fs); 9088 tcg_gen_ext_i32_tl(t0, fp0); 9089 } 9090 gen_store_gpr(t0, rt); 9091 break; 9092 case OPC_MTHC1: 9093 gen_load_gpr(t0, rt); 9094 { 9095 TCGv_i32 fp0 = tcg_temp_new_i32(); 9096 9097 tcg_gen_trunc_tl_i32(fp0, t0); 9098 gen_store_fpr32h(ctx, fp0, fs); 9099 } 9100 break; 9101 default: 9102 MIPS_INVAL("cp1 move"); 9103 gen_reserved_instruction(ctx); 9104 return; 9105 } 9106 } 9107 9108 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf) 9109 { 9110 TCGLabel *l1; 9111 TCGCond cond; 9112 TCGv_i32 t0; 9113 9114 if (rd == 0) { 9115 /* Treat as NOP. */ 9116 return; 9117 } 9118 9119 if (tf) { 9120 cond = TCG_COND_EQ; 9121 } else { 9122 cond = TCG_COND_NE; 9123 } 9124 9125 l1 = gen_new_label(); 9126 t0 = tcg_temp_new_i32(); 9127 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9128 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9129 gen_load_gpr(cpu_gpr[rd], rs); 9130 gen_set_label(l1); 9131 } 9132 9133 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, 9134 int tf) 9135 { 9136 int cond; 9137 TCGv_i32 t0 = tcg_temp_new_i32(); 9138 TCGLabel *l1 = gen_new_label(); 9139 9140 if (tf) { 9141 cond = TCG_COND_EQ; 9142 } else { 9143 cond = TCG_COND_NE; 9144 } 9145 9146 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9147 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9148 gen_load_fpr32(ctx, t0, fs); 9149 gen_store_fpr32(ctx, t0, fd); 9150 gen_set_label(l1); 9151 } 9152 9153 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, 9154 int tf) 9155 { 9156 int cond; 9157 TCGv_i32 t0 = tcg_temp_new_i32(); 9158 TCGv_i64 fp0; 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 fp0 = tcg_temp_new_i64(); 9170 gen_load_fpr64(ctx, fp0, fs); 9171 gen_store_fpr64(ctx, fp0, fd); 9172 gen_set_label(l1); 9173 } 9174 9175 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, 9176 int cc, int tf) 9177 { 9178 int cond; 9179 TCGv_i32 t0 = tcg_temp_new_i32(); 9180 TCGLabel *l1 = gen_new_label(); 9181 TCGLabel *l2 = gen_new_label(); 9182 9183 if (tf) { 9184 cond = TCG_COND_EQ; 9185 } else { 9186 cond = TCG_COND_NE; 9187 } 9188 9189 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9190 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9191 gen_load_fpr32(ctx, t0, fs); 9192 gen_store_fpr32(ctx, t0, fd); 9193 gen_set_label(l1); 9194 9195 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1)); 9196 tcg_gen_brcondi_i32(cond, t0, 0, l2); 9197 gen_load_fpr32h(ctx, t0, fs); 9198 gen_store_fpr32h(ctx, t0, fd); 9199 gen_set_label(l2); 9200 } 9201 9202 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9203 int fs) 9204 { 9205 TCGv_i32 t1 = tcg_constant_i32(0); 9206 TCGv_i32 fp0 = tcg_temp_new_i32(); 9207 TCGv_i32 fp1 = tcg_temp_new_i32(); 9208 TCGv_i32 fp2 = tcg_temp_new_i32(); 9209 gen_load_fpr32(ctx, fp0, fd); 9210 gen_load_fpr32(ctx, fp1, ft); 9211 gen_load_fpr32(ctx, fp2, fs); 9212 9213 switch (op1) { 9214 case OPC_SEL_S: 9215 tcg_gen_andi_i32(fp0, fp0, 1); 9216 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9217 break; 9218 case OPC_SELEQZ_S: 9219 tcg_gen_andi_i32(fp1, fp1, 1); 9220 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9221 break; 9222 case OPC_SELNEZ_S: 9223 tcg_gen_andi_i32(fp1, fp1, 1); 9224 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9225 break; 9226 default: 9227 MIPS_INVAL("gen_sel_s"); 9228 gen_reserved_instruction(ctx); 9229 break; 9230 } 9231 9232 gen_store_fpr32(ctx, fp0, fd); 9233 } 9234 9235 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9236 int fs) 9237 { 9238 TCGv_i64 t1 = tcg_constant_i64(0); 9239 TCGv_i64 fp0 = tcg_temp_new_i64(); 9240 TCGv_i64 fp1 = tcg_temp_new_i64(); 9241 TCGv_i64 fp2 = tcg_temp_new_i64(); 9242 gen_load_fpr64(ctx, fp0, fd); 9243 gen_load_fpr64(ctx, fp1, ft); 9244 gen_load_fpr64(ctx, fp2, fs); 9245 9246 switch (op1) { 9247 case OPC_SEL_D: 9248 tcg_gen_andi_i64(fp0, fp0, 1); 9249 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9250 break; 9251 case OPC_SELEQZ_D: 9252 tcg_gen_andi_i64(fp1, fp1, 1); 9253 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9254 break; 9255 case OPC_SELNEZ_D: 9256 tcg_gen_andi_i64(fp1, fp1, 1); 9257 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9258 break; 9259 default: 9260 MIPS_INVAL("gen_sel_d"); 9261 gen_reserved_instruction(ctx); 9262 break; 9263 } 9264 9265 gen_store_fpr64(ctx, fp0, fd); 9266 } 9267 9268 static void gen_farith(DisasContext *ctx, enum fopcode op1, 9269 int ft, int fs, int fd, int cc) 9270 { 9271 uint32_t func = ctx->opcode & 0x3f; 9272 switch (op1) { 9273 case OPC_ADD_S: 9274 { 9275 TCGv_i32 fp0 = tcg_temp_new_i32(); 9276 TCGv_i32 fp1 = tcg_temp_new_i32(); 9277 9278 gen_load_fpr32(ctx, fp0, fs); 9279 gen_load_fpr32(ctx, fp1, ft); 9280 gen_helper_float_add_s(fp0, tcg_env, fp0, fp1); 9281 gen_store_fpr32(ctx, fp0, fd); 9282 } 9283 break; 9284 case OPC_SUB_S: 9285 { 9286 TCGv_i32 fp0 = tcg_temp_new_i32(); 9287 TCGv_i32 fp1 = tcg_temp_new_i32(); 9288 9289 gen_load_fpr32(ctx, fp0, fs); 9290 gen_load_fpr32(ctx, fp1, ft); 9291 gen_helper_float_sub_s(fp0, tcg_env, fp0, fp1); 9292 gen_store_fpr32(ctx, fp0, fd); 9293 } 9294 break; 9295 case OPC_MUL_S: 9296 { 9297 TCGv_i32 fp0 = tcg_temp_new_i32(); 9298 TCGv_i32 fp1 = tcg_temp_new_i32(); 9299 9300 gen_load_fpr32(ctx, fp0, fs); 9301 gen_load_fpr32(ctx, fp1, ft); 9302 gen_helper_float_mul_s(fp0, tcg_env, fp0, fp1); 9303 gen_store_fpr32(ctx, fp0, fd); 9304 } 9305 break; 9306 case OPC_DIV_S: 9307 { 9308 TCGv_i32 fp0 = tcg_temp_new_i32(); 9309 TCGv_i32 fp1 = tcg_temp_new_i32(); 9310 9311 gen_load_fpr32(ctx, fp0, fs); 9312 gen_load_fpr32(ctx, fp1, ft); 9313 gen_helper_float_div_s(fp0, tcg_env, fp0, fp1); 9314 gen_store_fpr32(ctx, fp0, fd); 9315 } 9316 break; 9317 case OPC_SQRT_S: 9318 { 9319 TCGv_i32 fp0 = tcg_temp_new_i32(); 9320 9321 gen_load_fpr32(ctx, fp0, fs); 9322 gen_helper_float_sqrt_s(fp0, tcg_env, fp0); 9323 gen_store_fpr32(ctx, fp0, fd); 9324 } 9325 break; 9326 case OPC_ABS_S: 9327 { 9328 TCGv_i32 fp0 = tcg_temp_new_i32(); 9329 9330 gen_load_fpr32(ctx, fp0, fs); 9331 if (ctx->abs2008) { 9332 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL); 9333 } else { 9334 gen_helper_float_abs_s(fp0, fp0); 9335 } 9336 gen_store_fpr32(ctx, fp0, fd); 9337 } 9338 break; 9339 case OPC_MOV_S: 9340 { 9341 TCGv_i32 fp0 = tcg_temp_new_i32(); 9342 9343 gen_load_fpr32(ctx, fp0, fs); 9344 gen_store_fpr32(ctx, fp0, fd); 9345 } 9346 break; 9347 case OPC_NEG_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_xori_i32(fp0, fp0, 1UL << 31); 9354 } else { 9355 gen_helper_float_chs_s(fp0, fp0); 9356 } 9357 gen_store_fpr32(ctx, fp0, fd); 9358 } 9359 break; 9360 case OPC_ROUND_L_S: 9361 check_cp1_64bitmode(ctx); 9362 { 9363 TCGv_i32 fp32 = tcg_temp_new_i32(); 9364 TCGv_i64 fp64 = tcg_temp_new_i64(); 9365 9366 gen_load_fpr32(ctx, fp32, fs); 9367 if (ctx->nan2008) { 9368 gen_helper_float_round_2008_l_s(fp64, tcg_env, fp32); 9369 } else { 9370 gen_helper_float_round_l_s(fp64, tcg_env, fp32); 9371 } 9372 gen_store_fpr64(ctx, fp64, fd); 9373 } 9374 break; 9375 case OPC_TRUNC_L_S: 9376 check_cp1_64bitmode(ctx); 9377 { 9378 TCGv_i32 fp32 = tcg_temp_new_i32(); 9379 TCGv_i64 fp64 = tcg_temp_new_i64(); 9380 9381 gen_load_fpr32(ctx, fp32, fs); 9382 if (ctx->nan2008) { 9383 gen_helper_float_trunc_2008_l_s(fp64, tcg_env, fp32); 9384 } else { 9385 gen_helper_float_trunc_l_s(fp64, tcg_env, fp32); 9386 } 9387 gen_store_fpr64(ctx, fp64, fd); 9388 } 9389 break; 9390 case OPC_CEIL_L_S: 9391 check_cp1_64bitmode(ctx); 9392 { 9393 TCGv_i32 fp32 = tcg_temp_new_i32(); 9394 TCGv_i64 fp64 = tcg_temp_new_i64(); 9395 9396 gen_load_fpr32(ctx, fp32, fs); 9397 if (ctx->nan2008) { 9398 gen_helper_float_ceil_2008_l_s(fp64, tcg_env, fp32); 9399 } else { 9400 gen_helper_float_ceil_l_s(fp64, tcg_env, fp32); 9401 } 9402 gen_store_fpr64(ctx, fp64, fd); 9403 } 9404 break; 9405 case OPC_FLOOR_L_S: 9406 check_cp1_64bitmode(ctx); 9407 { 9408 TCGv_i32 fp32 = tcg_temp_new_i32(); 9409 TCGv_i64 fp64 = tcg_temp_new_i64(); 9410 9411 gen_load_fpr32(ctx, fp32, fs); 9412 if (ctx->nan2008) { 9413 gen_helper_float_floor_2008_l_s(fp64, tcg_env, fp32); 9414 } else { 9415 gen_helper_float_floor_l_s(fp64, tcg_env, fp32); 9416 } 9417 gen_store_fpr64(ctx, fp64, fd); 9418 } 9419 break; 9420 case OPC_ROUND_W_S: 9421 { 9422 TCGv_i32 fp0 = tcg_temp_new_i32(); 9423 9424 gen_load_fpr32(ctx, fp0, fs); 9425 if (ctx->nan2008) { 9426 gen_helper_float_round_2008_w_s(fp0, tcg_env, fp0); 9427 } else { 9428 gen_helper_float_round_w_s(fp0, tcg_env, fp0); 9429 } 9430 gen_store_fpr32(ctx, fp0, fd); 9431 } 9432 break; 9433 case OPC_TRUNC_W_S: 9434 { 9435 TCGv_i32 fp0 = tcg_temp_new_i32(); 9436 9437 gen_load_fpr32(ctx, fp0, fs); 9438 if (ctx->nan2008) { 9439 gen_helper_float_trunc_2008_w_s(fp0, tcg_env, fp0); 9440 } else { 9441 gen_helper_float_trunc_w_s(fp0, tcg_env, fp0); 9442 } 9443 gen_store_fpr32(ctx, fp0, fd); 9444 } 9445 break; 9446 case OPC_CEIL_W_S: 9447 { 9448 TCGv_i32 fp0 = tcg_temp_new_i32(); 9449 9450 gen_load_fpr32(ctx, fp0, fs); 9451 if (ctx->nan2008) { 9452 gen_helper_float_ceil_2008_w_s(fp0, tcg_env, fp0); 9453 } else { 9454 gen_helper_float_ceil_w_s(fp0, tcg_env, fp0); 9455 } 9456 gen_store_fpr32(ctx, fp0, fd); 9457 } 9458 break; 9459 case OPC_FLOOR_W_S: 9460 { 9461 TCGv_i32 fp0 = tcg_temp_new_i32(); 9462 9463 gen_load_fpr32(ctx, fp0, fs); 9464 if (ctx->nan2008) { 9465 gen_helper_float_floor_2008_w_s(fp0, tcg_env, fp0); 9466 } else { 9467 gen_helper_float_floor_w_s(fp0, tcg_env, fp0); 9468 } 9469 gen_store_fpr32(ctx, fp0, fd); 9470 } 9471 break; 9472 case OPC_SEL_S: 9473 check_insn(ctx, ISA_MIPS_R6); 9474 gen_sel_s(ctx, op1, fd, ft, fs); 9475 break; 9476 case OPC_SELEQZ_S: 9477 check_insn(ctx, ISA_MIPS_R6); 9478 gen_sel_s(ctx, op1, fd, ft, fs); 9479 break; 9480 case OPC_SELNEZ_S: 9481 check_insn(ctx, ISA_MIPS_R6); 9482 gen_sel_s(ctx, op1, fd, ft, fs); 9483 break; 9484 case OPC_MOVCF_S: 9485 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9486 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 9487 break; 9488 case OPC_MOVZ_S: 9489 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9490 { 9491 TCGLabel *l1 = gen_new_label(); 9492 TCGv_i32 fp0; 9493 9494 if (ft != 0) { 9495 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 9496 } 9497 fp0 = tcg_temp_new_i32(); 9498 gen_load_fpr32(ctx, fp0, fs); 9499 gen_store_fpr32(ctx, fp0, fd); 9500 gen_set_label(l1); 9501 } 9502 break; 9503 case OPC_MOVN_S: 9504 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9505 { 9506 TCGLabel *l1 = gen_new_label(); 9507 TCGv_i32 fp0; 9508 9509 if (ft != 0) { 9510 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 9511 fp0 = tcg_temp_new_i32(); 9512 gen_load_fpr32(ctx, fp0, fs); 9513 gen_store_fpr32(ctx, fp0, fd); 9514 gen_set_label(l1); 9515 } 9516 } 9517 break; 9518 case OPC_RECIP_S: 9519 { 9520 TCGv_i32 fp0 = tcg_temp_new_i32(); 9521 9522 gen_load_fpr32(ctx, fp0, fs); 9523 gen_helper_float_recip_s(fp0, tcg_env, fp0); 9524 gen_store_fpr32(ctx, fp0, fd); 9525 } 9526 break; 9527 case OPC_RSQRT_S: 9528 { 9529 TCGv_i32 fp0 = tcg_temp_new_i32(); 9530 9531 gen_load_fpr32(ctx, fp0, fs); 9532 gen_helper_float_rsqrt_s(fp0, tcg_env, fp0); 9533 gen_store_fpr32(ctx, fp0, fd); 9534 } 9535 break; 9536 case OPC_MADDF_S: 9537 check_insn(ctx, ISA_MIPS_R6); 9538 { 9539 TCGv_i32 fp0 = tcg_temp_new_i32(); 9540 TCGv_i32 fp1 = tcg_temp_new_i32(); 9541 TCGv_i32 fp2 = tcg_temp_new_i32(); 9542 gen_load_fpr32(ctx, fp0, fs); 9543 gen_load_fpr32(ctx, fp1, ft); 9544 gen_load_fpr32(ctx, fp2, fd); 9545 gen_helper_float_maddf_s(fp2, tcg_env, fp0, fp1, fp2); 9546 gen_store_fpr32(ctx, fp2, fd); 9547 } 9548 break; 9549 case OPC_MSUBF_S: 9550 check_insn(ctx, ISA_MIPS_R6); 9551 { 9552 TCGv_i32 fp0 = tcg_temp_new_i32(); 9553 TCGv_i32 fp1 = tcg_temp_new_i32(); 9554 TCGv_i32 fp2 = tcg_temp_new_i32(); 9555 gen_load_fpr32(ctx, fp0, fs); 9556 gen_load_fpr32(ctx, fp1, ft); 9557 gen_load_fpr32(ctx, fp2, fd); 9558 gen_helper_float_msubf_s(fp2, tcg_env, fp0, fp1, fp2); 9559 gen_store_fpr32(ctx, fp2, fd); 9560 } 9561 break; 9562 case OPC_RINT_S: 9563 check_insn(ctx, ISA_MIPS_R6); 9564 { 9565 TCGv_i32 fp0 = tcg_temp_new_i32(); 9566 gen_load_fpr32(ctx, fp0, fs); 9567 gen_helper_float_rint_s(fp0, tcg_env, fp0); 9568 gen_store_fpr32(ctx, fp0, fd); 9569 } 9570 break; 9571 case OPC_CLASS_S: 9572 check_insn(ctx, ISA_MIPS_R6); 9573 { 9574 TCGv_i32 fp0 = tcg_temp_new_i32(); 9575 gen_load_fpr32(ctx, fp0, fs); 9576 gen_helper_float_class_s(fp0, tcg_env, fp0); 9577 gen_store_fpr32(ctx, fp0, fd); 9578 } 9579 break; 9580 case OPC_MIN_S: /* OPC_RECIP2_S */ 9581 if (ctx->insn_flags & ISA_MIPS_R6) { 9582 /* OPC_MIN_S */ 9583 TCGv_i32 fp0 = tcg_temp_new_i32(); 9584 TCGv_i32 fp1 = tcg_temp_new_i32(); 9585 TCGv_i32 fp2 = tcg_temp_new_i32(); 9586 gen_load_fpr32(ctx, fp0, fs); 9587 gen_load_fpr32(ctx, fp1, ft); 9588 gen_helper_float_min_s(fp2, tcg_env, fp0, fp1); 9589 gen_store_fpr32(ctx, fp2, fd); 9590 } else { 9591 /* OPC_RECIP2_S */ 9592 check_cp1_64bitmode(ctx); 9593 { 9594 TCGv_i32 fp0 = tcg_temp_new_i32(); 9595 TCGv_i32 fp1 = tcg_temp_new_i32(); 9596 9597 gen_load_fpr32(ctx, fp0, fs); 9598 gen_load_fpr32(ctx, fp1, ft); 9599 gen_helper_float_recip2_s(fp0, tcg_env, fp0, fp1); 9600 gen_store_fpr32(ctx, fp0, fd); 9601 } 9602 } 9603 break; 9604 case OPC_MINA_S: /* OPC_RECIP1_S */ 9605 if (ctx->insn_flags & ISA_MIPS_R6) { 9606 /* OPC_MINA_S */ 9607 TCGv_i32 fp0 = tcg_temp_new_i32(); 9608 TCGv_i32 fp1 = tcg_temp_new_i32(); 9609 TCGv_i32 fp2 = tcg_temp_new_i32(); 9610 gen_load_fpr32(ctx, fp0, fs); 9611 gen_load_fpr32(ctx, fp1, ft); 9612 gen_helper_float_mina_s(fp2, tcg_env, fp0, fp1); 9613 gen_store_fpr32(ctx, fp2, fd); 9614 } else { 9615 /* OPC_RECIP1_S */ 9616 check_cp1_64bitmode(ctx); 9617 { 9618 TCGv_i32 fp0 = tcg_temp_new_i32(); 9619 9620 gen_load_fpr32(ctx, fp0, fs); 9621 gen_helper_float_recip1_s(fp0, tcg_env, fp0); 9622 gen_store_fpr32(ctx, fp0, fd); 9623 } 9624 } 9625 break; 9626 case OPC_MAX_S: /* OPC_RSQRT1_S */ 9627 if (ctx->insn_flags & ISA_MIPS_R6) { 9628 /* OPC_MAX_S */ 9629 TCGv_i32 fp0 = tcg_temp_new_i32(); 9630 TCGv_i32 fp1 = tcg_temp_new_i32(); 9631 gen_load_fpr32(ctx, fp0, fs); 9632 gen_load_fpr32(ctx, fp1, ft); 9633 gen_helper_float_max_s(fp1, tcg_env, fp0, fp1); 9634 gen_store_fpr32(ctx, fp1, fd); 9635 } else { 9636 /* OPC_RSQRT1_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_rsqrt1_s(fp0, tcg_env, fp0); 9643 gen_store_fpr32(ctx, fp0, fd); 9644 } 9645 } 9646 break; 9647 case OPC_MAXA_S: /* OPC_RSQRT2_S */ 9648 if (ctx->insn_flags & ISA_MIPS_R6) { 9649 /* OPC_MAXA_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_maxa_s(fp1, tcg_env, fp0, fp1); 9655 gen_store_fpr32(ctx, fp1, fd); 9656 } else { 9657 /* OPC_RSQRT2_S */ 9658 check_cp1_64bitmode(ctx); 9659 { 9660 TCGv_i32 fp0 = tcg_temp_new_i32(); 9661 TCGv_i32 fp1 = tcg_temp_new_i32(); 9662 9663 gen_load_fpr32(ctx, fp0, fs); 9664 gen_load_fpr32(ctx, fp1, ft); 9665 gen_helper_float_rsqrt2_s(fp0, tcg_env, fp0, fp1); 9666 gen_store_fpr32(ctx, fp0, fd); 9667 } 9668 } 9669 break; 9670 case OPC_CVT_D_S: 9671 check_cp1_registers(ctx, fd); 9672 { 9673 TCGv_i32 fp32 = tcg_temp_new_i32(); 9674 TCGv_i64 fp64 = tcg_temp_new_i64(); 9675 9676 gen_load_fpr32(ctx, fp32, fs); 9677 gen_helper_float_cvtd_s(fp64, tcg_env, fp32); 9678 gen_store_fpr64(ctx, fp64, fd); 9679 } 9680 break; 9681 case OPC_CVT_W_S: 9682 { 9683 TCGv_i32 fp0 = tcg_temp_new_i32(); 9684 9685 gen_load_fpr32(ctx, fp0, fs); 9686 if (ctx->nan2008) { 9687 gen_helper_float_cvt_2008_w_s(fp0, tcg_env, fp0); 9688 } else { 9689 gen_helper_float_cvt_w_s(fp0, tcg_env, fp0); 9690 } 9691 gen_store_fpr32(ctx, fp0, fd); 9692 } 9693 break; 9694 case OPC_CVT_L_S: 9695 check_cp1_64bitmode(ctx); 9696 { 9697 TCGv_i32 fp32 = tcg_temp_new_i32(); 9698 TCGv_i64 fp64 = tcg_temp_new_i64(); 9699 9700 gen_load_fpr32(ctx, fp32, fs); 9701 if (ctx->nan2008) { 9702 gen_helper_float_cvt_2008_l_s(fp64, tcg_env, fp32); 9703 } else { 9704 gen_helper_float_cvt_l_s(fp64, tcg_env, fp32); 9705 } 9706 gen_store_fpr64(ctx, fp64, fd); 9707 } 9708 break; 9709 case OPC_CVT_PS_S: 9710 check_ps(ctx); 9711 { 9712 TCGv_i64 fp64 = tcg_temp_new_i64(); 9713 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 9714 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 9715 9716 gen_load_fpr32(ctx, fp32_0, fs); 9717 gen_load_fpr32(ctx, fp32_1, ft); 9718 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); 9719 gen_store_fpr64(ctx, fp64, fd); 9720 } 9721 break; 9722 case OPC_CMP_F_S: 9723 case OPC_CMP_UN_S: 9724 case OPC_CMP_EQ_S: 9725 case OPC_CMP_UEQ_S: 9726 case OPC_CMP_OLT_S: 9727 case OPC_CMP_ULT_S: 9728 case OPC_CMP_OLE_S: 9729 case OPC_CMP_ULE_S: 9730 case OPC_CMP_SF_S: 9731 case OPC_CMP_NGLE_S: 9732 case OPC_CMP_SEQ_S: 9733 case OPC_CMP_NGL_S: 9734 case OPC_CMP_LT_S: 9735 case OPC_CMP_NGE_S: 9736 case OPC_CMP_LE_S: 9737 case OPC_CMP_NGT_S: 9738 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9739 if (ctx->opcode & (1 << 6)) { 9740 gen_cmpabs_s(ctx, func - 48, ft, fs, cc); 9741 } else { 9742 gen_cmp_s(ctx, func - 48, ft, fs, cc); 9743 } 9744 break; 9745 case OPC_ADD_D: 9746 check_cp1_registers(ctx, fs | ft | fd); 9747 { 9748 TCGv_i64 fp0 = tcg_temp_new_i64(); 9749 TCGv_i64 fp1 = tcg_temp_new_i64(); 9750 9751 gen_load_fpr64(ctx, fp0, fs); 9752 gen_load_fpr64(ctx, fp1, ft); 9753 gen_helper_float_add_d(fp0, tcg_env, fp0, fp1); 9754 gen_store_fpr64(ctx, fp0, fd); 9755 } 9756 break; 9757 case OPC_SUB_D: 9758 check_cp1_registers(ctx, fs | ft | fd); 9759 { 9760 TCGv_i64 fp0 = tcg_temp_new_i64(); 9761 TCGv_i64 fp1 = tcg_temp_new_i64(); 9762 9763 gen_load_fpr64(ctx, fp0, fs); 9764 gen_load_fpr64(ctx, fp1, ft); 9765 gen_helper_float_sub_d(fp0, tcg_env, fp0, fp1); 9766 gen_store_fpr64(ctx, fp0, fd); 9767 } 9768 break; 9769 case OPC_MUL_D: 9770 check_cp1_registers(ctx, fs | ft | fd); 9771 { 9772 TCGv_i64 fp0 = tcg_temp_new_i64(); 9773 TCGv_i64 fp1 = tcg_temp_new_i64(); 9774 9775 gen_load_fpr64(ctx, fp0, fs); 9776 gen_load_fpr64(ctx, fp1, ft); 9777 gen_helper_float_mul_d(fp0, tcg_env, fp0, fp1); 9778 gen_store_fpr64(ctx, fp0, fd); 9779 } 9780 break; 9781 case OPC_DIV_D: 9782 check_cp1_registers(ctx, fs | ft | fd); 9783 { 9784 TCGv_i64 fp0 = tcg_temp_new_i64(); 9785 TCGv_i64 fp1 = tcg_temp_new_i64(); 9786 9787 gen_load_fpr64(ctx, fp0, fs); 9788 gen_load_fpr64(ctx, fp1, ft); 9789 gen_helper_float_div_d(fp0, tcg_env, fp0, fp1); 9790 gen_store_fpr64(ctx, fp0, fd); 9791 } 9792 break; 9793 case OPC_SQRT_D: 9794 check_cp1_registers(ctx, fs | fd); 9795 { 9796 TCGv_i64 fp0 = tcg_temp_new_i64(); 9797 9798 gen_load_fpr64(ctx, fp0, fs); 9799 gen_helper_float_sqrt_d(fp0, tcg_env, fp0); 9800 gen_store_fpr64(ctx, fp0, fd); 9801 } 9802 break; 9803 case OPC_ABS_D: 9804 check_cp1_registers(ctx, fs | fd); 9805 { 9806 TCGv_i64 fp0 = tcg_temp_new_i64(); 9807 9808 gen_load_fpr64(ctx, fp0, fs); 9809 if (ctx->abs2008) { 9810 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL); 9811 } else { 9812 gen_helper_float_abs_d(fp0, fp0); 9813 } 9814 gen_store_fpr64(ctx, fp0, fd); 9815 } 9816 break; 9817 case OPC_MOV_D: 9818 check_cp1_registers(ctx, fs | fd); 9819 { 9820 TCGv_i64 fp0 = tcg_temp_new_i64(); 9821 9822 gen_load_fpr64(ctx, fp0, fs); 9823 gen_store_fpr64(ctx, fp0, fd); 9824 } 9825 break; 9826 case OPC_NEG_D: 9827 check_cp1_registers(ctx, fs | fd); 9828 { 9829 TCGv_i64 fp0 = tcg_temp_new_i64(); 9830 9831 gen_load_fpr64(ctx, fp0, fs); 9832 if (ctx->abs2008) { 9833 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63); 9834 } else { 9835 gen_helper_float_chs_d(fp0, fp0); 9836 } 9837 gen_store_fpr64(ctx, fp0, fd); 9838 } 9839 break; 9840 case OPC_ROUND_L_D: 9841 check_cp1_64bitmode(ctx); 9842 { 9843 TCGv_i64 fp0 = tcg_temp_new_i64(); 9844 9845 gen_load_fpr64(ctx, fp0, fs); 9846 if (ctx->nan2008) { 9847 gen_helper_float_round_2008_l_d(fp0, tcg_env, fp0); 9848 } else { 9849 gen_helper_float_round_l_d(fp0, tcg_env, fp0); 9850 } 9851 gen_store_fpr64(ctx, fp0, fd); 9852 } 9853 break; 9854 case OPC_TRUNC_L_D: 9855 check_cp1_64bitmode(ctx); 9856 { 9857 TCGv_i64 fp0 = tcg_temp_new_i64(); 9858 9859 gen_load_fpr64(ctx, fp0, fs); 9860 if (ctx->nan2008) { 9861 gen_helper_float_trunc_2008_l_d(fp0, tcg_env, fp0); 9862 } else { 9863 gen_helper_float_trunc_l_d(fp0, tcg_env, fp0); 9864 } 9865 gen_store_fpr64(ctx, fp0, fd); 9866 } 9867 break; 9868 case OPC_CEIL_L_D: 9869 check_cp1_64bitmode(ctx); 9870 { 9871 TCGv_i64 fp0 = tcg_temp_new_i64(); 9872 9873 gen_load_fpr64(ctx, fp0, fs); 9874 if (ctx->nan2008) { 9875 gen_helper_float_ceil_2008_l_d(fp0, tcg_env, fp0); 9876 } else { 9877 gen_helper_float_ceil_l_d(fp0, tcg_env, fp0); 9878 } 9879 gen_store_fpr64(ctx, fp0, fd); 9880 } 9881 break; 9882 case OPC_FLOOR_L_D: 9883 check_cp1_64bitmode(ctx); 9884 { 9885 TCGv_i64 fp0 = tcg_temp_new_i64(); 9886 9887 gen_load_fpr64(ctx, fp0, fs); 9888 if (ctx->nan2008) { 9889 gen_helper_float_floor_2008_l_d(fp0, tcg_env, fp0); 9890 } else { 9891 gen_helper_float_floor_l_d(fp0, tcg_env, fp0); 9892 } 9893 gen_store_fpr64(ctx, fp0, fd); 9894 } 9895 break; 9896 case OPC_ROUND_W_D: 9897 check_cp1_registers(ctx, fs); 9898 { 9899 TCGv_i32 fp32 = tcg_temp_new_i32(); 9900 TCGv_i64 fp64 = tcg_temp_new_i64(); 9901 9902 gen_load_fpr64(ctx, fp64, fs); 9903 if (ctx->nan2008) { 9904 gen_helper_float_round_2008_w_d(fp32, tcg_env, fp64); 9905 } else { 9906 gen_helper_float_round_w_d(fp32, tcg_env, fp64); 9907 } 9908 gen_store_fpr32(ctx, fp32, fd); 9909 } 9910 break; 9911 case OPC_TRUNC_W_D: 9912 check_cp1_registers(ctx, fs); 9913 { 9914 TCGv_i32 fp32 = tcg_temp_new_i32(); 9915 TCGv_i64 fp64 = tcg_temp_new_i64(); 9916 9917 gen_load_fpr64(ctx, fp64, fs); 9918 if (ctx->nan2008) { 9919 gen_helper_float_trunc_2008_w_d(fp32, tcg_env, fp64); 9920 } else { 9921 gen_helper_float_trunc_w_d(fp32, tcg_env, fp64); 9922 } 9923 gen_store_fpr32(ctx, fp32, fd); 9924 } 9925 break; 9926 case OPC_CEIL_W_D: 9927 check_cp1_registers(ctx, fs); 9928 { 9929 TCGv_i32 fp32 = tcg_temp_new_i32(); 9930 TCGv_i64 fp64 = tcg_temp_new_i64(); 9931 9932 gen_load_fpr64(ctx, fp64, fs); 9933 if (ctx->nan2008) { 9934 gen_helper_float_ceil_2008_w_d(fp32, tcg_env, fp64); 9935 } else { 9936 gen_helper_float_ceil_w_d(fp32, tcg_env, fp64); 9937 } 9938 gen_store_fpr32(ctx, fp32, fd); 9939 } 9940 break; 9941 case OPC_FLOOR_W_D: 9942 check_cp1_registers(ctx, fs); 9943 { 9944 TCGv_i32 fp32 = tcg_temp_new_i32(); 9945 TCGv_i64 fp64 = tcg_temp_new_i64(); 9946 9947 gen_load_fpr64(ctx, fp64, fs); 9948 if (ctx->nan2008) { 9949 gen_helper_float_floor_2008_w_d(fp32, tcg_env, fp64); 9950 } else { 9951 gen_helper_float_floor_w_d(fp32, tcg_env, fp64); 9952 } 9953 gen_store_fpr32(ctx, fp32, fd); 9954 } 9955 break; 9956 case OPC_SEL_D: 9957 check_insn(ctx, ISA_MIPS_R6); 9958 gen_sel_d(ctx, op1, fd, ft, fs); 9959 break; 9960 case OPC_SELEQZ_D: 9961 check_insn(ctx, ISA_MIPS_R6); 9962 gen_sel_d(ctx, op1, fd, ft, fs); 9963 break; 9964 case OPC_SELNEZ_D: 9965 check_insn(ctx, ISA_MIPS_R6); 9966 gen_sel_d(ctx, op1, fd, ft, fs); 9967 break; 9968 case OPC_MOVCF_D: 9969 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9970 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 9971 break; 9972 case OPC_MOVZ_D: 9973 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9974 { 9975 TCGLabel *l1 = gen_new_label(); 9976 TCGv_i64 fp0; 9977 9978 if (ft != 0) { 9979 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 9980 } 9981 fp0 = tcg_temp_new_i64(); 9982 gen_load_fpr64(ctx, fp0, fs); 9983 gen_store_fpr64(ctx, fp0, fd); 9984 gen_set_label(l1); 9985 } 9986 break; 9987 case OPC_MOVN_D: 9988 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9989 { 9990 TCGLabel *l1 = gen_new_label(); 9991 TCGv_i64 fp0; 9992 9993 if (ft != 0) { 9994 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 9995 fp0 = tcg_temp_new_i64(); 9996 gen_load_fpr64(ctx, fp0, fs); 9997 gen_store_fpr64(ctx, fp0, fd); 9998 gen_set_label(l1); 9999 } 10000 } 10001 break; 10002 case OPC_RECIP_D: 10003 check_cp1_registers(ctx, fs | fd); 10004 { 10005 TCGv_i64 fp0 = tcg_temp_new_i64(); 10006 10007 gen_load_fpr64(ctx, fp0, fs); 10008 gen_helper_float_recip_d(fp0, tcg_env, fp0); 10009 gen_store_fpr64(ctx, fp0, fd); 10010 } 10011 break; 10012 case OPC_RSQRT_D: 10013 check_cp1_registers(ctx, fs | fd); 10014 { 10015 TCGv_i64 fp0 = tcg_temp_new_i64(); 10016 10017 gen_load_fpr64(ctx, fp0, fs); 10018 gen_helper_float_rsqrt_d(fp0, tcg_env, fp0); 10019 gen_store_fpr64(ctx, fp0, fd); 10020 } 10021 break; 10022 case OPC_MADDF_D: 10023 check_insn(ctx, ISA_MIPS_R6); 10024 { 10025 TCGv_i64 fp0 = tcg_temp_new_i64(); 10026 TCGv_i64 fp1 = tcg_temp_new_i64(); 10027 TCGv_i64 fp2 = tcg_temp_new_i64(); 10028 gen_load_fpr64(ctx, fp0, fs); 10029 gen_load_fpr64(ctx, fp1, ft); 10030 gen_load_fpr64(ctx, fp2, fd); 10031 gen_helper_float_maddf_d(fp2, tcg_env, fp0, fp1, fp2); 10032 gen_store_fpr64(ctx, fp2, fd); 10033 } 10034 break; 10035 case OPC_MSUBF_D: 10036 check_insn(ctx, ISA_MIPS_R6); 10037 { 10038 TCGv_i64 fp0 = tcg_temp_new_i64(); 10039 TCGv_i64 fp1 = tcg_temp_new_i64(); 10040 TCGv_i64 fp2 = tcg_temp_new_i64(); 10041 gen_load_fpr64(ctx, fp0, fs); 10042 gen_load_fpr64(ctx, fp1, ft); 10043 gen_load_fpr64(ctx, fp2, fd); 10044 gen_helper_float_msubf_d(fp2, tcg_env, fp0, fp1, fp2); 10045 gen_store_fpr64(ctx, fp2, fd); 10046 } 10047 break; 10048 case OPC_RINT_D: 10049 check_insn(ctx, ISA_MIPS_R6); 10050 { 10051 TCGv_i64 fp0 = tcg_temp_new_i64(); 10052 gen_load_fpr64(ctx, fp0, fs); 10053 gen_helper_float_rint_d(fp0, tcg_env, fp0); 10054 gen_store_fpr64(ctx, fp0, fd); 10055 } 10056 break; 10057 case OPC_CLASS_D: 10058 check_insn(ctx, ISA_MIPS_R6); 10059 { 10060 TCGv_i64 fp0 = tcg_temp_new_i64(); 10061 gen_load_fpr64(ctx, fp0, fs); 10062 gen_helper_float_class_d(fp0, tcg_env, fp0); 10063 gen_store_fpr64(ctx, fp0, fd); 10064 } 10065 break; 10066 case OPC_MIN_D: /* OPC_RECIP2_D */ 10067 if (ctx->insn_flags & ISA_MIPS_R6) { 10068 /* OPC_MIN_D */ 10069 TCGv_i64 fp0 = tcg_temp_new_i64(); 10070 TCGv_i64 fp1 = tcg_temp_new_i64(); 10071 gen_load_fpr64(ctx, fp0, fs); 10072 gen_load_fpr64(ctx, fp1, ft); 10073 gen_helper_float_min_d(fp1, tcg_env, fp0, fp1); 10074 gen_store_fpr64(ctx, fp1, fd); 10075 } else { 10076 /* OPC_RECIP2_D */ 10077 check_cp1_64bitmode(ctx); 10078 { 10079 TCGv_i64 fp0 = tcg_temp_new_i64(); 10080 TCGv_i64 fp1 = tcg_temp_new_i64(); 10081 10082 gen_load_fpr64(ctx, fp0, fs); 10083 gen_load_fpr64(ctx, fp1, ft); 10084 gen_helper_float_recip2_d(fp0, tcg_env, fp0, fp1); 10085 gen_store_fpr64(ctx, fp0, fd); 10086 } 10087 } 10088 break; 10089 case OPC_MINA_D: /* OPC_RECIP1_D */ 10090 if (ctx->insn_flags & ISA_MIPS_R6) { 10091 /* OPC_MINA_D */ 10092 TCGv_i64 fp0 = tcg_temp_new_i64(); 10093 TCGv_i64 fp1 = tcg_temp_new_i64(); 10094 gen_load_fpr64(ctx, fp0, fs); 10095 gen_load_fpr64(ctx, fp1, ft); 10096 gen_helper_float_mina_d(fp1, tcg_env, fp0, fp1); 10097 gen_store_fpr64(ctx, fp1, fd); 10098 } else { 10099 /* OPC_RECIP1_D */ 10100 check_cp1_64bitmode(ctx); 10101 { 10102 TCGv_i64 fp0 = tcg_temp_new_i64(); 10103 10104 gen_load_fpr64(ctx, fp0, fs); 10105 gen_helper_float_recip1_d(fp0, tcg_env, fp0); 10106 gen_store_fpr64(ctx, fp0, fd); 10107 } 10108 } 10109 break; 10110 case OPC_MAX_D: /* OPC_RSQRT1_D */ 10111 if (ctx->insn_flags & ISA_MIPS_R6) { 10112 /* OPC_MAX_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_max_d(fp1, tcg_env, fp0, fp1); 10118 gen_store_fpr64(ctx, fp1, fd); 10119 } else { 10120 /* OPC_RSQRT1_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_rsqrt1_d(fp0, tcg_env, fp0); 10127 gen_store_fpr64(ctx, fp0, fd); 10128 } 10129 } 10130 break; 10131 case OPC_MAXA_D: /* OPC_RSQRT2_D */ 10132 if (ctx->insn_flags & ISA_MIPS_R6) { 10133 /* OPC_MAXA_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_maxa_d(fp1, tcg_env, fp0, fp1); 10139 gen_store_fpr64(ctx, fp1, fd); 10140 } else { 10141 /* OPC_RSQRT2_D */ 10142 check_cp1_64bitmode(ctx); 10143 { 10144 TCGv_i64 fp0 = tcg_temp_new_i64(); 10145 TCGv_i64 fp1 = tcg_temp_new_i64(); 10146 10147 gen_load_fpr64(ctx, fp0, fs); 10148 gen_load_fpr64(ctx, fp1, ft); 10149 gen_helper_float_rsqrt2_d(fp0, tcg_env, fp0, fp1); 10150 gen_store_fpr64(ctx, fp0, fd); 10151 } 10152 } 10153 break; 10154 case OPC_CMP_F_D: 10155 case OPC_CMP_UN_D: 10156 case OPC_CMP_EQ_D: 10157 case OPC_CMP_UEQ_D: 10158 case OPC_CMP_OLT_D: 10159 case OPC_CMP_ULT_D: 10160 case OPC_CMP_OLE_D: 10161 case OPC_CMP_ULE_D: 10162 case OPC_CMP_SF_D: 10163 case OPC_CMP_NGLE_D: 10164 case OPC_CMP_SEQ_D: 10165 case OPC_CMP_NGL_D: 10166 case OPC_CMP_LT_D: 10167 case OPC_CMP_NGE_D: 10168 case OPC_CMP_LE_D: 10169 case OPC_CMP_NGT_D: 10170 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10171 if (ctx->opcode & (1 << 6)) { 10172 gen_cmpabs_d(ctx, func - 48, ft, fs, cc); 10173 } else { 10174 gen_cmp_d(ctx, func - 48, ft, fs, cc); 10175 } 10176 break; 10177 case OPC_CVT_S_D: 10178 check_cp1_registers(ctx, fs); 10179 { 10180 TCGv_i32 fp32 = tcg_temp_new_i32(); 10181 TCGv_i64 fp64 = tcg_temp_new_i64(); 10182 10183 gen_load_fpr64(ctx, fp64, fs); 10184 gen_helper_float_cvts_d(fp32, tcg_env, fp64); 10185 gen_store_fpr32(ctx, fp32, fd); 10186 } 10187 break; 10188 case OPC_CVT_W_D: 10189 check_cp1_registers(ctx, fs); 10190 { 10191 TCGv_i32 fp32 = tcg_temp_new_i32(); 10192 TCGv_i64 fp64 = tcg_temp_new_i64(); 10193 10194 gen_load_fpr64(ctx, fp64, fs); 10195 if (ctx->nan2008) { 10196 gen_helper_float_cvt_2008_w_d(fp32, tcg_env, fp64); 10197 } else { 10198 gen_helper_float_cvt_w_d(fp32, tcg_env, fp64); 10199 } 10200 gen_store_fpr32(ctx, fp32, fd); 10201 } 10202 break; 10203 case OPC_CVT_L_D: 10204 check_cp1_64bitmode(ctx); 10205 { 10206 TCGv_i64 fp0 = tcg_temp_new_i64(); 10207 10208 gen_load_fpr64(ctx, fp0, fs); 10209 if (ctx->nan2008) { 10210 gen_helper_float_cvt_2008_l_d(fp0, tcg_env, fp0); 10211 } else { 10212 gen_helper_float_cvt_l_d(fp0, tcg_env, fp0); 10213 } 10214 gen_store_fpr64(ctx, fp0, fd); 10215 } 10216 break; 10217 case OPC_CVT_S_W: 10218 { 10219 TCGv_i32 fp0 = tcg_temp_new_i32(); 10220 10221 gen_load_fpr32(ctx, fp0, fs); 10222 gen_helper_float_cvts_w(fp0, tcg_env, fp0); 10223 gen_store_fpr32(ctx, fp0, fd); 10224 } 10225 break; 10226 case OPC_CVT_D_W: 10227 check_cp1_registers(ctx, fd); 10228 { 10229 TCGv_i32 fp32 = tcg_temp_new_i32(); 10230 TCGv_i64 fp64 = tcg_temp_new_i64(); 10231 10232 gen_load_fpr32(ctx, fp32, fs); 10233 gen_helper_float_cvtd_w(fp64, tcg_env, fp32); 10234 gen_store_fpr64(ctx, fp64, fd); 10235 } 10236 break; 10237 case OPC_CVT_S_L: 10238 check_cp1_64bitmode(ctx); 10239 { 10240 TCGv_i32 fp32 = tcg_temp_new_i32(); 10241 TCGv_i64 fp64 = tcg_temp_new_i64(); 10242 10243 gen_load_fpr64(ctx, fp64, fs); 10244 gen_helper_float_cvts_l(fp32, tcg_env, fp64); 10245 gen_store_fpr32(ctx, fp32, fd); 10246 } 10247 break; 10248 case OPC_CVT_D_L: 10249 check_cp1_64bitmode(ctx); 10250 { 10251 TCGv_i64 fp0 = tcg_temp_new_i64(); 10252 10253 gen_load_fpr64(ctx, fp0, fs); 10254 gen_helper_float_cvtd_l(fp0, tcg_env, fp0); 10255 gen_store_fpr64(ctx, fp0, fd); 10256 } 10257 break; 10258 case OPC_CVT_PS_PW: 10259 check_ps(ctx); 10260 { 10261 TCGv_i64 fp0 = tcg_temp_new_i64(); 10262 10263 gen_load_fpr64(ctx, fp0, fs); 10264 gen_helper_float_cvtps_pw(fp0, tcg_env, fp0); 10265 gen_store_fpr64(ctx, fp0, fd); 10266 } 10267 break; 10268 case OPC_ADD_PS: 10269 check_ps(ctx); 10270 { 10271 TCGv_i64 fp0 = tcg_temp_new_i64(); 10272 TCGv_i64 fp1 = tcg_temp_new_i64(); 10273 10274 gen_load_fpr64(ctx, fp0, fs); 10275 gen_load_fpr64(ctx, fp1, ft); 10276 gen_helper_float_add_ps(fp0, tcg_env, fp0, fp1); 10277 gen_store_fpr64(ctx, fp0, fd); 10278 } 10279 break; 10280 case OPC_SUB_PS: 10281 check_ps(ctx); 10282 { 10283 TCGv_i64 fp0 = tcg_temp_new_i64(); 10284 TCGv_i64 fp1 = tcg_temp_new_i64(); 10285 10286 gen_load_fpr64(ctx, fp0, fs); 10287 gen_load_fpr64(ctx, fp1, ft); 10288 gen_helper_float_sub_ps(fp0, tcg_env, fp0, fp1); 10289 gen_store_fpr64(ctx, fp0, fd); 10290 } 10291 break; 10292 case OPC_MUL_PS: 10293 check_ps(ctx); 10294 { 10295 TCGv_i64 fp0 = tcg_temp_new_i64(); 10296 TCGv_i64 fp1 = tcg_temp_new_i64(); 10297 10298 gen_load_fpr64(ctx, fp0, fs); 10299 gen_load_fpr64(ctx, fp1, ft); 10300 gen_helper_float_mul_ps(fp0, tcg_env, fp0, fp1); 10301 gen_store_fpr64(ctx, fp0, fd); 10302 } 10303 break; 10304 case OPC_ABS_PS: 10305 check_ps(ctx); 10306 { 10307 TCGv_i64 fp0 = tcg_temp_new_i64(); 10308 10309 gen_load_fpr64(ctx, fp0, fs); 10310 gen_helper_float_abs_ps(fp0, fp0); 10311 gen_store_fpr64(ctx, fp0, fd); 10312 } 10313 break; 10314 case OPC_MOV_PS: 10315 check_ps(ctx); 10316 { 10317 TCGv_i64 fp0 = tcg_temp_new_i64(); 10318 10319 gen_load_fpr64(ctx, fp0, fs); 10320 gen_store_fpr64(ctx, fp0, fd); 10321 } 10322 break; 10323 case OPC_NEG_PS: 10324 check_ps(ctx); 10325 { 10326 TCGv_i64 fp0 = tcg_temp_new_i64(); 10327 10328 gen_load_fpr64(ctx, fp0, fs); 10329 gen_helper_float_chs_ps(fp0, fp0); 10330 gen_store_fpr64(ctx, fp0, fd); 10331 } 10332 break; 10333 case OPC_MOVCF_PS: 10334 check_ps(ctx); 10335 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10336 break; 10337 case OPC_MOVZ_PS: 10338 check_ps(ctx); 10339 { 10340 TCGLabel *l1 = gen_new_label(); 10341 TCGv_i64 fp0; 10342 10343 if (ft != 0) { 10344 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10345 } 10346 fp0 = tcg_temp_new_i64(); 10347 gen_load_fpr64(ctx, fp0, fs); 10348 gen_store_fpr64(ctx, fp0, fd); 10349 gen_set_label(l1); 10350 } 10351 break; 10352 case OPC_MOVN_PS: 10353 check_ps(ctx); 10354 { 10355 TCGLabel *l1 = gen_new_label(); 10356 TCGv_i64 fp0; 10357 10358 if (ft != 0) { 10359 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10360 fp0 = tcg_temp_new_i64(); 10361 gen_load_fpr64(ctx, fp0, fs); 10362 gen_store_fpr64(ctx, fp0, fd); 10363 gen_set_label(l1); 10364 } 10365 } 10366 break; 10367 case OPC_ADDR_PS: 10368 check_ps(ctx); 10369 { 10370 TCGv_i64 fp0 = tcg_temp_new_i64(); 10371 TCGv_i64 fp1 = tcg_temp_new_i64(); 10372 10373 gen_load_fpr64(ctx, fp0, ft); 10374 gen_load_fpr64(ctx, fp1, fs); 10375 gen_helper_float_addr_ps(fp0, tcg_env, fp0, fp1); 10376 gen_store_fpr64(ctx, fp0, fd); 10377 } 10378 break; 10379 case OPC_MULR_PS: 10380 check_ps(ctx); 10381 { 10382 TCGv_i64 fp0 = tcg_temp_new_i64(); 10383 TCGv_i64 fp1 = tcg_temp_new_i64(); 10384 10385 gen_load_fpr64(ctx, fp0, ft); 10386 gen_load_fpr64(ctx, fp1, fs); 10387 gen_helper_float_mulr_ps(fp0, tcg_env, fp0, fp1); 10388 gen_store_fpr64(ctx, fp0, fd); 10389 } 10390 break; 10391 case OPC_RECIP2_PS: 10392 check_ps(ctx); 10393 { 10394 TCGv_i64 fp0 = tcg_temp_new_i64(); 10395 TCGv_i64 fp1 = tcg_temp_new_i64(); 10396 10397 gen_load_fpr64(ctx, fp0, fs); 10398 gen_load_fpr64(ctx, fp1, ft); 10399 gen_helper_float_recip2_ps(fp0, tcg_env, fp0, fp1); 10400 gen_store_fpr64(ctx, fp0, fd); 10401 } 10402 break; 10403 case OPC_RECIP1_PS: 10404 check_ps(ctx); 10405 { 10406 TCGv_i64 fp0 = tcg_temp_new_i64(); 10407 10408 gen_load_fpr64(ctx, fp0, fs); 10409 gen_helper_float_recip1_ps(fp0, tcg_env, fp0); 10410 gen_store_fpr64(ctx, fp0, fd); 10411 } 10412 break; 10413 case OPC_RSQRT1_PS: 10414 check_ps(ctx); 10415 { 10416 TCGv_i64 fp0 = tcg_temp_new_i64(); 10417 10418 gen_load_fpr64(ctx, fp0, fs); 10419 gen_helper_float_rsqrt1_ps(fp0, tcg_env, fp0); 10420 gen_store_fpr64(ctx, fp0, fd); 10421 } 10422 break; 10423 case OPC_RSQRT2_PS: 10424 check_ps(ctx); 10425 { 10426 TCGv_i64 fp0 = tcg_temp_new_i64(); 10427 TCGv_i64 fp1 = tcg_temp_new_i64(); 10428 10429 gen_load_fpr64(ctx, fp0, fs); 10430 gen_load_fpr64(ctx, fp1, ft); 10431 gen_helper_float_rsqrt2_ps(fp0, tcg_env, fp0, fp1); 10432 gen_store_fpr64(ctx, fp0, fd); 10433 } 10434 break; 10435 case OPC_CVT_S_PU: 10436 check_cp1_64bitmode(ctx); 10437 { 10438 TCGv_i32 fp0 = tcg_temp_new_i32(); 10439 10440 gen_load_fpr32h(ctx, fp0, fs); 10441 gen_helper_float_cvts_pu(fp0, tcg_env, fp0); 10442 gen_store_fpr32(ctx, fp0, fd); 10443 } 10444 break; 10445 case OPC_CVT_PW_PS: 10446 check_ps(ctx); 10447 { 10448 TCGv_i64 fp0 = tcg_temp_new_i64(); 10449 10450 gen_load_fpr64(ctx, fp0, fs); 10451 gen_helper_float_cvtpw_ps(fp0, tcg_env, fp0); 10452 gen_store_fpr64(ctx, fp0, fd); 10453 } 10454 break; 10455 case OPC_CVT_S_PL: 10456 check_cp1_64bitmode(ctx); 10457 { 10458 TCGv_i32 fp0 = tcg_temp_new_i32(); 10459 10460 gen_load_fpr32(ctx, fp0, fs); 10461 gen_helper_float_cvts_pl(fp0, tcg_env, fp0); 10462 gen_store_fpr32(ctx, fp0, fd); 10463 } 10464 break; 10465 case OPC_PLL_PS: 10466 check_ps(ctx); 10467 { 10468 TCGv_i32 fp0 = tcg_temp_new_i32(); 10469 TCGv_i32 fp1 = tcg_temp_new_i32(); 10470 10471 gen_load_fpr32(ctx, fp0, fs); 10472 gen_load_fpr32(ctx, fp1, ft); 10473 gen_store_fpr32h(ctx, fp0, fd); 10474 gen_store_fpr32(ctx, fp1, fd); 10475 } 10476 break; 10477 case OPC_PLU_PS: 10478 check_ps(ctx); 10479 { 10480 TCGv_i32 fp0 = tcg_temp_new_i32(); 10481 TCGv_i32 fp1 = tcg_temp_new_i32(); 10482 10483 gen_load_fpr32(ctx, fp0, fs); 10484 gen_load_fpr32h(ctx, fp1, ft); 10485 gen_store_fpr32(ctx, fp1, fd); 10486 gen_store_fpr32h(ctx, fp0, fd); 10487 } 10488 break; 10489 case OPC_PUL_PS: 10490 check_ps(ctx); 10491 { 10492 TCGv_i32 fp0 = tcg_temp_new_i32(); 10493 TCGv_i32 fp1 = tcg_temp_new_i32(); 10494 10495 gen_load_fpr32h(ctx, fp0, fs); 10496 gen_load_fpr32(ctx, fp1, ft); 10497 gen_store_fpr32(ctx, fp1, fd); 10498 gen_store_fpr32h(ctx, fp0, fd); 10499 } 10500 break; 10501 case OPC_PUU_PS: 10502 check_ps(ctx); 10503 { 10504 TCGv_i32 fp0 = tcg_temp_new_i32(); 10505 TCGv_i32 fp1 = tcg_temp_new_i32(); 10506 10507 gen_load_fpr32h(ctx, fp0, fs); 10508 gen_load_fpr32h(ctx, fp1, ft); 10509 gen_store_fpr32(ctx, fp1, fd); 10510 gen_store_fpr32h(ctx, fp0, fd); 10511 } 10512 break; 10513 case OPC_CMP_F_PS: 10514 case OPC_CMP_UN_PS: 10515 case OPC_CMP_EQ_PS: 10516 case OPC_CMP_UEQ_PS: 10517 case OPC_CMP_OLT_PS: 10518 case OPC_CMP_ULT_PS: 10519 case OPC_CMP_OLE_PS: 10520 case OPC_CMP_ULE_PS: 10521 case OPC_CMP_SF_PS: 10522 case OPC_CMP_NGLE_PS: 10523 case OPC_CMP_SEQ_PS: 10524 case OPC_CMP_NGL_PS: 10525 case OPC_CMP_LT_PS: 10526 case OPC_CMP_NGE_PS: 10527 case OPC_CMP_LE_PS: 10528 case OPC_CMP_NGT_PS: 10529 if (ctx->opcode & (1 << 6)) { 10530 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc); 10531 } else { 10532 gen_cmp_ps(ctx, func - 48, ft, fs, cc); 10533 } 10534 break; 10535 default: 10536 MIPS_INVAL("farith"); 10537 gen_reserved_instruction(ctx); 10538 return; 10539 } 10540 } 10541 10542 /* Coprocessor 3 (FPU) */ 10543 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, 10544 int fd, int fs, int base, int index) 10545 { 10546 TCGv t0 = tcg_temp_new(); 10547 10548 if (base == 0) { 10549 gen_load_gpr(t0, index); 10550 } else if (index == 0) { 10551 gen_load_gpr(t0, base); 10552 } else { 10553 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); 10554 } 10555 /* 10556 * Don't do NOP if destination is zero: we must perform the actual 10557 * memory access. 10558 */ 10559 switch (opc) { 10560 case OPC_LWXC1: 10561 check_cop1x(ctx); 10562 { 10563 TCGv_i32 fp0 = tcg_temp_new_i32(); 10564 10565 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 10566 tcg_gen_trunc_tl_i32(fp0, t0); 10567 gen_store_fpr32(ctx, fp0, fd); 10568 } 10569 break; 10570 case OPC_LDXC1: 10571 check_cop1x(ctx); 10572 check_cp1_registers(ctx, fd); 10573 { 10574 TCGv_i64 fp0 = tcg_temp_new_i64(); 10575 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10576 gen_store_fpr64(ctx, fp0, fd); 10577 } 10578 break; 10579 case OPC_LUXC1: 10580 check_cp1_64bitmode(ctx); 10581 tcg_gen_andi_tl(t0, t0, ~0x7); 10582 { 10583 TCGv_i64 fp0 = tcg_temp_new_i64(); 10584 10585 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10586 gen_store_fpr64(ctx, fp0, fd); 10587 } 10588 break; 10589 case OPC_SWXC1: 10590 check_cop1x(ctx); 10591 { 10592 TCGv_i32 fp0 = tcg_temp_new_i32(); 10593 gen_load_fpr32(ctx, fp0, fs); 10594 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 10595 } 10596 break; 10597 case OPC_SDXC1: 10598 check_cop1x(ctx); 10599 check_cp1_registers(ctx, fs); 10600 { 10601 TCGv_i64 fp0 = tcg_temp_new_i64(); 10602 gen_load_fpr64(ctx, fp0, fs); 10603 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10604 } 10605 break; 10606 case OPC_SUXC1: 10607 check_cp1_64bitmode(ctx); 10608 tcg_gen_andi_tl(t0, t0, ~0x7); 10609 { 10610 TCGv_i64 fp0 = tcg_temp_new_i64(); 10611 gen_load_fpr64(ctx, fp0, fs); 10612 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10613 } 10614 break; 10615 } 10616 } 10617 10618 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, 10619 int fd, int fr, int fs, int ft) 10620 { 10621 switch (opc) { 10622 case OPC_ALNV_PS: 10623 check_ps(ctx); 10624 { 10625 TCGv t0 = tcg_temp_new(); 10626 TCGv_i32 fp = tcg_temp_new_i32(); 10627 TCGv_i32 fph = tcg_temp_new_i32(); 10628 TCGLabel *l1 = gen_new_label(); 10629 TCGLabel *l2 = gen_new_label(); 10630 10631 gen_load_gpr(t0, fr); 10632 tcg_gen_andi_tl(t0, t0, 0x7); 10633 10634 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 10635 gen_load_fpr32(ctx, fp, fs); 10636 gen_load_fpr32h(ctx, fph, fs); 10637 gen_store_fpr32(ctx, fp, fd); 10638 gen_store_fpr32h(ctx, fph, fd); 10639 tcg_gen_br(l2); 10640 gen_set_label(l1); 10641 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 10642 if (disas_is_bigendian(ctx)) { 10643 gen_load_fpr32(ctx, fp, fs); 10644 gen_load_fpr32h(ctx, fph, ft); 10645 gen_store_fpr32h(ctx, fp, fd); 10646 gen_store_fpr32(ctx, fph, fd); 10647 } else { 10648 gen_load_fpr32h(ctx, fph, fs); 10649 gen_load_fpr32(ctx, fp, ft); 10650 gen_store_fpr32(ctx, fph, fd); 10651 gen_store_fpr32h(ctx, fp, fd); 10652 } 10653 gen_set_label(l2); 10654 } 10655 break; 10656 case OPC_MADD_S: 10657 check_cop1x(ctx); 10658 { 10659 TCGv_i32 fp0 = tcg_temp_new_i32(); 10660 TCGv_i32 fp1 = tcg_temp_new_i32(); 10661 TCGv_i32 fp2 = tcg_temp_new_i32(); 10662 10663 gen_load_fpr32(ctx, fp0, fs); 10664 gen_load_fpr32(ctx, fp1, ft); 10665 gen_load_fpr32(ctx, fp2, fr); 10666 gen_helper_float_madd_s(fp2, tcg_env, fp0, fp1, fp2); 10667 gen_store_fpr32(ctx, fp2, fd); 10668 } 10669 break; 10670 case OPC_MADD_D: 10671 check_cop1x(ctx); 10672 check_cp1_registers(ctx, fd | fs | ft | fr); 10673 { 10674 TCGv_i64 fp0 = tcg_temp_new_i64(); 10675 TCGv_i64 fp1 = tcg_temp_new_i64(); 10676 TCGv_i64 fp2 = tcg_temp_new_i64(); 10677 10678 gen_load_fpr64(ctx, fp0, fs); 10679 gen_load_fpr64(ctx, fp1, ft); 10680 gen_load_fpr64(ctx, fp2, fr); 10681 gen_helper_float_madd_d(fp2, tcg_env, fp0, fp1, fp2); 10682 gen_store_fpr64(ctx, fp2, fd); 10683 } 10684 break; 10685 case OPC_MADD_PS: 10686 check_ps(ctx); 10687 { 10688 TCGv_i64 fp0 = tcg_temp_new_i64(); 10689 TCGv_i64 fp1 = tcg_temp_new_i64(); 10690 TCGv_i64 fp2 = tcg_temp_new_i64(); 10691 10692 gen_load_fpr64(ctx, fp0, fs); 10693 gen_load_fpr64(ctx, fp1, ft); 10694 gen_load_fpr64(ctx, fp2, fr); 10695 gen_helper_float_madd_ps(fp2, tcg_env, fp0, fp1, fp2); 10696 gen_store_fpr64(ctx, fp2, fd); 10697 } 10698 break; 10699 case OPC_MSUB_S: 10700 check_cop1x(ctx); 10701 { 10702 TCGv_i32 fp0 = tcg_temp_new_i32(); 10703 TCGv_i32 fp1 = tcg_temp_new_i32(); 10704 TCGv_i32 fp2 = tcg_temp_new_i32(); 10705 10706 gen_load_fpr32(ctx, fp0, fs); 10707 gen_load_fpr32(ctx, fp1, ft); 10708 gen_load_fpr32(ctx, fp2, fr); 10709 gen_helper_float_msub_s(fp2, tcg_env, fp0, fp1, fp2); 10710 gen_store_fpr32(ctx, fp2, fd); 10711 } 10712 break; 10713 case OPC_MSUB_D: 10714 check_cop1x(ctx); 10715 check_cp1_registers(ctx, fd | fs | ft | fr); 10716 { 10717 TCGv_i64 fp0 = tcg_temp_new_i64(); 10718 TCGv_i64 fp1 = tcg_temp_new_i64(); 10719 TCGv_i64 fp2 = tcg_temp_new_i64(); 10720 10721 gen_load_fpr64(ctx, fp0, fs); 10722 gen_load_fpr64(ctx, fp1, ft); 10723 gen_load_fpr64(ctx, fp2, fr); 10724 gen_helper_float_msub_d(fp2, tcg_env, fp0, fp1, fp2); 10725 gen_store_fpr64(ctx, fp2, fd); 10726 } 10727 break; 10728 case OPC_MSUB_PS: 10729 check_ps(ctx); 10730 { 10731 TCGv_i64 fp0 = tcg_temp_new_i64(); 10732 TCGv_i64 fp1 = tcg_temp_new_i64(); 10733 TCGv_i64 fp2 = tcg_temp_new_i64(); 10734 10735 gen_load_fpr64(ctx, fp0, fs); 10736 gen_load_fpr64(ctx, fp1, ft); 10737 gen_load_fpr64(ctx, fp2, fr); 10738 gen_helper_float_msub_ps(fp2, tcg_env, fp0, fp1, fp2); 10739 gen_store_fpr64(ctx, fp2, fd); 10740 } 10741 break; 10742 case OPC_NMADD_S: 10743 check_cop1x(ctx); 10744 { 10745 TCGv_i32 fp0 = tcg_temp_new_i32(); 10746 TCGv_i32 fp1 = tcg_temp_new_i32(); 10747 TCGv_i32 fp2 = tcg_temp_new_i32(); 10748 10749 gen_load_fpr32(ctx, fp0, fs); 10750 gen_load_fpr32(ctx, fp1, ft); 10751 gen_load_fpr32(ctx, fp2, fr); 10752 gen_helper_float_nmadd_s(fp2, tcg_env, fp0, fp1, fp2); 10753 gen_store_fpr32(ctx, fp2, fd); 10754 } 10755 break; 10756 case OPC_NMADD_D: 10757 check_cop1x(ctx); 10758 check_cp1_registers(ctx, fd | fs | ft | fr); 10759 { 10760 TCGv_i64 fp0 = tcg_temp_new_i64(); 10761 TCGv_i64 fp1 = tcg_temp_new_i64(); 10762 TCGv_i64 fp2 = tcg_temp_new_i64(); 10763 10764 gen_load_fpr64(ctx, fp0, fs); 10765 gen_load_fpr64(ctx, fp1, ft); 10766 gen_load_fpr64(ctx, fp2, fr); 10767 gen_helper_float_nmadd_d(fp2, tcg_env, fp0, fp1, fp2); 10768 gen_store_fpr64(ctx, fp2, fd); 10769 } 10770 break; 10771 case OPC_NMADD_PS: 10772 check_ps(ctx); 10773 { 10774 TCGv_i64 fp0 = tcg_temp_new_i64(); 10775 TCGv_i64 fp1 = tcg_temp_new_i64(); 10776 TCGv_i64 fp2 = tcg_temp_new_i64(); 10777 10778 gen_load_fpr64(ctx, fp0, fs); 10779 gen_load_fpr64(ctx, fp1, ft); 10780 gen_load_fpr64(ctx, fp2, fr); 10781 gen_helper_float_nmadd_ps(fp2, tcg_env, fp0, fp1, fp2); 10782 gen_store_fpr64(ctx, fp2, fd); 10783 } 10784 break; 10785 case OPC_NMSUB_S: 10786 check_cop1x(ctx); 10787 { 10788 TCGv_i32 fp0 = tcg_temp_new_i32(); 10789 TCGv_i32 fp1 = tcg_temp_new_i32(); 10790 TCGv_i32 fp2 = tcg_temp_new_i32(); 10791 10792 gen_load_fpr32(ctx, fp0, fs); 10793 gen_load_fpr32(ctx, fp1, ft); 10794 gen_load_fpr32(ctx, fp2, fr); 10795 gen_helper_float_nmsub_s(fp2, tcg_env, fp0, fp1, fp2); 10796 gen_store_fpr32(ctx, fp2, fd); 10797 } 10798 break; 10799 case OPC_NMSUB_D: 10800 check_cop1x(ctx); 10801 check_cp1_registers(ctx, fd | fs | ft | fr); 10802 { 10803 TCGv_i64 fp0 = tcg_temp_new_i64(); 10804 TCGv_i64 fp1 = tcg_temp_new_i64(); 10805 TCGv_i64 fp2 = tcg_temp_new_i64(); 10806 10807 gen_load_fpr64(ctx, fp0, fs); 10808 gen_load_fpr64(ctx, fp1, ft); 10809 gen_load_fpr64(ctx, fp2, fr); 10810 gen_helper_float_nmsub_d(fp2, tcg_env, fp0, fp1, fp2); 10811 gen_store_fpr64(ctx, fp2, fd); 10812 } 10813 break; 10814 case OPC_NMSUB_PS: 10815 check_ps(ctx); 10816 { 10817 TCGv_i64 fp0 = tcg_temp_new_i64(); 10818 TCGv_i64 fp1 = tcg_temp_new_i64(); 10819 TCGv_i64 fp2 = tcg_temp_new_i64(); 10820 10821 gen_load_fpr64(ctx, fp0, fs); 10822 gen_load_fpr64(ctx, fp1, ft); 10823 gen_load_fpr64(ctx, fp2, fr); 10824 gen_helper_float_nmsub_ps(fp2, tcg_env, fp0, fp1, fp2); 10825 gen_store_fpr64(ctx, fp2, fd); 10826 } 10827 break; 10828 default: 10829 MIPS_INVAL("flt3_arith"); 10830 gen_reserved_instruction(ctx); 10831 return; 10832 } 10833 } 10834 10835 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) 10836 { 10837 TCGv t0; 10838 10839 #if !defined(CONFIG_USER_ONLY) 10840 /* 10841 * The Linux kernel will emulate rdhwr if it's not supported natively. 10842 * Therefore only check the ISA in system mode. 10843 */ 10844 check_insn(ctx, ISA_MIPS_R2); 10845 #endif 10846 t0 = tcg_temp_new(); 10847 10848 switch (rd) { 10849 case 0: 10850 gen_helper_rdhwr_cpunum(t0, tcg_env); 10851 gen_store_gpr(t0, rt); 10852 break; 10853 case 1: 10854 gen_helper_rdhwr_synci_step(t0, tcg_env); 10855 gen_store_gpr(t0, rt); 10856 break; 10857 case 2: 10858 translator_io_start(&ctx->base); 10859 gen_helper_rdhwr_cc(t0, tcg_env); 10860 gen_store_gpr(t0, rt); 10861 /* 10862 * Break the TB to be able to take timer interrupts immediately 10863 * after reading count. DISAS_STOP isn't sufficient, we need to ensure 10864 * we break completely out of translated code. 10865 */ 10866 gen_save_pc(ctx->base.pc_next + 4); 10867 ctx->base.is_jmp = DISAS_EXIT; 10868 break; 10869 case 3: 10870 gen_helper_rdhwr_ccres(t0, tcg_env); 10871 gen_store_gpr(t0, rt); 10872 break; 10873 case 4: 10874 check_insn(ctx, ISA_MIPS_R6); 10875 if (sel != 0) { 10876 /* 10877 * Performance counter registers are not implemented other than 10878 * control register 0. 10879 */ 10880 generate_exception(ctx, EXCP_RI); 10881 } 10882 gen_helper_rdhwr_performance(t0, tcg_env); 10883 gen_store_gpr(t0, rt); 10884 break; 10885 case 5: 10886 check_insn(ctx, ISA_MIPS_R6); 10887 gen_helper_rdhwr_xnp(t0, tcg_env); 10888 gen_store_gpr(t0, rt); 10889 break; 10890 case 29: 10891 #if defined(CONFIG_USER_ONLY) 10892 tcg_gen_ld_tl(t0, tcg_env, 10893 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 10894 gen_store_gpr(t0, rt); 10895 break; 10896 #else 10897 if ((ctx->hflags & MIPS_HFLAG_CP0) || 10898 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) { 10899 tcg_gen_ld_tl(t0, tcg_env, 10900 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 10901 gen_store_gpr(t0, rt); 10902 } else { 10903 gen_reserved_instruction(ctx); 10904 } 10905 break; 10906 #endif 10907 default: /* Invalid */ 10908 MIPS_INVAL("rdhwr"); 10909 gen_reserved_instruction(ctx); 10910 break; 10911 } 10912 } 10913 10914 static inline void clear_branch_hflags(DisasContext *ctx) 10915 { 10916 ctx->hflags &= ~MIPS_HFLAG_BMASK; 10917 if (ctx->base.is_jmp == DISAS_NEXT) { 10918 save_cpu_state(ctx, 0); 10919 } else { 10920 /* 10921 * It is not safe to save ctx->hflags as hflags may be changed 10922 * in execution time by the instruction in delay / forbidden slot. 10923 */ 10924 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK); 10925 } 10926 } 10927 10928 static void gen_branch(DisasContext *ctx, int insn_bytes) 10929 { 10930 if (ctx->hflags & MIPS_HFLAG_BMASK) { 10931 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK; 10932 /* Branches completion */ 10933 clear_branch_hflags(ctx); 10934 ctx->base.is_jmp = DISAS_NORETURN; 10935 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) { 10936 case MIPS_HFLAG_FBNSLOT: 10937 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes); 10938 break; 10939 case MIPS_HFLAG_B: 10940 /* unconditional branch */ 10941 if (proc_hflags & MIPS_HFLAG_BX) { 10942 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16); 10943 } 10944 gen_goto_tb(ctx, 0, ctx->btarget); 10945 break; 10946 case MIPS_HFLAG_BL: 10947 /* blikely taken case */ 10948 gen_goto_tb(ctx, 0, ctx->btarget); 10949 break; 10950 case MIPS_HFLAG_BC: 10951 /* Conditional branch */ 10952 { 10953 TCGLabel *l1 = gen_new_label(); 10954 10955 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 10956 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); 10957 gen_set_label(l1); 10958 gen_goto_tb(ctx, 0, ctx->btarget); 10959 } 10960 break; 10961 case MIPS_HFLAG_BR: 10962 /* unconditional branch to register */ 10963 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) { 10964 TCGv t0 = tcg_temp_new(); 10965 TCGv_i32 t1 = tcg_temp_new_i32(); 10966 10967 tcg_gen_andi_tl(t0, btarget, 0x1); 10968 tcg_gen_trunc_tl_i32(t1, t0); 10969 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16); 10970 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT); 10971 tcg_gen_or_i32(hflags, hflags, t1); 10972 10973 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1); 10974 } else { 10975 tcg_gen_mov_tl(cpu_PC, btarget); 10976 } 10977 tcg_gen_lookup_and_goto_ptr(); 10978 break; 10979 default: 10980 LOG_DISAS("unknown branch 0x%x\n", proc_hflags); 10981 gen_reserved_instruction(ctx); 10982 } 10983 } 10984 } 10985 10986 /* Compact Branches */ 10987 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, 10988 int rs, int rt, int32_t offset) 10989 { 10990 int bcond_compute = 0; 10991 TCGv t0 = tcg_temp_new(); 10992 TCGv t1 = tcg_temp_new(); 10993 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; 10994 10995 if (ctx->hflags & MIPS_HFLAG_BMASK) { 10996 #ifdef MIPS_DEBUG_DISAS 10997 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 10998 VADDR_PRIx "\n", ctx->base.pc_next); 10999 #endif 11000 gen_reserved_instruction(ctx); 11001 return; 11002 } 11003 11004 /* Load needed operands and calculate btarget */ 11005 switch (opc) { 11006 /* compact branch */ 11007 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11008 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11009 gen_load_gpr(t0, rs); 11010 gen_load_gpr(t1, rt); 11011 bcond_compute = 1; 11012 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11013 if (rs <= rt && rs == 0) { 11014 /* OPC_BEQZALC, OPC_BNEZALC */ 11015 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11016 } 11017 break; 11018 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11019 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11020 gen_load_gpr(t0, rs); 11021 gen_load_gpr(t1, rt); 11022 bcond_compute = 1; 11023 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11024 break; 11025 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11026 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11027 if (rs == 0 || rs == rt) { 11028 /* OPC_BLEZALC, OPC_BGEZALC */ 11029 /* OPC_BGTZALC, OPC_BLTZALC */ 11030 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11031 } 11032 gen_load_gpr(t0, rs); 11033 gen_load_gpr(t1, rt); 11034 bcond_compute = 1; 11035 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11036 break; 11037 case OPC_BC: 11038 case OPC_BALC: 11039 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11040 break; 11041 case OPC_BEQZC: 11042 case OPC_BNEZC: 11043 if (rs != 0) { 11044 /* OPC_BEQZC, OPC_BNEZC */ 11045 gen_load_gpr(t0, rs); 11046 bcond_compute = 1; 11047 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11048 } else { 11049 /* OPC_JIC, OPC_JIALC */ 11050 TCGv tbase = tcg_temp_new(); 11051 11052 gen_load_gpr(tbase, rt); 11053 gen_op_addr_addi(ctx, btarget, tbase, offset); 11054 } 11055 break; 11056 default: 11057 MIPS_INVAL("Compact branch/jump"); 11058 gen_reserved_instruction(ctx); 11059 return; 11060 } 11061 11062 if (bcond_compute == 0) { 11063 /* Unconditional compact branch */ 11064 switch (opc) { 11065 case OPC_JIALC: 11066 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11067 /* Fallthrough */ 11068 case OPC_JIC: 11069 ctx->hflags |= MIPS_HFLAG_BR; 11070 break; 11071 case OPC_BALC: 11072 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11073 /* Fallthrough */ 11074 case OPC_BC: 11075 ctx->hflags |= MIPS_HFLAG_B; 11076 break; 11077 default: 11078 MIPS_INVAL("Compact branch/jump"); 11079 gen_reserved_instruction(ctx); 11080 return; 11081 } 11082 11083 /* Generating branch here as compact branches don't have delay slot */ 11084 gen_branch(ctx, 4); 11085 } else { 11086 /* Conditional compact branch */ 11087 TCGLabel *fs = gen_new_label(); 11088 save_cpu_state(ctx, 0); 11089 11090 switch (opc) { 11091 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11092 if (rs == 0 && rt != 0) { 11093 /* OPC_BLEZALC */ 11094 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11095 } else if (rs != 0 && rt != 0 && rs == rt) { 11096 /* OPC_BGEZALC */ 11097 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11098 } else { 11099 /* OPC_BGEUC */ 11100 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 11101 } 11102 break; 11103 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11104 if (rs == 0 && rt != 0) { 11105 /* OPC_BGTZALC */ 11106 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11107 } else if (rs != 0 && rt != 0 && rs == rt) { 11108 /* OPC_BLTZALC */ 11109 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11110 } else { 11111 /* OPC_BLTUC */ 11112 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 11113 } 11114 break; 11115 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11116 if (rs == 0 && rt != 0) { 11117 /* OPC_BLEZC */ 11118 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11119 } else if (rs != 0 && rt != 0 && rs == rt) { 11120 /* OPC_BGEZC */ 11121 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11122 } else { 11123 /* OPC_BGEC */ 11124 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 11125 } 11126 break; 11127 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11128 if (rs == 0 && rt != 0) { 11129 /* OPC_BGTZC */ 11130 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11131 } else if (rs != 0 && rt != 0 && rs == rt) { 11132 /* OPC_BLTZC */ 11133 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11134 } else { 11135 /* OPC_BLTC */ 11136 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 11137 } 11138 break; 11139 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11140 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11141 if (rs >= rt) { 11142 /* OPC_BOVC, OPC_BNVC */ 11143 TCGv t2 = tcg_temp_new(); 11144 TCGv t3 = tcg_temp_new(); 11145 TCGv t4 = tcg_temp_new(); 11146 TCGv input_overflow = tcg_temp_new(); 11147 11148 gen_load_gpr(t0, rs); 11149 gen_load_gpr(t1, rt); 11150 tcg_gen_ext32s_tl(t2, t0); 11151 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0); 11152 tcg_gen_ext32s_tl(t3, t1); 11153 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1); 11154 tcg_gen_or_tl(input_overflow, input_overflow, t4); 11155 11156 tcg_gen_add_tl(t4, t2, t3); 11157 tcg_gen_ext32s_tl(t4, t4); 11158 tcg_gen_xor_tl(t2, t2, t3); 11159 tcg_gen_xor_tl(t3, t4, t3); 11160 tcg_gen_andc_tl(t2, t3, t2); 11161 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0); 11162 tcg_gen_or_tl(t4, t4, input_overflow); 11163 if (opc == OPC_BOVC) { 11164 /* OPC_BOVC */ 11165 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs); 11166 } else { 11167 /* OPC_BNVC */ 11168 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs); 11169 } 11170 } else if (rs < rt && rs == 0) { 11171 /* OPC_BEQZALC, OPC_BNEZALC */ 11172 if (opc == OPC_BEQZALC) { 11173 /* OPC_BEQZALC */ 11174 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs); 11175 } else { 11176 /* OPC_BNEZALC */ 11177 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs); 11178 } 11179 } else { 11180 /* OPC_BEQC, OPC_BNEC */ 11181 if (opc == OPC_BEQC) { 11182 /* OPC_BEQC */ 11183 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); 11184 } else { 11185 /* OPC_BNEC */ 11186 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); 11187 } 11188 } 11189 break; 11190 case OPC_BEQZC: 11191 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 11192 break; 11193 case OPC_BNEZC: 11194 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs); 11195 break; 11196 default: 11197 MIPS_INVAL("Compact conditional branch/jump"); 11198 gen_reserved_instruction(ctx); 11199 return; 11200 } 11201 11202 /* Generating branch here as compact branches don't have delay slot */ 11203 gen_goto_tb(ctx, 1, ctx->btarget); 11204 gen_set_label(fs); 11205 11206 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 11207 } 11208 } 11209 11210 void gen_addiupc(DisasContext *ctx, int rx, int imm, 11211 int is_64_bit, int extended) 11212 { 11213 target_ulong npc; 11214 11215 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { 11216 gen_reserved_instruction(ctx); 11217 return; 11218 } 11219 11220 npc = pc_relative_pc(ctx) + imm; 11221 if (!is_64_bit) { 11222 npc = (int32_t)npc; 11223 } 11224 tcg_gen_movi_tl(cpu_gpr[rx], npc); 11225 } 11226 11227 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, 11228 int16_t offset) 11229 { 11230 TCGv_i32 t0 = tcg_constant_i32(op); 11231 TCGv t1 = tcg_temp_new(); 11232 gen_base_offset_addr(ctx, t1, base, offset); 11233 gen_helper_cache(tcg_env, t1, t0); 11234 } 11235 11236 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code) 11237 { 11238 #ifdef CONFIG_USER_ONLY 11239 return false; 11240 #else 11241 bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM; 11242 return semihosting_enabled(is_user) && sdbbp_code == 1; 11243 #endif 11244 } 11245 11246 void gen_ldxs(DisasContext *ctx, int base, int index, int rd) 11247 { 11248 TCGv t0 = tcg_temp_new(); 11249 TCGv t1 = tcg_temp_new(); 11250 11251 gen_load_gpr(t0, base); 11252 11253 if (index != 0) { 11254 gen_load_gpr(t1, index); 11255 tcg_gen_shli_tl(t1, t1, 2); 11256 gen_op_addr_add(ctx, t0, t1, t0); 11257 } 11258 11259 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 11260 gen_store_gpr(t1, rd); 11261 } 11262 11263 static void gen_sync(int stype) 11264 { 11265 TCGBar tcg_mo = TCG_BAR_SC; 11266 11267 switch (stype) { 11268 case 0x4: /* SYNC_WMB */ 11269 tcg_mo |= TCG_MO_ST_ST; 11270 break; 11271 case 0x10: /* SYNC_MB */ 11272 tcg_mo |= TCG_MO_ALL; 11273 break; 11274 case 0x11: /* SYNC_ACQUIRE */ 11275 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; 11276 break; 11277 case 0x12: /* SYNC_RELEASE */ 11278 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; 11279 break; 11280 case 0x13: /* SYNC_RMB */ 11281 tcg_mo |= TCG_MO_LD_LD; 11282 break; 11283 default: 11284 tcg_mo |= TCG_MO_ALL; 11285 break; 11286 } 11287 11288 tcg_gen_mb(tcg_mo); 11289 } 11290 11291 /* ISA extensions (ASEs) */ 11292 11293 /* MIPS16 extension to MIPS32 */ 11294 #include "mips16e_translate.c.inc" 11295 11296 /* microMIPS extension to MIPS32/MIPS64 */ 11297 11298 /* 11299 * Values for microMIPS fmt field. Variable-width, depending on which 11300 * formats the instruction supports. 11301 */ 11302 enum { 11303 FMT_SD_S = 0, 11304 FMT_SD_D = 1, 11305 11306 FMT_SDPS_S = 0, 11307 FMT_SDPS_D = 1, 11308 FMT_SDPS_PS = 2, 11309 11310 FMT_SWL_S = 0, 11311 FMT_SWL_W = 1, 11312 FMT_SWL_L = 2, 11313 11314 FMT_DWL_D = 0, 11315 FMT_DWL_W = 1, 11316 FMT_DWL_L = 2 11317 }; 11318 11319 #include "micromips_translate.c.inc" 11320 11321 #include "nanomips_translate.c.inc" 11322 11323 /* MIPSDSP functions. */ 11324 11325 /* Indexed load is not for DSP only */ 11326 static void gen_mips_lx(DisasContext *ctx, uint32_t opc, 11327 int rd, int base, int offset) 11328 { 11329 TCGv t0; 11330 11331 if (!(ctx->insn_flags & INSN_OCTEON)) { 11332 check_dsp(ctx); 11333 } 11334 t0 = tcg_temp_new(); 11335 11336 if (base == 0) { 11337 gen_load_gpr(t0, offset); 11338 } else if (offset == 0) { 11339 gen_load_gpr(t0, base); 11340 } else { 11341 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]); 11342 } 11343 11344 switch (opc) { 11345 case OPC_LBUX: 11346 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB); 11347 gen_store_gpr(t0, rd); 11348 break; 11349 case OPC_LHX: 11350 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW); 11351 gen_store_gpr(t0, rd); 11352 break; 11353 case OPC_LWX: 11354 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 11355 gen_store_gpr(t0, rd); 11356 break; 11357 #if defined(TARGET_MIPS64) 11358 case OPC_LDX: 11359 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 11360 gen_store_gpr(t0, rd); 11361 break; 11362 #endif 11363 } 11364 } 11365 11366 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2, 11367 int ret, int v1, int v2) 11368 { 11369 TCGv v1_t; 11370 TCGv v2_t; 11371 11372 if (ret == 0) { 11373 /* Treat as NOP. */ 11374 return; 11375 } 11376 11377 v1_t = tcg_temp_new(); 11378 v2_t = tcg_temp_new(); 11379 11380 gen_load_gpr(v1_t, v1); 11381 gen_load_gpr(v2_t, v2); 11382 11383 switch (op1) { 11384 case OPC_ADDUH_QB_DSP: 11385 check_dsp_r2(ctx); 11386 switch (op2) { 11387 case OPC_ADDUH_QB: 11388 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); 11389 break; 11390 case OPC_ADDUH_R_QB: 11391 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); 11392 break; 11393 case OPC_ADDQH_PH: 11394 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); 11395 break; 11396 case OPC_ADDQH_R_PH: 11397 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 11398 break; 11399 case OPC_ADDQH_W: 11400 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); 11401 break; 11402 case OPC_ADDQH_R_W: 11403 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); 11404 break; 11405 case OPC_SUBUH_QB: 11406 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); 11407 break; 11408 case OPC_SUBUH_R_QB: 11409 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); 11410 break; 11411 case OPC_SUBQH_PH: 11412 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); 11413 break; 11414 case OPC_SUBQH_R_PH: 11415 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 11416 break; 11417 case OPC_SUBQH_W: 11418 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); 11419 break; 11420 case OPC_SUBQH_R_W: 11421 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); 11422 break; 11423 } 11424 break; 11425 case OPC_ABSQ_S_PH_DSP: 11426 switch (op2) { 11427 case OPC_ABSQ_S_QB: 11428 check_dsp_r2(ctx); 11429 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, tcg_env); 11430 break; 11431 case OPC_ABSQ_S_PH: 11432 check_dsp(ctx); 11433 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, tcg_env); 11434 break; 11435 case OPC_ABSQ_S_W: 11436 check_dsp(ctx); 11437 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, tcg_env); 11438 break; 11439 case OPC_PRECEQ_W_PHL: 11440 check_dsp(ctx); 11441 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); 11442 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 11443 break; 11444 case OPC_PRECEQ_W_PHR: 11445 check_dsp(ctx); 11446 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); 11447 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); 11448 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 11449 break; 11450 case OPC_PRECEQU_PH_QBL: 11451 check_dsp(ctx); 11452 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); 11453 break; 11454 case OPC_PRECEQU_PH_QBR: 11455 check_dsp(ctx); 11456 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); 11457 break; 11458 case OPC_PRECEQU_PH_QBLA: 11459 check_dsp(ctx); 11460 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); 11461 break; 11462 case OPC_PRECEQU_PH_QBRA: 11463 check_dsp(ctx); 11464 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); 11465 break; 11466 case OPC_PRECEU_PH_QBL: 11467 check_dsp(ctx); 11468 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); 11469 break; 11470 case OPC_PRECEU_PH_QBR: 11471 check_dsp(ctx); 11472 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); 11473 break; 11474 case OPC_PRECEU_PH_QBLA: 11475 check_dsp(ctx); 11476 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); 11477 break; 11478 case OPC_PRECEU_PH_QBRA: 11479 check_dsp(ctx); 11480 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); 11481 break; 11482 } 11483 break; 11484 case OPC_ADDU_QB_DSP: 11485 switch (op2) { 11486 case OPC_ADDQ_PH: 11487 check_dsp(ctx); 11488 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11489 break; 11490 case OPC_ADDQ_S_PH: 11491 check_dsp(ctx); 11492 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11493 break; 11494 case OPC_ADDQ_S_W: 11495 check_dsp(ctx); 11496 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11497 break; 11498 case OPC_ADDU_QB: 11499 check_dsp(ctx); 11500 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11501 break; 11502 case OPC_ADDU_S_QB: 11503 check_dsp(ctx); 11504 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11505 break; 11506 case OPC_ADDU_PH: 11507 check_dsp_r2(ctx); 11508 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11509 break; 11510 case OPC_ADDU_S_PH: 11511 check_dsp_r2(ctx); 11512 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11513 break; 11514 case OPC_SUBQ_PH: 11515 check_dsp(ctx); 11516 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11517 break; 11518 case OPC_SUBQ_S_PH: 11519 check_dsp(ctx); 11520 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11521 break; 11522 case OPC_SUBQ_S_W: 11523 check_dsp(ctx); 11524 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11525 break; 11526 case OPC_SUBU_QB: 11527 check_dsp(ctx); 11528 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11529 break; 11530 case OPC_SUBU_S_QB: 11531 check_dsp(ctx); 11532 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11533 break; 11534 case OPC_SUBU_PH: 11535 check_dsp_r2(ctx); 11536 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11537 break; 11538 case OPC_SUBU_S_PH: 11539 check_dsp_r2(ctx); 11540 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11541 break; 11542 case OPC_ADDSC: 11543 check_dsp(ctx); 11544 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11545 break; 11546 case OPC_ADDWC: 11547 check_dsp(ctx); 11548 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11549 break; 11550 case OPC_MODSUB: 11551 check_dsp(ctx); 11552 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); 11553 break; 11554 case OPC_RADDU_W_QB: 11555 check_dsp(ctx); 11556 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); 11557 break; 11558 } 11559 break; 11560 case OPC_CMPU_EQ_QB_DSP: 11561 switch (op2) { 11562 case OPC_PRECR_QB_PH: 11563 check_dsp_r2(ctx); 11564 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); 11565 break; 11566 case OPC_PRECRQ_QB_PH: 11567 check_dsp(ctx); 11568 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); 11569 break; 11570 case OPC_PRECR_SRA_PH_W: 11571 check_dsp_r2(ctx); 11572 { 11573 TCGv_i32 sa_t = tcg_constant_i32(v2); 11574 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, 11575 cpu_gpr[ret]); 11576 break; 11577 } 11578 case OPC_PRECR_SRA_R_PH_W: 11579 check_dsp_r2(ctx); 11580 { 11581 TCGv_i32 sa_t = tcg_constant_i32(v2); 11582 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, 11583 cpu_gpr[ret]); 11584 break; 11585 } 11586 case OPC_PRECRQ_PH_W: 11587 check_dsp(ctx); 11588 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); 11589 break; 11590 case OPC_PRECRQ_RS_PH_W: 11591 check_dsp(ctx); 11592 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11593 break; 11594 case OPC_PRECRQU_S_QB_PH: 11595 check_dsp(ctx); 11596 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11597 break; 11598 } 11599 break; 11600 #ifdef TARGET_MIPS64 11601 case OPC_ABSQ_S_QH_DSP: 11602 switch (op2) { 11603 case OPC_PRECEQ_L_PWL: 11604 check_dsp(ctx); 11605 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); 11606 break; 11607 case OPC_PRECEQ_L_PWR: 11608 check_dsp(ctx); 11609 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); 11610 break; 11611 case OPC_PRECEQ_PW_QHL: 11612 check_dsp(ctx); 11613 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); 11614 break; 11615 case OPC_PRECEQ_PW_QHR: 11616 check_dsp(ctx); 11617 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); 11618 break; 11619 case OPC_PRECEQ_PW_QHLA: 11620 check_dsp(ctx); 11621 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); 11622 break; 11623 case OPC_PRECEQ_PW_QHRA: 11624 check_dsp(ctx); 11625 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); 11626 break; 11627 case OPC_PRECEQU_QH_OBL: 11628 check_dsp(ctx); 11629 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); 11630 break; 11631 case OPC_PRECEQU_QH_OBR: 11632 check_dsp(ctx); 11633 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); 11634 break; 11635 case OPC_PRECEQU_QH_OBLA: 11636 check_dsp(ctx); 11637 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); 11638 break; 11639 case OPC_PRECEQU_QH_OBRA: 11640 check_dsp(ctx); 11641 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); 11642 break; 11643 case OPC_PRECEU_QH_OBL: 11644 check_dsp(ctx); 11645 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); 11646 break; 11647 case OPC_PRECEU_QH_OBR: 11648 check_dsp(ctx); 11649 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); 11650 break; 11651 case OPC_PRECEU_QH_OBLA: 11652 check_dsp(ctx); 11653 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); 11654 break; 11655 case OPC_PRECEU_QH_OBRA: 11656 check_dsp(ctx); 11657 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); 11658 break; 11659 case OPC_ABSQ_S_OB: 11660 check_dsp_r2(ctx); 11661 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, tcg_env); 11662 break; 11663 case OPC_ABSQ_S_PW: 11664 check_dsp(ctx); 11665 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, tcg_env); 11666 break; 11667 case OPC_ABSQ_S_QH: 11668 check_dsp(ctx); 11669 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, tcg_env); 11670 break; 11671 } 11672 break; 11673 case OPC_ADDU_OB_DSP: 11674 switch (op2) { 11675 case OPC_RADDU_L_OB: 11676 check_dsp(ctx); 11677 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); 11678 break; 11679 case OPC_SUBQ_PW: 11680 check_dsp(ctx); 11681 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11682 break; 11683 case OPC_SUBQ_S_PW: 11684 check_dsp(ctx); 11685 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11686 break; 11687 case OPC_SUBQ_QH: 11688 check_dsp(ctx); 11689 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11690 break; 11691 case OPC_SUBQ_S_QH: 11692 check_dsp(ctx); 11693 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11694 break; 11695 case OPC_SUBU_OB: 11696 check_dsp(ctx); 11697 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11698 break; 11699 case OPC_SUBU_S_OB: 11700 check_dsp(ctx); 11701 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11702 break; 11703 case OPC_SUBU_QH: 11704 check_dsp_r2(ctx); 11705 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11706 break; 11707 case OPC_SUBU_S_QH: 11708 check_dsp_r2(ctx); 11709 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11710 break; 11711 case OPC_SUBUH_OB: 11712 check_dsp_r2(ctx); 11713 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); 11714 break; 11715 case OPC_SUBUH_R_OB: 11716 check_dsp_r2(ctx); 11717 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); 11718 break; 11719 case OPC_ADDQ_PW: 11720 check_dsp(ctx); 11721 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11722 break; 11723 case OPC_ADDQ_S_PW: 11724 check_dsp(ctx); 11725 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11726 break; 11727 case OPC_ADDQ_QH: 11728 check_dsp(ctx); 11729 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11730 break; 11731 case OPC_ADDQ_S_QH: 11732 check_dsp(ctx); 11733 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11734 break; 11735 case OPC_ADDU_OB: 11736 check_dsp(ctx); 11737 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11738 break; 11739 case OPC_ADDU_S_OB: 11740 check_dsp(ctx); 11741 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11742 break; 11743 case OPC_ADDU_QH: 11744 check_dsp_r2(ctx); 11745 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11746 break; 11747 case OPC_ADDU_S_QH: 11748 check_dsp_r2(ctx); 11749 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11750 break; 11751 case OPC_ADDUH_OB: 11752 check_dsp_r2(ctx); 11753 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); 11754 break; 11755 case OPC_ADDUH_R_OB: 11756 check_dsp_r2(ctx); 11757 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); 11758 break; 11759 } 11760 break; 11761 case OPC_CMPU_EQ_OB_DSP: 11762 switch (op2) { 11763 case OPC_PRECR_OB_QH: 11764 check_dsp_r2(ctx); 11765 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); 11766 break; 11767 case OPC_PRECR_SRA_QH_PW: 11768 check_dsp_r2(ctx); 11769 { 11770 TCGv_i32 ret_t = tcg_constant_i32(ret); 11771 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); 11772 break; 11773 } 11774 case OPC_PRECR_SRA_R_QH_PW: 11775 check_dsp_r2(ctx); 11776 { 11777 TCGv_i32 sa_v = tcg_constant_i32(ret); 11778 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); 11779 break; 11780 } 11781 case OPC_PRECRQ_OB_QH: 11782 check_dsp(ctx); 11783 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); 11784 break; 11785 case OPC_PRECRQ_PW_L: 11786 check_dsp(ctx); 11787 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); 11788 break; 11789 case OPC_PRECRQ_QH_PW: 11790 check_dsp(ctx); 11791 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); 11792 break; 11793 case OPC_PRECRQ_RS_QH_PW: 11794 check_dsp(ctx); 11795 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11796 break; 11797 case OPC_PRECRQU_S_OB_QH: 11798 check_dsp(ctx); 11799 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11800 break; 11801 } 11802 break; 11803 #endif 11804 } 11805 } 11806 11807 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, 11808 int ret, int v1, int v2) 11809 { 11810 uint32_t op2; 11811 TCGv t0; 11812 TCGv v1_t; 11813 TCGv v2_t; 11814 11815 if (ret == 0) { 11816 /* Treat as NOP. */ 11817 return; 11818 } 11819 11820 t0 = tcg_temp_new(); 11821 v1_t = tcg_temp_new(); 11822 v2_t = tcg_temp_new(); 11823 11824 tcg_gen_movi_tl(t0, v1); 11825 gen_load_gpr(v1_t, v1); 11826 gen_load_gpr(v2_t, v2); 11827 11828 switch (opc) { 11829 case OPC_SHLL_QB_DSP: 11830 { 11831 op2 = MASK_SHLL_QB(ctx->opcode); 11832 switch (op2) { 11833 case OPC_SHLL_QB: 11834 check_dsp(ctx); 11835 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, tcg_env); 11836 break; 11837 case OPC_SHLLV_QB: 11838 check_dsp(ctx); 11839 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11840 break; 11841 case OPC_SHLL_PH: 11842 check_dsp(ctx); 11843 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, tcg_env); 11844 break; 11845 case OPC_SHLLV_PH: 11846 check_dsp(ctx); 11847 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11848 break; 11849 case OPC_SHLL_S_PH: 11850 check_dsp(ctx); 11851 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, tcg_env); 11852 break; 11853 case OPC_SHLLV_S_PH: 11854 check_dsp(ctx); 11855 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11856 break; 11857 case OPC_SHLL_S_W: 11858 check_dsp(ctx); 11859 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, tcg_env); 11860 break; 11861 case OPC_SHLLV_S_W: 11862 check_dsp(ctx); 11863 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11864 break; 11865 case OPC_SHRL_QB: 11866 check_dsp(ctx); 11867 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); 11868 break; 11869 case OPC_SHRLV_QB: 11870 check_dsp(ctx); 11871 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); 11872 break; 11873 case OPC_SHRL_PH: 11874 check_dsp_r2(ctx); 11875 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); 11876 break; 11877 case OPC_SHRLV_PH: 11878 check_dsp_r2(ctx); 11879 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); 11880 break; 11881 case OPC_SHRA_QB: 11882 check_dsp_r2(ctx); 11883 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); 11884 break; 11885 case OPC_SHRA_R_QB: 11886 check_dsp_r2(ctx); 11887 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); 11888 break; 11889 case OPC_SHRAV_QB: 11890 check_dsp_r2(ctx); 11891 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); 11892 break; 11893 case OPC_SHRAV_R_QB: 11894 check_dsp_r2(ctx); 11895 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); 11896 break; 11897 case OPC_SHRA_PH: 11898 check_dsp(ctx); 11899 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); 11900 break; 11901 case OPC_SHRA_R_PH: 11902 check_dsp(ctx); 11903 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); 11904 break; 11905 case OPC_SHRAV_PH: 11906 check_dsp(ctx); 11907 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); 11908 break; 11909 case OPC_SHRAV_R_PH: 11910 check_dsp(ctx); 11911 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); 11912 break; 11913 case OPC_SHRA_R_W: 11914 check_dsp(ctx); 11915 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); 11916 break; 11917 case OPC_SHRAV_R_W: 11918 check_dsp(ctx); 11919 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); 11920 break; 11921 default: /* Invalid */ 11922 MIPS_INVAL("MASK SHLL.QB"); 11923 gen_reserved_instruction(ctx); 11924 break; 11925 } 11926 break; 11927 } 11928 #ifdef TARGET_MIPS64 11929 case OPC_SHLL_OB_DSP: 11930 op2 = MASK_SHLL_OB(ctx->opcode); 11931 switch (op2) { 11932 case OPC_SHLL_PW: 11933 check_dsp(ctx); 11934 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, tcg_env); 11935 break; 11936 case OPC_SHLLV_PW: 11937 check_dsp(ctx); 11938 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11939 break; 11940 case OPC_SHLL_S_PW: 11941 check_dsp(ctx); 11942 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, tcg_env); 11943 break; 11944 case OPC_SHLLV_S_PW: 11945 check_dsp(ctx); 11946 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11947 break; 11948 case OPC_SHLL_OB: 11949 check_dsp(ctx); 11950 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, tcg_env); 11951 break; 11952 case OPC_SHLLV_OB: 11953 check_dsp(ctx); 11954 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11955 break; 11956 case OPC_SHLL_QH: 11957 check_dsp(ctx); 11958 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, tcg_env); 11959 break; 11960 case OPC_SHLLV_QH: 11961 check_dsp(ctx); 11962 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11963 break; 11964 case OPC_SHLL_S_QH: 11965 check_dsp(ctx); 11966 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, tcg_env); 11967 break; 11968 case OPC_SHLLV_S_QH: 11969 check_dsp(ctx); 11970 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11971 break; 11972 case OPC_SHRA_OB: 11973 check_dsp_r2(ctx); 11974 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); 11975 break; 11976 case OPC_SHRAV_OB: 11977 check_dsp_r2(ctx); 11978 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); 11979 break; 11980 case OPC_SHRA_R_OB: 11981 check_dsp_r2(ctx); 11982 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); 11983 break; 11984 case OPC_SHRAV_R_OB: 11985 check_dsp_r2(ctx); 11986 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); 11987 break; 11988 case OPC_SHRA_PW: 11989 check_dsp(ctx); 11990 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); 11991 break; 11992 case OPC_SHRAV_PW: 11993 check_dsp(ctx); 11994 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); 11995 break; 11996 case OPC_SHRA_R_PW: 11997 check_dsp(ctx); 11998 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); 11999 break; 12000 case OPC_SHRAV_R_PW: 12001 check_dsp(ctx); 12002 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); 12003 break; 12004 case OPC_SHRA_QH: 12005 check_dsp(ctx); 12006 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); 12007 break; 12008 case OPC_SHRAV_QH: 12009 check_dsp(ctx); 12010 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); 12011 break; 12012 case OPC_SHRA_R_QH: 12013 check_dsp(ctx); 12014 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); 12015 break; 12016 case OPC_SHRAV_R_QH: 12017 check_dsp(ctx); 12018 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); 12019 break; 12020 case OPC_SHRL_OB: 12021 check_dsp(ctx); 12022 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); 12023 break; 12024 case OPC_SHRLV_OB: 12025 check_dsp(ctx); 12026 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); 12027 break; 12028 case OPC_SHRL_QH: 12029 check_dsp_r2(ctx); 12030 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); 12031 break; 12032 case OPC_SHRLV_QH: 12033 check_dsp_r2(ctx); 12034 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); 12035 break; 12036 default: /* Invalid */ 12037 MIPS_INVAL("MASK SHLL.OB"); 12038 gen_reserved_instruction(ctx); 12039 break; 12040 } 12041 break; 12042 #endif 12043 } 12044 } 12045 12046 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2, 12047 int ret, int v1, int v2, int check_ret) 12048 { 12049 TCGv_i32 t0; 12050 TCGv v1_t; 12051 TCGv v2_t; 12052 12053 if ((ret == 0) && (check_ret == 1)) { 12054 /* Treat as NOP. */ 12055 return; 12056 } 12057 12058 t0 = tcg_temp_new_i32(); 12059 v1_t = tcg_temp_new(); 12060 v2_t = tcg_temp_new(); 12061 12062 tcg_gen_movi_i32(t0, ret); 12063 gen_load_gpr(v1_t, v1); 12064 gen_load_gpr(v2_t, v2); 12065 12066 switch (op1) { 12067 case OPC_MUL_PH_DSP: 12068 check_dsp_r2(ctx); 12069 switch (op2) { 12070 case OPC_MUL_PH: 12071 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12072 break; 12073 case OPC_MUL_S_PH: 12074 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12075 break; 12076 case OPC_MULQ_S_W: 12077 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12078 break; 12079 case OPC_MULQ_RS_W: 12080 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12081 break; 12082 } 12083 break; 12084 case OPC_DPA_W_PH_DSP: 12085 switch (op2) { 12086 case OPC_DPAU_H_QBL: 12087 check_dsp(ctx); 12088 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, tcg_env); 12089 break; 12090 case OPC_DPAU_H_QBR: 12091 check_dsp(ctx); 12092 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, tcg_env); 12093 break; 12094 case OPC_DPSU_H_QBL: 12095 check_dsp(ctx); 12096 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, tcg_env); 12097 break; 12098 case OPC_DPSU_H_QBR: 12099 check_dsp(ctx); 12100 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, tcg_env); 12101 break; 12102 case OPC_DPA_W_PH: 12103 check_dsp_r2(ctx); 12104 gen_helper_dpa_w_ph(t0, v1_t, v2_t, tcg_env); 12105 break; 12106 case OPC_DPAX_W_PH: 12107 check_dsp_r2(ctx); 12108 gen_helper_dpax_w_ph(t0, v1_t, v2_t, tcg_env); 12109 break; 12110 case OPC_DPAQ_S_W_PH: 12111 check_dsp(ctx); 12112 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12113 break; 12114 case OPC_DPAQX_S_W_PH: 12115 check_dsp_r2(ctx); 12116 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, tcg_env); 12117 break; 12118 case OPC_DPAQX_SA_W_PH: 12119 check_dsp_r2(ctx); 12120 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, tcg_env); 12121 break; 12122 case OPC_DPS_W_PH: 12123 check_dsp_r2(ctx); 12124 gen_helper_dps_w_ph(t0, v1_t, v2_t, tcg_env); 12125 break; 12126 case OPC_DPSX_W_PH: 12127 check_dsp_r2(ctx); 12128 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, tcg_env); 12129 break; 12130 case OPC_DPSQ_S_W_PH: 12131 check_dsp(ctx); 12132 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12133 break; 12134 case OPC_DPSQX_S_W_PH: 12135 check_dsp_r2(ctx); 12136 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, tcg_env); 12137 break; 12138 case OPC_DPSQX_SA_W_PH: 12139 check_dsp_r2(ctx); 12140 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, tcg_env); 12141 break; 12142 case OPC_MULSAQ_S_W_PH: 12143 check_dsp(ctx); 12144 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12145 break; 12146 case OPC_DPAQ_SA_L_W: 12147 check_dsp(ctx); 12148 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, tcg_env); 12149 break; 12150 case OPC_DPSQ_SA_L_W: 12151 check_dsp(ctx); 12152 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, tcg_env); 12153 break; 12154 case OPC_MAQ_S_W_PHL: 12155 check_dsp(ctx); 12156 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, tcg_env); 12157 break; 12158 case OPC_MAQ_S_W_PHR: 12159 check_dsp(ctx); 12160 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, tcg_env); 12161 break; 12162 case OPC_MAQ_SA_W_PHL: 12163 check_dsp(ctx); 12164 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, tcg_env); 12165 break; 12166 case OPC_MAQ_SA_W_PHR: 12167 check_dsp(ctx); 12168 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, tcg_env); 12169 break; 12170 case OPC_MULSA_W_PH: 12171 check_dsp_r2(ctx); 12172 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, tcg_env); 12173 break; 12174 } 12175 break; 12176 #ifdef TARGET_MIPS64 12177 case OPC_DPAQ_W_QH_DSP: 12178 { 12179 int ac = ret & 0x03; 12180 tcg_gen_movi_i32(t0, ac); 12181 12182 switch (op2) { 12183 case OPC_DMADD: 12184 check_dsp(ctx); 12185 gen_helper_dmadd(v1_t, v2_t, t0, tcg_env); 12186 break; 12187 case OPC_DMADDU: 12188 check_dsp(ctx); 12189 gen_helper_dmaddu(v1_t, v2_t, t0, tcg_env); 12190 break; 12191 case OPC_DMSUB: 12192 check_dsp(ctx); 12193 gen_helper_dmsub(v1_t, v2_t, t0, tcg_env); 12194 break; 12195 case OPC_DMSUBU: 12196 check_dsp(ctx); 12197 gen_helper_dmsubu(v1_t, v2_t, t0, tcg_env); 12198 break; 12199 case OPC_DPA_W_QH: 12200 check_dsp_r2(ctx); 12201 gen_helper_dpa_w_qh(v1_t, v2_t, t0, tcg_env); 12202 break; 12203 case OPC_DPAQ_S_W_QH: 12204 check_dsp(ctx); 12205 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12206 break; 12207 case OPC_DPAQ_SA_L_PW: 12208 check_dsp(ctx); 12209 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, tcg_env); 12210 break; 12211 case OPC_DPAU_H_OBL: 12212 check_dsp(ctx); 12213 gen_helper_dpau_h_obl(v1_t, v2_t, t0, tcg_env); 12214 break; 12215 case OPC_DPAU_H_OBR: 12216 check_dsp(ctx); 12217 gen_helper_dpau_h_obr(v1_t, v2_t, t0, tcg_env); 12218 break; 12219 case OPC_DPS_W_QH: 12220 check_dsp_r2(ctx); 12221 gen_helper_dps_w_qh(v1_t, v2_t, t0, tcg_env); 12222 break; 12223 case OPC_DPSQ_S_W_QH: 12224 check_dsp(ctx); 12225 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12226 break; 12227 case OPC_DPSQ_SA_L_PW: 12228 check_dsp(ctx); 12229 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, tcg_env); 12230 break; 12231 case OPC_DPSU_H_OBL: 12232 check_dsp(ctx); 12233 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, tcg_env); 12234 break; 12235 case OPC_DPSU_H_OBR: 12236 check_dsp(ctx); 12237 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, tcg_env); 12238 break; 12239 case OPC_MAQ_S_L_PWL: 12240 check_dsp(ctx); 12241 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, tcg_env); 12242 break; 12243 case OPC_MAQ_S_L_PWR: 12244 check_dsp(ctx); 12245 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, tcg_env); 12246 break; 12247 case OPC_MAQ_S_W_QHLL: 12248 check_dsp(ctx); 12249 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, tcg_env); 12250 break; 12251 case OPC_MAQ_SA_W_QHLL: 12252 check_dsp(ctx); 12253 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, tcg_env); 12254 break; 12255 case OPC_MAQ_S_W_QHLR: 12256 check_dsp(ctx); 12257 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, tcg_env); 12258 break; 12259 case OPC_MAQ_SA_W_QHLR: 12260 check_dsp(ctx); 12261 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, tcg_env); 12262 break; 12263 case OPC_MAQ_S_W_QHRL: 12264 check_dsp(ctx); 12265 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, tcg_env); 12266 break; 12267 case OPC_MAQ_SA_W_QHRL: 12268 check_dsp(ctx); 12269 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, tcg_env); 12270 break; 12271 case OPC_MAQ_S_W_QHRR: 12272 check_dsp(ctx); 12273 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, tcg_env); 12274 break; 12275 case OPC_MAQ_SA_W_QHRR: 12276 check_dsp(ctx); 12277 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, tcg_env); 12278 break; 12279 case OPC_MULSAQ_S_L_PW: 12280 check_dsp(ctx); 12281 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, tcg_env); 12282 break; 12283 case OPC_MULSAQ_S_W_QH: 12284 check_dsp(ctx); 12285 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12286 break; 12287 } 12288 } 12289 break; 12290 #endif 12291 case OPC_ADDU_QB_DSP: 12292 switch (op2) { 12293 case OPC_MULEU_S_PH_QBL: 12294 check_dsp(ctx); 12295 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12296 break; 12297 case OPC_MULEU_S_PH_QBR: 12298 check_dsp(ctx); 12299 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12300 break; 12301 case OPC_MULQ_RS_PH: 12302 check_dsp(ctx); 12303 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12304 break; 12305 case OPC_MULEQ_S_W_PHL: 12306 check_dsp(ctx); 12307 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12308 break; 12309 case OPC_MULEQ_S_W_PHR: 12310 check_dsp(ctx); 12311 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12312 break; 12313 case OPC_MULQ_S_PH: 12314 check_dsp_r2(ctx); 12315 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12316 break; 12317 } 12318 break; 12319 #ifdef TARGET_MIPS64 12320 case OPC_ADDU_OB_DSP: 12321 switch (op2) { 12322 case OPC_MULEQ_S_PW_QHL: 12323 check_dsp(ctx); 12324 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12325 break; 12326 case OPC_MULEQ_S_PW_QHR: 12327 check_dsp(ctx); 12328 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12329 break; 12330 case OPC_MULEU_S_QH_OBL: 12331 check_dsp(ctx); 12332 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12333 break; 12334 case OPC_MULEU_S_QH_OBR: 12335 check_dsp(ctx); 12336 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12337 break; 12338 case OPC_MULQ_RS_QH: 12339 check_dsp(ctx); 12340 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12341 break; 12342 } 12343 break; 12344 #endif 12345 } 12346 } 12347 12348 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 12349 int ret, int val) 12350 { 12351 int16_t imm; 12352 TCGv t0; 12353 TCGv val_t; 12354 12355 if (ret == 0) { 12356 /* Treat as NOP. */ 12357 return; 12358 } 12359 12360 t0 = tcg_temp_new(); 12361 val_t = tcg_temp_new(); 12362 gen_load_gpr(val_t, val); 12363 12364 switch (op1) { 12365 case OPC_ABSQ_S_PH_DSP: 12366 switch (op2) { 12367 case OPC_BITREV: 12368 check_dsp(ctx); 12369 gen_helper_bitrev(cpu_gpr[ret], val_t); 12370 break; 12371 case OPC_REPL_QB: 12372 check_dsp(ctx); 12373 { 12374 target_long result; 12375 imm = (ctx->opcode >> 16) & 0xFF; 12376 result = (uint32_t)imm << 24 | 12377 (uint32_t)imm << 16 | 12378 (uint32_t)imm << 8 | 12379 (uint32_t)imm; 12380 result = (int32_t)result; 12381 tcg_gen_movi_tl(cpu_gpr[ret], result); 12382 } 12383 break; 12384 case OPC_REPLV_QB: 12385 check_dsp(ctx); 12386 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 12387 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 12388 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12389 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12390 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12391 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12392 break; 12393 case OPC_REPL_PH: 12394 check_dsp(ctx); 12395 { 12396 imm = (ctx->opcode >> 16) & 0x03FF; 12397 imm = (int16_t)(imm << 6) >> 6; 12398 tcg_gen_movi_tl(cpu_gpr[ret], \ 12399 (target_long)((int32_t)imm << 16 | \ 12400 (uint16_t)imm)); 12401 } 12402 break; 12403 case OPC_REPLV_PH: 12404 check_dsp(ctx); 12405 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 12406 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12407 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12408 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12409 break; 12410 } 12411 break; 12412 #ifdef TARGET_MIPS64 12413 case OPC_ABSQ_S_QH_DSP: 12414 switch (op2) { 12415 case OPC_REPL_OB: 12416 check_dsp(ctx); 12417 { 12418 target_long temp; 12419 12420 imm = (ctx->opcode >> 16) & 0xFF; 12421 temp = ((uint64_t)imm << 8) | (uint64_t)imm; 12422 temp = (temp << 16) | temp; 12423 temp = (temp << 32) | temp; 12424 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12425 break; 12426 } 12427 case OPC_REPL_PW: 12428 check_dsp(ctx); 12429 { 12430 target_long temp; 12431 12432 imm = (ctx->opcode >> 16) & 0x03FF; 12433 imm = (int16_t)(imm << 6) >> 6; 12434 temp = ((target_long)imm << 32) \ 12435 | ((target_long)imm & 0xFFFFFFFF); 12436 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12437 break; 12438 } 12439 case OPC_REPL_QH: 12440 check_dsp(ctx); 12441 { 12442 target_long temp; 12443 12444 imm = (ctx->opcode >> 16) & 0x03FF; 12445 imm = (int16_t)(imm << 6) >> 6; 12446 12447 temp = ((uint64_t)(uint16_t)imm << 48) | 12448 ((uint64_t)(uint16_t)imm << 32) | 12449 ((uint64_t)(uint16_t)imm << 16) | 12450 (uint64_t)(uint16_t)imm; 12451 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12452 break; 12453 } 12454 case OPC_REPLV_OB: 12455 check_dsp(ctx); 12456 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 12457 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 12458 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12459 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12460 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12461 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12462 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12463 break; 12464 case OPC_REPLV_PW: 12465 check_dsp(ctx); 12466 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); 12467 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12468 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12469 break; 12470 case OPC_REPLV_QH: 12471 check_dsp(ctx); 12472 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 12473 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12474 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12475 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12476 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12477 break; 12478 } 12479 break; 12480 #endif 12481 } 12482 } 12483 12484 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, 12485 uint32_t op1, uint32_t op2, 12486 int ret, int v1, int v2, int check_ret) 12487 { 12488 TCGv t1; 12489 TCGv v1_t; 12490 TCGv v2_t; 12491 12492 if ((ret == 0) && (check_ret == 1)) { 12493 /* Treat as NOP. */ 12494 return; 12495 } 12496 12497 t1 = tcg_temp_new(); 12498 v1_t = tcg_temp_new(); 12499 v2_t = tcg_temp_new(); 12500 12501 gen_load_gpr(v1_t, v1); 12502 gen_load_gpr(v2_t, v2); 12503 12504 switch (op1) { 12505 case OPC_CMPU_EQ_QB_DSP: 12506 switch (op2) { 12507 case OPC_CMPU_EQ_QB: 12508 check_dsp(ctx); 12509 gen_helper_cmpu_eq_qb(v1_t, v2_t, tcg_env); 12510 break; 12511 case OPC_CMPU_LT_QB: 12512 check_dsp(ctx); 12513 gen_helper_cmpu_lt_qb(v1_t, v2_t, tcg_env); 12514 break; 12515 case OPC_CMPU_LE_QB: 12516 check_dsp(ctx); 12517 gen_helper_cmpu_le_qb(v1_t, v2_t, tcg_env); 12518 break; 12519 case OPC_CMPGU_EQ_QB: 12520 check_dsp(ctx); 12521 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); 12522 break; 12523 case OPC_CMPGU_LT_QB: 12524 check_dsp(ctx); 12525 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); 12526 break; 12527 case OPC_CMPGU_LE_QB: 12528 check_dsp(ctx); 12529 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); 12530 break; 12531 case OPC_CMPGDU_EQ_QB: 12532 check_dsp_r2(ctx); 12533 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); 12534 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12535 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12536 tcg_gen_shli_tl(t1, t1, 24); 12537 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12538 break; 12539 case OPC_CMPGDU_LT_QB: 12540 check_dsp_r2(ctx); 12541 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); 12542 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12543 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12544 tcg_gen_shli_tl(t1, t1, 24); 12545 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12546 break; 12547 case OPC_CMPGDU_LE_QB: 12548 check_dsp_r2(ctx); 12549 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); 12550 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12551 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12552 tcg_gen_shli_tl(t1, t1, 24); 12553 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12554 break; 12555 case OPC_CMP_EQ_PH: 12556 check_dsp(ctx); 12557 gen_helper_cmp_eq_ph(v1_t, v2_t, tcg_env); 12558 break; 12559 case OPC_CMP_LT_PH: 12560 check_dsp(ctx); 12561 gen_helper_cmp_lt_ph(v1_t, v2_t, tcg_env); 12562 break; 12563 case OPC_CMP_LE_PH: 12564 check_dsp(ctx); 12565 gen_helper_cmp_le_ph(v1_t, v2_t, tcg_env); 12566 break; 12567 case OPC_PICK_QB: 12568 check_dsp(ctx); 12569 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12570 break; 12571 case OPC_PICK_PH: 12572 check_dsp(ctx); 12573 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12574 break; 12575 case OPC_PACKRL_PH: 12576 check_dsp(ctx); 12577 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); 12578 break; 12579 } 12580 break; 12581 #ifdef TARGET_MIPS64 12582 case OPC_CMPU_EQ_OB_DSP: 12583 switch (op2) { 12584 case OPC_CMP_EQ_PW: 12585 check_dsp(ctx); 12586 gen_helper_cmp_eq_pw(v1_t, v2_t, tcg_env); 12587 break; 12588 case OPC_CMP_LT_PW: 12589 check_dsp(ctx); 12590 gen_helper_cmp_lt_pw(v1_t, v2_t, tcg_env); 12591 break; 12592 case OPC_CMP_LE_PW: 12593 check_dsp(ctx); 12594 gen_helper_cmp_le_pw(v1_t, v2_t, tcg_env); 12595 break; 12596 case OPC_CMP_EQ_QH: 12597 check_dsp(ctx); 12598 gen_helper_cmp_eq_qh(v1_t, v2_t, tcg_env); 12599 break; 12600 case OPC_CMP_LT_QH: 12601 check_dsp(ctx); 12602 gen_helper_cmp_lt_qh(v1_t, v2_t, tcg_env); 12603 break; 12604 case OPC_CMP_LE_QH: 12605 check_dsp(ctx); 12606 gen_helper_cmp_le_qh(v1_t, v2_t, tcg_env); 12607 break; 12608 case OPC_CMPGDU_EQ_OB: 12609 check_dsp_r2(ctx); 12610 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12611 break; 12612 case OPC_CMPGDU_LT_OB: 12613 check_dsp_r2(ctx); 12614 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12615 break; 12616 case OPC_CMPGDU_LE_OB: 12617 check_dsp_r2(ctx); 12618 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12619 break; 12620 case OPC_CMPGU_EQ_OB: 12621 check_dsp(ctx); 12622 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); 12623 break; 12624 case OPC_CMPGU_LT_OB: 12625 check_dsp(ctx); 12626 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); 12627 break; 12628 case OPC_CMPGU_LE_OB: 12629 check_dsp(ctx); 12630 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); 12631 break; 12632 case OPC_CMPU_EQ_OB: 12633 check_dsp(ctx); 12634 gen_helper_cmpu_eq_ob(v1_t, v2_t, tcg_env); 12635 break; 12636 case OPC_CMPU_LT_OB: 12637 check_dsp(ctx); 12638 gen_helper_cmpu_lt_ob(v1_t, v2_t, tcg_env); 12639 break; 12640 case OPC_CMPU_LE_OB: 12641 check_dsp(ctx); 12642 gen_helper_cmpu_le_ob(v1_t, v2_t, tcg_env); 12643 break; 12644 case OPC_PACKRL_PW: 12645 check_dsp(ctx); 12646 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); 12647 break; 12648 case OPC_PICK_OB: 12649 check_dsp(ctx); 12650 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12651 break; 12652 case OPC_PICK_PW: 12653 check_dsp(ctx); 12654 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12655 break; 12656 case OPC_PICK_QH: 12657 check_dsp(ctx); 12658 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12659 break; 12660 } 12661 break; 12662 #endif 12663 } 12664 } 12665 12666 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, 12667 uint32_t op1, int rt, int rs, int sa) 12668 { 12669 TCGv t0; 12670 12671 check_dsp_r2(ctx); 12672 12673 if (rt == 0) { 12674 /* Treat as NOP. */ 12675 return; 12676 } 12677 12678 t0 = tcg_temp_new(); 12679 gen_load_gpr(t0, rs); 12680 12681 switch (op1) { 12682 case OPC_APPEND_DSP: 12683 switch (MASK_APPEND(ctx->opcode)) { 12684 case OPC_APPEND: 12685 if (sa != 0) { 12686 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa); 12687 } 12688 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12689 break; 12690 case OPC_PREPEND: 12691 if (sa != 0) { 12692 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); 12693 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 12694 tcg_gen_shli_tl(t0, t0, 32 - sa); 12695 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12696 } 12697 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12698 break; 12699 case OPC_BALIGN: 12700 sa &= 3; 12701 if (sa != 0 && sa != 2) { 12702 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 12703 tcg_gen_ext32u_tl(t0, t0); 12704 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); 12705 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12706 } 12707 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12708 break; 12709 default: /* Invalid */ 12710 MIPS_INVAL("MASK APPEND"); 12711 gen_reserved_instruction(ctx); 12712 break; 12713 } 12714 break; 12715 #ifdef TARGET_MIPS64 12716 case OPC_DAPPEND_DSP: 12717 switch (MASK_DAPPEND(ctx->opcode)) { 12718 case OPC_DAPPEND: 12719 if (sa != 0) { 12720 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa); 12721 } 12722 break; 12723 case OPC_PREPENDD: 12724 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); 12725 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); 12726 tcg_gen_or_tl(cpu_gpr[rt], t0, t0); 12727 break; 12728 case OPC_PREPENDW: 12729 if (sa != 0) { 12730 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 12731 tcg_gen_shli_tl(t0, t0, 64 - sa); 12732 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12733 } 12734 break; 12735 case OPC_DBALIGN: 12736 sa &= 7; 12737 if (sa != 0 && sa != 2 && sa != 4) { 12738 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 12739 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); 12740 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12741 } 12742 break; 12743 default: /* Invalid */ 12744 MIPS_INVAL("MASK DAPPEND"); 12745 gen_reserved_instruction(ctx); 12746 break; 12747 } 12748 break; 12749 #endif 12750 } 12751 } 12752 12753 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 12754 int ret, int v1, int v2, int check_ret) 12755 12756 { 12757 TCGv t0; 12758 TCGv t1; 12759 TCGv v1_t; 12760 int16_t imm; 12761 12762 if ((ret == 0) && (check_ret == 1)) { 12763 /* Treat as NOP. */ 12764 return; 12765 } 12766 12767 t0 = tcg_temp_new(); 12768 t1 = tcg_temp_new(); 12769 v1_t = tcg_temp_new(); 12770 12771 gen_load_gpr(v1_t, v1); 12772 12773 switch (op1) { 12774 case OPC_EXTR_W_DSP: 12775 check_dsp(ctx); 12776 switch (op2) { 12777 case OPC_EXTR_W: 12778 tcg_gen_movi_tl(t0, v2); 12779 tcg_gen_movi_tl(t1, v1); 12780 gen_helper_extr_w(cpu_gpr[ret], t0, t1, tcg_env); 12781 break; 12782 case OPC_EXTR_R_W: 12783 tcg_gen_movi_tl(t0, v2); 12784 tcg_gen_movi_tl(t1, v1); 12785 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, tcg_env); 12786 break; 12787 case OPC_EXTR_RS_W: 12788 tcg_gen_movi_tl(t0, v2); 12789 tcg_gen_movi_tl(t1, v1); 12790 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, tcg_env); 12791 break; 12792 case OPC_EXTR_S_H: 12793 tcg_gen_movi_tl(t0, v2); 12794 tcg_gen_movi_tl(t1, v1); 12795 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, tcg_env); 12796 break; 12797 case OPC_EXTRV_S_H: 12798 tcg_gen_movi_tl(t0, v2); 12799 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env); 12800 break; 12801 case OPC_EXTRV_W: 12802 tcg_gen_movi_tl(t0, v2); 12803 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12804 break; 12805 case OPC_EXTRV_R_W: 12806 tcg_gen_movi_tl(t0, v2); 12807 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12808 break; 12809 case OPC_EXTRV_RS_W: 12810 tcg_gen_movi_tl(t0, v2); 12811 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12812 break; 12813 case OPC_EXTP: 12814 tcg_gen_movi_tl(t0, v2); 12815 tcg_gen_movi_tl(t1, v1); 12816 gen_helper_extp(cpu_gpr[ret], t0, t1, tcg_env); 12817 break; 12818 case OPC_EXTPV: 12819 tcg_gen_movi_tl(t0, v2); 12820 gen_helper_extp(cpu_gpr[ret], t0, v1_t, tcg_env); 12821 break; 12822 case OPC_EXTPDP: 12823 tcg_gen_movi_tl(t0, v2); 12824 tcg_gen_movi_tl(t1, v1); 12825 gen_helper_extpdp(cpu_gpr[ret], t0, t1, tcg_env); 12826 break; 12827 case OPC_EXTPDPV: 12828 tcg_gen_movi_tl(t0, v2); 12829 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, tcg_env); 12830 break; 12831 case OPC_SHILO: 12832 imm = (ctx->opcode >> 20) & 0x3F; 12833 tcg_gen_movi_tl(t0, ret); 12834 tcg_gen_movi_tl(t1, imm); 12835 gen_helper_shilo(t0, t1, tcg_env); 12836 break; 12837 case OPC_SHILOV: 12838 tcg_gen_movi_tl(t0, ret); 12839 gen_helper_shilo(t0, v1_t, tcg_env); 12840 break; 12841 case OPC_MTHLIP: 12842 tcg_gen_movi_tl(t0, ret); 12843 gen_helper_mthlip(t0, v1_t, tcg_env); 12844 break; 12845 case OPC_WRDSP: 12846 imm = (ctx->opcode >> 11) & 0x3FF; 12847 tcg_gen_movi_tl(t0, imm); 12848 gen_helper_wrdsp(v1_t, t0, tcg_env); 12849 break; 12850 case OPC_RDDSP: 12851 imm = (ctx->opcode >> 16) & 0x03FF; 12852 tcg_gen_movi_tl(t0, imm); 12853 gen_helper_rddsp(cpu_gpr[ret], t0, tcg_env); 12854 break; 12855 } 12856 break; 12857 #ifdef TARGET_MIPS64 12858 case OPC_DEXTR_W_DSP: 12859 check_dsp(ctx); 12860 switch (op2) { 12861 case OPC_DMTHLIP: 12862 tcg_gen_movi_tl(t0, ret); 12863 gen_helper_dmthlip(v1_t, t0, tcg_env); 12864 break; 12865 case OPC_DSHILO: 12866 { 12867 int shift = (ctx->opcode >> 19) & 0x7F; 12868 int ac = (ctx->opcode >> 11) & 0x03; 12869 tcg_gen_movi_tl(t0, shift); 12870 tcg_gen_movi_tl(t1, ac); 12871 gen_helper_dshilo(t0, t1, tcg_env); 12872 break; 12873 } 12874 case OPC_DSHILOV: 12875 { 12876 int ac = (ctx->opcode >> 11) & 0x03; 12877 tcg_gen_movi_tl(t0, ac); 12878 gen_helper_dshilo(v1_t, t0, tcg_env); 12879 break; 12880 } 12881 case OPC_DEXTP: 12882 tcg_gen_movi_tl(t0, v2); 12883 tcg_gen_movi_tl(t1, v1); 12884 12885 gen_helper_dextp(cpu_gpr[ret], t0, t1, tcg_env); 12886 break; 12887 case OPC_DEXTPV: 12888 tcg_gen_movi_tl(t0, v2); 12889 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, tcg_env); 12890 break; 12891 case OPC_DEXTPDP: 12892 tcg_gen_movi_tl(t0, v2); 12893 tcg_gen_movi_tl(t1, v1); 12894 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, tcg_env); 12895 break; 12896 case OPC_DEXTPDPV: 12897 tcg_gen_movi_tl(t0, v2); 12898 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, tcg_env); 12899 break; 12900 case OPC_DEXTR_L: 12901 tcg_gen_movi_tl(t0, v2); 12902 tcg_gen_movi_tl(t1, v1); 12903 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, tcg_env); 12904 break; 12905 case OPC_DEXTR_R_L: 12906 tcg_gen_movi_tl(t0, v2); 12907 tcg_gen_movi_tl(t1, v1); 12908 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, tcg_env); 12909 break; 12910 case OPC_DEXTR_RS_L: 12911 tcg_gen_movi_tl(t0, v2); 12912 tcg_gen_movi_tl(t1, v1); 12913 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, tcg_env); 12914 break; 12915 case OPC_DEXTR_W: 12916 tcg_gen_movi_tl(t0, v2); 12917 tcg_gen_movi_tl(t1, v1); 12918 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, tcg_env); 12919 break; 12920 case OPC_DEXTR_R_W: 12921 tcg_gen_movi_tl(t0, v2); 12922 tcg_gen_movi_tl(t1, v1); 12923 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, tcg_env); 12924 break; 12925 case OPC_DEXTR_RS_W: 12926 tcg_gen_movi_tl(t0, v2); 12927 tcg_gen_movi_tl(t1, v1); 12928 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, tcg_env); 12929 break; 12930 case OPC_DEXTR_S_H: 12931 tcg_gen_movi_tl(t0, v2); 12932 tcg_gen_movi_tl(t1, v1); 12933 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, tcg_env); 12934 break; 12935 case OPC_DEXTRV_S_H: 12936 tcg_gen_movi_tl(t0, v2); 12937 gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env); 12938 break; 12939 case OPC_DEXTRV_L: 12940 tcg_gen_movi_tl(t0, v2); 12941 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, tcg_env); 12942 break; 12943 case OPC_DEXTRV_R_L: 12944 tcg_gen_movi_tl(t0, v2); 12945 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, tcg_env); 12946 break; 12947 case OPC_DEXTRV_RS_L: 12948 tcg_gen_movi_tl(t0, v2); 12949 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, tcg_env); 12950 break; 12951 case OPC_DEXTRV_W: 12952 tcg_gen_movi_tl(t0, v2); 12953 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12954 break; 12955 case OPC_DEXTRV_R_W: 12956 tcg_gen_movi_tl(t0, v2); 12957 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12958 break; 12959 case OPC_DEXTRV_RS_W: 12960 tcg_gen_movi_tl(t0, v2); 12961 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12962 break; 12963 } 12964 break; 12965 #endif 12966 } 12967 } 12968 12969 /* End MIPSDSP functions. */ 12970 12971 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) 12972 { 12973 int rs, rt, rd, sa; 12974 uint32_t op1, op2; 12975 12976 rs = (ctx->opcode >> 21) & 0x1f; 12977 rt = (ctx->opcode >> 16) & 0x1f; 12978 rd = (ctx->opcode >> 11) & 0x1f; 12979 sa = (ctx->opcode >> 6) & 0x1f; 12980 12981 op1 = MASK_SPECIAL(ctx->opcode); 12982 switch (op1) { 12983 case OPC_MULT: 12984 case OPC_MULTU: 12985 case OPC_DIV: 12986 case OPC_DIVU: 12987 op2 = MASK_R6_MULDIV(ctx->opcode); 12988 switch (op2) { 12989 case R6_OPC_MUL: 12990 case R6_OPC_MUH: 12991 case R6_OPC_MULU: 12992 case R6_OPC_MUHU: 12993 case R6_OPC_DIV: 12994 case R6_OPC_MOD: 12995 case R6_OPC_DIVU: 12996 case R6_OPC_MODU: 12997 gen_r6_muldiv(ctx, op2, rd, rs, rt); 12998 break; 12999 default: 13000 MIPS_INVAL("special_r6 muldiv"); 13001 gen_reserved_instruction(ctx); 13002 break; 13003 } 13004 break; 13005 case OPC_SELEQZ: 13006 case OPC_SELNEZ: 13007 gen_cond_move(ctx, op1, rd, rs, rt); 13008 break; 13009 case R6_OPC_CLO: 13010 case R6_OPC_CLZ: 13011 if (rt == 0 && sa == 1) { 13012 /* 13013 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13014 * We need additionally to check other fields. 13015 */ 13016 gen_cl(ctx, op1, rd, rs); 13017 } else { 13018 gen_reserved_instruction(ctx); 13019 } 13020 break; 13021 case R6_OPC_SDBBP: 13022 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 13023 ctx->base.is_jmp = DISAS_SEMIHOST; 13024 } else { 13025 if (ctx->hflags & MIPS_HFLAG_SBRI) { 13026 gen_reserved_instruction(ctx); 13027 } else { 13028 generate_exception_end(ctx, EXCP_DBp); 13029 } 13030 } 13031 break; 13032 #if defined(TARGET_MIPS64) 13033 case R6_OPC_DCLO: 13034 case R6_OPC_DCLZ: 13035 if (rt == 0 && sa == 1) { 13036 /* 13037 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13038 * We need additionally to check other fields. 13039 */ 13040 check_mips_64(ctx); 13041 gen_cl(ctx, op1, rd, rs); 13042 } else { 13043 gen_reserved_instruction(ctx); 13044 } 13045 break; 13046 case OPC_DMULT: 13047 case OPC_DMULTU: 13048 case OPC_DDIV: 13049 case OPC_DDIVU: 13050 13051 op2 = MASK_R6_MULDIV(ctx->opcode); 13052 switch (op2) { 13053 case R6_OPC_DMUL: 13054 case R6_OPC_DMUH: 13055 case R6_OPC_DMULU: 13056 case R6_OPC_DMUHU: 13057 case R6_OPC_DDIV: 13058 case R6_OPC_DMOD: 13059 case R6_OPC_DDIVU: 13060 case R6_OPC_DMODU: 13061 check_mips_64(ctx); 13062 gen_r6_muldiv(ctx, op2, rd, rs, rt); 13063 break; 13064 default: 13065 MIPS_INVAL("special_r6 muldiv"); 13066 gen_reserved_instruction(ctx); 13067 break; 13068 } 13069 break; 13070 #endif 13071 default: /* Invalid */ 13072 MIPS_INVAL("special_r6"); 13073 gen_reserved_instruction(ctx); 13074 break; 13075 } 13076 } 13077 13078 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) 13079 { 13080 int rs = extract32(ctx->opcode, 21, 5); 13081 int rt = extract32(ctx->opcode, 16, 5); 13082 int rd = extract32(ctx->opcode, 11, 5); 13083 uint32_t op1 = MASK_SPECIAL(ctx->opcode); 13084 13085 switch (op1) { 13086 case OPC_MOVN: /* Conditional move */ 13087 case OPC_MOVZ: 13088 gen_cond_move(ctx, op1, rd, rs, rt); 13089 break; 13090 case OPC_MFHI: /* Move from HI/LO */ 13091 case OPC_MFLO: 13092 gen_HILO(ctx, op1, 0, rd); 13093 break; 13094 case OPC_MTHI: 13095 case OPC_MTLO: /* Move to HI/LO */ 13096 gen_HILO(ctx, op1, 0, rs); 13097 break; 13098 case OPC_MULT: 13099 case OPC_MULTU: 13100 gen_mul_txx9(ctx, op1, rd, rs, rt); 13101 break; 13102 case OPC_DIV: 13103 case OPC_DIVU: 13104 gen_muldiv(ctx, op1, 0, rs, rt); 13105 break; 13106 #if defined(TARGET_MIPS64) 13107 case OPC_DMULT: 13108 case OPC_DMULTU: 13109 case OPC_DDIV: 13110 case OPC_DDIVU: 13111 check_insn_opc_user_only(ctx, INSN_R5900); 13112 gen_muldiv(ctx, op1, 0, rs, rt); 13113 break; 13114 #endif 13115 case OPC_JR: 13116 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13117 break; 13118 default: /* Invalid */ 13119 MIPS_INVAL("special_tx79"); 13120 gen_reserved_instruction(ctx); 13121 break; 13122 } 13123 } 13124 13125 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) 13126 { 13127 int rs, rt, rd; 13128 uint32_t op1; 13129 13130 rs = (ctx->opcode >> 21) & 0x1f; 13131 rt = (ctx->opcode >> 16) & 0x1f; 13132 rd = (ctx->opcode >> 11) & 0x1f; 13133 13134 op1 = MASK_SPECIAL(ctx->opcode); 13135 switch (op1) { 13136 case OPC_MOVN: /* Conditional move */ 13137 case OPC_MOVZ: 13138 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | 13139 INSN_LOONGSON2E | INSN_LOONGSON2F); 13140 gen_cond_move(ctx, op1, rd, rs, rt); 13141 break; 13142 case OPC_MFHI: /* Move from HI/LO */ 13143 case OPC_MFLO: 13144 gen_HILO(ctx, op1, rs & 3, rd); 13145 break; 13146 case OPC_MTHI: 13147 case OPC_MTLO: /* Move to HI/LO */ 13148 gen_HILO(ctx, op1, rd & 3, rs); 13149 break; 13150 case OPC_MOVCI: 13151 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 13152 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 13153 check_cp1_enabled(ctx); 13154 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 13155 (ctx->opcode >> 16) & 1); 13156 } else { 13157 generate_exception_err(ctx, EXCP_CpU, 1); 13158 } 13159 break; 13160 case OPC_MULT: 13161 case OPC_MULTU: 13162 gen_muldiv(ctx, op1, rd & 3, rs, rt); 13163 break; 13164 case OPC_DIV: 13165 case OPC_DIVU: 13166 gen_muldiv(ctx, op1, 0, rs, rt); 13167 break; 13168 #if defined(TARGET_MIPS64) 13169 case OPC_DMULT: 13170 case OPC_DMULTU: 13171 case OPC_DDIV: 13172 case OPC_DDIVU: 13173 check_insn(ctx, ISA_MIPS3); 13174 check_mips_64(ctx); 13175 gen_muldiv(ctx, op1, 0, rs, rt); 13176 break; 13177 #endif 13178 case OPC_JR: 13179 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13180 break; 13181 case OPC_SPIM: 13182 #ifdef MIPS_STRICT_STANDARD 13183 MIPS_INVAL("SPIM"); 13184 gen_reserved_instruction(ctx); 13185 #else 13186 /* Implemented as RI exception for now. */ 13187 MIPS_INVAL("spim (unofficial)"); 13188 gen_reserved_instruction(ctx); 13189 #endif 13190 break; 13191 default: /* Invalid */ 13192 MIPS_INVAL("special_legacy"); 13193 gen_reserved_instruction(ctx); 13194 break; 13195 } 13196 } 13197 13198 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) 13199 { 13200 int rs, rt, rd, sa; 13201 uint32_t op1; 13202 13203 rs = (ctx->opcode >> 21) & 0x1f; 13204 rt = (ctx->opcode >> 16) & 0x1f; 13205 rd = (ctx->opcode >> 11) & 0x1f; 13206 sa = (ctx->opcode >> 6) & 0x1f; 13207 13208 op1 = MASK_SPECIAL(ctx->opcode); 13209 switch (op1) { 13210 case OPC_SLL: /* Shift with immediate */ 13211 if (sa == 5 && rd == 0 && 13212 rs == 0 && rt == 0) { /* PAUSE */ 13213 if ((ctx->insn_flags & ISA_MIPS_R6) && 13214 (ctx->hflags & MIPS_HFLAG_BMASK)) { 13215 gen_reserved_instruction(ctx); 13216 break; 13217 } 13218 } 13219 /* Fallthrough */ 13220 case OPC_SRA: 13221 gen_shift_imm(ctx, op1, rd, rt, sa); 13222 break; 13223 case OPC_SRL: 13224 switch ((ctx->opcode >> 21) & 0x1f) { 13225 case 1: 13226 /* rotr is decoded as srl on non-R2 CPUs */ 13227 if (ctx->insn_flags & ISA_MIPS_R2) { 13228 op1 = OPC_ROTR; 13229 } 13230 /* Fallthrough */ 13231 case 0: 13232 gen_shift_imm(ctx, op1, rd, rt, sa); 13233 break; 13234 default: 13235 gen_reserved_instruction(ctx); 13236 break; 13237 } 13238 break; 13239 case OPC_ADD: 13240 case OPC_ADDU: 13241 case OPC_SUB: 13242 case OPC_SUBU: 13243 gen_arith(ctx, op1, rd, rs, rt); 13244 break; 13245 case OPC_SLLV: /* Shifts */ 13246 case OPC_SRAV: 13247 gen_shift(ctx, op1, rd, rs, rt); 13248 break; 13249 case OPC_SRLV: 13250 switch ((ctx->opcode >> 6) & 0x1f) { 13251 case 1: 13252 /* rotrv is decoded as srlv on non-R2 CPUs */ 13253 if (ctx->insn_flags & ISA_MIPS_R2) { 13254 op1 = OPC_ROTRV; 13255 } 13256 /* Fallthrough */ 13257 case 0: 13258 gen_shift(ctx, op1, rd, rs, rt); 13259 break; 13260 default: 13261 gen_reserved_instruction(ctx); 13262 break; 13263 } 13264 break; 13265 case OPC_SLT: /* Set on less than */ 13266 case OPC_SLTU: 13267 gen_slt(ctx, op1, rd, rs, rt); 13268 break; 13269 case OPC_AND: /* Logic*/ 13270 case OPC_OR: 13271 case OPC_NOR: 13272 case OPC_XOR: 13273 gen_logic(ctx, op1, rd, rs, rt); 13274 break; 13275 case OPC_JALR: 13276 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 13277 break; 13278 case OPC_TGE: /* Traps */ 13279 case OPC_TGEU: 13280 case OPC_TLT: 13281 case OPC_TLTU: 13282 case OPC_TEQ: 13283 case OPC_TNE: 13284 check_insn(ctx, ISA_MIPS2); 13285 gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10)); 13286 break; 13287 case OPC_PMON: 13288 /* Pmon entry point, also R4010 selsl */ 13289 #ifdef MIPS_STRICT_STANDARD 13290 MIPS_INVAL("PMON / selsl"); 13291 gen_reserved_instruction(ctx); 13292 #else 13293 gen_helper_pmon(tcg_env, tcg_constant_i32(sa)); 13294 #endif 13295 break; 13296 case OPC_SYSCALL: 13297 generate_exception_end(ctx, EXCP_SYSCALL); 13298 break; 13299 case OPC_BREAK: 13300 generate_exception_break(ctx, extract32(ctx->opcode, 6, 20)); 13301 break; 13302 case OPC_SYNC: 13303 check_insn(ctx, ISA_MIPS2); 13304 gen_sync(extract32(ctx->opcode, 6, 5)); 13305 break; 13306 13307 #if defined(TARGET_MIPS64) 13308 /* MIPS64 specific opcodes */ 13309 case OPC_DSLL: 13310 case OPC_DSRA: 13311 case OPC_DSLL32: 13312 case OPC_DSRA32: 13313 check_insn(ctx, ISA_MIPS3); 13314 check_mips_64(ctx); 13315 gen_shift_imm(ctx, op1, rd, rt, sa); 13316 break; 13317 case OPC_DSRL: 13318 switch ((ctx->opcode >> 21) & 0x1f) { 13319 case 1: 13320 /* drotr is decoded as dsrl on non-R2 CPUs */ 13321 if (ctx->insn_flags & ISA_MIPS_R2) { 13322 op1 = OPC_DROTR; 13323 } 13324 /* Fallthrough */ 13325 case 0: 13326 check_insn(ctx, ISA_MIPS3); 13327 check_mips_64(ctx); 13328 gen_shift_imm(ctx, op1, rd, rt, sa); 13329 break; 13330 default: 13331 gen_reserved_instruction(ctx); 13332 break; 13333 } 13334 break; 13335 case OPC_DSRL32: 13336 switch ((ctx->opcode >> 21) & 0x1f) { 13337 case 1: 13338 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 13339 if (ctx->insn_flags & ISA_MIPS_R2) { 13340 op1 = OPC_DROTR32; 13341 } 13342 /* Fallthrough */ 13343 case 0: 13344 check_insn(ctx, ISA_MIPS3); 13345 check_mips_64(ctx); 13346 gen_shift_imm(ctx, op1, rd, rt, sa); 13347 break; 13348 default: 13349 gen_reserved_instruction(ctx); 13350 break; 13351 } 13352 break; 13353 case OPC_DADD: 13354 case OPC_DADDU: 13355 case OPC_DSUB: 13356 case OPC_DSUBU: 13357 check_insn(ctx, ISA_MIPS3); 13358 check_mips_64(ctx); 13359 gen_arith(ctx, op1, rd, rs, rt); 13360 break; 13361 case OPC_DSLLV: 13362 case OPC_DSRAV: 13363 check_insn(ctx, ISA_MIPS3); 13364 check_mips_64(ctx); 13365 gen_shift(ctx, op1, rd, rs, rt); 13366 break; 13367 case OPC_DSRLV: 13368 switch ((ctx->opcode >> 6) & 0x1f) { 13369 case 1: 13370 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 13371 if (ctx->insn_flags & ISA_MIPS_R2) { 13372 op1 = OPC_DROTRV; 13373 } 13374 /* Fallthrough */ 13375 case 0: 13376 check_insn(ctx, ISA_MIPS3); 13377 check_mips_64(ctx); 13378 gen_shift(ctx, op1, rd, rs, rt); 13379 break; 13380 default: 13381 gen_reserved_instruction(ctx); 13382 break; 13383 } 13384 break; 13385 #endif 13386 default: 13387 if (ctx->insn_flags & ISA_MIPS_R6) { 13388 decode_opc_special_r6(env, ctx); 13389 } else if (ctx->insn_flags & INSN_R5900) { 13390 decode_opc_special_tx79(env, ctx); 13391 } else { 13392 decode_opc_special_legacy(env, ctx); 13393 } 13394 } 13395 } 13396 13397 13398 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) 13399 { 13400 int rs, rt, rd; 13401 uint32_t op1; 13402 13403 rs = (ctx->opcode >> 21) & 0x1f; 13404 rt = (ctx->opcode >> 16) & 0x1f; 13405 rd = (ctx->opcode >> 11) & 0x1f; 13406 13407 op1 = MASK_SPECIAL2(ctx->opcode); 13408 switch (op1) { 13409 case OPC_MADD: /* Multiply and add/sub */ 13410 case OPC_MADDU: 13411 case OPC_MSUB: 13412 case OPC_MSUBU: 13413 check_insn(ctx, ISA_MIPS_R1); 13414 gen_muldiv(ctx, op1, rd & 3, rs, rt); 13415 break; 13416 case OPC_MUL: 13417 gen_arith(ctx, op1, rd, rs, rt); 13418 break; 13419 case OPC_CLO: 13420 case OPC_CLZ: 13421 check_insn(ctx, ISA_MIPS_R1); 13422 gen_cl(ctx, op1, rd, rs); 13423 break; 13424 case OPC_SDBBP: 13425 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 13426 ctx->base.is_jmp = DISAS_SEMIHOST; 13427 } else { 13428 /* 13429 * XXX: not clear which exception should be raised 13430 * when in debug mode... 13431 */ 13432 check_insn(ctx, ISA_MIPS_R1); 13433 generate_exception_end(ctx, EXCP_DBp); 13434 } 13435 break; 13436 #if defined(TARGET_MIPS64) 13437 case OPC_DCLO: 13438 case OPC_DCLZ: 13439 check_insn(ctx, ISA_MIPS_R1); 13440 check_mips_64(ctx); 13441 gen_cl(ctx, op1, rd, rs); 13442 break; 13443 #endif 13444 default: /* Invalid */ 13445 MIPS_INVAL("special2_legacy"); 13446 gen_reserved_instruction(ctx); 13447 break; 13448 } 13449 } 13450 13451 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) 13452 { 13453 int rs, rt, rd, sa; 13454 uint32_t op1, op2; 13455 int16_t imm; 13456 13457 rs = (ctx->opcode >> 21) & 0x1f; 13458 rt = (ctx->opcode >> 16) & 0x1f; 13459 rd = (ctx->opcode >> 11) & 0x1f; 13460 sa = (ctx->opcode >> 6) & 0x1f; 13461 imm = (int16_t)ctx->opcode >> 7; 13462 13463 op1 = MASK_SPECIAL3(ctx->opcode); 13464 switch (op1) { 13465 case R6_OPC_PREF: 13466 if (rt >= 24) { 13467 /* hint codes 24-31 are reserved and signal RI */ 13468 gen_reserved_instruction(ctx); 13469 } 13470 /* Treat as NOP. */ 13471 break; 13472 case R6_OPC_CACHE: 13473 check_cp0_enabled(ctx); 13474 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 13475 gen_cache_operation(ctx, rt, rs, imm); 13476 } 13477 break; 13478 case R6_OPC_SC: 13479 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false); 13480 break; 13481 case R6_OPC_LL: 13482 gen_ld(ctx, op1, rt, rs, imm); 13483 break; 13484 case OPC_BSHFL: 13485 { 13486 if (rd == 0) { 13487 /* Treat as NOP. */ 13488 break; 13489 } 13490 op2 = MASK_BSHFL(ctx->opcode); 13491 switch (op2) { 13492 case OPC_ALIGN: 13493 case OPC_ALIGN_1: 13494 case OPC_ALIGN_2: 13495 case OPC_ALIGN_3: 13496 gen_align(ctx, 32, rd, rs, rt, sa & 3); 13497 break; 13498 case OPC_BITSWAP: 13499 gen_bitswap(ctx, op2, rd, rt); 13500 break; 13501 } 13502 } 13503 break; 13504 #ifndef CONFIG_USER_ONLY 13505 case OPC_GINV: 13506 if (unlikely(ctx->gi <= 1)) { 13507 gen_reserved_instruction(ctx); 13508 } 13509 check_cp0_enabled(ctx); 13510 switch ((ctx->opcode >> 6) & 3) { 13511 case 0: /* GINVI */ 13512 /* Treat as NOP. */ 13513 break; 13514 case 2: /* GINVT */ 13515 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); 13516 break; 13517 default: 13518 gen_reserved_instruction(ctx); 13519 break; 13520 } 13521 break; 13522 #endif 13523 #if defined(TARGET_MIPS64) 13524 case R6_OPC_SCD: 13525 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false); 13526 break; 13527 case R6_OPC_LLD: 13528 gen_ld(ctx, op1, rt, rs, imm); 13529 break; 13530 case OPC_DBSHFL: 13531 check_mips_64(ctx); 13532 { 13533 if (rd == 0) { 13534 /* Treat as NOP. */ 13535 break; 13536 } 13537 op2 = MASK_DBSHFL(ctx->opcode); 13538 switch (op2) { 13539 case OPC_DALIGN: 13540 case OPC_DALIGN_1: 13541 case OPC_DALIGN_2: 13542 case OPC_DALIGN_3: 13543 case OPC_DALIGN_4: 13544 case OPC_DALIGN_5: 13545 case OPC_DALIGN_6: 13546 case OPC_DALIGN_7: 13547 gen_align(ctx, 64, rd, rs, rt, sa & 7); 13548 break; 13549 case OPC_DBITSWAP: 13550 gen_bitswap(ctx, op2, rd, rt); 13551 break; 13552 } 13553 13554 } 13555 break; 13556 #endif 13557 default: /* Invalid */ 13558 MIPS_INVAL("special3_r6"); 13559 gen_reserved_instruction(ctx); 13560 break; 13561 } 13562 } 13563 13564 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) 13565 { 13566 int rs, rt, rd; 13567 uint32_t op1, op2; 13568 13569 rs = (ctx->opcode >> 21) & 0x1f; 13570 rt = (ctx->opcode >> 16) & 0x1f; 13571 rd = (ctx->opcode >> 11) & 0x1f; 13572 13573 op1 = MASK_SPECIAL3(ctx->opcode); 13574 switch (op1) { 13575 case OPC_MUL_PH_DSP: 13576 /* 13577 * OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 13578 * the same mask and op1. 13579 */ 13580 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MUL_PH_DSP)) { 13581 op2 = MASK_ADDUH_QB(ctx->opcode); 13582 switch (op2) { 13583 case OPC_ADDUH_QB: 13584 case OPC_ADDUH_R_QB: 13585 case OPC_ADDQH_PH: 13586 case OPC_ADDQH_R_PH: 13587 case OPC_ADDQH_W: 13588 case OPC_ADDQH_R_W: 13589 case OPC_SUBUH_QB: 13590 case OPC_SUBUH_R_QB: 13591 case OPC_SUBQH_PH: 13592 case OPC_SUBQH_R_PH: 13593 case OPC_SUBQH_W: 13594 case OPC_SUBQH_R_W: 13595 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13596 break; 13597 case OPC_MUL_PH: 13598 case OPC_MUL_S_PH: 13599 case OPC_MULQ_S_W: 13600 case OPC_MULQ_RS_W: 13601 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13602 break; 13603 default: 13604 MIPS_INVAL("MASK ADDUH.QB"); 13605 gen_reserved_instruction(ctx); 13606 break; 13607 } 13608 } else { 13609 gen_reserved_instruction(ctx); 13610 } 13611 break; 13612 case OPC_LX_DSP: 13613 op2 = MASK_LX(ctx->opcode); 13614 switch (op2) { 13615 #if defined(TARGET_MIPS64) 13616 case OPC_LDX: 13617 #endif 13618 case OPC_LBUX: 13619 case OPC_LHX: 13620 case OPC_LWX: 13621 gen_mips_lx(ctx, op2, rd, rs, rt); 13622 break; 13623 default: /* Invalid */ 13624 MIPS_INVAL("MASK LX"); 13625 gen_reserved_instruction(ctx); 13626 break; 13627 } 13628 break; 13629 case OPC_ABSQ_S_PH_DSP: 13630 op2 = MASK_ABSQ_S_PH(ctx->opcode); 13631 switch (op2) { 13632 case OPC_ABSQ_S_QB: 13633 case OPC_ABSQ_S_PH: 13634 case OPC_ABSQ_S_W: 13635 case OPC_PRECEQ_W_PHL: 13636 case OPC_PRECEQ_W_PHR: 13637 case OPC_PRECEQU_PH_QBL: 13638 case OPC_PRECEQU_PH_QBR: 13639 case OPC_PRECEQU_PH_QBLA: 13640 case OPC_PRECEQU_PH_QBRA: 13641 case OPC_PRECEU_PH_QBL: 13642 case OPC_PRECEU_PH_QBR: 13643 case OPC_PRECEU_PH_QBLA: 13644 case OPC_PRECEU_PH_QBRA: 13645 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13646 break; 13647 case OPC_BITREV: 13648 case OPC_REPL_QB: 13649 case OPC_REPLV_QB: 13650 case OPC_REPL_PH: 13651 case OPC_REPLV_PH: 13652 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 13653 break; 13654 default: 13655 MIPS_INVAL("MASK ABSQ_S.PH"); 13656 gen_reserved_instruction(ctx); 13657 break; 13658 } 13659 break; 13660 case OPC_ADDU_QB_DSP: 13661 op2 = MASK_ADDU_QB(ctx->opcode); 13662 switch (op2) { 13663 case OPC_ADDQ_PH: 13664 case OPC_ADDQ_S_PH: 13665 case OPC_ADDQ_S_W: 13666 case OPC_ADDU_QB: 13667 case OPC_ADDU_S_QB: 13668 case OPC_ADDU_PH: 13669 case OPC_ADDU_S_PH: 13670 case OPC_SUBQ_PH: 13671 case OPC_SUBQ_S_PH: 13672 case OPC_SUBQ_S_W: 13673 case OPC_SUBU_QB: 13674 case OPC_SUBU_S_QB: 13675 case OPC_SUBU_PH: 13676 case OPC_SUBU_S_PH: 13677 case OPC_ADDSC: 13678 case OPC_ADDWC: 13679 case OPC_MODSUB: 13680 case OPC_RADDU_W_QB: 13681 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13682 break; 13683 case OPC_MULEU_S_PH_QBL: 13684 case OPC_MULEU_S_PH_QBR: 13685 case OPC_MULQ_RS_PH: 13686 case OPC_MULEQ_S_W_PHL: 13687 case OPC_MULEQ_S_W_PHR: 13688 case OPC_MULQ_S_PH: 13689 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13690 break; 13691 default: /* Invalid */ 13692 MIPS_INVAL("MASK ADDU.QB"); 13693 gen_reserved_instruction(ctx); 13694 break; 13695 13696 } 13697 break; 13698 case OPC_CMPU_EQ_QB_DSP: 13699 op2 = MASK_CMPU_EQ_QB(ctx->opcode); 13700 switch (op2) { 13701 case OPC_PRECR_SRA_PH_W: 13702 case OPC_PRECR_SRA_R_PH_W: 13703 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 13704 break; 13705 case OPC_PRECR_QB_PH: 13706 case OPC_PRECRQ_QB_PH: 13707 case OPC_PRECRQ_PH_W: 13708 case OPC_PRECRQ_RS_PH_W: 13709 case OPC_PRECRQU_S_QB_PH: 13710 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13711 break; 13712 case OPC_CMPU_EQ_QB: 13713 case OPC_CMPU_LT_QB: 13714 case OPC_CMPU_LE_QB: 13715 case OPC_CMP_EQ_PH: 13716 case OPC_CMP_LT_PH: 13717 case OPC_CMP_LE_PH: 13718 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 13719 break; 13720 case OPC_CMPGU_EQ_QB: 13721 case OPC_CMPGU_LT_QB: 13722 case OPC_CMPGU_LE_QB: 13723 case OPC_CMPGDU_EQ_QB: 13724 case OPC_CMPGDU_LT_QB: 13725 case OPC_CMPGDU_LE_QB: 13726 case OPC_PICK_QB: 13727 case OPC_PICK_PH: 13728 case OPC_PACKRL_PH: 13729 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 13730 break; 13731 default: /* Invalid */ 13732 MIPS_INVAL("MASK CMPU.EQ.QB"); 13733 gen_reserved_instruction(ctx); 13734 break; 13735 } 13736 break; 13737 case OPC_SHLL_QB_DSP: 13738 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 13739 break; 13740 case OPC_DPA_W_PH_DSP: 13741 op2 = MASK_DPA_W_PH(ctx->opcode); 13742 switch (op2) { 13743 case OPC_DPAU_H_QBL: 13744 case OPC_DPAU_H_QBR: 13745 case OPC_DPSU_H_QBL: 13746 case OPC_DPSU_H_QBR: 13747 case OPC_DPA_W_PH: 13748 case OPC_DPAX_W_PH: 13749 case OPC_DPAQ_S_W_PH: 13750 case OPC_DPAQX_S_W_PH: 13751 case OPC_DPAQX_SA_W_PH: 13752 case OPC_DPS_W_PH: 13753 case OPC_DPSX_W_PH: 13754 case OPC_DPSQ_S_W_PH: 13755 case OPC_DPSQX_S_W_PH: 13756 case OPC_DPSQX_SA_W_PH: 13757 case OPC_MULSAQ_S_W_PH: 13758 case OPC_DPAQ_SA_L_W: 13759 case OPC_DPSQ_SA_L_W: 13760 case OPC_MAQ_S_W_PHL: 13761 case OPC_MAQ_S_W_PHR: 13762 case OPC_MAQ_SA_W_PHL: 13763 case OPC_MAQ_SA_W_PHR: 13764 case OPC_MULSA_W_PH: 13765 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 13766 break; 13767 default: /* Invalid */ 13768 MIPS_INVAL("MASK DPAW.PH"); 13769 gen_reserved_instruction(ctx); 13770 break; 13771 } 13772 break; 13773 case OPC_INSV_DSP: 13774 op2 = MASK_INSV(ctx->opcode); 13775 switch (op2) { 13776 case OPC_INSV: 13777 check_dsp(ctx); 13778 { 13779 TCGv t0, t1; 13780 13781 if (rt == 0) { 13782 break; 13783 } 13784 13785 t0 = tcg_temp_new(); 13786 t1 = tcg_temp_new(); 13787 13788 gen_load_gpr(t0, rt); 13789 gen_load_gpr(t1, rs); 13790 13791 gen_helper_insv(cpu_gpr[rt], tcg_env, t1, t0); 13792 break; 13793 } 13794 default: /* Invalid */ 13795 MIPS_INVAL("MASK INSV"); 13796 gen_reserved_instruction(ctx); 13797 break; 13798 } 13799 break; 13800 case OPC_APPEND_DSP: 13801 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 13802 break; 13803 case OPC_EXTR_W_DSP: 13804 op2 = MASK_EXTR_W(ctx->opcode); 13805 switch (op2) { 13806 case OPC_EXTR_W: 13807 case OPC_EXTR_R_W: 13808 case OPC_EXTR_RS_W: 13809 case OPC_EXTR_S_H: 13810 case OPC_EXTRV_S_H: 13811 case OPC_EXTRV_W: 13812 case OPC_EXTRV_R_W: 13813 case OPC_EXTRV_RS_W: 13814 case OPC_EXTP: 13815 case OPC_EXTPV: 13816 case OPC_EXTPDP: 13817 case OPC_EXTPDPV: 13818 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 13819 break; 13820 case OPC_RDDSP: 13821 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1); 13822 break; 13823 case OPC_SHILO: 13824 case OPC_SHILOV: 13825 case OPC_MTHLIP: 13826 case OPC_WRDSP: 13827 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 13828 break; 13829 default: /* Invalid */ 13830 MIPS_INVAL("MASK EXTR.W"); 13831 gen_reserved_instruction(ctx); 13832 break; 13833 } 13834 break; 13835 #if defined(TARGET_MIPS64) 13836 case OPC_ABSQ_S_QH_DSP: 13837 op2 = MASK_ABSQ_S_QH(ctx->opcode); 13838 switch (op2) { 13839 case OPC_PRECEQ_L_PWL: 13840 case OPC_PRECEQ_L_PWR: 13841 case OPC_PRECEQ_PW_QHL: 13842 case OPC_PRECEQ_PW_QHR: 13843 case OPC_PRECEQ_PW_QHLA: 13844 case OPC_PRECEQ_PW_QHRA: 13845 case OPC_PRECEQU_QH_OBL: 13846 case OPC_PRECEQU_QH_OBR: 13847 case OPC_PRECEQU_QH_OBLA: 13848 case OPC_PRECEQU_QH_OBRA: 13849 case OPC_PRECEU_QH_OBL: 13850 case OPC_PRECEU_QH_OBR: 13851 case OPC_PRECEU_QH_OBLA: 13852 case OPC_PRECEU_QH_OBRA: 13853 case OPC_ABSQ_S_OB: 13854 case OPC_ABSQ_S_PW: 13855 case OPC_ABSQ_S_QH: 13856 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13857 break; 13858 case OPC_REPL_OB: 13859 case OPC_REPL_PW: 13860 case OPC_REPL_QH: 13861 case OPC_REPLV_OB: 13862 case OPC_REPLV_PW: 13863 case OPC_REPLV_QH: 13864 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 13865 break; 13866 default: /* Invalid */ 13867 MIPS_INVAL("MASK ABSQ_S.QH"); 13868 gen_reserved_instruction(ctx); 13869 break; 13870 } 13871 break; 13872 case OPC_ADDU_OB_DSP: 13873 op2 = MASK_ADDU_OB(ctx->opcode); 13874 switch (op2) { 13875 case OPC_RADDU_L_OB: 13876 case OPC_SUBQ_PW: 13877 case OPC_SUBQ_S_PW: 13878 case OPC_SUBQ_QH: 13879 case OPC_SUBQ_S_QH: 13880 case OPC_SUBU_OB: 13881 case OPC_SUBU_S_OB: 13882 case OPC_SUBU_QH: 13883 case OPC_SUBU_S_QH: 13884 case OPC_SUBUH_OB: 13885 case OPC_SUBUH_R_OB: 13886 case OPC_ADDQ_PW: 13887 case OPC_ADDQ_S_PW: 13888 case OPC_ADDQ_QH: 13889 case OPC_ADDQ_S_QH: 13890 case OPC_ADDU_OB: 13891 case OPC_ADDU_S_OB: 13892 case OPC_ADDU_QH: 13893 case OPC_ADDU_S_QH: 13894 case OPC_ADDUH_OB: 13895 case OPC_ADDUH_R_OB: 13896 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13897 break; 13898 case OPC_MULEQ_S_PW_QHL: 13899 case OPC_MULEQ_S_PW_QHR: 13900 case OPC_MULEU_S_QH_OBL: 13901 case OPC_MULEU_S_QH_OBR: 13902 case OPC_MULQ_RS_QH: 13903 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13904 break; 13905 default: /* Invalid */ 13906 MIPS_INVAL("MASK ADDU.OB"); 13907 gen_reserved_instruction(ctx); 13908 break; 13909 } 13910 break; 13911 case OPC_CMPU_EQ_OB_DSP: 13912 op2 = MASK_CMPU_EQ_OB(ctx->opcode); 13913 switch (op2) { 13914 case OPC_PRECR_SRA_QH_PW: 13915 case OPC_PRECR_SRA_R_QH_PW: 13916 /* Return value is rt. */ 13917 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 13918 break; 13919 case OPC_PRECR_OB_QH: 13920 case OPC_PRECRQ_OB_QH: 13921 case OPC_PRECRQ_PW_L: 13922 case OPC_PRECRQ_QH_PW: 13923 case OPC_PRECRQ_RS_QH_PW: 13924 case OPC_PRECRQU_S_OB_QH: 13925 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13926 break; 13927 case OPC_CMPU_EQ_OB: 13928 case OPC_CMPU_LT_OB: 13929 case OPC_CMPU_LE_OB: 13930 case OPC_CMP_EQ_QH: 13931 case OPC_CMP_LT_QH: 13932 case OPC_CMP_LE_QH: 13933 case OPC_CMP_EQ_PW: 13934 case OPC_CMP_LT_PW: 13935 case OPC_CMP_LE_PW: 13936 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 13937 break; 13938 case OPC_CMPGDU_EQ_OB: 13939 case OPC_CMPGDU_LT_OB: 13940 case OPC_CMPGDU_LE_OB: 13941 case OPC_CMPGU_EQ_OB: 13942 case OPC_CMPGU_LT_OB: 13943 case OPC_CMPGU_LE_OB: 13944 case OPC_PACKRL_PW: 13945 case OPC_PICK_OB: 13946 case OPC_PICK_PW: 13947 case OPC_PICK_QH: 13948 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 13949 break; 13950 default: /* Invalid */ 13951 MIPS_INVAL("MASK CMPU_EQ.OB"); 13952 gen_reserved_instruction(ctx); 13953 break; 13954 } 13955 break; 13956 case OPC_DAPPEND_DSP: 13957 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 13958 break; 13959 case OPC_DEXTR_W_DSP: 13960 op2 = MASK_DEXTR_W(ctx->opcode); 13961 switch (op2) { 13962 case OPC_DEXTP: 13963 case OPC_DEXTPDP: 13964 case OPC_DEXTPDPV: 13965 case OPC_DEXTPV: 13966 case OPC_DEXTR_L: 13967 case OPC_DEXTR_R_L: 13968 case OPC_DEXTR_RS_L: 13969 case OPC_DEXTR_W: 13970 case OPC_DEXTR_R_W: 13971 case OPC_DEXTR_RS_W: 13972 case OPC_DEXTR_S_H: 13973 case OPC_DEXTRV_L: 13974 case OPC_DEXTRV_R_L: 13975 case OPC_DEXTRV_RS_L: 13976 case OPC_DEXTRV_S_H: 13977 case OPC_DEXTRV_W: 13978 case OPC_DEXTRV_R_W: 13979 case OPC_DEXTRV_RS_W: 13980 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 13981 break; 13982 case OPC_DMTHLIP: 13983 case OPC_DSHILO: 13984 case OPC_DSHILOV: 13985 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 13986 break; 13987 default: /* Invalid */ 13988 MIPS_INVAL("MASK EXTR.W"); 13989 gen_reserved_instruction(ctx); 13990 break; 13991 } 13992 break; 13993 case OPC_DPAQ_W_QH_DSP: 13994 op2 = MASK_DPAQ_W_QH(ctx->opcode); 13995 switch (op2) { 13996 case OPC_DPAU_H_OBL: 13997 case OPC_DPAU_H_OBR: 13998 case OPC_DPSU_H_OBL: 13999 case OPC_DPSU_H_OBR: 14000 case OPC_DPA_W_QH: 14001 case OPC_DPAQ_S_W_QH: 14002 case OPC_DPS_W_QH: 14003 case OPC_DPSQ_S_W_QH: 14004 case OPC_MULSAQ_S_W_QH: 14005 case OPC_DPAQ_SA_L_PW: 14006 case OPC_DPSQ_SA_L_PW: 14007 case OPC_MULSAQ_S_L_PW: 14008 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14009 break; 14010 case OPC_MAQ_S_W_QHLL: 14011 case OPC_MAQ_S_W_QHLR: 14012 case OPC_MAQ_S_W_QHRL: 14013 case OPC_MAQ_S_W_QHRR: 14014 case OPC_MAQ_SA_W_QHLL: 14015 case OPC_MAQ_SA_W_QHLR: 14016 case OPC_MAQ_SA_W_QHRL: 14017 case OPC_MAQ_SA_W_QHRR: 14018 case OPC_MAQ_S_L_PWL: 14019 case OPC_MAQ_S_L_PWR: 14020 case OPC_DMADD: 14021 case OPC_DMADDU: 14022 case OPC_DMSUB: 14023 case OPC_DMSUBU: 14024 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14025 break; 14026 default: /* Invalid */ 14027 MIPS_INVAL("MASK DPAQ.W.QH"); 14028 gen_reserved_instruction(ctx); 14029 break; 14030 } 14031 break; 14032 case OPC_DINSV_DSP: 14033 op2 = MASK_INSV(ctx->opcode); 14034 switch (op2) { 14035 case OPC_DINSV: 14036 { 14037 TCGv t0, t1; 14038 14039 check_dsp(ctx); 14040 14041 if (rt == 0) { 14042 break; 14043 } 14044 14045 t0 = tcg_temp_new(); 14046 t1 = tcg_temp_new(); 14047 14048 gen_load_gpr(t0, rt); 14049 gen_load_gpr(t1, rs); 14050 14051 gen_helper_dinsv(cpu_gpr[rt], tcg_env, t1, t0); 14052 break; 14053 } 14054 default: /* Invalid */ 14055 MIPS_INVAL("MASK DINSV"); 14056 gen_reserved_instruction(ctx); 14057 break; 14058 } 14059 break; 14060 case OPC_SHLL_OB_DSP: 14061 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14062 break; 14063 #endif 14064 default: /* Invalid */ 14065 MIPS_INVAL("special3_legacy"); 14066 gen_reserved_instruction(ctx); 14067 break; 14068 } 14069 } 14070 14071 14072 #if defined(TARGET_MIPS64) 14073 14074 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) 14075 { 14076 uint32_t opc = MASK_MMI(ctx->opcode); 14077 int rs = extract32(ctx->opcode, 21, 5); 14078 int rt = extract32(ctx->opcode, 16, 5); 14079 int rd = extract32(ctx->opcode, 11, 5); 14080 14081 switch (opc) { 14082 case MMI_OPC_MULT1: 14083 case MMI_OPC_MULTU1: 14084 case MMI_OPC_MADD: 14085 case MMI_OPC_MADDU: 14086 case MMI_OPC_MADD1: 14087 case MMI_OPC_MADDU1: 14088 gen_mul_txx9(ctx, opc, rd, rs, rt); 14089 break; 14090 case MMI_OPC_DIV1: 14091 case MMI_OPC_DIVU1: 14092 gen_div1_tx79(ctx, opc, rs, rt); 14093 break; 14094 default: 14095 MIPS_INVAL("TX79 MMI class"); 14096 gen_reserved_instruction(ctx); 14097 break; 14098 } 14099 } 14100 14101 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset) 14102 { 14103 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */ 14104 } 14105 14106 /* 14107 * The TX79-specific instruction Store Quadword 14108 * 14109 * +--------+-------+-------+------------------------+ 14110 * | 011111 | base | rt | offset | SQ 14111 * +--------+-------+-------+------------------------+ 14112 * 6 5 5 16 14113 * 14114 * has the same opcode as the Read Hardware Register instruction 14115 * 14116 * +--------+-------+-------+-------+-------+--------+ 14117 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR 14118 * +--------+-------+-------+-------+-------+--------+ 14119 * 6 5 5 5 5 6 14120 * 14121 * that is required, trapped and emulated by the Linux kernel. However, all 14122 * RDHWR encodings yield address error exceptions on the TX79 since the SQ 14123 * offset is odd. Therefore all valid SQ instructions can execute normally. 14124 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish 14125 * between SQ and RDHWR, as the Linux kernel does. 14126 */ 14127 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx) 14128 { 14129 int base = extract32(ctx->opcode, 21, 5); 14130 int rt = extract32(ctx->opcode, 16, 5); 14131 int offset = extract32(ctx->opcode, 0, 16); 14132 14133 #ifdef CONFIG_USER_ONLY 14134 uint32_t op1 = MASK_SPECIAL3(ctx->opcode); 14135 uint32_t op2 = extract32(ctx->opcode, 6, 5); 14136 14137 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) { 14138 int rd = extract32(ctx->opcode, 11, 5); 14139 14140 gen_rdhwr(ctx, rt, rd, 0); 14141 return; 14142 } 14143 #endif 14144 14145 gen_mmi_sq(ctx, base, rt, offset); 14146 } 14147 14148 #endif 14149 14150 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) 14151 { 14152 int rs, rt, rd, sa; 14153 uint32_t op1, op2; 14154 int16_t imm; 14155 14156 rs = (ctx->opcode >> 21) & 0x1f; 14157 rt = (ctx->opcode >> 16) & 0x1f; 14158 rd = (ctx->opcode >> 11) & 0x1f; 14159 sa = (ctx->opcode >> 6) & 0x1f; 14160 imm = sextract32(ctx->opcode, 7, 9); 14161 14162 op1 = MASK_SPECIAL3(ctx->opcode); 14163 14164 /* 14165 * EVA loads and stores overlap Loongson 2E instructions decoded by 14166 * decode_opc_special3_legacy(), so be careful to allow their decoding when 14167 * EVA is absent. 14168 */ 14169 if (ctx->eva) { 14170 switch (op1) { 14171 case OPC_LWLE: 14172 case OPC_LWRE: 14173 case OPC_LBUE: 14174 case OPC_LHUE: 14175 case OPC_LBE: 14176 case OPC_LHE: 14177 case OPC_LLE: 14178 case OPC_LWE: 14179 check_cp0_enabled(ctx); 14180 gen_ld(ctx, op1, rt, rs, imm); 14181 return; 14182 case OPC_SWLE: 14183 case OPC_SWRE: 14184 case OPC_SBE: 14185 case OPC_SHE: 14186 case OPC_SWE: 14187 check_cp0_enabled(ctx); 14188 gen_st(ctx, op1, rt, rs, imm); 14189 return; 14190 case OPC_SCE: 14191 check_cp0_enabled(ctx); 14192 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, true); 14193 return; 14194 case OPC_CACHEE: 14195 check_eva(ctx); 14196 check_cp0_enabled(ctx); 14197 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14198 gen_cache_operation(ctx, rt, rs, imm); 14199 } 14200 return; 14201 case OPC_PREFE: 14202 check_cp0_enabled(ctx); 14203 /* Treat as NOP. */ 14204 return; 14205 } 14206 } 14207 14208 switch (op1) { 14209 case OPC_EXT: 14210 case OPC_INS: 14211 check_insn(ctx, ISA_MIPS_R2); 14212 gen_bitops(ctx, op1, rt, rs, sa, rd); 14213 break; 14214 case OPC_BSHFL: 14215 op2 = MASK_BSHFL(ctx->opcode); 14216 switch (op2) { 14217 case OPC_ALIGN: 14218 case OPC_ALIGN_1: 14219 case OPC_ALIGN_2: 14220 case OPC_ALIGN_3: 14221 case OPC_BITSWAP: 14222 check_insn(ctx, ISA_MIPS_R6); 14223 decode_opc_special3_r6(env, ctx); 14224 break; 14225 default: 14226 check_insn(ctx, ISA_MIPS_R2); 14227 gen_bshfl(ctx, op2, rt, rd); 14228 break; 14229 } 14230 break; 14231 #if defined(TARGET_MIPS64) 14232 case OPC_DEXTM: 14233 case OPC_DEXTU: 14234 case OPC_DEXT: 14235 case OPC_DINSM: 14236 case OPC_DINSU: 14237 case OPC_DINS: 14238 check_insn(ctx, ISA_MIPS_R2); 14239 check_mips_64(ctx); 14240 gen_bitops(ctx, op1, rt, rs, sa, rd); 14241 break; 14242 case OPC_DBSHFL: 14243 op2 = MASK_DBSHFL(ctx->opcode); 14244 switch (op2) { 14245 case OPC_DALIGN: 14246 case OPC_DALIGN_1: 14247 case OPC_DALIGN_2: 14248 case OPC_DALIGN_3: 14249 case OPC_DALIGN_4: 14250 case OPC_DALIGN_5: 14251 case OPC_DALIGN_6: 14252 case OPC_DALIGN_7: 14253 case OPC_DBITSWAP: 14254 check_insn(ctx, ISA_MIPS_R6); 14255 decode_opc_special3_r6(env, ctx); 14256 break; 14257 default: 14258 check_insn(ctx, ISA_MIPS_R2); 14259 check_mips_64(ctx); 14260 op2 = MASK_DBSHFL(ctx->opcode); 14261 gen_bshfl(ctx, op2, rt, rd); 14262 break; 14263 } 14264 break; 14265 #endif 14266 case OPC_RDHWR: 14267 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3)); 14268 break; 14269 case OPC_FORK: 14270 check_mt(ctx); 14271 { 14272 TCGv t0 = tcg_temp_new(); 14273 TCGv t1 = tcg_temp_new(); 14274 14275 gen_load_gpr(t0, rt); 14276 gen_load_gpr(t1, rs); 14277 gen_helper_fork(t0, t1); 14278 } 14279 break; 14280 case OPC_YIELD: 14281 check_mt(ctx); 14282 { 14283 TCGv t0 = tcg_temp_new(); 14284 14285 gen_load_gpr(t0, rs); 14286 gen_helper_yield(t0, tcg_env, t0); 14287 gen_store_gpr(t0, rd); 14288 } 14289 break; 14290 default: 14291 if (ctx->insn_flags & ISA_MIPS_R6) { 14292 decode_opc_special3_r6(env, ctx); 14293 } else { 14294 decode_opc_special3_legacy(env, ctx); 14295 } 14296 } 14297 } 14298 14299 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) 14300 { 14301 int32_t offset; 14302 int rs, rt, rd, sa; 14303 uint32_t op, op1; 14304 int16_t imm; 14305 14306 op = MASK_OP_MAJOR(ctx->opcode); 14307 rs = (ctx->opcode >> 21) & 0x1f; 14308 rt = (ctx->opcode >> 16) & 0x1f; 14309 rd = (ctx->opcode >> 11) & 0x1f; 14310 sa = (ctx->opcode >> 6) & 0x1f; 14311 imm = (int16_t)ctx->opcode; 14312 switch (op) { 14313 case OPC_SPECIAL: 14314 decode_opc_special(env, ctx); 14315 break; 14316 case OPC_SPECIAL2: 14317 #if defined(TARGET_MIPS64) 14318 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { 14319 decode_mmi(env, ctx); 14320 break; 14321 } 14322 #endif 14323 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) { 14324 if (decode_ase_mxu(ctx, ctx->opcode)) { 14325 break; 14326 } 14327 } 14328 decode_opc_special2_legacy(env, ctx); 14329 break; 14330 case OPC_SPECIAL3: 14331 #if defined(TARGET_MIPS64) 14332 if (ctx->insn_flags & INSN_R5900) { 14333 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ 14334 } else { 14335 decode_opc_special3(env, ctx); 14336 } 14337 #else 14338 decode_opc_special3(env, ctx); 14339 #endif 14340 break; 14341 case OPC_REGIMM: 14342 op1 = MASK_REGIMM(ctx->opcode); 14343 switch (op1) { 14344 case OPC_BLTZL: /* REGIMM branches */ 14345 case OPC_BGEZL: 14346 case OPC_BLTZALL: 14347 case OPC_BGEZALL: 14348 check_insn(ctx, ISA_MIPS2); 14349 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14350 /* Fallthrough */ 14351 case OPC_BLTZ: 14352 case OPC_BGEZ: 14353 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 14354 break; 14355 case OPC_BLTZAL: 14356 case OPC_BGEZAL: 14357 if (ctx->insn_flags & ISA_MIPS_R6) { 14358 if (rs == 0) { 14359 /* OPC_NAL, OPC_BAL */ 14360 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); 14361 } else { 14362 gen_reserved_instruction(ctx); 14363 } 14364 } else { 14365 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 14366 } 14367 break; 14368 case OPC_TGEI: /* REGIMM traps */ 14369 case OPC_TGEIU: 14370 case OPC_TLTI: 14371 case OPC_TLTIU: 14372 case OPC_TEQI: 14373 case OPC_TNEI: 14374 check_insn(ctx, ISA_MIPS2); 14375 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14376 gen_trap(ctx, op1, rs, -1, imm, 0); 14377 break; 14378 case OPC_SIGRIE: 14379 check_insn(ctx, ISA_MIPS_R6); 14380 gen_reserved_instruction(ctx); 14381 break; 14382 case OPC_SYNCI: 14383 check_insn(ctx, ISA_MIPS_R2); 14384 /* 14385 * Break the TB to be able to sync copied instructions 14386 * immediately. 14387 */ 14388 ctx->base.is_jmp = DISAS_STOP; 14389 break; 14390 case OPC_BPOSGE32: /* MIPS DSP branch */ 14391 #if defined(TARGET_MIPS64) 14392 case OPC_BPOSGE64: 14393 #endif 14394 check_dsp(ctx); 14395 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); 14396 break; 14397 #if defined(TARGET_MIPS64) 14398 case OPC_DAHI: 14399 check_insn(ctx, ISA_MIPS_R6); 14400 check_mips_64(ctx); 14401 if (rs != 0) { 14402 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); 14403 } 14404 break; 14405 case OPC_DATI: 14406 check_insn(ctx, ISA_MIPS_R6); 14407 check_mips_64(ctx); 14408 if (rs != 0) { 14409 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); 14410 } 14411 break; 14412 #endif 14413 default: /* Invalid */ 14414 MIPS_INVAL("regimm"); 14415 gen_reserved_instruction(ctx); 14416 break; 14417 } 14418 break; 14419 case OPC_CP0: 14420 check_cp0_enabled(ctx); 14421 op1 = MASK_CP0(ctx->opcode); 14422 switch (op1) { 14423 case OPC_MFC0: 14424 case OPC_MTC0: 14425 case OPC_MFTR: 14426 case OPC_MTTR: 14427 case OPC_MFHC0: 14428 case OPC_MTHC0: 14429 #if defined(TARGET_MIPS64) 14430 case OPC_DMFC0: 14431 case OPC_DMTC0: 14432 #endif 14433 #ifndef CONFIG_USER_ONLY 14434 gen_cp0(env, ctx, op1, rt, rd); 14435 #endif /* !CONFIG_USER_ONLY */ 14436 break; 14437 case OPC_C0: 14438 case OPC_C0_1: 14439 case OPC_C0_2: 14440 case OPC_C0_3: 14441 case OPC_C0_4: 14442 case OPC_C0_5: 14443 case OPC_C0_6: 14444 case OPC_C0_7: 14445 case OPC_C0_8: 14446 case OPC_C0_9: 14447 case OPC_C0_A: 14448 case OPC_C0_B: 14449 case OPC_C0_C: 14450 case OPC_C0_D: 14451 case OPC_C0_E: 14452 case OPC_C0_F: 14453 #ifndef CONFIG_USER_ONLY 14454 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 14455 #endif /* !CONFIG_USER_ONLY */ 14456 break; 14457 case OPC_MFMC0: 14458 #ifndef CONFIG_USER_ONLY 14459 { 14460 uint32_t op2; 14461 TCGv t0 = tcg_temp_new(); 14462 14463 op2 = MASK_MFMC0(ctx->opcode); 14464 switch (op2) { 14465 case OPC_DMT: 14466 check_cp0_mt(ctx); 14467 gen_helper_dmt(t0); 14468 gen_store_gpr(t0, rt); 14469 break; 14470 case OPC_EMT: 14471 check_cp0_mt(ctx); 14472 gen_helper_emt(t0); 14473 gen_store_gpr(t0, rt); 14474 break; 14475 case OPC_DVPE: 14476 check_cp0_mt(ctx); 14477 gen_helper_dvpe(t0, tcg_env); 14478 gen_store_gpr(t0, rt); 14479 break; 14480 case OPC_EVPE: 14481 check_cp0_mt(ctx); 14482 gen_helper_evpe(t0, tcg_env); 14483 gen_store_gpr(t0, rt); 14484 break; 14485 case OPC_DVP: 14486 check_insn(ctx, ISA_MIPS_R6); 14487 if (ctx->vp) { 14488 gen_helper_dvp(t0, tcg_env); 14489 gen_store_gpr(t0, rt); 14490 } 14491 break; 14492 case OPC_EVP: 14493 check_insn(ctx, ISA_MIPS_R6); 14494 if (ctx->vp) { 14495 gen_helper_evp(t0, tcg_env); 14496 gen_store_gpr(t0, rt); 14497 } 14498 break; 14499 case OPC_DI: 14500 check_insn(ctx, ISA_MIPS_R2); 14501 save_cpu_state(ctx, 1); 14502 gen_helper_di(t0, tcg_env); 14503 gen_store_gpr(t0, rt); 14504 /* 14505 * Stop translation as we may have switched 14506 * the execution mode. 14507 */ 14508 ctx->base.is_jmp = DISAS_STOP; 14509 break; 14510 case OPC_EI: 14511 check_insn(ctx, ISA_MIPS_R2); 14512 save_cpu_state(ctx, 1); 14513 gen_helper_ei(t0, tcg_env); 14514 gen_store_gpr(t0, rt); 14515 /* 14516 * DISAS_STOP isn't sufficient, we need to ensure we break 14517 * out of translated code to check for pending interrupts. 14518 */ 14519 gen_save_pc(ctx->base.pc_next + 4); 14520 ctx->base.is_jmp = DISAS_EXIT; 14521 break; 14522 default: /* Invalid */ 14523 MIPS_INVAL("mfmc0"); 14524 gen_reserved_instruction(ctx); 14525 break; 14526 } 14527 } 14528 #endif /* !CONFIG_USER_ONLY */ 14529 break; 14530 case OPC_RDPGPR: 14531 check_insn(ctx, ISA_MIPS_R2); 14532 gen_load_srsgpr(rt, rd); 14533 break; 14534 case OPC_WRPGPR: 14535 check_insn(ctx, ISA_MIPS_R2); 14536 gen_store_srsgpr(rt, rd); 14537 break; 14538 default: 14539 MIPS_INVAL("cp0"); 14540 gen_reserved_instruction(ctx); 14541 break; 14542 } 14543 break; 14544 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */ 14545 if (ctx->insn_flags & ISA_MIPS_R6) { 14546 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */ 14547 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14548 } else { 14549 /* OPC_ADDI */ 14550 /* Arithmetic with immediate opcode */ 14551 gen_arith_imm(ctx, op, rt, rs, imm); 14552 } 14553 break; 14554 case OPC_ADDIU: 14555 gen_arith_imm(ctx, op, rt, rs, imm); 14556 break; 14557 case OPC_SLTI: /* Set on less than with immediate opcode */ 14558 case OPC_SLTIU: 14559 gen_slt_imm(ctx, op, rt, rs, imm); 14560 break; 14561 case OPC_ANDI: /* Arithmetic with immediate opcode */ 14562 case OPC_LUI: /* OPC_AUI */ 14563 case OPC_ORI: 14564 case OPC_XORI: 14565 gen_logic_imm(ctx, op, rt, rs, imm); 14566 break; 14567 case OPC_J: /* Jump */ 14568 case OPC_JAL: 14569 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 14570 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 14571 break; 14572 /* Branch */ 14573 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ 14574 if (ctx->insn_flags & ISA_MIPS_R6) { 14575 if (rt == 0) { 14576 gen_reserved_instruction(ctx); 14577 break; 14578 } 14579 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */ 14580 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14581 } else { 14582 /* OPC_BLEZL */ 14583 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14584 } 14585 break; 14586 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ 14587 if (ctx->insn_flags & ISA_MIPS_R6) { 14588 if (rt == 0) { 14589 gen_reserved_instruction(ctx); 14590 break; 14591 } 14592 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */ 14593 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14594 } else { 14595 /* OPC_BGTZL */ 14596 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14597 } 14598 break; 14599 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */ 14600 if (rt == 0) { 14601 /* OPC_BLEZ */ 14602 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14603 } else { 14604 check_insn(ctx, ISA_MIPS_R6); 14605 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */ 14606 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14607 } 14608 break; 14609 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */ 14610 if (rt == 0) { 14611 /* OPC_BGTZ */ 14612 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14613 } else { 14614 check_insn(ctx, ISA_MIPS_R6); 14615 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */ 14616 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14617 } 14618 break; 14619 case OPC_BEQL: 14620 case OPC_BNEL: 14621 check_insn(ctx, ISA_MIPS2); 14622 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14623 /* Fallthrough */ 14624 case OPC_BEQ: 14625 case OPC_BNE: 14626 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14627 break; 14628 case OPC_LL: /* Load and stores */ 14629 check_insn(ctx, ISA_MIPS2); 14630 if (ctx->insn_flags & INSN_R5900) { 14631 check_insn_opc_user_only(ctx, INSN_R5900); 14632 } 14633 /* Fallthrough */ 14634 case OPC_LWL: 14635 case OPC_LWR: 14636 case OPC_LB: 14637 case OPC_LH: 14638 case OPC_LW: 14639 case OPC_LWPC: 14640 case OPC_LBU: 14641 case OPC_LHU: 14642 gen_ld(ctx, op, rt, rs, imm); 14643 break; 14644 case OPC_SWL: 14645 case OPC_SWR: 14646 case OPC_SB: 14647 case OPC_SH: 14648 case OPC_SW: 14649 gen_st(ctx, op, rt, rs, imm); 14650 break; 14651 case OPC_SC: 14652 check_insn(ctx, ISA_MIPS2); 14653 if (ctx->insn_flags & INSN_R5900) { 14654 check_insn_opc_user_only(ctx, INSN_R5900); 14655 } 14656 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false); 14657 break; 14658 case OPC_CACHE: 14659 check_cp0_enabled(ctx); 14660 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 14661 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14662 gen_cache_operation(ctx, rt, rs, imm); 14663 } 14664 /* Treat as NOP. */ 14665 break; 14666 case OPC_PREF: 14667 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900); 14668 /* Treat as NOP. */ 14669 break; 14670 14671 /* Floating point (COP1). */ 14672 case OPC_LWC1: 14673 case OPC_LDC1: 14674 case OPC_SWC1: 14675 case OPC_SDC1: 14676 gen_cop1_ldst(ctx, op, rt, rs, imm); 14677 break; 14678 14679 case OPC_CP1: 14680 op1 = MASK_CP1(ctx->opcode); 14681 14682 switch (op1) { 14683 case OPC_MFHC1: 14684 case OPC_MTHC1: 14685 check_cp1_enabled(ctx); 14686 check_insn(ctx, ISA_MIPS_R2); 14687 /* fall through */ 14688 case OPC_MFC1: 14689 case OPC_CFC1: 14690 case OPC_MTC1: 14691 case OPC_CTC1: 14692 check_cp1_enabled(ctx); 14693 gen_cp1(ctx, op1, rt, rd); 14694 break; 14695 #if defined(TARGET_MIPS64) 14696 case OPC_DMFC1: 14697 case OPC_DMTC1: 14698 check_cp1_enabled(ctx); 14699 check_insn(ctx, ISA_MIPS3); 14700 check_mips_64(ctx); 14701 gen_cp1(ctx, op1, rt, rd); 14702 break; 14703 #endif 14704 case OPC_BC1EQZ: /* OPC_BC1ANY2 */ 14705 check_cp1_enabled(ctx); 14706 if (ctx->insn_flags & ISA_MIPS_R6) { 14707 /* OPC_BC1EQZ */ 14708 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 14709 rt, imm << 2, 4); 14710 } else { 14711 /* OPC_BC1ANY2 */ 14712 check_cop1x(ctx); 14713 if (!ase_3d_available(env)) { 14714 return false; 14715 } 14716 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 14717 (rt >> 2) & 0x7, imm << 2); 14718 } 14719 break; 14720 case OPC_BC1NEZ: 14721 check_cp1_enabled(ctx); 14722 check_insn(ctx, ISA_MIPS_R6); 14723 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 14724 rt, imm << 2, 4); 14725 break; 14726 case OPC_BC1ANY4: 14727 check_cp1_enabled(ctx); 14728 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14729 check_cop1x(ctx); 14730 if (!ase_3d_available(env)) { 14731 return false; 14732 } 14733 /* fall through */ 14734 case OPC_BC1: 14735 check_cp1_enabled(ctx); 14736 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14737 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 14738 (rt >> 2) & 0x7, imm << 2); 14739 break; 14740 case OPC_PS_FMT: 14741 check_ps(ctx); 14742 /* fall through */ 14743 case OPC_S_FMT: 14744 case OPC_D_FMT: 14745 check_cp1_enabled(ctx); 14746 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 14747 (imm >> 8) & 0x7); 14748 break; 14749 case OPC_W_FMT: 14750 case OPC_L_FMT: 14751 { 14752 int r6_op = ctx->opcode & FOP(0x3f, 0x1f); 14753 check_cp1_enabled(ctx); 14754 if (ctx->insn_flags & ISA_MIPS_R6) { 14755 switch (r6_op) { 14756 case R6_OPC_CMP_AF_S: 14757 case R6_OPC_CMP_UN_S: 14758 case R6_OPC_CMP_EQ_S: 14759 case R6_OPC_CMP_UEQ_S: 14760 case R6_OPC_CMP_LT_S: 14761 case R6_OPC_CMP_ULT_S: 14762 case R6_OPC_CMP_LE_S: 14763 case R6_OPC_CMP_ULE_S: 14764 case R6_OPC_CMP_SAF_S: 14765 case R6_OPC_CMP_SUN_S: 14766 case R6_OPC_CMP_SEQ_S: 14767 case R6_OPC_CMP_SEUQ_S: 14768 case R6_OPC_CMP_SLT_S: 14769 case R6_OPC_CMP_SULT_S: 14770 case R6_OPC_CMP_SLE_S: 14771 case R6_OPC_CMP_SULE_S: 14772 case R6_OPC_CMP_OR_S: 14773 case R6_OPC_CMP_UNE_S: 14774 case R6_OPC_CMP_NE_S: 14775 case R6_OPC_CMP_SOR_S: 14776 case R6_OPC_CMP_SUNE_S: 14777 case R6_OPC_CMP_SNE_S: 14778 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa); 14779 break; 14780 case R6_OPC_CMP_AF_D: 14781 case R6_OPC_CMP_UN_D: 14782 case R6_OPC_CMP_EQ_D: 14783 case R6_OPC_CMP_UEQ_D: 14784 case R6_OPC_CMP_LT_D: 14785 case R6_OPC_CMP_ULT_D: 14786 case R6_OPC_CMP_LE_D: 14787 case R6_OPC_CMP_ULE_D: 14788 case R6_OPC_CMP_SAF_D: 14789 case R6_OPC_CMP_SUN_D: 14790 case R6_OPC_CMP_SEQ_D: 14791 case R6_OPC_CMP_SEUQ_D: 14792 case R6_OPC_CMP_SLT_D: 14793 case R6_OPC_CMP_SULT_D: 14794 case R6_OPC_CMP_SLE_D: 14795 case R6_OPC_CMP_SULE_D: 14796 case R6_OPC_CMP_OR_D: 14797 case R6_OPC_CMP_UNE_D: 14798 case R6_OPC_CMP_NE_D: 14799 case R6_OPC_CMP_SOR_D: 14800 case R6_OPC_CMP_SUNE_D: 14801 case R6_OPC_CMP_SNE_D: 14802 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa); 14803 break; 14804 default: 14805 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), 14806 rt, rd, sa, (imm >> 8) & 0x7); 14807 14808 break; 14809 } 14810 } else { 14811 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 14812 (imm >> 8) & 0x7); 14813 } 14814 break; 14815 } 14816 default: 14817 MIPS_INVAL("cp1"); 14818 gen_reserved_instruction(ctx); 14819 break; 14820 } 14821 break; 14822 14823 /* Compact branches [R6] and COP2 [non-R6] */ 14824 case OPC_BC: /* OPC_LWC2 */ 14825 case OPC_BALC: /* OPC_SWC2 */ 14826 if (ctx->insn_flags & ISA_MIPS_R6) { 14827 /* OPC_BC, OPC_BALC */ 14828 gen_compute_compact_branch(ctx, op, 0, 0, 14829 sextract32(ctx->opcode << 2, 0, 28)); 14830 } else if (ctx->insn_flags & ASE_LEXT) { 14831 gen_loongson_lswc2(ctx, rt, rs, rd); 14832 } else { 14833 /* OPC_LWC2, OPC_SWC2 */ 14834 /* COP2: Not implemented. */ 14835 generate_exception_err(ctx, EXCP_CpU, 2); 14836 } 14837 break; 14838 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */ 14839 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */ 14840 if (ctx->insn_flags & ISA_MIPS_R6) { 14841 if (rs != 0) { 14842 /* OPC_BEQZC, OPC_BNEZC */ 14843 gen_compute_compact_branch(ctx, op, rs, 0, 14844 sextract32(ctx->opcode << 2, 0, 23)); 14845 } else { 14846 /* OPC_JIC, OPC_JIALC */ 14847 gen_compute_compact_branch(ctx, op, 0, rt, imm); 14848 } 14849 } else if (ctx->insn_flags & ASE_LEXT) { 14850 gen_loongson_lsdc2(ctx, rt, rs, rd); 14851 } else { 14852 /* OPC_LWC2, OPC_SWC2 */ 14853 /* COP2: Not implemented. */ 14854 generate_exception_err(ctx, EXCP_CpU, 2); 14855 } 14856 break; 14857 case OPC_CP2: 14858 check_insn(ctx, ASE_LMMI); 14859 /* Note that these instructions use different fields. */ 14860 gen_loongson_multimedia(ctx, sa, rd, rt); 14861 break; 14862 14863 case OPC_CP3: 14864 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 14865 check_cp1_enabled(ctx); 14866 op1 = MASK_CP3(ctx->opcode); 14867 switch (op1) { 14868 case OPC_LUXC1: 14869 case OPC_SUXC1: 14870 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 14871 /* Fallthrough */ 14872 case OPC_LWXC1: 14873 case OPC_LDXC1: 14874 case OPC_SWXC1: 14875 case OPC_SDXC1: 14876 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14877 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 14878 break; 14879 case OPC_PREFX: 14880 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14881 /* Treat as NOP. */ 14882 break; 14883 case OPC_ALNV_PS: 14884 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 14885 /* Fallthrough */ 14886 case OPC_MADD_S: 14887 case OPC_MADD_D: 14888 case OPC_MADD_PS: 14889 case OPC_MSUB_S: 14890 case OPC_MSUB_D: 14891 case OPC_MSUB_PS: 14892 case OPC_NMADD_S: 14893 case OPC_NMADD_D: 14894 case OPC_NMADD_PS: 14895 case OPC_NMSUB_S: 14896 case OPC_NMSUB_D: 14897 case OPC_NMSUB_PS: 14898 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14899 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 14900 break; 14901 default: 14902 MIPS_INVAL("cp3"); 14903 gen_reserved_instruction(ctx); 14904 break; 14905 } 14906 } else { 14907 generate_exception_err(ctx, EXCP_CpU, 1); 14908 } 14909 break; 14910 14911 #if defined(TARGET_MIPS64) 14912 /* MIPS64 opcodes */ 14913 case OPC_LLD: 14914 if (ctx->insn_flags & INSN_R5900) { 14915 check_insn_opc_user_only(ctx, INSN_R5900); 14916 } 14917 /* fall through */ 14918 case OPC_LDL: 14919 case OPC_LDR: 14920 case OPC_LWU: 14921 case OPC_LD: 14922 check_insn(ctx, ISA_MIPS3); 14923 check_mips_64(ctx); 14924 gen_ld(ctx, op, rt, rs, imm); 14925 break; 14926 case OPC_SDL: 14927 case OPC_SDR: 14928 case OPC_SD: 14929 check_insn(ctx, ISA_MIPS3); 14930 check_mips_64(ctx); 14931 gen_st(ctx, op, rt, rs, imm); 14932 break; 14933 case OPC_SCD: 14934 check_insn(ctx, ISA_MIPS3); 14935 if (ctx->insn_flags & INSN_R5900) { 14936 check_insn_opc_user_only(ctx, INSN_R5900); 14937 } 14938 check_mips_64(ctx); 14939 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false); 14940 break; 14941 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ 14942 if (ctx->insn_flags & ISA_MIPS_R6) { 14943 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */ 14944 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14945 } else { 14946 /* OPC_DADDI */ 14947 check_insn(ctx, ISA_MIPS3); 14948 check_mips_64(ctx); 14949 gen_arith_imm(ctx, op, rt, rs, imm); 14950 } 14951 break; 14952 case OPC_DADDIU: 14953 check_insn(ctx, ISA_MIPS3); 14954 check_mips_64(ctx); 14955 gen_arith_imm(ctx, op, rt, rs, imm); 14956 break; 14957 #else 14958 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 14959 if (ctx->insn_flags & ISA_MIPS_R6) { 14960 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14961 } else { 14962 MIPS_INVAL("major opcode"); 14963 gen_reserved_instruction(ctx); 14964 } 14965 break; 14966 #endif 14967 case OPC_DAUI: /* OPC_JALX */ 14968 if (ctx->insn_flags & ISA_MIPS_R6) { 14969 #if defined(TARGET_MIPS64) 14970 /* OPC_DAUI */ 14971 check_mips_64(ctx); 14972 if (rs == 0) { 14973 generate_exception(ctx, EXCP_RI); 14974 } else if (rt != 0) { 14975 TCGv t0 = tcg_temp_new(); 14976 gen_load_gpr(t0, rs); 14977 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16); 14978 } 14979 #else 14980 gen_reserved_instruction(ctx); 14981 MIPS_INVAL("major opcode"); 14982 #endif 14983 } else { 14984 /* OPC_JALX */ 14985 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS); 14986 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 14987 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 14988 } 14989 break; 14990 case OPC_MDMX: 14991 /* MDMX: Not implemented. */ 14992 break; 14993 case OPC_PCREL: 14994 check_insn(ctx, ISA_MIPS_R6); 14995 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs); 14996 break; 14997 default: /* Invalid */ 14998 MIPS_INVAL("major opcode"); 14999 return false; 15000 } 15001 return true; 15002 } 15003 15004 static void decode_opc(CPUMIPSState *env, DisasContext *ctx) 15005 { 15006 /* make sure instructions are on a word boundary */ 15007 if (ctx->base.pc_next & 0x3) { 15008 env->CP0_BadVAddr = ctx->base.pc_next; 15009 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); 15010 return; 15011 } 15012 15013 /* Handle blikely not taken case */ 15014 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { 15015 TCGLabel *l1 = gen_new_label(); 15016 15017 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 15018 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 15019 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); 15020 gen_set_label(l1); 15021 } 15022 15023 /* Transition to the auto-generated decoder. */ 15024 15025 /* Vendor specific extensions */ 15026 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { 15027 return; 15028 } 15029 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) { 15030 return; 15031 } 15032 if (TARGET_LONG_BITS == 64 && decode_ext_loongson(ctx, ctx->opcode)) { 15033 return; 15034 } 15035 #if defined(TARGET_MIPS64) 15036 if (ase_lcsr_available(env) && decode_ase_lcsr(ctx, ctx->opcode)) { 15037 return; 15038 } 15039 if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) { 15040 return; 15041 } 15042 #endif 15043 15044 /* ISA extensions */ 15045 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) { 15046 return; 15047 } 15048 15049 /* ISA (from latest to oldest) */ 15050 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) { 15051 return; 15052 } 15053 15054 if (decode_opc_legacy(env, ctx)) { 15055 return; 15056 } 15057 15058 gen_reserved_instruction(ctx); 15059 } 15060 15061 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 15062 { 15063 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15064 CPUMIPSState *env = cpu_env(cs); 15065 15066 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; 15067 ctx->saved_pc = -1; 15068 ctx->insn_flags = env->insn_flags; 15069 ctx->CP0_Config0 = env->CP0_Config0; 15070 ctx->CP0_Config1 = env->CP0_Config1; 15071 ctx->CP0_Config2 = env->CP0_Config2; 15072 ctx->CP0_Config3 = env->CP0_Config3; 15073 ctx->CP0_Config5 = env->CP0_Config5; 15074 ctx->btarget = 0; 15075 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; 15076 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; 15077 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3; 15078 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1; 15079 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1; 15080 ctx->PAMask = env->PAMask; 15081 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; 15082 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; 15083 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1; 15084 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift; 15085 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; 15086 /* Restore delay slot state from the tb context. */ 15087 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ 15088 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; 15089 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || 15090 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); 15091 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1; 15092 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; 15093 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; 15094 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; 15095 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1; 15096 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3; 15097 restore_cpu_state(env, ctx); 15098 #ifdef CONFIG_USER_ONLY 15099 ctx->mem_idx = MIPS_HFLAG_UM; 15100 #else 15101 ctx->mem_idx = hflags_mmu_index(ctx->hflags); 15102 #endif 15103 ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) && 15104 (ctx->insn_flags & (ISA_MIPS_R6 | 15105 INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN; 15106 15107 /* 15108 * Execute a branch and its delay slot as a single instruction. 15109 * This is what GDB expects and is consistent with what the 15110 * hardware does (e.g. if a delay slot instruction faults, the 15111 * reported PC is the PC of the branch). 15112 */ 15113 if ((tb_cflags(ctx->base.tb) & CF_SINGLE_STEP) && 15114 (ctx->hflags & MIPS_HFLAG_BMASK)) { 15115 ctx->base.max_insns = 2; 15116 } 15117 15118 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, 15119 ctx->hflags); 15120 } 15121 15122 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) 15123 { 15124 } 15125 15126 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 15127 { 15128 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15129 15130 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, 15131 ctx->btarget); 15132 } 15133 15134 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 15135 { 15136 CPUMIPSState *env = cpu_env(cs); 15137 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15138 int insn_bytes; 15139 int is_slot; 15140 15141 is_slot = ctx->hflags & MIPS_HFLAG_BMASK; 15142 if (ctx->insn_flags & ISA_NANOMIPS32) { 15143 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15144 insn_bytes = decode_isa_nanomips(env, ctx); 15145 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) { 15146 ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next); 15147 insn_bytes = 4; 15148 decode_opc(env, ctx); 15149 } else if (ctx->insn_flags & ASE_MICROMIPS) { 15150 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15151 insn_bytes = decode_isa_micromips(env, ctx); 15152 } else if (ctx->insn_flags & ASE_MIPS16) { 15153 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15154 insn_bytes = decode_ase_mips16e(env, ctx); 15155 } else { 15156 gen_reserved_instruction(ctx); 15157 g_assert(ctx->base.is_jmp == DISAS_NORETURN); 15158 return; 15159 } 15160 15161 if (ctx->hflags & MIPS_HFLAG_BMASK) { 15162 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 | 15163 MIPS_HFLAG_FBNSLOT))) { 15164 /* 15165 * Force to generate branch as there is neither delay nor 15166 * forbidden slot. 15167 */ 15168 is_slot = 1; 15169 } 15170 if ((ctx->hflags & MIPS_HFLAG_M16) && 15171 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) { 15172 /* 15173 * Force to generate branch as microMIPS R6 doesn't restrict 15174 * branches in the forbidden slot. 15175 */ 15176 is_slot = 1; 15177 } 15178 } 15179 if (is_slot) { 15180 gen_branch(ctx, insn_bytes); 15181 } 15182 if (ctx->base.is_jmp == DISAS_SEMIHOST) { 15183 generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes); 15184 } 15185 ctx->base.pc_next += insn_bytes; 15186 15187 if (ctx->base.is_jmp != DISAS_NEXT) { 15188 return; 15189 } 15190 15191 /* 15192 * End the TB on (most) page crossings. 15193 * See mips_tr_init_disas_context about single-stepping a branch 15194 * together with its delay slot. 15195 */ 15196 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE 15197 && !(tb_cflags(ctx->base.tb) & CF_SINGLE_STEP)) { 15198 ctx->base.is_jmp = DISAS_TOO_MANY; 15199 } 15200 } 15201 15202 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 15203 { 15204 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15205 15206 switch (ctx->base.is_jmp) { 15207 case DISAS_STOP: 15208 gen_save_pc(ctx->base.pc_next); 15209 tcg_gen_lookup_and_goto_ptr(); 15210 break; 15211 case DISAS_NEXT: 15212 case DISAS_TOO_MANY: 15213 save_cpu_state(ctx, 0); 15214 gen_goto_tb(ctx, 0, ctx->base.pc_next); 15215 break; 15216 case DISAS_EXIT: 15217 tcg_gen_exit_tb(NULL, 0); 15218 break; 15219 case DISAS_NORETURN: 15220 break; 15221 default: 15222 g_assert_not_reached(); 15223 } 15224 } 15225 15226 static const TranslatorOps mips_tr_ops = { 15227 .init_disas_context = mips_tr_init_disas_context, 15228 .tb_start = mips_tr_tb_start, 15229 .insn_start = mips_tr_insn_start, 15230 .translate_insn = mips_tr_translate_insn, 15231 .tb_stop = mips_tr_tb_stop, 15232 }; 15233 15234 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, 15235 vaddr pc, void *host_pc) 15236 { 15237 DisasContext ctx; 15238 15239 translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base); 15240 } 15241 15242 void mips_tcg_init(void) 15243 { 15244 cpu_gpr[0] = NULL; 15245 for (unsigned i = 1; i < 32; i++) 15246 cpu_gpr[i] = tcg_global_mem_new(tcg_env, 15247 offsetof(CPUMIPSState, 15248 active_tc.gpr[i]), 15249 regnames[i]); 15250 #if defined(TARGET_MIPS64) 15251 cpu_gpr_hi[0] = NULL; 15252 15253 for (unsigned i = 1; i < 32; i++) { 15254 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]); 15255 15256 cpu_gpr_hi[i] = tcg_global_mem_new_i64(tcg_env, 15257 offsetof(CPUMIPSState, 15258 active_tc.gpr_hi[i]), 15259 rname); 15260 } 15261 #endif /* !TARGET_MIPS64 */ 15262 for (unsigned i = 0; i < 32; i++) { 15263 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); 15264 15265 fpu_f64[i] = tcg_global_mem_new_i64(tcg_env, off, fregnames[i]); 15266 } 15267 msa_translate_init(); 15268 cpu_PC = tcg_global_mem_new(tcg_env, 15269 offsetof(CPUMIPSState, active_tc.PC), "PC"); 15270 for (unsigned i = 0; i < MIPS_DSP_ACC; i++) { 15271 cpu_HI[i] = tcg_global_mem_new(tcg_env, 15272 offsetof(CPUMIPSState, active_tc.HI[i]), 15273 regnames_HI[i]); 15274 cpu_LO[i] = tcg_global_mem_new(tcg_env, 15275 offsetof(CPUMIPSState, active_tc.LO[i]), 15276 regnames_LO[i]); 15277 } 15278 cpu_dspctrl = tcg_global_mem_new(tcg_env, 15279 offsetof(CPUMIPSState, 15280 active_tc.DSPControl), 15281 "DSPControl"); 15282 bcond = tcg_global_mem_new(tcg_env, 15283 offsetof(CPUMIPSState, bcond), "bcond"); 15284 btarget = tcg_global_mem_new(tcg_env, 15285 offsetof(CPUMIPSState, btarget), "btarget"); 15286 hflags = tcg_global_mem_new_i32(tcg_env, 15287 offsetof(CPUMIPSState, hflags), "hflags"); 15288 15289 fpu_fcr0 = tcg_global_mem_new_i32(tcg_env, 15290 offsetof(CPUMIPSState, active_fpu.fcr0), 15291 "fcr0"); 15292 fpu_fcr31 = tcg_global_mem_new_i32(tcg_env, 15293 offsetof(CPUMIPSState, active_fpu.fcr31), 15294 "fcr31"); 15295 cpu_lladdr = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, lladdr), 15296 "lladdr"); 15297 cpu_llval = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, llval), 15298 "llval"); 15299 15300 if (TARGET_LONG_BITS == 32) { 15301 mxu_translate_init(); 15302 } 15303 } 15304 15305 void mips_restore_state_to_opc(CPUState *cs, 15306 const TranslationBlock *tb, 15307 const uint64_t *data) 15308 { 15309 CPUMIPSState *env = cpu_env(cs); 15310 15311 env->active_tc.PC = data[0]; 15312 env->hflags &= ~MIPS_HFLAG_BMASK; 15313 env->hflags |= data[1]; 15314 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) { 15315 case MIPS_HFLAG_BR: 15316 break; 15317 case MIPS_HFLAG_BC: 15318 case MIPS_HFLAG_BL: 15319 case MIPS_HFLAG_B: 15320 env->btarget = data[2]; 15321 break; 15322 } 15323 } 15324