1 /* 2 * MIPS emulation for QEMU - main translation routines 3 * 4 * Copyright (c) 2004-2005 Jocelyn Mayer 5 * Copyright (c) 2006 Marius Groeger (FPU operations) 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) 9 * Copyright (c) 2020 Philippe Mathieu-Daudé 10 * 11 * This library is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU Lesser General Public 13 * License as published by the Free Software Foundation; either 14 * version 2.1 of the License, or (at your option) any later version. 15 * 16 * This library is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "translate.h" 27 #include "internal.h" 28 #include "exec/helper-proto.h" 29 #include "exec/translation-block.h" 30 #include "exec/target_page.h" 31 #include "semihosting/semihost.h" 32 #include "trace.h" 33 #include "fpu_helper.h" 34 35 #define HELPER_H "helper.h" 36 #include "exec/helper-info.c.inc" 37 #undef HELPER_H 38 39 40 /* 41 * Many system-only helpers are not reachable for user-only. 42 * Define stub generators here, so that we need not either sprinkle 43 * ifdefs through the translator, nor provide the helper function. 44 */ 45 #define STUB_HELPER(NAME, ...) \ 46 static inline void gen_helper_##NAME(__VA_ARGS__) \ 47 { g_assert_not_reached(); } 48 49 #ifdef CONFIG_USER_ONLY 50 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg) 51 #endif 52 53 enum { 54 /* indirect opcode tables */ 55 OPC_SPECIAL = (0x00 << 26), 56 OPC_REGIMM = (0x01 << 26), 57 OPC_CP0 = (0x10 << 26), 58 OPC_CP2 = (0x12 << 26), 59 OPC_CP3 = (0x13 << 26), 60 OPC_SPECIAL2 = (0x1C << 26), 61 OPC_SPECIAL3 = (0x1F << 26), 62 /* arithmetic with immediate */ 63 OPC_ADDI = (0x08 << 26), 64 OPC_ADDIU = (0x09 << 26), 65 OPC_SLTI = (0x0A << 26), 66 OPC_SLTIU = (0x0B << 26), 67 /* logic with immediate */ 68 OPC_ANDI = (0x0C << 26), 69 OPC_ORI = (0x0D << 26), 70 OPC_XORI = (0x0E << 26), 71 OPC_LUI = (0x0F << 26), 72 /* arithmetic with immediate */ 73 OPC_DADDI = (0x18 << 26), 74 OPC_DADDIU = (0x19 << 26), 75 /* Jump and branches */ 76 OPC_J = (0x02 << 26), 77 OPC_JAL = (0x03 << 26), 78 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */ 79 OPC_BEQL = (0x14 << 26), 80 OPC_BNE = (0x05 << 26), 81 OPC_BNEL = (0x15 << 26), 82 OPC_BLEZ = (0x06 << 26), 83 OPC_BLEZL = (0x16 << 26), 84 OPC_BGTZ = (0x07 << 26), 85 OPC_BGTZL = (0x17 << 26), 86 OPC_JALX = (0x1D << 26), 87 OPC_DAUI = (0x1D << 26), 88 /* Load and stores */ 89 OPC_LDL = (0x1A << 26), 90 OPC_LDR = (0x1B << 26), 91 OPC_LB = (0x20 << 26), 92 OPC_LH = (0x21 << 26), 93 OPC_LWL = (0x22 << 26), 94 OPC_LW = (0x23 << 26), 95 OPC_LWPC = OPC_LW | 0x5, 96 OPC_LBU = (0x24 << 26), 97 OPC_LHU = (0x25 << 26), 98 OPC_LWR = (0x26 << 26), 99 OPC_LWU = (0x27 << 26), 100 OPC_SB = (0x28 << 26), 101 OPC_SH = (0x29 << 26), 102 OPC_SWL = (0x2A << 26), 103 OPC_SW = (0x2B << 26), 104 OPC_SDL = (0x2C << 26), 105 OPC_SDR = (0x2D << 26), 106 OPC_SWR = (0x2E << 26), 107 OPC_LL = (0x30 << 26), 108 OPC_LLD = (0x34 << 26), 109 OPC_LD = (0x37 << 26), 110 OPC_LDPC = OPC_LD | 0x5, 111 OPC_SC = (0x38 << 26), 112 OPC_SCD = (0x3C << 26), 113 OPC_SD = (0x3F << 26), 114 /* Floating point load/store */ 115 OPC_LWC1 = (0x31 << 26), 116 OPC_LWC2 = (0x32 << 26), 117 OPC_LDC1 = (0x35 << 26), 118 OPC_LDC2 = (0x36 << 26), 119 OPC_SWC1 = (0x39 << 26), 120 OPC_SWC2 = (0x3A << 26), 121 OPC_SDC1 = (0x3D << 26), 122 OPC_SDC2 = (0x3E << 26), 123 /* Compact Branches */ 124 OPC_BLEZALC = (0x06 << 26), 125 OPC_BGEZALC = (0x06 << 26), 126 OPC_BGEUC = (0x06 << 26), 127 OPC_BGTZALC = (0x07 << 26), 128 OPC_BLTZALC = (0x07 << 26), 129 OPC_BLTUC = (0x07 << 26), 130 OPC_BOVC = (0x08 << 26), 131 OPC_BEQZALC = (0x08 << 26), 132 OPC_BEQC = (0x08 << 26), 133 OPC_BLEZC = (0x16 << 26), 134 OPC_BGEZC = (0x16 << 26), 135 OPC_BGEC = (0x16 << 26), 136 OPC_BGTZC = (0x17 << 26), 137 OPC_BLTZC = (0x17 << 26), 138 OPC_BLTC = (0x17 << 26), 139 OPC_BNVC = (0x18 << 26), 140 OPC_BNEZALC = (0x18 << 26), 141 OPC_BNEC = (0x18 << 26), 142 OPC_BC = (0x32 << 26), 143 OPC_BEQZC = (0x36 << 26), 144 OPC_JIC = (0x36 << 26), 145 OPC_BALC = (0x3A << 26), 146 OPC_BNEZC = (0x3E << 26), 147 OPC_JIALC = (0x3E << 26), 148 /* MDMX ASE specific */ 149 OPC_MDMX = (0x1E << 26), 150 /* Cache and prefetch */ 151 OPC_CACHE = (0x2F << 26), 152 OPC_PREF = (0x33 << 26), 153 /* PC-relative address computation / loads */ 154 OPC_PCREL = (0x3B << 26), 155 }; 156 157 /* PC-relative address computation / loads */ 158 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19))) 159 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16))) 160 enum { 161 /* Instructions determined by bits 19 and 20 */ 162 OPC_ADDIUPC = OPC_PCREL | (0 << 19), 163 R6_OPC_LWPC = OPC_PCREL | (1 << 19), 164 OPC_LWUPC = OPC_PCREL | (2 << 19), 165 166 /* Instructions determined by bits 16 ... 20 */ 167 OPC_AUIPC = OPC_PCREL | (0x1e << 16), 168 OPC_ALUIPC = OPC_PCREL | (0x1f << 16), 169 170 /* Other */ 171 R6_OPC_LDPC = OPC_PCREL | (6 << 18), 172 }; 173 174 /* MIPS special opcodes */ 175 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 176 177 enum { 178 /* Shifts */ 179 OPC_SLL = 0x00 | OPC_SPECIAL, 180 /* NOP is SLL r0, r0, 0 */ 181 /* SSNOP is SLL r0, r0, 1 */ 182 /* EHB is SLL r0, r0, 3 */ 183 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */ 184 OPC_ROTR = OPC_SRL | (1 << 21), 185 OPC_SRA = 0x03 | OPC_SPECIAL, 186 OPC_SLLV = 0x04 | OPC_SPECIAL, 187 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */ 188 OPC_ROTRV = OPC_SRLV | (1 << 6), 189 OPC_SRAV = 0x07 | OPC_SPECIAL, 190 OPC_DSLLV = 0x14 | OPC_SPECIAL, 191 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */ 192 OPC_DROTRV = OPC_DSRLV | (1 << 6), 193 OPC_DSRAV = 0x17 | OPC_SPECIAL, 194 OPC_DSLL = 0x38 | OPC_SPECIAL, 195 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */ 196 OPC_DROTR = OPC_DSRL | (1 << 21), 197 OPC_DSRA = 0x3B | OPC_SPECIAL, 198 OPC_DSLL32 = 0x3C | OPC_SPECIAL, 199 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */ 200 OPC_DROTR32 = OPC_DSRL32 | (1 << 21), 201 OPC_DSRA32 = 0x3F | OPC_SPECIAL, 202 /* Multiplication / division */ 203 OPC_MULT = 0x18 | OPC_SPECIAL, 204 OPC_MULTU = 0x19 | OPC_SPECIAL, 205 OPC_DIV = 0x1A | OPC_SPECIAL, 206 OPC_DIVU = 0x1B | OPC_SPECIAL, 207 OPC_DMULT = 0x1C | OPC_SPECIAL, 208 OPC_DMULTU = 0x1D | OPC_SPECIAL, 209 OPC_DDIV = 0x1E | OPC_SPECIAL, 210 OPC_DDIVU = 0x1F | OPC_SPECIAL, 211 212 /* 2 registers arithmetic / logic */ 213 OPC_ADD = 0x20 | OPC_SPECIAL, 214 OPC_ADDU = 0x21 | OPC_SPECIAL, 215 OPC_SUB = 0x22 | OPC_SPECIAL, 216 OPC_SUBU = 0x23 | OPC_SPECIAL, 217 OPC_AND = 0x24 | OPC_SPECIAL, 218 OPC_OR = 0x25 | OPC_SPECIAL, 219 OPC_XOR = 0x26 | OPC_SPECIAL, 220 OPC_NOR = 0x27 | OPC_SPECIAL, 221 OPC_SLT = 0x2A | OPC_SPECIAL, 222 OPC_SLTU = 0x2B | OPC_SPECIAL, 223 OPC_DADD = 0x2C | OPC_SPECIAL, 224 OPC_DADDU = 0x2D | OPC_SPECIAL, 225 OPC_DSUB = 0x2E | OPC_SPECIAL, 226 OPC_DSUBU = 0x2F | OPC_SPECIAL, 227 /* Jumps */ 228 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ 229 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ 230 /* Traps */ 231 OPC_TGE = 0x30 | OPC_SPECIAL, 232 OPC_TGEU = 0x31 | OPC_SPECIAL, 233 OPC_TLT = 0x32 | OPC_SPECIAL, 234 OPC_TLTU = 0x33 | OPC_SPECIAL, 235 OPC_TEQ = 0x34 | OPC_SPECIAL, 236 OPC_TNE = 0x36 | OPC_SPECIAL, 237 /* HI / LO registers load & stores */ 238 OPC_MFHI = 0x10 | OPC_SPECIAL, 239 OPC_MTHI = 0x11 | OPC_SPECIAL, 240 OPC_MFLO = 0x12 | OPC_SPECIAL, 241 OPC_MTLO = 0x13 | OPC_SPECIAL, 242 /* Conditional moves */ 243 OPC_MOVZ = 0x0A | OPC_SPECIAL, 244 OPC_MOVN = 0x0B | OPC_SPECIAL, 245 246 OPC_SELEQZ = 0x35 | OPC_SPECIAL, 247 OPC_SELNEZ = 0x37 | OPC_SPECIAL, 248 249 OPC_MOVCI = 0x01 | OPC_SPECIAL, 250 251 /* Special */ 252 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */ 253 OPC_SYSCALL = 0x0C | OPC_SPECIAL, 254 OPC_BREAK = 0x0D | OPC_SPECIAL, 255 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */ 256 OPC_SYNC = 0x0F | OPC_SPECIAL, 257 258 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, 259 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, 260 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, 261 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, 262 }; 263 264 /* 265 * R6 Multiply and Divide instructions have the same opcode 266 * and function field as legacy OPC_MULT[U]/OPC_DIV[U] 267 */ 268 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff))) 269 270 enum { 271 R6_OPC_MUL = OPC_MULT | (2 << 6), 272 R6_OPC_MUH = OPC_MULT | (3 << 6), 273 R6_OPC_MULU = OPC_MULTU | (2 << 6), 274 R6_OPC_MUHU = OPC_MULTU | (3 << 6), 275 R6_OPC_DIV = OPC_DIV | (2 << 6), 276 R6_OPC_MOD = OPC_DIV | (3 << 6), 277 R6_OPC_DIVU = OPC_DIVU | (2 << 6), 278 R6_OPC_MODU = OPC_DIVU | (3 << 6), 279 280 R6_OPC_DMUL = OPC_DMULT | (2 << 6), 281 R6_OPC_DMUH = OPC_DMULT | (3 << 6), 282 R6_OPC_DMULU = OPC_DMULTU | (2 << 6), 283 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6), 284 R6_OPC_DDIV = OPC_DDIV | (2 << 6), 285 R6_OPC_DMOD = OPC_DDIV | (3 << 6), 286 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6), 287 R6_OPC_DMODU = OPC_DDIVU | (3 << 6), 288 289 R6_OPC_CLZ = 0x10 | OPC_SPECIAL, 290 R6_OPC_CLO = 0x11 | OPC_SPECIAL, 291 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL, 292 R6_OPC_DCLO = 0x13 | OPC_SPECIAL, 293 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL, 294 }; 295 296 /* REGIMM (rt field) opcodes */ 297 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16))) 298 299 enum { 300 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM, 301 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM, 302 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM, 303 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM, 304 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM, 305 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM, 306 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM, 307 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM, 308 OPC_TGEI = (0x08 << 16) | OPC_REGIMM, 309 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM, 310 OPC_TLTI = (0x0A << 16) | OPC_REGIMM, 311 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM, 312 OPC_TEQI = (0x0C << 16) | OPC_REGIMM, 313 OPC_TNEI = (0x0E << 16) | OPC_REGIMM, 314 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM, 315 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM, 316 317 OPC_DAHI = (0x06 << 16) | OPC_REGIMM, 318 OPC_DATI = (0x1e << 16) | OPC_REGIMM, 319 }; 320 321 /* Special2 opcodes */ 322 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 323 324 enum { 325 /* Multiply & xxx operations */ 326 OPC_MADD = 0x00 | OPC_SPECIAL2, 327 OPC_MADDU = 0x01 | OPC_SPECIAL2, 328 OPC_MUL = 0x02 | OPC_SPECIAL2, 329 OPC_MSUB = 0x04 | OPC_SPECIAL2, 330 OPC_MSUBU = 0x05 | OPC_SPECIAL2, 331 /* Misc */ 332 OPC_CLZ = 0x20 | OPC_SPECIAL2, 333 OPC_CLO = 0x21 | OPC_SPECIAL2, 334 OPC_DCLZ = 0x24 | OPC_SPECIAL2, 335 OPC_DCLO = 0x25 | OPC_SPECIAL2, 336 /* Special */ 337 OPC_SDBBP = 0x3F | OPC_SPECIAL2, 338 }; 339 340 /* Special3 opcodes */ 341 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 342 343 enum { 344 OPC_EXT = 0x00 | OPC_SPECIAL3, 345 OPC_DEXTM = 0x01 | OPC_SPECIAL3, 346 OPC_DEXTU = 0x02 | OPC_SPECIAL3, 347 OPC_DEXT = 0x03 | OPC_SPECIAL3, 348 OPC_INS = 0x04 | OPC_SPECIAL3, 349 OPC_DINSM = 0x05 | OPC_SPECIAL3, 350 OPC_DINSU = 0x06 | OPC_SPECIAL3, 351 OPC_DINS = 0x07 | OPC_SPECIAL3, 352 OPC_FORK = 0x08 | OPC_SPECIAL3, 353 OPC_YIELD = 0x09 | OPC_SPECIAL3, 354 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 355 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 356 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 357 OPC_GINV = 0x3D | OPC_SPECIAL3, 358 359 /* MIPS DSP Load */ 360 OPC_LX_DSP = 0x0A | OPC_SPECIAL3, 361 /* MIPS DSP Arithmetic */ 362 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3, 363 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3, 364 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3, 365 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3, 366 OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, 367 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3, 368 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3, 369 /* MIPS DSP GPR-Based Shift Sub-class */ 370 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3, 371 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3, 372 /* MIPS DSP Multiply Sub-class insns */ 373 OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, 374 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3, 375 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3, 376 /* DSP Bit/Manipulation Sub-class */ 377 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, 378 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3, 379 /* MIPS DSP Append Sub-class */ 380 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3, 381 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3, 382 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 383 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, 384 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, 385 386 /* EVA */ 387 OPC_LWLE = 0x19 | OPC_SPECIAL3, 388 OPC_LWRE = 0x1A | OPC_SPECIAL3, 389 OPC_CACHEE = 0x1B | OPC_SPECIAL3, 390 OPC_SBE = 0x1C | OPC_SPECIAL3, 391 OPC_SHE = 0x1D | OPC_SPECIAL3, 392 OPC_SCE = 0x1E | OPC_SPECIAL3, 393 OPC_SWE = 0x1F | OPC_SPECIAL3, 394 OPC_SWLE = 0x21 | OPC_SPECIAL3, 395 OPC_SWRE = 0x22 | OPC_SPECIAL3, 396 OPC_PREFE = 0x23 | OPC_SPECIAL3, 397 OPC_LBUE = 0x28 | OPC_SPECIAL3, 398 OPC_LHUE = 0x29 | OPC_SPECIAL3, 399 OPC_LBE = 0x2C | OPC_SPECIAL3, 400 OPC_LHE = 0x2D | OPC_SPECIAL3, 401 OPC_LLE = 0x2E | OPC_SPECIAL3, 402 OPC_LWE = 0x2F | OPC_SPECIAL3, 403 404 /* R6 */ 405 R6_OPC_PREF = 0x35 | OPC_SPECIAL3, 406 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, 407 R6_OPC_LL = 0x36 | OPC_SPECIAL3, 408 R6_OPC_SC = 0x26 | OPC_SPECIAL3, 409 R6_OPC_LLD = 0x37 | OPC_SPECIAL3, 410 R6_OPC_SCD = 0x27 | OPC_SPECIAL3, 411 }; 412 413 /* Loongson EXT load/store quad word opcodes */ 414 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020)) 415 enum { 416 OPC_GSLQ = 0x0020 | OPC_LWC2, 417 OPC_GSLQC1 = 0x8020 | OPC_LWC2, 418 OPC_GSSHFL = OPC_LWC2, 419 OPC_GSSQ = 0x0020 | OPC_SWC2, 420 OPC_GSSQC1 = 0x8020 | OPC_SWC2, 421 OPC_GSSHFS = OPC_SWC2, 422 }; 423 424 /* Loongson EXT shifted load/store opcodes */ 425 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f)) 426 enum { 427 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL, 428 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL, 429 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL, 430 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL, 431 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS, 432 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS, 433 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS, 434 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS, 435 }; 436 437 /* Loongson EXT LDC2/SDC2 opcodes */ 438 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7)) 439 440 enum { 441 OPC_GSLBX = 0x0 | OPC_LDC2, 442 OPC_GSLHX = 0x1 | OPC_LDC2, 443 OPC_GSLWX = 0x2 | OPC_LDC2, 444 OPC_GSLDX = 0x3 | OPC_LDC2, 445 OPC_GSLWXC1 = 0x6 | OPC_LDC2, 446 OPC_GSLDXC1 = 0x7 | OPC_LDC2, 447 OPC_GSSBX = 0x0 | OPC_SDC2, 448 OPC_GSSHX = 0x1 | OPC_SDC2, 449 OPC_GSSWX = 0x2 | OPC_SDC2, 450 OPC_GSSDX = 0x3 | OPC_SDC2, 451 OPC_GSSWXC1 = 0x6 | OPC_SDC2, 452 OPC_GSSDXC1 = 0x7 | OPC_SDC2, 453 }; 454 455 /* BSHFL opcodes */ 456 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 457 458 enum { 459 OPC_WSBH = (0x02 << 6) | OPC_BSHFL, 460 OPC_SEB = (0x10 << 6) | OPC_BSHFL, 461 OPC_SEH = (0x18 << 6) | OPC_BSHFL, 462 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */ 463 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL, 464 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL, 465 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL, 466 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */ 467 }; 468 469 /* DBSHFL opcodes */ 470 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 471 472 enum { 473 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, 474 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, 475 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */ 476 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL, 477 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL, 478 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL, 479 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL, 480 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL, 481 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL, 482 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL, 483 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */ 484 }; 485 486 /* MIPS DSP REGIMM opcodes */ 487 enum { 488 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM, 489 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM, 490 }; 491 492 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 493 /* MIPS DSP Load */ 494 enum { 495 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP, 496 OPC_LHX = (0x04 << 6) | OPC_LX_DSP, 497 OPC_LWX = (0x00 << 6) | OPC_LX_DSP, 498 OPC_LDX = (0x08 << 6) | OPC_LX_DSP, 499 }; 500 501 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 502 enum { 503 /* MIPS DSP Arithmetic Sub-class */ 504 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP, 505 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP, 506 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP, 507 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP, 508 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP, 509 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP, 510 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP, 511 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP, 512 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP, 513 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP, 514 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP, 515 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP, 516 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP, 517 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP, 518 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP, 519 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP, 520 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP, 521 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP, 522 /* MIPS DSP Multiply Sub-class insns */ 523 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP, 524 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP, 525 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP, 526 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP, 527 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP, 528 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP, 529 }; 530 531 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 532 enum { 533 /* MIPS DSP Arithmetic Sub-class */ 534 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP, 535 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP, 536 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP, 537 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP, 538 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP, 539 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP, 540 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP, 541 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP, 542 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP, 543 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP, 544 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP, 545 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP, 546 /* MIPS DSP Multiply Sub-class insns */ 547 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP, 548 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP, 549 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP, 550 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP, 551 }; 552 553 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 554 enum { 555 /* MIPS DSP Arithmetic Sub-class */ 556 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP, 557 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP, 558 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP, 559 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP, 560 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP, 561 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP, 562 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP, 563 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP, 564 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP, 565 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP, 566 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP, 567 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP, 568 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP, 569 /* DSP Bit/Manipulation Sub-class */ 570 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP, 571 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP, 572 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP, 573 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP, 574 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP, 575 }; 576 577 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 578 enum { 579 /* MIPS DSP Arithmetic Sub-class */ 580 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP, 581 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP, 582 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP, 583 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP, 584 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP, 585 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP, 586 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP, 587 /* DSP Compare-Pick Sub-class */ 588 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP, 589 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP, 590 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP, 591 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP, 592 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP, 593 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP, 594 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP, 595 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP, 596 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP, 597 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP, 598 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP, 599 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP, 600 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, 601 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, 602 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, 603 }; 604 605 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 606 enum { 607 /* MIPS DSP GPR-Based Shift Sub-class */ 608 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP, 609 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP, 610 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP, 611 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP, 612 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP, 613 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP, 614 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP, 615 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP, 616 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP, 617 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP, 618 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP, 619 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP, 620 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP, 621 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP, 622 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP, 623 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP, 624 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP, 625 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP, 626 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP, 627 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP, 628 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP, 629 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP, 630 }; 631 632 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 633 enum { 634 /* MIPS DSP Multiply Sub-class insns */ 635 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP, 636 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP, 637 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP, 638 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP, 639 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP, 640 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP, 641 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP, 642 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP, 643 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP, 644 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP, 645 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP, 646 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP, 647 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP, 648 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP, 649 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP, 650 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP, 651 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP, 652 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP, 653 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP, 654 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP, 655 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP, 656 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP, 657 }; 658 659 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 660 enum { 661 /* DSP Bit/Manipulation Sub-class */ 662 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP, 663 }; 664 665 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 666 enum { 667 /* MIPS DSP Append Sub-class */ 668 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP, 669 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP, 670 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP, 671 }; 672 673 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 674 enum { 675 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 676 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP, 677 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP, 678 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP, 679 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP, 680 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP, 681 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP, 682 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP, 683 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP, 684 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP, 685 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP, 686 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP, 687 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP, 688 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP, 689 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP, 690 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP, 691 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP, 692 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP, 693 }; 694 695 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 696 enum { 697 /* MIPS DSP Arithmetic Sub-class */ 698 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP, 699 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP, 700 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP, 701 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP, 702 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP, 703 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP, 704 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP, 705 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP, 706 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP, 707 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP, 708 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP, 709 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP, 710 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP, 711 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP, 712 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP, 713 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP, 714 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP, 715 /* DSP Bit/Manipulation Sub-class */ 716 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP, 717 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP, 718 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP, 719 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP, 720 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP, 721 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP, 722 }; 723 724 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 725 enum { 726 /* MIPS DSP Multiply Sub-class insns */ 727 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP, 728 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP, 729 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP, 730 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP, 731 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP, 732 /* MIPS DSP Arithmetic Sub-class */ 733 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP, 734 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP, 735 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP, 736 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP, 737 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP, 738 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP, 739 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP, 740 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP, 741 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP, 742 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP, 743 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP, 744 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP, 745 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP, 746 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP, 747 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP, 748 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP, 749 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP, 750 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP, 751 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP, 752 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP, 753 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP, 754 }; 755 756 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 757 enum { 758 /* DSP Compare-Pick Sub-class */ 759 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP, 760 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP, 761 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP, 762 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP, 763 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP, 764 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP, 765 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP, 766 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP, 767 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP, 768 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP, 769 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP, 770 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP, 771 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP, 772 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP, 773 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP, 774 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP, 775 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP, 776 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP, 777 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP, 778 /* MIPS DSP Arithmetic Sub-class */ 779 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP, 780 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP, 781 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP, 782 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP, 783 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP, 784 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP, 785 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP, 786 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP, 787 }; 788 789 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 790 enum { 791 /* DSP Append Sub-class */ 792 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP, 793 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP, 794 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP, 795 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP, 796 }; 797 798 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 799 enum { 800 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 801 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP, 802 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP, 803 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP, 804 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP, 805 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP, 806 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP, 807 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP, 808 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP, 809 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP, 810 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP, 811 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP, 812 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP, 813 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP, 814 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP, 815 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP, 816 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP, 817 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP, 818 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP, 819 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP, 820 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP, 821 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP, 822 }; 823 824 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 825 enum { 826 /* DSP Bit/Manipulation Sub-class */ 827 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP, 828 }; 829 830 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 831 enum { 832 /* MIPS DSP Multiply Sub-class insns */ 833 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP, 834 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP, 835 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP, 836 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP, 837 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP, 838 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP, 839 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP, 840 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP, 841 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP, 842 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP, 843 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP, 844 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP, 845 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP, 846 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP, 847 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP, 848 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP, 849 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP, 850 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP, 851 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP, 852 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP, 853 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP, 854 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP, 855 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP, 856 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP, 857 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP, 858 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP, 859 }; 860 861 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 862 enum { 863 /* MIPS DSP GPR-Based Shift Sub-class */ 864 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP, 865 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP, 866 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP, 867 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP, 868 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP, 869 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP, 870 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP, 871 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP, 872 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP, 873 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP, 874 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP, 875 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP, 876 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP, 877 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP, 878 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP, 879 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP, 880 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP, 881 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP, 882 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP, 883 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP, 884 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP, 885 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP, 886 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP, 887 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP, 888 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP, 889 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP, 890 }; 891 892 /* Coprocessor 0 (rs field) */ 893 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 894 895 enum { 896 OPC_MFC0 = (0x00 << 21) | OPC_CP0, 897 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 898 OPC_MFHC0 = (0x02 << 21) | OPC_CP0, 899 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 900 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 901 OPC_MTHC0 = (0x06 << 21) | OPC_CP0, 902 OPC_MFTR = (0x08 << 21) | OPC_CP0, 903 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 904 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 905 OPC_MTTR = (0x0C << 21) | OPC_CP0, 906 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 907 OPC_C0 = (0x10 << 21) | OPC_CP0, 908 OPC_C0_1 = (0x11 << 21) | OPC_CP0, 909 OPC_C0_2 = (0x12 << 21) | OPC_CP0, 910 OPC_C0_3 = (0x13 << 21) | OPC_CP0, 911 OPC_C0_4 = (0x14 << 21) | OPC_CP0, 912 OPC_C0_5 = (0x15 << 21) | OPC_CP0, 913 OPC_C0_6 = (0x16 << 21) | OPC_CP0, 914 OPC_C0_7 = (0x17 << 21) | OPC_CP0, 915 OPC_C0_8 = (0x18 << 21) | OPC_CP0, 916 OPC_C0_9 = (0x19 << 21) | OPC_CP0, 917 OPC_C0_A = (0x1A << 21) | OPC_CP0, 918 OPC_C0_B = (0x1B << 21) | OPC_CP0, 919 OPC_C0_C = (0x1C << 21) | OPC_CP0, 920 OPC_C0_D = (0x1D << 21) | OPC_CP0, 921 OPC_C0_E = (0x1E << 21) | OPC_CP0, 922 OPC_C0_F = (0x1F << 21) | OPC_CP0, 923 }; 924 925 /* MFMC0 opcodes */ 926 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF)) 927 928 enum { 929 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 930 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 931 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0, 932 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0, 933 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 934 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 935 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0, 936 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0, 937 }; 938 939 /* Coprocessor 0 (with rs == C0) */ 940 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F)) 941 942 enum { 943 OPC_TLBR = 0x01 | OPC_C0, 944 OPC_TLBWI = 0x02 | OPC_C0, 945 OPC_TLBINV = 0x03 | OPC_C0, 946 OPC_TLBINVF = 0x04 | OPC_C0, 947 OPC_TLBWR = 0x06 | OPC_C0, 948 OPC_TLBP = 0x08 | OPC_C0, 949 OPC_RFE = 0x10 | OPC_C0, 950 OPC_ERET = 0x18 | OPC_C0, 951 OPC_DERET = 0x1F | OPC_C0, 952 OPC_WAIT = 0x20 | OPC_C0, 953 }; 954 955 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 956 957 enum { 958 OPC_MFC2 = (0x00 << 21) | OPC_CP2, 959 OPC_DMFC2 = (0x01 << 21) | OPC_CP2, 960 OPC_CFC2 = (0x02 << 21) | OPC_CP2, 961 OPC_MFHC2 = (0x03 << 21) | OPC_CP2, 962 OPC_MTC2 = (0x04 << 21) | OPC_CP2, 963 OPC_DMTC2 = (0x05 << 21) | OPC_CP2, 964 OPC_CTC2 = (0x06 << 21) | OPC_CP2, 965 OPC_MTHC2 = (0x07 << 21) | OPC_CP2, 966 OPC_BC2 = (0x08 << 21) | OPC_CP2, 967 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2, 968 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2, 969 }; 970 971 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F)) 972 973 enum { 974 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2, 975 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2, 976 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2, 977 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2, 978 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2, 979 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2, 980 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2, 981 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2, 982 983 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2, 984 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2, 985 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2, 986 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2, 987 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2, 988 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2, 989 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2, 990 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2, 991 992 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2, 993 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2, 994 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2, 995 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2, 996 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2, 997 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2, 998 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2, 999 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2, 1000 1001 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2, 1002 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2, 1003 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2, 1004 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2, 1005 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2, 1006 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2, 1007 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2, 1008 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2, 1009 1010 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2, 1011 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2, 1012 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2, 1013 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2, 1014 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2, 1015 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2, 1016 1017 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2, 1018 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2, 1019 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2, 1020 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2, 1021 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2, 1022 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2, 1023 1024 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2, 1025 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2, 1026 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2, 1027 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2, 1028 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2, 1029 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2, 1030 1031 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2, 1032 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2, 1033 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2, 1034 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2, 1035 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2, 1036 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2, 1037 1038 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2, 1039 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2, 1040 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2, 1041 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2, 1042 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2, 1043 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2, 1044 1045 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2, 1046 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2, 1047 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2, 1048 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2, 1049 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2, 1050 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2, 1051 1052 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2, 1053 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2, 1054 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2, 1055 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2, 1056 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2, 1057 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2, 1058 1059 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2, 1060 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2, 1061 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2, 1062 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2, 1063 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2, 1064 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2, 1065 }; 1066 1067 1068 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 1069 1070 enum { 1071 OPC_LWXC1 = 0x00 | OPC_CP3, 1072 OPC_LDXC1 = 0x01 | OPC_CP3, 1073 OPC_LUXC1 = 0x05 | OPC_CP3, 1074 OPC_SWXC1 = 0x08 | OPC_CP3, 1075 OPC_SDXC1 = 0x09 | OPC_CP3, 1076 OPC_SUXC1 = 0x0D | OPC_CP3, 1077 OPC_PREFX = 0x0F | OPC_CP3, 1078 OPC_ALNV_PS = 0x1E | OPC_CP3, 1079 OPC_MADD_S = 0x20 | OPC_CP3, 1080 OPC_MADD_D = 0x21 | OPC_CP3, 1081 OPC_MADD_PS = 0x26 | OPC_CP3, 1082 OPC_MSUB_S = 0x28 | OPC_CP3, 1083 OPC_MSUB_D = 0x29 | OPC_CP3, 1084 OPC_MSUB_PS = 0x2E | OPC_CP3, 1085 OPC_NMADD_S = 0x30 | OPC_CP3, 1086 OPC_NMADD_D = 0x31 | OPC_CP3, 1087 OPC_NMADD_PS = 0x36 | OPC_CP3, 1088 OPC_NMSUB_S = 0x38 | OPC_CP3, 1089 OPC_NMSUB_D = 0x39 | OPC_CP3, 1090 OPC_NMSUB_PS = 0x3E | OPC_CP3, 1091 }; 1092 1093 /* 1094 * MMI (MultiMedia Instruction) encodings 1095 * ====================================== 1096 * 1097 * MMI instructions encoding table keys: 1098 * 1099 * * This code is reserved for future use. An attempt to execute it 1100 * causes a Reserved Instruction exception. 1101 * % This code indicates an instruction class. The instruction word 1102 * must be further decoded by examining additional tables that show 1103 * the values for other instruction fields. 1104 * # This code is reserved for the unsupported instructions DMULT, 1105 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt 1106 * to execute it causes a Reserved Instruction exception. 1107 * 1108 * MMI instructions encoded by opcode field (MMI, LQ, SQ): 1109 * 1110 * 31 26 0 1111 * +--------+----------------------------------------+ 1112 * | opcode | | 1113 * +--------+----------------------------------------+ 1114 * 1115 * opcode bits 28..26 1116 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1117 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1118 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1119 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ 1120 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI 1121 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL 1122 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ 1123 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU 1124 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE 1125 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD 1126 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD 1127 */ 1128 1129 enum { 1130 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */ 1131 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */ 1132 }; 1133 1134 /* 1135 * MMI instructions with opcode field = MMI: 1136 * 1137 * 31 26 5 0 1138 * +--------+-------------------------------+--------+ 1139 * | MMI | |function| 1140 * +--------+-------------------------------+--------+ 1141 * 1142 * function bits 2..0 1143 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1144 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1145 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1146 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * 1147 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * 1148 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * 1149 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * 1150 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * 1151 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * 1152 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH 1153 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW 1154 */ 1155 1156 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) 1157 enum { 1158 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */ 1159 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */ 1160 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */ 1161 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */ 1162 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */ 1163 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */ 1164 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI, 1165 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI, 1166 }; 1167 1168 /* global register indices */ 1169 TCGv cpu_gpr[32], cpu_PC; 1170 /* 1171 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[]) 1172 * and the upper halves in cpu_gpr_hi[]. 1173 */ 1174 TCGv_i64 cpu_gpr_hi[32]; 1175 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; 1176 static TCGv cpu_dspctrl, btarget; 1177 TCGv bcond; 1178 static TCGv cpu_lladdr, cpu_llval; 1179 static TCGv_i32 hflags; 1180 TCGv_i32 fpu_fcr0, fpu_fcr31; 1181 TCGv_i64 fpu_f64[32]; 1182 1183 static const char regnames_HI[][4] = { 1184 "HI0", "HI1", "HI2", "HI3", 1185 }; 1186 1187 static const char regnames_LO[][4] = { 1188 "LO0", "LO1", "LO2", "LO3", 1189 }; 1190 1191 /* General purpose registers moves. */ 1192 void gen_load_gpr(TCGv t, int reg) 1193 { 1194 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr)); 1195 if (reg == 0) { 1196 tcg_gen_movi_tl(t, 0); 1197 } else { 1198 tcg_gen_mov_tl(t, cpu_gpr[reg]); 1199 } 1200 } 1201 1202 void gen_store_gpr(TCGv t, int reg) 1203 { 1204 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr)); 1205 if (reg != 0) { 1206 tcg_gen_mov_tl(cpu_gpr[reg], t); 1207 } 1208 } 1209 1210 #if defined(TARGET_MIPS64) 1211 void gen_load_gpr_hi(TCGv_i64 t, int reg) 1212 { 1213 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi)); 1214 if (reg == 0) { 1215 tcg_gen_movi_i64(t, 0); 1216 } else { 1217 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]); 1218 } 1219 } 1220 1221 void gen_store_gpr_hi(TCGv_i64 t, int reg) 1222 { 1223 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi)); 1224 if (reg != 0) { 1225 tcg_gen_mov_i64(cpu_gpr_hi[reg], t); 1226 } 1227 } 1228 #endif /* TARGET_MIPS64 */ 1229 1230 /* Moves to/from shadow registers. */ 1231 static inline void gen_load_srsgpr(int from, int to) 1232 { 1233 TCGv t0 = tcg_temp_new(); 1234 1235 if (from == 0) { 1236 tcg_gen_movi_tl(t0, 0); 1237 } else { 1238 TCGv_i32 t2 = tcg_temp_new_i32(); 1239 TCGv_ptr addr = tcg_temp_new_ptr(); 1240 1241 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1242 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1243 tcg_gen_andi_i32(t2, t2, 0xf); 1244 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1245 tcg_gen_ext_i32_ptr(addr, t2); 1246 tcg_gen_add_ptr(addr, tcg_env, addr); 1247 1248 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 1249 } 1250 gen_store_gpr(t0, to); 1251 } 1252 1253 static inline void gen_store_srsgpr(int from, int to) 1254 { 1255 if (to != 0) { 1256 TCGv t0 = tcg_temp_new(); 1257 TCGv_i32 t2 = tcg_temp_new_i32(); 1258 TCGv_ptr addr = tcg_temp_new_ptr(); 1259 1260 gen_load_gpr(t0, from); 1261 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1262 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1263 tcg_gen_andi_i32(t2, t2, 0xf); 1264 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1265 tcg_gen_ext_i32_ptr(addr, t2); 1266 tcg_gen_add_ptr(addr, tcg_env, addr); 1267 1268 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 1269 } 1270 } 1271 1272 /* Tests */ 1273 static inline void gen_save_pc(target_ulong pc) 1274 { 1275 tcg_gen_movi_tl(cpu_PC, pc); 1276 } 1277 1278 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) 1279 { 1280 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 1281 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { 1282 gen_save_pc(ctx->base.pc_next); 1283 ctx->saved_pc = ctx->base.pc_next; 1284 } 1285 if (ctx->hflags != ctx->saved_hflags) { 1286 tcg_gen_movi_i32(hflags, ctx->hflags); 1287 ctx->saved_hflags = ctx->hflags; 1288 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1289 case MIPS_HFLAG_BR: 1290 break; 1291 case MIPS_HFLAG_BC: 1292 case MIPS_HFLAG_BL: 1293 case MIPS_HFLAG_B: 1294 tcg_gen_movi_tl(btarget, ctx->btarget); 1295 break; 1296 } 1297 } 1298 } 1299 1300 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) 1301 { 1302 ctx->saved_hflags = ctx->hflags; 1303 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1304 case MIPS_HFLAG_BR: 1305 break; 1306 case MIPS_HFLAG_BC: 1307 case MIPS_HFLAG_BL: 1308 case MIPS_HFLAG_B: 1309 ctx->btarget = env->btarget; 1310 break; 1311 } 1312 } 1313 1314 void generate_exception_err(DisasContext *ctx, int excp, int err) 1315 { 1316 save_cpu_state(ctx, 1); 1317 gen_helper_raise_exception_err(tcg_env, tcg_constant_i32(excp), 1318 tcg_constant_i32(err)); 1319 ctx->base.is_jmp = DISAS_NORETURN; 1320 } 1321 1322 void generate_exception(DisasContext *ctx, int excp) 1323 { 1324 gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp)); 1325 } 1326 1327 void generate_exception_end(DisasContext *ctx, int excp) 1328 { 1329 generate_exception_err(ctx, excp, 0); 1330 } 1331 1332 void generate_exception_break(DisasContext *ctx, int code) 1333 { 1334 #ifdef CONFIG_USER_ONLY 1335 /* Pass the break code along to cpu_loop. */ 1336 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 1337 offsetof(CPUMIPSState, error_code)); 1338 #endif 1339 generate_exception_end(ctx, EXCP_BREAK); 1340 } 1341 1342 void gen_reserved_instruction(DisasContext *ctx) 1343 { 1344 generate_exception_end(ctx, EXCP_RI); 1345 } 1346 1347 /* Floating point register moves. */ 1348 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1349 { 1350 if (ctx->hflags & MIPS_HFLAG_FRE) { 1351 generate_exception(ctx, EXCP_RI); 1352 } 1353 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); 1354 } 1355 1356 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1357 { 1358 TCGv_i64 t64; 1359 if (ctx->hflags & MIPS_HFLAG_FRE) { 1360 generate_exception(ctx, EXCP_RI); 1361 } 1362 t64 = tcg_temp_new_i64(); 1363 tcg_gen_extu_i32_i64(t64, t); 1364 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); 1365 } 1366 1367 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1368 { 1369 if (ctx->hflags & MIPS_HFLAG_F64) { 1370 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); 1371 } else { 1372 gen_load_fpr32(ctx, t, reg | 1); 1373 } 1374 } 1375 1376 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1377 { 1378 if (ctx->hflags & MIPS_HFLAG_F64) { 1379 TCGv_i64 t64 = tcg_temp_new_i64(); 1380 tcg_gen_extu_i32_i64(t64, t); 1381 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); 1382 } else { 1383 gen_store_fpr32(ctx, t, reg | 1); 1384 } 1385 } 1386 1387 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1388 { 1389 if (ctx->hflags & MIPS_HFLAG_F64) { 1390 tcg_gen_mov_i64(t, fpu_f64[reg]); 1391 } else { 1392 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]); 1393 } 1394 } 1395 1396 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1397 { 1398 if (ctx->hflags & MIPS_HFLAG_F64) { 1399 tcg_gen_mov_i64(fpu_f64[reg], t); 1400 } else { 1401 TCGv_i64 t0; 1402 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32); 1403 t0 = tcg_temp_new_i64(); 1404 tcg_gen_shri_i64(t0, t, 32); 1405 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32); 1406 } 1407 } 1408 1409 int get_fp_bit(int cc) 1410 { 1411 if (cc) { 1412 return 24 + cc; 1413 } else { 1414 return 23; 1415 } 1416 } 1417 1418 /* Addresses computation */ 1419 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 1420 { 1421 tcg_gen_add_tl(ret, arg0, arg1); 1422 1423 #if defined(TARGET_MIPS64) 1424 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1425 tcg_gen_ext32s_i64(ret, ret); 1426 } 1427 #endif 1428 } 1429 1430 void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, target_long ofs) 1431 { 1432 tcg_gen_addi_tl(ret, base, ofs); 1433 1434 #if defined(TARGET_MIPS64) 1435 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1436 tcg_gen_ext32s_i64(ret, ret); 1437 } 1438 #endif 1439 } 1440 1441 /* Addresses computation (translation time) */ 1442 static target_long addr_add(DisasContext *ctx, target_long base, 1443 target_long offset) 1444 { 1445 target_long sum = base + offset; 1446 1447 #if defined(TARGET_MIPS64) 1448 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1449 sum = (int32_t)sum; 1450 } 1451 #endif 1452 return sum; 1453 } 1454 1455 /* Sign-extract the low 32-bits to a target_long. */ 1456 void gen_move_low32(TCGv ret, TCGv_i64 arg) 1457 { 1458 #if defined(TARGET_MIPS64) 1459 tcg_gen_ext32s_i64(ret, arg); 1460 #else 1461 tcg_gen_extrl_i64_i32(ret, arg); 1462 #endif 1463 } 1464 1465 /* Sign-extract the high 32-bits to a target_long. */ 1466 void gen_move_high32(TCGv ret, TCGv_i64 arg) 1467 { 1468 #if defined(TARGET_MIPS64) 1469 tcg_gen_sari_i64(ret, arg, 32); 1470 #else 1471 tcg_gen_extrh_i64_i32(ret, arg); 1472 #endif 1473 } 1474 1475 bool check_cp0_enabled(DisasContext *ctx) 1476 { 1477 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1478 generate_exception_end(ctx, EXCP_CpU); 1479 return false; 1480 } 1481 return true; 1482 } 1483 1484 void check_cp1_enabled(DisasContext *ctx) 1485 { 1486 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) { 1487 generate_exception_err(ctx, EXCP_CpU, 1); 1488 } 1489 } 1490 1491 /* 1492 * Verify that the processor is running with COP1X instructions enabled. 1493 * This is associated with the nabla symbol in the MIPS32 and MIPS64 1494 * opcode tables. 1495 */ 1496 void check_cop1x(DisasContext *ctx) 1497 { 1498 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { 1499 gen_reserved_instruction(ctx); 1500 } 1501 } 1502 1503 /* 1504 * Verify that the processor is running with 64-bit floating-point 1505 * operations enabled. 1506 */ 1507 void check_cp1_64bitmode(DisasContext *ctx) 1508 { 1509 if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) { 1510 gen_reserved_instruction(ctx); 1511 } 1512 } 1513 1514 /* 1515 * Verify if floating point register is valid; an operation is not defined 1516 * if bit 0 of any register specification is set and the FR bit in the 1517 * Status register equals zero, since the register numbers specify an 1518 * even-odd pair of adjacent coprocessor general registers. When the FR bit 1519 * in the Status register equals one, both even and odd register numbers 1520 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 1521 * 1522 * Multiple 64 bit wide registers can be checked by calling 1523 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 1524 */ 1525 void check_cp1_registers(DisasContext *ctx, int regs) 1526 { 1527 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { 1528 gen_reserved_instruction(ctx); 1529 } 1530 } 1531 1532 /* 1533 * Verify that the processor is running with DSP instructions enabled. 1534 * This is enabled by CP0 Status register MX(24) bit. 1535 */ 1536 static inline void check_dsp(DisasContext *ctx) 1537 { 1538 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { 1539 if (ctx->insn_flags & ASE_DSP) { 1540 generate_exception_end(ctx, EXCP_DSPDIS); 1541 } else { 1542 gen_reserved_instruction(ctx); 1543 } 1544 } 1545 } 1546 1547 static inline void check_dsp_r2(DisasContext *ctx) 1548 { 1549 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { 1550 if (ctx->insn_flags & ASE_DSP) { 1551 generate_exception_end(ctx, EXCP_DSPDIS); 1552 } else { 1553 gen_reserved_instruction(ctx); 1554 } 1555 } 1556 } 1557 1558 static inline void check_dsp_r3(DisasContext *ctx) 1559 { 1560 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { 1561 if (ctx->insn_flags & ASE_DSP) { 1562 generate_exception_end(ctx, EXCP_DSPDIS); 1563 } else { 1564 gen_reserved_instruction(ctx); 1565 } 1566 } 1567 } 1568 1569 /* 1570 * This code generates a "reserved instruction" exception if the 1571 * CPU does not support the instruction set corresponding to flags. 1572 */ 1573 void check_insn(DisasContext *ctx, uint64_t flags) 1574 { 1575 if (unlikely(!(ctx->insn_flags & flags))) { 1576 gen_reserved_instruction(ctx); 1577 } 1578 } 1579 1580 /* 1581 * This code generates a "reserved instruction" exception if the 1582 * CPU has corresponding flag set which indicates that the instruction 1583 * has been removed. 1584 */ 1585 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) 1586 { 1587 if (unlikely(ctx->insn_flags & flags)) { 1588 gen_reserved_instruction(ctx); 1589 } 1590 } 1591 1592 /* 1593 * The Linux kernel traps certain reserved instruction exceptions to 1594 * emulate the corresponding instructions. QEMU is the kernel in user 1595 * mode, so those traps are emulated by accepting the instructions. 1596 * 1597 * A reserved instruction exception is generated for flagged CPUs if 1598 * QEMU runs in system mode. 1599 */ 1600 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) 1601 { 1602 #ifndef CONFIG_USER_ONLY 1603 check_insn_opc_removed(ctx, flags); 1604 #endif 1605 } 1606 1607 /* 1608 * This code generates a "reserved instruction" exception if the 1609 * CPU does not support 64-bit paired-single (PS) floating point data type. 1610 */ 1611 static inline void check_ps(DisasContext *ctx) 1612 { 1613 if (unlikely(!ctx->ps)) { 1614 generate_exception(ctx, EXCP_RI); 1615 } 1616 check_cp1_64bitmode(ctx); 1617 } 1618 1619 bool decode_64bit_enabled(DisasContext *ctx) 1620 { 1621 return ctx->hflags & MIPS_HFLAG_64; 1622 } 1623 1624 /* 1625 * This code generates a "reserved instruction" exception if cpu is not 1626 * 64-bit or 64-bit instructions are not enabled. 1627 */ 1628 void check_mips_64(DisasContext *ctx) 1629 { 1630 if (unlikely((TARGET_LONG_BITS != 64) || !decode_64bit_enabled(ctx))) { 1631 gen_reserved_instruction(ctx); 1632 } 1633 } 1634 1635 #ifndef CONFIG_USER_ONLY 1636 static inline void check_mvh(DisasContext *ctx) 1637 { 1638 if (unlikely(!ctx->mvh)) { 1639 generate_exception(ctx, EXCP_RI); 1640 } 1641 } 1642 #endif 1643 1644 /* 1645 * This code generates a "reserved instruction" exception if the 1646 * Config5 XNP bit is set. 1647 */ 1648 static inline void check_xnp(DisasContext *ctx) 1649 { 1650 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) { 1651 gen_reserved_instruction(ctx); 1652 } 1653 } 1654 1655 #ifndef CONFIG_USER_ONLY 1656 /* 1657 * This code generates a "reserved instruction" exception if the 1658 * Config3 PW bit is NOT set. 1659 */ 1660 static inline void check_pw(DisasContext *ctx) 1661 { 1662 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) { 1663 gen_reserved_instruction(ctx); 1664 } 1665 } 1666 #endif 1667 1668 /* 1669 * This code generates a "reserved instruction" exception if the 1670 * Config3 MT bit is NOT set. 1671 */ 1672 static inline void check_mt(DisasContext *ctx) 1673 { 1674 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1675 gen_reserved_instruction(ctx); 1676 } 1677 } 1678 1679 #ifndef CONFIG_USER_ONLY 1680 /* 1681 * This code generates a "coprocessor unusable" exception if CP0 is not 1682 * available, and, if that is not the case, generates a "reserved instruction" 1683 * exception if the Config5 MT bit is NOT set. This is needed for availability 1684 * control of some of MT ASE instructions. 1685 */ 1686 static inline void check_cp0_mt(DisasContext *ctx) 1687 { 1688 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1689 generate_exception_end(ctx, EXCP_CpU); 1690 } else { 1691 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1692 gen_reserved_instruction(ctx); 1693 } 1694 } 1695 } 1696 #endif 1697 1698 /* 1699 * This code generates a "reserved instruction" exception if the 1700 * Config5 NMS bit is set. 1701 */ 1702 static inline void check_nms(DisasContext *ctx) 1703 { 1704 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) { 1705 gen_reserved_instruction(ctx); 1706 } 1707 } 1708 1709 /* 1710 * This code generates a "reserved instruction" exception if the 1711 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, 1712 * Config2 TL, and Config5 L2C are unset. 1713 */ 1714 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) 1715 { 1716 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) && 1717 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) && 1718 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) && 1719 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && 1720 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && 1721 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) { 1722 gen_reserved_instruction(ctx); 1723 } 1724 } 1725 1726 /* 1727 * This code generates a "reserved instruction" exception if the 1728 * Config5 EVA bit is NOT set. 1729 */ 1730 static inline void check_eva(DisasContext *ctx) 1731 { 1732 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) { 1733 gen_reserved_instruction(ctx); 1734 } 1735 } 1736 1737 1738 /* 1739 * Define small wrappers for gen_load_fpr* so that we have a uniform 1740 * calling interface for 32 and 64-bit FPRs. No sense in changing 1741 * all callers for gen_load_fpr32 when we need the CTX parameter for 1742 * this one use. 1743 */ 1744 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) 1745 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) 1746 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \ 1747 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ 1748 int ft, int fs, int cc) \ 1749 { \ 1750 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ 1751 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ 1752 switch (ifmt) { \ 1753 case FMT_PS: \ 1754 check_ps(ctx); \ 1755 break; \ 1756 case FMT_D: \ 1757 if (abs) { \ 1758 check_cop1x(ctx); \ 1759 } \ 1760 check_cp1_registers(ctx, fs | ft); \ 1761 break; \ 1762 case FMT_S: \ 1763 if (abs) { \ 1764 check_cop1x(ctx); \ 1765 } \ 1766 break; \ 1767 } \ 1768 gen_ldcmp_fpr##bits(ctx, fp0, fs); \ 1769 gen_ldcmp_fpr##bits(ctx, fp1, ft); \ 1770 switch (n) { \ 1771 case 0: \ 1772 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \ 1773 break; \ 1774 case 1: \ 1775 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \ 1776 break; \ 1777 case 2: \ 1778 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \ 1779 break; \ 1780 case 3: \ 1781 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \ 1782 break; \ 1783 case 4: \ 1784 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \ 1785 break; \ 1786 case 5: \ 1787 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \ 1788 break; \ 1789 case 6: \ 1790 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \ 1791 break; \ 1792 case 7: \ 1793 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \ 1794 break; \ 1795 case 8: \ 1796 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \ 1797 break; \ 1798 case 9: \ 1799 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \ 1800 break; \ 1801 case 10: \ 1802 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \ 1803 break; \ 1804 case 11: \ 1805 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \ 1806 break; \ 1807 case 12: \ 1808 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \ 1809 break; \ 1810 case 13: \ 1811 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \ 1812 break; \ 1813 case 14: \ 1814 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \ 1815 break; \ 1816 case 15: \ 1817 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \ 1818 break; \ 1819 default: \ 1820 abort(); \ 1821 } \ 1822 } 1823 1824 FOP_CONDS(, 0, d, FMT_D, 64) 1825 FOP_CONDS(abs, 1, d, FMT_D, 64) 1826 FOP_CONDS(, 0, s, FMT_S, 32) 1827 FOP_CONDS(abs, 1, s, FMT_S, 32) 1828 FOP_CONDS(, 0, ps, FMT_PS, 64) 1829 FOP_CONDS(abs, 1, ps, FMT_PS, 64) 1830 #undef FOP_CONDS 1831 1832 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \ 1833 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \ 1834 int ft, int fs, int fd) \ 1835 { \ 1836 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ 1837 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ 1838 if (ifmt == FMT_D) { \ 1839 check_cp1_registers(ctx, fs | ft | fd); \ 1840 } \ 1841 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ 1842 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ 1843 switch (n) { \ 1844 case 0: \ 1845 gen_helper_r6_cmp_ ## fmt ## _af(fp0, tcg_env, fp0, fp1); \ 1846 break; \ 1847 case 1: \ 1848 gen_helper_r6_cmp_ ## fmt ## _un(fp0, tcg_env, fp0, fp1); \ 1849 break; \ 1850 case 2: \ 1851 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, tcg_env, fp0, fp1); \ 1852 break; \ 1853 case 3: \ 1854 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, tcg_env, fp0, fp1); \ 1855 break; \ 1856 case 4: \ 1857 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, tcg_env, fp0, fp1); \ 1858 break; \ 1859 case 5: \ 1860 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, tcg_env, fp0, fp1); \ 1861 break; \ 1862 case 6: \ 1863 gen_helper_r6_cmp_ ## fmt ## _le(fp0, tcg_env, fp0, fp1); \ 1864 break; \ 1865 case 7: \ 1866 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, tcg_env, fp0, fp1); \ 1867 break; \ 1868 case 8: \ 1869 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, tcg_env, fp0, fp1); \ 1870 break; \ 1871 case 9: \ 1872 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, tcg_env, fp0, fp1); \ 1873 break; \ 1874 case 10: \ 1875 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, tcg_env, fp0, fp1); \ 1876 break; \ 1877 case 11: \ 1878 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, tcg_env, fp0, fp1); \ 1879 break; \ 1880 case 12: \ 1881 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, tcg_env, fp0, fp1); \ 1882 break; \ 1883 case 13: \ 1884 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, tcg_env, fp0, fp1); \ 1885 break; \ 1886 case 14: \ 1887 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, tcg_env, fp0, fp1); \ 1888 break; \ 1889 case 15: \ 1890 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, tcg_env, fp0, fp1); \ 1891 break; \ 1892 case 17: \ 1893 gen_helper_r6_cmp_ ## fmt ## _or(fp0, tcg_env, fp0, fp1); \ 1894 break; \ 1895 case 18: \ 1896 gen_helper_r6_cmp_ ## fmt ## _une(fp0, tcg_env, fp0, fp1); \ 1897 break; \ 1898 case 19: \ 1899 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, tcg_env, fp0, fp1); \ 1900 break; \ 1901 case 25: \ 1902 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, tcg_env, fp0, fp1); \ 1903 break; \ 1904 case 26: \ 1905 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, tcg_env, fp0, fp1); \ 1906 break; \ 1907 case 27: \ 1908 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, tcg_env, fp0, fp1); \ 1909 break; \ 1910 default: \ 1911 abort(); \ 1912 } \ 1913 STORE; \ 1914 } 1915 1916 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) 1917 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd)) 1918 #undef FOP_CONDNS 1919 #undef gen_ldcmp_fpr32 1920 #undef gen_ldcmp_fpr64 1921 1922 /* load/store instructions. */ 1923 #ifdef CONFIG_USER_ONLY 1924 #define OP_LD_ATOMIC(insn, memop) \ 1925 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1926 DisasContext *ctx) \ 1927 { \ 1928 TCGv t0 = tcg_temp_new(); \ 1929 tcg_gen_mov_tl(t0, arg1); \ 1930 tcg_gen_qemu_ld_tl(ret, arg1, ctx->mem_idx, memop); \ 1931 tcg_gen_st_tl(t0, tcg_env, offsetof(CPUMIPSState, lladdr)); \ 1932 tcg_gen_st_tl(ret, tcg_env, offsetof(CPUMIPSState, llval)); \ 1933 } 1934 #else 1935 #define OP_LD_ATOMIC(insn, ignored_memop) \ 1936 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1937 DisasContext *ctx) \ 1938 { \ 1939 gen_helper_##insn(ret, tcg_env, arg1, tcg_constant_i32(mem_idx)); \ 1940 } 1941 #endif 1942 OP_LD_ATOMIC(ll, mo_endian(ctx) | MO_SL); 1943 #if defined(TARGET_MIPS64) 1944 OP_LD_ATOMIC(lld, mo_endian(ctx) | MO_UQ); 1945 #endif 1946 #undef OP_LD_ATOMIC 1947 1948 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset) 1949 { 1950 if (base == 0) { 1951 tcg_gen_movi_tl(addr, offset); 1952 } else if (offset == 0) { 1953 gen_load_gpr(addr, base); 1954 } else { 1955 tcg_gen_movi_tl(addr, offset); 1956 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); 1957 } 1958 } 1959 1960 static target_ulong pc_relative_pc(DisasContext *ctx) 1961 { 1962 target_ulong pc = ctx->base.pc_next; 1963 1964 if (ctx->hflags & MIPS_HFLAG_BMASK) { 1965 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4; 1966 1967 pc -= branch_bytes; 1968 } 1969 1970 pc &= ~(target_ulong)3; 1971 return pc; 1972 } 1973 1974 /* LWL or LDL, depending on MemOp. */ 1975 static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr, 1976 int mem_idx, MemOp mop) 1977 { 1978 int sizem1 = memop_size(mop) - 1; 1979 TCGv t0 = tcg_temp_new(); 1980 TCGv t1 = tcg_temp_new(); 1981 1982 /* 1983 * Do a byte access to possibly trigger a page 1984 * fault with the unaligned address. 1985 */ 1986 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); 1987 tcg_gen_andi_tl(t1, addr, sizem1); 1988 if (!disas_is_bigendian(ctx)) { 1989 tcg_gen_xori_tl(t1, t1, sizem1); 1990 } 1991 tcg_gen_shli_tl(t1, t1, 3); 1992 tcg_gen_andi_tl(t0, addr, ~sizem1); 1993 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); 1994 tcg_gen_shl_tl(t0, t0, t1); 1995 tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1); 1996 tcg_gen_andc_tl(t1, reg, t1); 1997 tcg_gen_or_tl(reg, t0, t1); 1998 } 1999 2000 /* LWR or LDR, depending on MemOp. */ 2001 static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr, 2002 int mem_idx, MemOp mop) 2003 { 2004 int size = memop_size(mop); 2005 int sizem1 = size - 1; 2006 TCGv t0 = tcg_temp_new(); 2007 TCGv t1 = tcg_temp_new(); 2008 2009 /* 2010 * Do a byte access to possibly trigger a page 2011 * fault with the unaligned address. 2012 */ 2013 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); 2014 tcg_gen_andi_tl(t1, addr, sizem1); 2015 if (disas_is_bigendian(ctx)) { 2016 tcg_gen_xori_tl(t1, t1, sizem1); 2017 } 2018 tcg_gen_shli_tl(t1, t1, 3); 2019 tcg_gen_andi_tl(t0, addr, ~sizem1); 2020 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); 2021 tcg_gen_shr_tl(t0, t0, t1); 2022 tcg_gen_xori_tl(t1, t1, size * 8 - 1); 2023 tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1); 2024 tcg_gen_and_tl(t1, reg, t1); 2025 tcg_gen_or_tl(reg, t0, t1); 2026 } 2027 2028 /* Load */ 2029 static void gen_ld(DisasContext *ctx, uint32_t opc, 2030 int rt, int base, int offset) 2031 { 2032 TCGv t0, t1; 2033 int mem_idx = ctx->mem_idx; 2034 2035 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F | 2036 INSN_LOONGSON3A)) { 2037 /* 2038 * Loongson CPU uses a load to zero register for prefetch. 2039 * We emulate it as a NOP. On other CPU we must perform the 2040 * actual memory access. 2041 */ 2042 return; 2043 } 2044 2045 t0 = tcg_temp_new(); 2046 gen_base_offset_addr(ctx, t0, base, offset); 2047 2048 switch (opc) { 2049 #if defined(TARGET_MIPS64) 2050 case OPC_LWU: 2051 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UL | 2052 ctx->default_tcg_memop_mask); 2053 gen_store_gpr(t0, rt); 2054 break; 2055 case OPC_LD: 2056 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ | 2057 ctx->default_tcg_memop_mask); 2058 gen_store_gpr(t0, rt); 2059 break; 2060 case OPC_LLD: 2061 case R6_OPC_LLD: 2062 op_ld_lld(t0, t0, mem_idx, ctx); 2063 gen_store_gpr(t0, rt); 2064 break; 2065 case OPC_LDL: 2066 t1 = tcg_temp_new(); 2067 gen_load_gpr(t1, rt); 2068 gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2069 gen_store_gpr(t1, rt); 2070 break; 2071 case OPC_LDR: 2072 t1 = tcg_temp_new(); 2073 gen_load_gpr(t1, rt); 2074 gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2075 gen_store_gpr(t1, rt); 2076 break; 2077 case OPC_LDPC: 2078 t1 = tcg_constant_tl(pc_relative_pc(ctx)); 2079 gen_op_addr_add(ctx, t0, t0, t1); 2080 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2081 gen_store_gpr(t0, rt); 2082 break; 2083 #endif 2084 case OPC_LWPC: 2085 t1 = tcg_constant_tl(pc_relative_pc(ctx)); 2086 gen_op_addr_add(ctx, t0, t0, t1); 2087 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL); 2088 gen_store_gpr(t0, rt); 2089 break; 2090 case OPC_LWE: 2091 mem_idx = MIPS_HFLAG_UM; 2092 /* fall through */ 2093 case OPC_LW: 2094 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL | 2095 ctx->default_tcg_memop_mask); 2096 gen_store_gpr(t0, rt); 2097 break; 2098 case OPC_LHE: 2099 mem_idx = MIPS_HFLAG_UM; 2100 /* fall through */ 2101 case OPC_LH: 2102 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SW | 2103 ctx->default_tcg_memop_mask); 2104 gen_store_gpr(t0, rt); 2105 break; 2106 case OPC_LHUE: 2107 mem_idx = MIPS_HFLAG_UM; 2108 /* fall through */ 2109 case OPC_LHU: 2110 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UW | 2111 ctx->default_tcg_memop_mask); 2112 gen_store_gpr(t0, rt); 2113 break; 2114 case OPC_LBE: 2115 mem_idx = MIPS_HFLAG_UM; 2116 /* fall through */ 2117 case OPC_LB: 2118 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); 2119 gen_store_gpr(t0, rt); 2120 break; 2121 case OPC_LBUE: 2122 mem_idx = MIPS_HFLAG_UM; 2123 /* fall through */ 2124 case OPC_LBU: 2125 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); 2126 gen_store_gpr(t0, rt); 2127 break; 2128 case OPC_LWLE: 2129 mem_idx = MIPS_HFLAG_UM; 2130 /* fall through */ 2131 case OPC_LWL: 2132 t1 = tcg_temp_new(); 2133 gen_load_gpr(t1, rt); 2134 gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL); 2135 tcg_gen_ext32s_tl(t1, t1); 2136 gen_store_gpr(t1, rt); 2137 break; 2138 case OPC_LWRE: 2139 mem_idx = MIPS_HFLAG_UM; 2140 /* fall through */ 2141 case OPC_LWR: 2142 t1 = tcg_temp_new(); 2143 gen_load_gpr(t1, rt); 2144 gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL); 2145 tcg_gen_ext32s_tl(t1, t1); 2146 gen_store_gpr(t1, rt); 2147 break; 2148 case OPC_LLE: 2149 mem_idx = MIPS_HFLAG_UM; 2150 /* fall through */ 2151 case OPC_LL: 2152 case R6_OPC_LL: 2153 op_ld_ll(t0, t0, mem_idx, ctx); 2154 gen_store_gpr(t0, rt); 2155 break; 2156 } 2157 } 2158 2159 /* Store */ 2160 static void gen_st(DisasContext *ctx, uint32_t opc, int rt, 2161 int base, int offset) 2162 { 2163 TCGv t0 = tcg_temp_new(); 2164 TCGv t1 = tcg_temp_new(); 2165 int mem_idx = ctx->mem_idx; 2166 2167 gen_base_offset_addr(ctx, t0, base, offset); 2168 gen_load_gpr(t1, rt); 2169 switch (opc) { 2170 #if defined(TARGET_MIPS64) 2171 case OPC_SD: 2172 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UQ | 2173 ctx->default_tcg_memop_mask); 2174 break; 2175 case OPC_SDL: 2176 gen_helper_0e2i(sdl, t1, t0, mem_idx); 2177 break; 2178 case OPC_SDR: 2179 gen_helper_0e2i(sdr, t1, t0, mem_idx); 2180 break; 2181 #endif 2182 case OPC_SWE: 2183 mem_idx = MIPS_HFLAG_UM; 2184 /* fall through */ 2185 case OPC_SW: 2186 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UL | 2187 ctx->default_tcg_memop_mask); 2188 break; 2189 case OPC_SHE: 2190 mem_idx = MIPS_HFLAG_UM; 2191 /* fall through */ 2192 case OPC_SH: 2193 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UW | 2194 ctx->default_tcg_memop_mask); 2195 break; 2196 case OPC_SBE: 2197 mem_idx = MIPS_HFLAG_UM; 2198 /* fall through */ 2199 case OPC_SB: 2200 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); 2201 break; 2202 case OPC_SWLE: 2203 mem_idx = MIPS_HFLAG_UM; 2204 /* fall through */ 2205 case OPC_SWL: 2206 gen_helper_0e2i(swl, t1, t0, mem_idx); 2207 break; 2208 case OPC_SWRE: 2209 mem_idx = MIPS_HFLAG_UM; 2210 /* fall through */ 2211 case OPC_SWR: 2212 gen_helper_0e2i(swr, t1, t0, mem_idx); 2213 break; 2214 } 2215 } 2216 2217 2218 /* Store conditional */ 2219 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, 2220 MemOp tcg_mo, bool eva) 2221 { 2222 TCGv addr, t0, val; 2223 TCGLabel *l1 = gen_new_label(); 2224 TCGLabel *done = gen_new_label(); 2225 2226 t0 = tcg_temp_new(); 2227 addr = tcg_temp_new(); 2228 /* compare the address against that of the preceding LL */ 2229 gen_base_offset_addr(ctx, addr, base, offset); 2230 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); 2231 gen_store_gpr(tcg_constant_tl(0), rt); 2232 tcg_gen_br(done); 2233 2234 gen_set_label(l1); 2235 /* generate cmpxchg */ 2236 val = tcg_temp_new(); 2237 gen_load_gpr(val, rt); 2238 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, 2239 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo); 2240 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); 2241 gen_store_gpr(t0, rt); 2242 2243 gen_set_label(done); 2244 } 2245 2246 /* Load and store */ 2247 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, 2248 TCGv t0) 2249 { 2250 /* 2251 * Don't do NOP if destination is zero: we must perform the actual 2252 * memory access. 2253 */ 2254 switch (opc) { 2255 case OPC_LWC1: 2256 { 2257 TCGv_i32 fp0 = tcg_temp_new_i32(); 2258 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 2259 ctx->default_tcg_memop_mask); 2260 gen_store_fpr32(ctx, fp0, ft); 2261 } 2262 break; 2263 case OPC_SWC1: 2264 { 2265 TCGv_i32 fp0 = tcg_temp_new_i32(); 2266 gen_load_fpr32(ctx, fp0, ft); 2267 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 2268 ctx->default_tcg_memop_mask); 2269 } 2270 break; 2271 case OPC_LDC1: 2272 { 2273 TCGv_i64 fp0 = tcg_temp_new_i64(); 2274 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 2275 ctx->default_tcg_memop_mask); 2276 gen_store_fpr64(ctx, fp0, ft); 2277 } 2278 break; 2279 case OPC_SDC1: 2280 { 2281 TCGv_i64 fp0 = tcg_temp_new_i64(); 2282 gen_load_fpr64(ctx, fp0, ft); 2283 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 2284 ctx->default_tcg_memop_mask); 2285 } 2286 break; 2287 default: 2288 MIPS_INVAL("flt_ldst"); 2289 gen_reserved_instruction(ctx); 2290 break; 2291 } 2292 } 2293 2294 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, 2295 int rs, int16_t imm) 2296 { 2297 TCGv t0 = tcg_temp_new(); 2298 2299 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2300 check_cp1_enabled(ctx); 2301 switch (op) { 2302 case OPC_LDC1: 2303 case OPC_SDC1: 2304 check_insn(ctx, ISA_MIPS2); 2305 /* Fallthrough */ 2306 default: 2307 gen_base_offset_addr(ctx, t0, rs, imm); 2308 gen_flt_ldst(ctx, op, rt, t0); 2309 } 2310 } else { 2311 generate_exception_err(ctx, EXCP_CpU, 1); 2312 } 2313 } 2314 2315 /* Arithmetic with immediate operand */ 2316 static void gen_arith_imm(DisasContext *ctx, uint32_t opc, 2317 int rt, int rs, int imm) 2318 { 2319 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2320 2321 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 2322 /* 2323 * If no destination, treat it as a NOP. 2324 * For addi, we must generate the overflow exception when needed. 2325 */ 2326 return; 2327 } 2328 switch (opc) { 2329 case OPC_ADDI: 2330 { 2331 TCGv t0 = tcg_temp_new(); 2332 TCGv t1 = tcg_temp_new(); 2333 TCGv t2 = tcg_temp_new(); 2334 TCGLabel *l1 = gen_new_label(); 2335 2336 gen_load_gpr(t1, rs); 2337 tcg_gen_addi_tl(t0, t1, uimm); 2338 tcg_gen_ext32s_tl(t0, t0); 2339 2340 tcg_gen_xori_tl(t1, t1, ~uimm); 2341 tcg_gen_xori_tl(t2, t0, uimm); 2342 tcg_gen_and_tl(t1, t1, t2); 2343 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2344 /* operands of same sign, result different sign */ 2345 generate_exception(ctx, EXCP_OVERFLOW); 2346 gen_set_label(l1); 2347 tcg_gen_ext32s_tl(t0, t0); 2348 gen_store_gpr(t0, rt); 2349 } 2350 break; 2351 case OPC_ADDIU: 2352 if (rs != 0) { 2353 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2354 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2355 } else { 2356 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2357 } 2358 break; 2359 #if defined(TARGET_MIPS64) 2360 case OPC_DADDI: 2361 { 2362 TCGv t0 = tcg_temp_new(); 2363 TCGv t1 = tcg_temp_new(); 2364 TCGv t2 = tcg_temp_new(); 2365 TCGLabel *l1 = gen_new_label(); 2366 2367 gen_load_gpr(t1, rs); 2368 tcg_gen_addi_tl(t0, t1, uimm); 2369 2370 tcg_gen_xori_tl(t1, t1, ~uimm); 2371 tcg_gen_xori_tl(t2, t0, uimm); 2372 tcg_gen_and_tl(t1, t1, t2); 2373 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2374 /* operands of same sign, result different sign */ 2375 generate_exception(ctx, EXCP_OVERFLOW); 2376 gen_set_label(l1); 2377 gen_store_gpr(t0, rt); 2378 } 2379 break; 2380 case OPC_DADDIU: 2381 if (rs != 0) { 2382 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2383 } else { 2384 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2385 } 2386 break; 2387 #endif 2388 } 2389 } 2390 2391 /* Logic with immediate operand */ 2392 static void gen_logic_imm(DisasContext *ctx, uint32_t opc, 2393 int rt, int rs, int16_t imm) 2394 { 2395 target_ulong uimm; 2396 2397 if (rt == 0) { 2398 /* If no destination, treat it as a NOP. */ 2399 return; 2400 } 2401 uimm = (uint16_t)imm; 2402 switch (opc) { 2403 case OPC_ANDI: 2404 if (likely(rs != 0)) { 2405 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2406 } else { 2407 tcg_gen_movi_tl(cpu_gpr[rt], 0); 2408 } 2409 break; 2410 case OPC_ORI: 2411 if (rs != 0) { 2412 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2413 } else { 2414 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2415 } 2416 break; 2417 case OPC_XORI: 2418 if (likely(rs != 0)) { 2419 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2420 } else { 2421 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2422 } 2423 break; 2424 case OPC_LUI: 2425 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) { 2426 /* OPC_AUI */ 2427 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16); 2428 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2429 } else { 2430 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 2431 } 2432 break; 2433 2434 default: 2435 break; 2436 } 2437 } 2438 2439 /* Set on less than with immediate operand */ 2440 static void gen_slt_imm(DisasContext *ctx, uint32_t opc, 2441 int rt, int rs, int16_t imm) 2442 { 2443 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2444 TCGv t0; 2445 2446 if (rt == 0) { 2447 /* If no destination, treat it as a NOP. */ 2448 return; 2449 } 2450 t0 = tcg_temp_new(); 2451 gen_load_gpr(t0, rs); 2452 switch (opc) { 2453 case OPC_SLTI: 2454 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); 2455 break; 2456 case OPC_SLTIU: 2457 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); 2458 break; 2459 } 2460 } 2461 2462 /* Shifts with immediate operand */ 2463 static void gen_shift_imm(DisasContext *ctx, uint32_t opc, 2464 int rt, int rs, int16_t imm) 2465 { 2466 target_ulong uimm = ((uint16_t)imm) & 0x1f; 2467 TCGv t0; 2468 2469 if (rt == 0) { 2470 /* If no destination, treat it as a NOP. */ 2471 return; 2472 } 2473 2474 t0 = tcg_temp_new(); 2475 gen_load_gpr(t0, rs); 2476 switch (opc) { 2477 case OPC_SLL: 2478 tcg_gen_shli_tl(t0, t0, uimm); 2479 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2480 break; 2481 case OPC_SRA: 2482 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2483 break; 2484 case OPC_SRL: 2485 if (uimm != 0) { 2486 tcg_gen_ext32u_tl(t0, t0); 2487 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2488 } else { 2489 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2490 } 2491 break; 2492 case OPC_ROTR: 2493 if (uimm != 0) { 2494 TCGv_i32 t1 = tcg_temp_new_i32(); 2495 2496 tcg_gen_trunc_tl_i32(t1, t0); 2497 tcg_gen_rotri_i32(t1, t1, uimm); 2498 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 2499 } else { 2500 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2501 } 2502 break; 2503 #if defined(TARGET_MIPS64) 2504 case OPC_DSLL: 2505 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 2506 break; 2507 case OPC_DSRA: 2508 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2509 break; 2510 case OPC_DSRL: 2511 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2512 break; 2513 case OPC_DROTR: 2514 if (uimm != 0) { 2515 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 2516 } else { 2517 tcg_gen_mov_tl(cpu_gpr[rt], t0); 2518 } 2519 break; 2520 case OPC_DSLL32: 2521 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 2522 break; 2523 case OPC_DSRA32: 2524 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 2525 break; 2526 case OPC_DSRL32: 2527 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 2528 break; 2529 case OPC_DROTR32: 2530 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 2531 break; 2532 #endif 2533 } 2534 } 2535 2536 /* Arithmetic */ 2537 static void gen_arith(DisasContext *ctx, uint32_t opc, 2538 int rd, int rs, int rt) 2539 { 2540 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 2541 && opc != OPC_DADD && opc != OPC_DSUB) { 2542 /* 2543 * If no destination, treat it as a NOP. 2544 * For add & sub, we must generate the overflow exception when needed. 2545 */ 2546 return; 2547 } 2548 2549 switch (opc) { 2550 case OPC_ADD: 2551 { 2552 TCGv t0 = tcg_temp_new(); 2553 TCGv t1 = tcg_temp_new(); 2554 TCGv t2 = tcg_temp_new(); 2555 TCGLabel *l1 = gen_new_label(); 2556 2557 gen_load_gpr(t1, rs); 2558 gen_load_gpr(t2, rt); 2559 tcg_gen_add_tl(t0, t1, t2); 2560 tcg_gen_ext32s_tl(t0, t0); 2561 tcg_gen_xor_tl(t1, t1, t2); 2562 tcg_gen_xor_tl(t2, t0, t2); 2563 tcg_gen_andc_tl(t1, t2, t1); 2564 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2565 /* operands of same sign, result different sign */ 2566 generate_exception(ctx, EXCP_OVERFLOW); 2567 gen_set_label(l1); 2568 gen_store_gpr(t0, rd); 2569 } 2570 break; 2571 case OPC_ADDU: 2572 if (rs != 0 && rt != 0) { 2573 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2574 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2575 } else if (rs == 0 && rt != 0) { 2576 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2577 } else if (rs != 0 && rt == 0) { 2578 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2579 } else { 2580 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2581 } 2582 break; 2583 case OPC_SUB: 2584 { 2585 TCGv t0 = tcg_temp_new(); 2586 TCGv t1 = tcg_temp_new(); 2587 TCGv t2 = tcg_temp_new(); 2588 TCGLabel *l1 = gen_new_label(); 2589 2590 gen_load_gpr(t1, rs); 2591 gen_load_gpr(t2, rt); 2592 tcg_gen_sub_tl(t0, t1, t2); 2593 tcg_gen_ext32s_tl(t0, t0); 2594 tcg_gen_xor_tl(t2, t1, t2); 2595 tcg_gen_xor_tl(t1, t0, t1); 2596 tcg_gen_and_tl(t1, t1, t2); 2597 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2598 /* 2599 * operands of different sign, first operand and the result 2600 * of different sign 2601 */ 2602 generate_exception(ctx, EXCP_OVERFLOW); 2603 gen_set_label(l1); 2604 gen_store_gpr(t0, rd); 2605 } 2606 break; 2607 case OPC_SUBU: 2608 if (rs != 0 && rt != 0) { 2609 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2610 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2611 } else if (rs == 0 && rt != 0) { 2612 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2613 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2614 } else if (rs != 0 && rt == 0) { 2615 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2616 } else { 2617 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2618 } 2619 break; 2620 #if defined(TARGET_MIPS64) 2621 case OPC_DADD: 2622 { 2623 TCGv t0 = tcg_temp_new(); 2624 TCGv t1 = tcg_temp_new(); 2625 TCGv t2 = tcg_temp_new(); 2626 TCGLabel *l1 = gen_new_label(); 2627 2628 gen_load_gpr(t1, rs); 2629 gen_load_gpr(t2, rt); 2630 tcg_gen_add_tl(t0, t1, t2); 2631 tcg_gen_xor_tl(t1, t1, t2); 2632 tcg_gen_xor_tl(t2, t0, t2); 2633 tcg_gen_andc_tl(t1, t2, t1); 2634 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2635 /* operands of same sign, result different sign */ 2636 generate_exception(ctx, EXCP_OVERFLOW); 2637 gen_set_label(l1); 2638 gen_store_gpr(t0, rd); 2639 } 2640 break; 2641 case OPC_DADDU: 2642 if (rs != 0 && rt != 0) { 2643 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2644 } else if (rs == 0 && rt != 0) { 2645 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2646 } else if (rs != 0 && rt == 0) { 2647 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2648 } else { 2649 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2650 } 2651 break; 2652 case OPC_DSUB: 2653 { 2654 TCGv t0 = tcg_temp_new(); 2655 TCGv t1 = tcg_temp_new(); 2656 TCGv t2 = tcg_temp_new(); 2657 TCGLabel *l1 = gen_new_label(); 2658 2659 gen_load_gpr(t1, rs); 2660 gen_load_gpr(t2, rt); 2661 tcg_gen_sub_tl(t0, t1, t2); 2662 tcg_gen_xor_tl(t2, t1, t2); 2663 tcg_gen_xor_tl(t1, t0, t1); 2664 tcg_gen_and_tl(t1, t1, t2); 2665 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2666 /* 2667 * Operands of different sign, first operand and result different 2668 * sign. 2669 */ 2670 generate_exception(ctx, EXCP_OVERFLOW); 2671 gen_set_label(l1); 2672 gen_store_gpr(t0, rd); 2673 } 2674 break; 2675 case OPC_DSUBU: 2676 if (rs != 0 && rt != 0) { 2677 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2678 } else if (rs == 0 && rt != 0) { 2679 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2680 } else if (rs != 0 && rt == 0) { 2681 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2682 } else { 2683 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2684 } 2685 break; 2686 #endif 2687 case OPC_MUL: 2688 if (likely(rs != 0 && rt != 0)) { 2689 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2690 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2691 } else { 2692 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2693 } 2694 break; 2695 } 2696 } 2697 2698 /* Conditional move */ 2699 static void gen_cond_move(DisasContext *ctx, uint32_t opc, 2700 int rd, int rs, int rt) 2701 { 2702 TCGv t0, t1, t2; 2703 2704 if (rd == 0) { 2705 /* If no destination, treat it as a NOP. */ 2706 return; 2707 } 2708 2709 t0 = tcg_temp_new(); 2710 gen_load_gpr(t0, rt); 2711 t1 = tcg_constant_tl(0); 2712 t2 = tcg_temp_new(); 2713 gen_load_gpr(t2, rs); 2714 switch (opc) { 2715 case OPC_MOVN: 2716 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2717 break; 2718 case OPC_MOVZ: 2719 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2720 break; 2721 case OPC_SELNEZ: 2722 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); 2723 break; 2724 case OPC_SELEQZ: 2725 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); 2726 break; 2727 } 2728 } 2729 2730 /* Logic */ 2731 static void gen_logic(DisasContext *ctx, uint32_t opc, 2732 int rd, int rs, int rt) 2733 { 2734 if (rd == 0) { 2735 /* If no destination, treat it as a NOP. */ 2736 return; 2737 } 2738 2739 switch (opc) { 2740 case OPC_AND: 2741 if (likely(rs != 0 && rt != 0)) { 2742 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2743 } else { 2744 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2745 } 2746 break; 2747 case OPC_NOR: 2748 if (rs != 0 && rt != 0) { 2749 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2750 } else if (rs == 0 && rt != 0) { 2751 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 2752 } else if (rs != 0 && rt == 0) { 2753 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 2754 } else { 2755 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 2756 } 2757 break; 2758 case OPC_OR: 2759 if (likely(rs != 0 && rt != 0)) { 2760 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2761 } else if (rs == 0 && rt != 0) { 2762 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2763 } else if (rs != 0 && rt == 0) { 2764 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2765 } else { 2766 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2767 } 2768 break; 2769 case OPC_XOR: 2770 if (likely(rs != 0 && rt != 0)) { 2771 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2772 } else if (rs == 0 && rt != 0) { 2773 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2774 } else if (rs != 0 && rt == 0) { 2775 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2776 } else { 2777 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2778 } 2779 break; 2780 } 2781 } 2782 2783 /* Set on lower than */ 2784 static void gen_slt(DisasContext *ctx, uint32_t opc, 2785 int rd, int rs, int rt) 2786 { 2787 TCGv t0, t1; 2788 2789 if (rd == 0) { 2790 /* If no destination, treat it as a NOP. */ 2791 return; 2792 } 2793 2794 t0 = tcg_temp_new(); 2795 t1 = tcg_temp_new(); 2796 gen_load_gpr(t0, rs); 2797 gen_load_gpr(t1, rt); 2798 switch (opc) { 2799 case OPC_SLT: 2800 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); 2801 break; 2802 case OPC_SLTU: 2803 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); 2804 break; 2805 } 2806 } 2807 2808 /* Shifts */ 2809 static void gen_shift(DisasContext *ctx, uint32_t opc, 2810 int rd, int rs, int rt) 2811 { 2812 TCGv t0, t1; 2813 2814 if (rd == 0) { 2815 /* 2816 * If no destination, treat it as a NOP. 2817 * For add & sub, we must generate the overflow exception when needed. 2818 */ 2819 return; 2820 } 2821 2822 t0 = tcg_temp_new(); 2823 t1 = tcg_temp_new(); 2824 gen_load_gpr(t0, rs); 2825 gen_load_gpr(t1, rt); 2826 switch (opc) { 2827 case OPC_SLLV: 2828 tcg_gen_andi_tl(t0, t0, 0x1f); 2829 tcg_gen_shl_tl(t0, t1, t0); 2830 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2831 break; 2832 case OPC_SRAV: 2833 tcg_gen_andi_tl(t0, t0, 0x1f); 2834 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2835 break; 2836 case OPC_SRLV: 2837 tcg_gen_ext32u_tl(t1, t1); 2838 tcg_gen_andi_tl(t0, t0, 0x1f); 2839 tcg_gen_shr_tl(t0, t1, t0); 2840 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2841 break; 2842 case OPC_ROTRV: 2843 { 2844 TCGv_i32 t2 = tcg_temp_new_i32(); 2845 TCGv_i32 t3 = tcg_temp_new_i32(); 2846 2847 tcg_gen_trunc_tl_i32(t2, t0); 2848 tcg_gen_trunc_tl_i32(t3, t1); 2849 tcg_gen_andi_i32(t2, t2, 0x1f); 2850 tcg_gen_rotr_i32(t2, t3, t2); 2851 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 2852 } 2853 break; 2854 #if defined(TARGET_MIPS64) 2855 case OPC_DSLLV: 2856 tcg_gen_andi_tl(t0, t0, 0x3f); 2857 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 2858 break; 2859 case OPC_DSRAV: 2860 tcg_gen_andi_tl(t0, t0, 0x3f); 2861 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2862 break; 2863 case OPC_DSRLV: 2864 tcg_gen_andi_tl(t0, t0, 0x3f); 2865 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 2866 break; 2867 case OPC_DROTRV: 2868 tcg_gen_andi_tl(t0, t0, 0x3f); 2869 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 2870 break; 2871 #endif 2872 } 2873 } 2874 2875 /* Arithmetic on HI/LO registers */ 2876 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) 2877 { 2878 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 2879 /* Treat as NOP. */ 2880 return; 2881 } 2882 2883 if (acc != 0) { 2884 check_dsp(ctx); 2885 } 2886 2887 switch (opc) { 2888 case OPC_MFHI: 2889 #if defined(TARGET_MIPS64) 2890 if (acc != 0) { 2891 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); 2892 } else 2893 #endif 2894 { 2895 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); 2896 } 2897 break; 2898 case OPC_MFLO: 2899 #if defined(TARGET_MIPS64) 2900 if (acc != 0) { 2901 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); 2902 } else 2903 #endif 2904 { 2905 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); 2906 } 2907 break; 2908 case OPC_MTHI: 2909 if (reg != 0) { 2910 #if defined(TARGET_MIPS64) 2911 if (acc != 0) { 2912 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); 2913 } else 2914 #endif 2915 { 2916 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); 2917 } 2918 } else { 2919 tcg_gen_movi_tl(cpu_HI[acc], 0); 2920 } 2921 break; 2922 case OPC_MTLO: 2923 if (reg != 0) { 2924 #if defined(TARGET_MIPS64) 2925 if (acc != 0) { 2926 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); 2927 } else 2928 #endif 2929 { 2930 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); 2931 } 2932 } else { 2933 tcg_gen_movi_tl(cpu_LO[acc], 0); 2934 } 2935 break; 2936 } 2937 } 2938 2939 static inline void gen_r6_ld(target_long addr, int reg, int memidx, 2940 MemOp memop) 2941 { 2942 TCGv t0 = tcg_temp_new(); 2943 tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop); 2944 gen_store_gpr(t0, reg); 2945 } 2946 2947 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, 2948 int rs) 2949 { 2950 target_long offset; 2951 target_long addr; 2952 2953 switch (MASK_OPC_PCREL_TOP2BITS(opc)) { 2954 case OPC_ADDIUPC: 2955 if (rs != 0) { 2956 offset = sextract32(ctx->opcode << 2, 0, 21); 2957 addr = addr_add(ctx, pc, offset); 2958 tcg_gen_movi_tl(cpu_gpr[rs], addr); 2959 } 2960 break; 2961 case R6_OPC_LWPC: 2962 offset = sextract32(ctx->opcode << 2, 0, 21); 2963 addr = addr_add(ctx, pc, offset); 2964 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_SL); 2965 break; 2966 #if defined(TARGET_MIPS64) 2967 case OPC_LWUPC: 2968 check_mips_64(ctx); 2969 offset = sextract32(ctx->opcode << 2, 0, 21); 2970 addr = addr_add(ctx, pc, offset); 2971 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UL); 2972 break; 2973 #endif 2974 default: 2975 switch (MASK_OPC_PCREL_TOP5BITS(opc)) { 2976 case OPC_AUIPC: 2977 if (rs != 0) { 2978 offset = sextract32(ctx->opcode, 0, 16) << 16; 2979 addr = addr_add(ctx, pc, offset); 2980 tcg_gen_movi_tl(cpu_gpr[rs], addr); 2981 } 2982 break; 2983 case OPC_ALUIPC: 2984 if (rs != 0) { 2985 offset = sextract32(ctx->opcode, 0, 16) << 16; 2986 addr = ~0xFFFF & addr_add(ctx, pc, offset); 2987 tcg_gen_movi_tl(cpu_gpr[rs], addr); 2988 } 2989 break; 2990 #if defined(TARGET_MIPS64) 2991 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */ 2992 case R6_OPC_LDPC + (1 << 16): 2993 case R6_OPC_LDPC + (2 << 16): 2994 case R6_OPC_LDPC + (3 << 16): 2995 check_mips_64(ctx); 2996 offset = sextract32(ctx->opcode << 3, 0, 21); 2997 addr = addr_add(ctx, (pc & ~0x7), offset); 2998 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 2999 break; 3000 #endif 3001 default: 3002 MIPS_INVAL("OPC_PCREL"); 3003 gen_reserved_instruction(ctx); 3004 break; 3005 } 3006 break; 3007 } 3008 } 3009 3010 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) 3011 { 3012 TCGv t0, t1; 3013 3014 if (rd == 0) { 3015 /* Treat as NOP. */ 3016 return; 3017 } 3018 3019 t0 = tcg_temp_new(); 3020 t1 = tcg_temp_new(); 3021 3022 gen_load_gpr(t0, rs); 3023 gen_load_gpr(t1, rt); 3024 3025 switch (opc) { 3026 case R6_OPC_DIV: 3027 { 3028 TCGv t2 = tcg_temp_new(); 3029 TCGv t3 = tcg_temp_new(); 3030 tcg_gen_ext32s_tl(t0, t0); 3031 tcg_gen_ext32s_tl(t1, t1); 3032 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3033 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3034 tcg_gen_and_tl(t2, t2, t3); 3035 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3036 tcg_gen_or_tl(t2, t2, t3); 3037 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3038 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3039 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3040 } 3041 break; 3042 case R6_OPC_MOD: 3043 { 3044 TCGv t2 = tcg_temp_new(); 3045 TCGv t3 = tcg_temp_new(); 3046 tcg_gen_ext32s_tl(t0, t0); 3047 tcg_gen_ext32s_tl(t1, t1); 3048 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3049 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3050 tcg_gen_and_tl(t2, t2, t3); 3051 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3052 tcg_gen_or_tl(t2, t2, t3); 3053 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3054 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3055 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3056 } 3057 break; 3058 case R6_OPC_DIVU: 3059 { 3060 tcg_gen_ext32u_tl(t0, t0); 3061 tcg_gen_ext32u_tl(t1, t1); 3062 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3063 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3064 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3065 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3066 } 3067 break; 3068 case R6_OPC_MODU: 3069 { 3070 tcg_gen_ext32u_tl(t0, t0); 3071 tcg_gen_ext32u_tl(t1, t1); 3072 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3073 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3074 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3075 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3076 } 3077 break; 3078 case R6_OPC_MUL: 3079 { 3080 TCGv_i32 t2 = tcg_temp_new_i32(); 3081 TCGv_i32 t3 = tcg_temp_new_i32(); 3082 tcg_gen_trunc_tl_i32(t2, t0); 3083 tcg_gen_trunc_tl_i32(t3, t1); 3084 tcg_gen_mul_i32(t2, t2, t3); 3085 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3086 } 3087 break; 3088 case R6_OPC_MUH: 3089 { 3090 TCGv_i32 t2 = tcg_temp_new_i32(); 3091 TCGv_i32 t3 = tcg_temp_new_i32(); 3092 tcg_gen_trunc_tl_i32(t2, t0); 3093 tcg_gen_trunc_tl_i32(t3, t1); 3094 tcg_gen_muls2_i32(t2, t3, t2, t3); 3095 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3096 } 3097 break; 3098 case R6_OPC_MULU: 3099 { 3100 TCGv_i32 t2 = tcg_temp_new_i32(); 3101 TCGv_i32 t3 = tcg_temp_new_i32(); 3102 tcg_gen_trunc_tl_i32(t2, t0); 3103 tcg_gen_trunc_tl_i32(t3, t1); 3104 tcg_gen_mul_i32(t2, t2, t3); 3105 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3106 } 3107 break; 3108 case R6_OPC_MUHU: 3109 { 3110 TCGv_i32 t2 = tcg_temp_new_i32(); 3111 TCGv_i32 t3 = tcg_temp_new_i32(); 3112 tcg_gen_trunc_tl_i32(t2, t0); 3113 tcg_gen_trunc_tl_i32(t3, t1); 3114 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3115 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3116 } 3117 break; 3118 #if defined(TARGET_MIPS64) 3119 case R6_OPC_DDIV: 3120 { 3121 TCGv t2 = tcg_temp_new(); 3122 TCGv t3 = tcg_temp_new(); 3123 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3124 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3125 tcg_gen_and_tl(t2, t2, t3); 3126 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3127 tcg_gen_or_tl(t2, t2, t3); 3128 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3129 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3130 } 3131 break; 3132 case R6_OPC_DMOD: 3133 { 3134 TCGv t2 = tcg_temp_new(); 3135 TCGv t3 = tcg_temp_new(); 3136 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3137 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3138 tcg_gen_and_tl(t2, t2, t3); 3139 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3140 tcg_gen_or_tl(t2, t2, t3); 3141 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3142 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3143 } 3144 break; 3145 case R6_OPC_DDIVU: 3146 { 3147 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3148 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3149 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); 3150 } 3151 break; 3152 case R6_OPC_DMODU: 3153 { 3154 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3155 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3156 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); 3157 } 3158 break; 3159 case R6_OPC_DMUL: 3160 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3161 break; 3162 case R6_OPC_DMUH: 3163 { 3164 TCGv t2 = tcg_temp_new(); 3165 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); 3166 } 3167 break; 3168 case R6_OPC_DMULU: 3169 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3170 break; 3171 case R6_OPC_DMUHU: 3172 { 3173 TCGv t2 = tcg_temp_new(); 3174 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); 3175 } 3176 break; 3177 #endif 3178 default: 3179 MIPS_INVAL("r6 mul/div"); 3180 gen_reserved_instruction(ctx); 3181 break; 3182 } 3183 } 3184 3185 #if defined(TARGET_MIPS64) 3186 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) 3187 { 3188 TCGv t0, t1; 3189 3190 t0 = tcg_temp_new(); 3191 t1 = tcg_temp_new(); 3192 3193 gen_load_gpr(t0, rs); 3194 gen_load_gpr(t1, rt); 3195 3196 switch (opc) { 3197 case MMI_OPC_DIV1: 3198 { 3199 TCGv t2 = tcg_temp_new(); 3200 TCGv t3 = tcg_temp_new(); 3201 tcg_gen_ext32s_tl(t0, t0); 3202 tcg_gen_ext32s_tl(t1, t1); 3203 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3204 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3205 tcg_gen_and_tl(t2, t2, t3); 3206 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3207 tcg_gen_or_tl(t2, t2, t3); 3208 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3209 tcg_gen_div_tl(cpu_LO[1], t0, t1); 3210 tcg_gen_rem_tl(cpu_HI[1], t0, t1); 3211 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3212 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3213 } 3214 break; 3215 case MMI_OPC_DIVU1: 3216 { 3217 TCGv t2 = tcg_constant_tl(0); 3218 TCGv t3 = tcg_constant_tl(1); 3219 tcg_gen_ext32u_tl(t0, t0); 3220 tcg_gen_ext32u_tl(t1, t1); 3221 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3222 tcg_gen_divu_tl(cpu_LO[1], t0, t1); 3223 tcg_gen_remu_tl(cpu_HI[1], t0, t1); 3224 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3225 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3226 } 3227 break; 3228 default: 3229 MIPS_INVAL("div1 TX79"); 3230 gen_reserved_instruction(ctx); 3231 break; 3232 } 3233 } 3234 #endif 3235 3236 static void gen_muldiv(DisasContext *ctx, uint32_t opc, 3237 int acc, int rs, int rt) 3238 { 3239 TCGv t0, t1; 3240 3241 t0 = tcg_temp_new(); 3242 t1 = tcg_temp_new(); 3243 3244 gen_load_gpr(t0, rs); 3245 gen_load_gpr(t1, rt); 3246 3247 if (acc != 0) { 3248 check_dsp(ctx); 3249 } 3250 3251 switch (opc) { 3252 case OPC_DIV: 3253 { 3254 TCGv t2 = tcg_temp_new(); 3255 TCGv t3 = tcg_temp_new(); 3256 tcg_gen_ext32s_tl(t0, t0); 3257 tcg_gen_ext32s_tl(t1, t1); 3258 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3259 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3260 tcg_gen_and_tl(t2, t2, t3); 3261 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3262 tcg_gen_or_tl(t2, t2, t3); 3263 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3264 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3265 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3266 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3267 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3268 } 3269 break; 3270 case OPC_DIVU: 3271 { 3272 TCGv t2 = tcg_constant_tl(0); 3273 TCGv t3 = tcg_constant_tl(1); 3274 tcg_gen_ext32u_tl(t0, t0); 3275 tcg_gen_ext32u_tl(t1, t1); 3276 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3277 tcg_gen_divu_tl(cpu_LO[acc], t0, t1); 3278 tcg_gen_remu_tl(cpu_HI[acc], t0, t1); 3279 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3280 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3281 } 3282 break; 3283 case OPC_MULT: 3284 { 3285 TCGv_i32 t2 = tcg_temp_new_i32(); 3286 TCGv_i32 t3 = tcg_temp_new_i32(); 3287 tcg_gen_trunc_tl_i32(t2, t0); 3288 tcg_gen_trunc_tl_i32(t3, t1); 3289 tcg_gen_muls2_i32(t2, t3, t2, t3); 3290 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3291 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3292 } 3293 break; 3294 case OPC_MULTU: 3295 { 3296 TCGv_i32 t2 = tcg_temp_new_i32(); 3297 TCGv_i32 t3 = tcg_temp_new_i32(); 3298 tcg_gen_trunc_tl_i32(t2, t0); 3299 tcg_gen_trunc_tl_i32(t3, t1); 3300 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3301 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3302 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3303 } 3304 break; 3305 #if defined(TARGET_MIPS64) 3306 case OPC_DDIV: 3307 { 3308 TCGv t2 = tcg_temp_new(); 3309 TCGv t3 = tcg_temp_new(); 3310 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3311 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3312 tcg_gen_and_tl(t2, t2, t3); 3313 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3314 tcg_gen_or_tl(t2, t2, t3); 3315 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3316 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3317 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3318 } 3319 break; 3320 case OPC_DDIVU: 3321 { 3322 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3323 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3324 tcg_gen_divu_i64(cpu_LO[acc], t0, t1); 3325 tcg_gen_remu_i64(cpu_HI[acc], t0, t1); 3326 } 3327 break; 3328 case OPC_DMULT: 3329 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3330 break; 3331 case OPC_DMULTU: 3332 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3333 break; 3334 #endif 3335 case OPC_MADD: 3336 { 3337 TCGv_i64 t2 = tcg_temp_new_i64(); 3338 TCGv_i64 t3 = tcg_temp_new_i64(); 3339 3340 tcg_gen_ext_tl_i64(t2, t0); 3341 tcg_gen_ext_tl_i64(t3, t1); 3342 tcg_gen_mul_i64(t2, t2, t3); 3343 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3344 tcg_gen_add_i64(t2, t2, t3); 3345 gen_move_low32(cpu_LO[acc], t2); 3346 gen_move_high32(cpu_HI[acc], t2); 3347 } 3348 break; 3349 case OPC_MADDU: 3350 { 3351 TCGv_i64 t2 = tcg_temp_new_i64(); 3352 TCGv_i64 t3 = tcg_temp_new_i64(); 3353 3354 tcg_gen_ext32u_tl(t0, t0); 3355 tcg_gen_ext32u_tl(t1, t1); 3356 tcg_gen_extu_tl_i64(t2, t0); 3357 tcg_gen_extu_tl_i64(t3, t1); 3358 tcg_gen_mul_i64(t2, t2, t3); 3359 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3360 tcg_gen_add_i64(t2, t2, t3); 3361 gen_move_low32(cpu_LO[acc], t2); 3362 gen_move_high32(cpu_HI[acc], t2); 3363 } 3364 break; 3365 case OPC_MSUB: 3366 { 3367 TCGv_i64 t2 = tcg_temp_new_i64(); 3368 TCGv_i64 t3 = tcg_temp_new_i64(); 3369 3370 tcg_gen_ext_tl_i64(t2, t0); 3371 tcg_gen_ext_tl_i64(t3, t1); 3372 tcg_gen_mul_i64(t2, t2, t3); 3373 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3374 tcg_gen_sub_i64(t2, t3, t2); 3375 gen_move_low32(cpu_LO[acc], t2); 3376 gen_move_high32(cpu_HI[acc], t2); 3377 } 3378 break; 3379 case OPC_MSUBU: 3380 { 3381 TCGv_i64 t2 = tcg_temp_new_i64(); 3382 TCGv_i64 t3 = tcg_temp_new_i64(); 3383 3384 tcg_gen_ext32u_tl(t0, t0); 3385 tcg_gen_ext32u_tl(t1, t1); 3386 tcg_gen_extu_tl_i64(t2, t0); 3387 tcg_gen_extu_tl_i64(t3, t1); 3388 tcg_gen_mul_i64(t2, t2, t3); 3389 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3390 tcg_gen_sub_i64(t2, t3, t2); 3391 gen_move_low32(cpu_LO[acc], t2); 3392 gen_move_high32(cpu_HI[acc], t2); 3393 } 3394 break; 3395 default: 3396 MIPS_INVAL("mul/div"); 3397 gen_reserved_instruction(ctx); 3398 break; 3399 } 3400 } 3401 3402 /* 3403 * These MULT[U] and MADD[U] instructions implemented in for example 3404 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core 3405 * architectures are special three-operand variants with the syntax 3406 * 3407 * MULT[U][1] rd, rs, rt 3408 * 3409 * such that 3410 * 3411 * (rd, LO, HI) <- rs * rt 3412 * 3413 * and 3414 * 3415 * MADD[U][1] rd, rs, rt 3416 * 3417 * such that 3418 * 3419 * (rd, LO, HI) <- (LO, HI) + rs * rt 3420 * 3421 * where the low-order 32-bits of the result is placed into both the 3422 * GPR rd and the special register LO. The high-order 32-bits of the 3423 * result is placed into the special register HI. 3424 * 3425 * If the GPR rd is omitted in assembly language, it is taken to be 0, 3426 * which is the zero register that always reads as 0. 3427 */ 3428 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, 3429 int rd, int rs, int rt) 3430 { 3431 TCGv t0 = tcg_temp_new(); 3432 TCGv t1 = tcg_temp_new(); 3433 int acc = 0; 3434 3435 gen_load_gpr(t0, rs); 3436 gen_load_gpr(t1, rt); 3437 3438 switch (opc) { 3439 case MMI_OPC_MULT1: 3440 acc = 1; 3441 /* Fall through */ 3442 case OPC_MULT: 3443 { 3444 TCGv_i32 t2 = tcg_temp_new_i32(); 3445 TCGv_i32 t3 = tcg_temp_new_i32(); 3446 tcg_gen_trunc_tl_i32(t2, t0); 3447 tcg_gen_trunc_tl_i32(t3, t1); 3448 tcg_gen_muls2_i32(t2, t3, t2, t3); 3449 if (rd) { 3450 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3451 } 3452 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3453 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3454 } 3455 break; 3456 case MMI_OPC_MULTU1: 3457 acc = 1; 3458 /* Fall through */ 3459 case OPC_MULTU: 3460 { 3461 TCGv_i32 t2 = tcg_temp_new_i32(); 3462 TCGv_i32 t3 = tcg_temp_new_i32(); 3463 tcg_gen_trunc_tl_i32(t2, t0); 3464 tcg_gen_trunc_tl_i32(t3, t1); 3465 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3466 if (rd) { 3467 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3468 } 3469 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3470 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3471 } 3472 break; 3473 case MMI_OPC_MADD1: 3474 acc = 1; 3475 /* Fall through */ 3476 case MMI_OPC_MADD: 3477 { 3478 TCGv_i64 t2 = tcg_temp_new_i64(); 3479 TCGv_i64 t3 = tcg_temp_new_i64(); 3480 3481 tcg_gen_ext_tl_i64(t2, t0); 3482 tcg_gen_ext_tl_i64(t3, t1); 3483 tcg_gen_mul_i64(t2, t2, t3); 3484 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3485 tcg_gen_add_i64(t2, t2, t3); 3486 gen_move_low32(cpu_LO[acc], t2); 3487 gen_move_high32(cpu_HI[acc], t2); 3488 if (rd) { 3489 gen_move_low32(cpu_gpr[rd], t2); 3490 } 3491 } 3492 break; 3493 case MMI_OPC_MADDU1: 3494 acc = 1; 3495 /* Fall through */ 3496 case MMI_OPC_MADDU: 3497 { 3498 TCGv_i64 t2 = tcg_temp_new_i64(); 3499 TCGv_i64 t3 = tcg_temp_new_i64(); 3500 3501 tcg_gen_ext32u_tl(t0, t0); 3502 tcg_gen_ext32u_tl(t1, t1); 3503 tcg_gen_extu_tl_i64(t2, t0); 3504 tcg_gen_extu_tl_i64(t3, t1); 3505 tcg_gen_mul_i64(t2, t2, t3); 3506 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3507 tcg_gen_add_i64(t2, t2, t3); 3508 gen_move_low32(cpu_LO[acc], t2); 3509 gen_move_high32(cpu_HI[acc], t2); 3510 if (rd) { 3511 gen_move_low32(cpu_gpr[rd], t2); 3512 } 3513 } 3514 break; 3515 default: 3516 MIPS_INVAL("mul/madd TXx9"); 3517 gen_reserved_instruction(ctx); 3518 break; 3519 } 3520 } 3521 3522 static void gen_cl(DisasContext *ctx, uint32_t opc, 3523 int rd, int rs) 3524 { 3525 TCGv t0; 3526 3527 if (rd == 0) { 3528 /* Treat as NOP. */ 3529 return; 3530 } 3531 t0 = cpu_gpr[rd]; 3532 gen_load_gpr(t0, rs); 3533 3534 switch (opc) { 3535 case OPC_CLO: 3536 case R6_OPC_CLO: 3537 #if defined(TARGET_MIPS64) 3538 case OPC_DCLO: 3539 case R6_OPC_DCLO: 3540 #endif 3541 tcg_gen_not_tl(t0, t0); 3542 break; 3543 } 3544 3545 switch (opc) { 3546 case OPC_CLO: 3547 case R6_OPC_CLO: 3548 case OPC_CLZ: 3549 case R6_OPC_CLZ: 3550 tcg_gen_ext32u_tl(t0, t0); 3551 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); 3552 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); 3553 break; 3554 #if defined(TARGET_MIPS64) 3555 case OPC_DCLO: 3556 case R6_OPC_DCLO: 3557 case OPC_DCLZ: 3558 case R6_OPC_DCLZ: 3559 tcg_gen_clzi_i64(t0, t0, 64); 3560 break; 3561 #endif 3562 } 3563 } 3564 3565 /* Loongson multimedia instructions */ 3566 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) 3567 { 3568 uint32_t opc, shift_max; 3569 TCGv_i64 t0, t1; 3570 TCGCond cond; 3571 3572 opc = MASK_LMMI(ctx->opcode); 3573 check_cp1_enabled(ctx); 3574 3575 t0 = tcg_temp_new_i64(); 3576 t1 = tcg_temp_new_i64(); 3577 gen_load_fpr64(ctx, t0, rs); 3578 gen_load_fpr64(ctx, t1, rt); 3579 3580 switch (opc) { 3581 case OPC_PADDSH: 3582 gen_helper_paddsh(t0, t0, t1); 3583 break; 3584 case OPC_PADDUSH: 3585 gen_helper_paddush(t0, t0, t1); 3586 break; 3587 case OPC_PADDH: 3588 gen_helper_paddh(t0, t0, t1); 3589 break; 3590 case OPC_PADDW: 3591 gen_helper_paddw(t0, t0, t1); 3592 break; 3593 case OPC_PADDSB: 3594 gen_helper_paddsb(t0, t0, t1); 3595 break; 3596 case OPC_PADDUSB: 3597 gen_helper_paddusb(t0, t0, t1); 3598 break; 3599 case OPC_PADDB: 3600 gen_helper_paddb(t0, t0, t1); 3601 break; 3602 3603 case OPC_PSUBSH: 3604 gen_helper_psubsh(t0, t0, t1); 3605 break; 3606 case OPC_PSUBUSH: 3607 gen_helper_psubush(t0, t0, t1); 3608 break; 3609 case OPC_PSUBH: 3610 gen_helper_psubh(t0, t0, t1); 3611 break; 3612 case OPC_PSUBW: 3613 gen_helper_psubw(t0, t0, t1); 3614 break; 3615 case OPC_PSUBSB: 3616 gen_helper_psubsb(t0, t0, t1); 3617 break; 3618 case OPC_PSUBUSB: 3619 gen_helper_psubusb(t0, t0, t1); 3620 break; 3621 case OPC_PSUBB: 3622 gen_helper_psubb(t0, t0, t1); 3623 break; 3624 3625 case OPC_PSHUFH: 3626 gen_helper_pshufh(t0, t0, t1); 3627 break; 3628 case OPC_PACKSSWH: 3629 gen_helper_packsswh(t0, t0, t1); 3630 break; 3631 case OPC_PACKSSHB: 3632 gen_helper_packsshb(t0, t0, t1); 3633 break; 3634 case OPC_PACKUSHB: 3635 gen_helper_packushb(t0, t0, t1); 3636 break; 3637 3638 case OPC_PUNPCKLHW: 3639 gen_helper_punpcklhw(t0, t0, t1); 3640 break; 3641 case OPC_PUNPCKHHW: 3642 gen_helper_punpckhhw(t0, t0, t1); 3643 break; 3644 case OPC_PUNPCKLBH: 3645 gen_helper_punpcklbh(t0, t0, t1); 3646 break; 3647 case OPC_PUNPCKHBH: 3648 gen_helper_punpckhbh(t0, t0, t1); 3649 break; 3650 case OPC_PUNPCKLWD: 3651 gen_helper_punpcklwd(t0, t0, t1); 3652 break; 3653 case OPC_PUNPCKHWD: 3654 gen_helper_punpckhwd(t0, t0, t1); 3655 break; 3656 3657 case OPC_PAVGH: 3658 gen_helper_pavgh(t0, t0, t1); 3659 break; 3660 case OPC_PAVGB: 3661 gen_helper_pavgb(t0, t0, t1); 3662 break; 3663 case OPC_PMAXSH: 3664 gen_helper_pmaxsh(t0, t0, t1); 3665 break; 3666 case OPC_PMINSH: 3667 gen_helper_pminsh(t0, t0, t1); 3668 break; 3669 case OPC_PMAXUB: 3670 gen_helper_pmaxub(t0, t0, t1); 3671 break; 3672 case OPC_PMINUB: 3673 gen_helper_pminub(t0, t0, t1); 3674 break; 3675 3676 case OPC_PCMPEQW: 3677 gen_helper_pcmpeqw(t0, t0, t1); 3678 break; 3679 case OPC_PCMPGTW: 3680 gen_helper_pcmpgtw(t0, t0, t1); 3681 break; 3682 case OPC_PCMPEQH: 3683 gen_helper_pcmpeqh(t0, t0, t1); 3684 break; 3685 case OPC_PCMPGTH: 3686 gen_helper_pcmpgth(t0, t0, t1); 3687 break; 3688 case OPC_PCMPEQB: 3689 gen_helper_pcmpeqb(t0, t0, t1); 3690 break; 3691 case OPC_PCMPGTB: 3692 gen_helper_pcmpgtb(t0, t0, t1); 3693 break; 3694 3695 case OPC_PSLLW: 3696 gen_helper_psllw(t0, t0, t1); 3697 break; 3698 case OPC_PSLLH: 3699 gen_helper_psllh(t0, t0, t1); 3700 break; 3701 case OPC_PSRLW: 3702 gen_helper_psrlw(t0, t0, t1); 3703 break; 3704 case OPC_PSRLH: 3705 gen_helper_psrlh(t0, t0, t1); 3706 break; 3707 case OPC_PSRAW: 3708 gen_helper_psraw(t0, t0, t1); 3709 break; 3710 case OPC_PSRAH: 3711 gen_helper_psrah(t0, t0, t1); 3712 break; 3713 3714 case OPC_PMULLH: 3715 gen_helper_pmullh(t0, t0, t1); 3716 break; 3717 case OPC_PMULHH: 3718 gen_helper_pmulhh(t0, t0, t1); 3719 break; 3720 case OPC_PMULHUH: 3721 gen_helper_pmulhuh(t0, t0, t1); 3722 break; 3723 case OPC_PMADDHW: 3724 gen_helper_pmaddhw(t0, t0, t1); 3725 break; 3726 3727 case OPC_PASUBUB: 3728 gen_helper_pasubub(t0, t0, t1); 3729 break; 3730 case OPC_BIADD: 3731 gen_helper_biadd(t0, t0); 3732 break; 3733 case OPC_PMOVMSKB: 3734 gen_helper_pmovmskb(t0, t0); 3735 break; 3736 3737 case OPC_PADDD: 3738 tcg_gen_add_i64(t0, t0, t1); 3739 break; 3740 case OPC_PSUBD: 3741 tcg_gen_sub_i64(t0, t0, t1); 3742 break; 3743 case OPC_XOR_CP2: 3744 tcg_gen_xor_i64(t0, t0, t1); 3745 break; 3746 case OPC_NOR_CP2: 3747 tcg_gen_nor_i64(t0, t0, t1); 3748 break; 3749 case OPC_AND_CP2: 3750 tcg_gen_and_i64(t0, t0, t1); 3751 break; 3752 case OPC_OR_CP2: 3753 tcg_gen_or_i64(t0, t0, t1); 3754 break; 3755 3756 case OPC_PANDN: 3757 tcg_gen_andc_i64(t0, t1, t0); 3758 break; 3759 3760 case OPC_PINSRH_0: 3761 tcg_gen_deposit_i64(t0, t0, t1, 0, 16); 3762 break; 3763 case OPC_PINSRH_1: 3764 tcg_gen_deposit_i64(t0, t0, t1, 16, 16); 3765 break; 3766 case OPC_PINSRH_2: 3767 tcg_gen_deposit_i64(t0, t0, t1, 32, 16); 3768 break; 3769 case OPC_PINSRH_3: 3770 tcg_gen_deposit_i64(t0, t0, t1, 48, 16); 3771 break; 3772 3773 case OPC_PEXTRH: 3774 tcg_gen_andi_i64(t1, t1, 3); 3775 tcg_gen_shli_i64(t1, t1, 4); 3776 tcg_gen_shr_i64(t0, t0, t1); 3777 tcg_gen_ext16u_i64(t0, t0); 3778 break; 3779 3780 case OPC_ADDU_CP2: 3781 tcg_gen_add_i64(t0, t0, t1); 3782 tcg_gen_ext32s_i64(t0, t0); 3783 break; 3784 case OPC_SUBU_CP2: 3785 tcg_gen_sub_i64(t0, t0, t1); 3786 tcg_gen_ext32s_i64(t0, t0); 3787 break; 3788 3789 case OPC_SLL_CP2: 3790 shift_max = 32; 3791 goto do_shift; 3792 case OPC_SRL_CP2: 3793 shift_max = 32; 3794 goto do_shift; 3795 case OPC_SRA_CP2: 3796 shift_max = 32; 3797 goto do_shift; 3798 case OPC_DSLL_CP2: 3799 shift_max = 64; 3800 goto do_shift; 3801 case OPC_DSRL_CP2: 3802 shift_max = 64; 3803 goto do_shift; 3804 case OPC_DSRA_CP2: 3805 shift_max = 64; 3806 goto do_shift; 3807 do_shift: 3808 /* Make sure shift count isn't TCG undefined behaviour. */ 3809 tcg_gen_andi_i64(t1, t1, shift_max - 1); 3810 3811 switch (opc) { 3812 case OPC_SLL_CP2: 3813 case OPC_DSLL_CP2: 3814 tcg_gen_shl_i64(t0, t0, t1); 3815 break; 3816 case OPC_SRA_CP2: 3817 case OPC_DSRA_CP2: 3818 /* 3819 * Since SRA is UndefinedResult without sign-extended inputs, 3820 * we can treat SRA and DSRA the same. 3821 */ 3822 tcg_gen_sar_i64(t0, t0, t1); 3823 break; 3824 case OPC_SRL_CP2: 3825 /* We want to shift in zeros for SRL; zero-extend first. */ 3826 tcg_gen_ext32u_i64(t0, t0); 3827 /* FALLTHRU */ 3828 case OPC_DSRL_CP2: 3829 tcg_gen_shr_i64(t0, t0, t1); 3830 break; 3831 } 3832 3833 if (shift_max == 32) { 3834 tcg_gen_ext32s_i64(t0, t0); 3835 } 3836 3837 /* Shifts larger than MAX produce zero. */ 3838 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); 3839 tcg_gen_neg_i64(t1, t1); 3840 tcg_gen_and_i64(t0, t0, t1); 3841 break; 3842 3843 case OPC_ADD_CP2: 3844 case OPC_DADD_CP2: 3845 { 3846 TCGv_i64 t2 = tcg_temp_new_i64(); 3847 TCGLabel *lab = gen_new_label(); 3848 3849 tcg_gen_mov_i64(t2, t0); 3850 tcg_gen_add_i64(t0, t1, t2); 3851 if (opc == OPC_ADD_CP2) { 3852 tcg_gen_ext32s_i64(t0, t0); 3853 } 3854 tcg_gen_xor_i64(t1, t1, t2); 3855 tcg_gen_xor_i64(t2, t2, t0); 3856 tcg_gen_andc_i64(t1, t2, t1); 3857 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 3858 generate_exception(ctx, EXCP_OVERFLOW); 3859 gen_set_label(lab); 3860 break; 3861 } 3862 3863 case OPC_SUB_CP2: 3864 case OPC_DSUB_CP2: 3865 { 3866 TCGv_i64 t2 = tcg_temp_new_i64(); 3867 TCGLabel *lab = gen_new_label(); 3868 3869 tcg_gen_mov_i64(t2, t0); 3870 tcg_gen_sub_i64(t0, t1, t2); 3871 if (opc == OPC_SUB_CP2) { 3872 tcg_gen_ext32s_i64(t0, t0); 3873 } 3874 tcg_gen_xor_i64(t1, t1, t2); 3875 tcg_gen_xor_i64(t2, t2, t0); 3876 tcg_gen_and_i64(t1, t1, t2); 3877 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 3878 generate_exception(ctx, EXCP_OVERFLOW); 3879 gen_set_label(lab); 3880 break; 3881 } 3882 3883 case OPC_PMULUW: 3884 tcg_gen_ext32u_i64(t0, t0); 3885 tcg_gen_ext32u_i64(t1, t1); 3886 tcg_gen_mul_i64(t0, t0, t1); 3887 break; 3888 3889 case OPC_SEQU_CP2: 3890 case OPC_SEQ_CP2: 3891 cond = TCG_COND_EQ; 3892 goto do_cc_cond; 3893 break; 3894 case OPC_SLTU_CP2: 3895 cond = TCG_COND_LTU; 3896 goto do_cc_cond; 3897 break; 3898 case OPC_SLT_CP2: 3899 cond = TCG_COND_LT; 3900 goto do_cc_cond; 3901 break; 3902 case OPC_SLEU_CP2: 3903 cond = TCG_COND_LEU; 3904 goto do_cc_cond; 3905 break; 3906 case OPC_SLE_CP2: 3907 cond = TCG_COND_LE; 3908 do_cc_cond: 3909 { 3910 int cc = (ctx->opcode >> 8) & 0x7; 3911 TCGv_i64 t64 = tcg_temp_new_i64(); 3912 TCGv_i32 t32 = tcg_temp_new_i32(); 3913 3914 tcg_gen_setcond_i64(cond, t64, t0, t1); 3915 tcg_gen_extrl_i64_i32(t32, t64); 3916 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, 3917 get_fp_bit(cc), 1); 3918 } 3919 return; 3920 default: 3921 MIPS_INVAL("loongson_cp2"); 3922 gen_reserved_instruction(ctx); 3923 return; 3924 } 3925 3926 gen_store_fpr64(ctx, t0, rd); 3927 } 3928 3929 static void gen_loongson_lswc2(DisasContext *ctx, int rt, 3930 int rs, int rd) 3931 { 3932 TCGv t0, t1; 3933 TCGv_i32 fp0; 3934 #if defined(TARGET_MIPS64) 3935 int lsq_rt1 = ctx->opcode & 0x1f; 3936 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4; 3937 #endif 3938 int shf_offset = sextract32(ctx->opcode, 6, 8); 3939 3940 t0 = tcg_temp_new(); 3941 3942 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { 3943 #if defined(TARGET_MIPS64) 3944 case OPC_GSLQ: 3945 t1 = tcg_temp_new(); 3946 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3947 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3948 ctx->default_tcg_memop_mask); 3949 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 3950 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3951 ctx->default_tcg_memop_mask); 3952 gen_store_gpr(t1, rt); 3953 gen_store_gpr(t0, lsq_rt1); 3954 break; 3955 case OPC_GSLQC1: 3956 check_cp1_enabled(ctx); 3957 t1 = tcg_temp_new(); 3958 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3959 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3960 ctx->default_tcg_memop_mask); 3961 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 3962 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3963 ctx->default_tcg_memop_mask); 3964 gen_store_fpr64(ctx, t1, rt); 3965 gen_store_fpr64(ctx, t0, lsq_rt1); 3966 break; 3967 case OPC_GSSQ: 3968 t1 = tcg_temp_new(); 3969 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3970 gen_load_gpr(t1, rt); 3971 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3972 ctx->default_tcg_memop_mask); 3973 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 3974 gen_load_gpr(t1, lsq_rt1); 3975 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3976 ctx->default_tcg_memop_mask); 3977 break; 3978 case OPC_GSSQC1: 3979 check_cp1_enabled(ctx); 3980 t1 = tcg_temp_new(); 3981 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3982 gen_load_fpr64(ctx, t1, rt); 3983 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3984 ctx->default_tcg_memop_mask); 3985 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 3986 gen_load_fpr64(ctx, t1, lsq_rt1); 3987 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3988 ctx->default_tcg_memop_mask); 3989 break; 3990 #endif 3991 case OPC_GSSHFL: 3992 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 3993 case OPC_GSLWLC1: 3994 check_cp1_enabled(ctx); 3995 gen_base_offset_addr(ctx, t0, rs, shf_offset); 3996 fp0 = tcg_temp_new_i32(); 3997 gen_load_fpr32(ctx, fp0, rt); 3998 t1 = tcg_temp_new(); 3999 tcg_gen_ext_i32_tl(t1, fp0); 4000 gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 4001 tcg_gen_trunc_tl_i32(fp0, t1); 4002 gen_store_fpr32(ctx, fp0, rt); 4003 break; 4004 case OPC_GSLWRC1: 4005 check_cp1_enabled(ctx); 4006 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4007 fp0 = tcg_temp_new_i32(); 4008 gen_load_fpr32(ctx, fp0, rt); 4009 t1 = tcg_temp_new(); 4010 tcg_gen_ext_i32_tl(t1, fp0); 4011 gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 4012 tcg_gen_trunc_tl_i32(fp0, t1); 4013 gen_store_fpr32(ctx, fp0, rt); 4014 break; 4015 #if defined(TARGET_MIPS64) 4016 case OPC_GSLDLC1: 4017 check_cp1_enabled(ctx); 4018 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4019 t1 = tcg_temp_new(); 4020 gen_load_fpr64(ctx, t1, rt); 4021 gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 4022 gen_store_fpr64(ctx, t1, rt); 4023 break; 4024 case OPC_GSLDRC1: 4025 check_cp1_enabled(ctx); 4026 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4027 t1 = tcg_temp_new(); 4028 gen_load_fpr64(ctx, t1, rt); 4029 gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 4030 gen_store_fpr64(ctx, t1, rt); 4031 break; 4032 #endif 4033 default: 4034 MIPS_INVAL("loongson_gsshfl"); 4035 gen_reserved_instruction(ctx); 4036 break; 4037 } 4038 break; 4039 case OPC_GSSHFS: 4040 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4041 case OPC_GSSWLC1: 4042 check_cp1_enabled(ctx); 4043 t1 = tcg_temp_new(); 4044 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4045 fp0 = tcg_temp_new_i32(); 4046 gen_load_fpr32(ctx, fp0, rt); 4047 tcg_gen_ext_i32_tl(t1, fp0); 4048 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); 4049 break; 4050 case OPC_GSSWRC1: 4051 check_cp1_enabled(ctx); 4052 t1 = tcg_temp_new(); 4053 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4054 fp0 = tcg_temp_new_i32(); 4055 gen_load_fpr32(ctx, fp0, rt); 4056 tcg_gen_ext_i32_tl(t1, fp0); 4057 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); 4058 break; 4059 #if defined(TARGET_MIPS64) 4060 case OPC_GSSDLC1: 4061 check_cp1_enabled(ctx); 4062 t1 = tcg_temp_new(); 4063 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4064 gen_load_fpr64(ctx, t1, rt); 4065 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); 4066 break; 4067 case OPC_GSSDRC1: 4068 check_cp1_enabled(ctx); 4069 t1 = tcg_temp_new(); 4070 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4071 gen_load_fpr64(ctx, t1, rt); 4072 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); 4073 break; 4074 #endif 4075 default: 4076 MIPS_INVAL("loongson_gsshfs"); 4077 gen_reserved_instruction(ctx); 4078 break; 4079 } 4080 break; 4081 default: 4082 MIPS_INVAL("loongson_gslsq"); 4083 gen_reserved_instruction(ctx); 4084 break; 4085 } 4086 } 4087 4088 /* Loongson EXT LDC2/SDC2 */ 4089 static void gen_loongson_lsdc2(DisasContext *ctx, int rt, 4090 int rs, int rd) 4091 { 4092 int offset = sextract32(ctx->opcode, 3, 8); 4093 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode); 4094 TCGv t0, t1; 4095 TCGv_i32 fp0; 4096 4097 /* Pre-conditions */ 4098 switch (opc) { 4099 case OPC_GSLBX: 4100 case OPC_GSLHX: 4101 case OPC_GSLWX: 4102 case OPC_GSLDX: 4103 /* prefetch, implement as NOP */ 4104 if (rt == 0) { 4105 return; 4106 } 4107 break; 4108 case OPC_GSSBX: 4109 case OPC_GSSHX: 4110 case OPC_GSSWX: 4111 case OPC_GSSDX: 4112 break; 4113 case OPC_GSLWXC1: 4114 #if defined(TARGET_MIPS64) 4115 case OPC_GSLDXC1: 4116 #endif 4117 check_cp1_enabled(ctx); 4118 /* prefetch, implement as NOP */ 4119 if (rt == 0) { 4120 return; 4121 } 4122 break; 4123 case OPC_GSSWXC1: 4124 #if defined(TARGET_MIPS64) 4125 case OPC_GSSDXC1: 4126 #endif 4127 check_cp1_enabled(ctx); 4128 break; 4129 default: 4130 MIPS_INVAL("loongson_lsdc2"); 4131 gen_reserved_instruction(ctx); 4132 return; 4133 break; 4134 } 4135 4136 t0 = tcg_temp_new(); 4137 4138 gen_base_offset_addr(ctx, t0, rs, offset); 4139 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4140 4141 switch (opc) { 4142 case OPC_GSLBX: 4143 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); 4144 gen_store_gpr(t0, rt); 4145 break; 4146 case OPC_GSLHX: 4147 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW | 4148 ctx->default_tcg_memop_mask); 4149 gen_store_gpr(t0, rt); 4150 break; 4151 case OPC_GSLWX: 4152 gen_base_offset_addr(ctx, t0, rs, offset); 4153 if (rd) { 4154 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4155 } 4156 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 4157 ctx->default_tcg_memop_mask); 4158 gen_store_gpr(t0, rt); 4159 break; 4160 #if defined(TARGET_MIPS64) 4161 case OPC_GSLDX: 4162 gen_base_offset_addr(ctx, t0, rs, offset); 4163 if (rd) { 4164 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4165 } 4166 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4167 ctx->default_tcg_memop_mask); 4168 gen_store_gpr(t0, rt); 4169 break; 4170 #endif 4171 case OPC_GSLWXC1: 4172 gen_base_offset_addr(ctx, t0, rs, offset); 4173 if (rd) { 4174 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4175 } 4176 fp0 = tcg_temp_new_i32(); 4177 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 4178 ctx->default_tcg_memop_mask); 4179 gen_store_fpr32(ctx, fp0, rt); 4180 break; 4181 #if defined(TARGET_MIPS64) 4182 case OPC_GSLDXC1: 4183 gen_base_offset_addr(ctx, t0, rs, offset); 4184 if (rd) { 4185 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4186 } 4187 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4188 ctx->default_tcg_memop_mask); 4189 gen_store_fpr64(ctx, t0, rt); 4190 break; 4191 #endif 4192 case OPC_GSSBX: 4193 t1 = tcg_temp_new(); 4194 gen_load_gpr(t1, rt); 4195 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); 4196 break; 4197 case OPC_GSSHX: 4198 t1 = tcg_temp_new(); 4199 gen_load_gpr(t1, rt); 4200 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UW | 4201 ctx->default_tcg_memop_mask); 4202 break; 4203 case OPC_GSSWX: 4204 t1 = tcg_temp_new(); 4205 gen_load_gpr(t1, rt); 4206 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 4207 ctx->default_tcg_memop_mask); 4208 break; 4209 #if defined(TARGET_MIPS64) 4210 case OPC_GSSDX: 4211 t1 = tcg_temp_new(); 4212 gen_load_gpr(t1, rt); 4213 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4214 ctx->default_tcg_memop_mask); 4215 break; 4216 #endif 4217 case OPC_GSSWXC1: 4218 fp0 = tcg_temp_new_i32(); 4219 gen_load_fpr32(ctx, fp0, rt); 4220 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 4221 ctx->default_tcg_memop_mask); 4222 break; 4223 #if defined(TARGET_MIPS64) 4224 case OPC_GSSDXC1: 4225 t1 = tcg_temp_new(); 4226 gen_load_fpr64(ctx, t1, rt); 4227 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4228 ctx->default_tcg_memop_mask); 4229 break; 4230 #endif 4231 default: 4232 break; 4233 } 4234 } 4235 4236 /* Traps */ 4237 static void gen_trap(DisasContext *ctx, uint32_t opc, 4238 int rs, int rt, int16_t imm, int code) 4239 { 4240 int cond; 4241 TCGv t0 = tcg_temp_new(); 4242 TCGv t1 = tcg_temp_new(); 4243 4244 cond = 0; 4245 /* Load needed operands */ 4246 switch (opc) { 4247 case OPC_TEQ: 4248 case OPC_TGE: 4249 case OPC_TGEU: 4250 case OPC_TLT: 4251 case OPC_TLTU: 4252 case OPC_TNE: 4253 /* Compare two registers */ 4254 if (rs != rt) { 4255 gen_load_gpr(t0, rs); 4256 gen_load_gpr(t1, rt); 4257 cond = 1; 4258 } 4259 break; 4260 case OPC_TEQI: 4261 case OPC_TGEI: 4262 case OPC_TGEIU: 4263 case OPC_TLTI: 4264 case OPC_TLTIU: 4265 case OPC_TNEI: 4266 /* Compare register to immediate */ 4267 if (rs != 0 || imm != 0) { 4268 gen_load_gpr(t0, rs); 4269 tcg_gen_movi_tl(t1, (int32_t)imm); 4270 cond = 1; 4271 } 4272 break; 4273 } 4274 if (cond == 0) { 4275 switch (opc) { 4276 case OPC_TEQ: /* rs == rs */ 4277 case OPC_TEQI: /* r0 == 0 */ 4278 case OPC_TGE: /* rs >= rs */ 4279 case OPC_TGEI: /* r0 >= 0 */ 4280 case OPC_TGEU: /* rs >= rs unsigned */ 4281 case OPC_TGEIU: /* r0 >= 0 unsigned */ 4282 /* Always trap */ 4283 #ifdef CONFIG_USER_ONLY 4284 /* Pass the break code along to cpu_loop. */ 4285 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 4286 offsetof(CPUMIPSState, error_code)); 4287 #endif 4288 generate_exception_end(ctx, EXCP_TRAP); 4289 break; 4290 case OPC_TLT: /* rs < rs */ 4291 case OPC_TLTI: /* r0 < 0 */ 4292 case OPC_TLTU: /* rs < rs unsigned */ 4293 case OPC_TLTIU: /* r0 < 0 unsigned */ 4294 case OPC_TNE: /* rs != rs */ 4295 case OPC_TNEI: /* r0 != 0 */ 4296 /* Never trap: treat as NOP. */ 4297 break; 4298 } 4299 } else { 4300 TCGLabel *l1 = gen_new_label(); 4301 4302 switch (opc) { 4303 case OPC_TEQ: 4304 case OPC_TEQI: 4305 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 4306 break; 4307 case OPC_TGE: 4308 case OPC_TGEI: 4309 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 4310 break; 4311 case OPC_TGEU: 4312 case OPC_TGEIU: 4313 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 4314 break; 4315 case OPC_TLT: 4316 case OPC_TLTI: 4317 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 4318 break; 4319 case OPC_TLTU: 4320 case OPC_TLTIU: 4321 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 4322 break; 4323 case OPC_TNE: 4324 case OPC_TNEI: 4325 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 4326 break; 4327 } 4328 #ifdef CONFIG_USER_ONLY 4329 /* Pass the break code along to cpu_loop. */ 4330 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 4331 offsetof(CPUMIPSState, error_code)); 4332 #endif 4333 /* Like save_cpu_state, only don't update saved values. */ 4334 if (ctx->base.pc_next != ctx->saved_pc) { 4335 gen_save_pc(ctx->base.pc_next); 4336 } 4337 if (ctx->hflags != ctx->saved_hflags) { 4338 tcg_gen_movi_i32(hflags, ctx->hflags); 4339 } 4340 generate_exception(ctx, EXCP_TRAP); 4341 gen_set_label(l1); 4342 } 4343 } 4344 4345 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 4346 { 4347 if (translator_use_goto_tb(&ctx->base, dest)) { 4348 tcg_gen_goto_tb(n); 4349 gen_save_pc(dest); 4350 tcg_gen_exit_tb(ctx->base.tb, n); 4351 } else { 4352 gen_save_pc(dest); 4353 tcg_gen_lookup_and_goto_ptr(); 4354 } 4355 } 4356 4357 /* Branches (before delay slot) */ 4358 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, 4359 int insn_bytes, 4360 int rs, int rt, int32_t offset, 4361 int delayslot_size) 4362 { 4363 target_ulong btgt = -1; 4364 int blink = 0; 4365 int bcond_compute = 0; 4366 TCGv t0 = tcg_temp_new(); 4367 TCGv t1 = tcg_temp_new(); 4368 4369 if (ctx->hflags & MIPS_HFLAG_BMASK) { 4370 #ifdef MIPS_DEBUG_DISAS 4371 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 4372 VADDR_PRIx "\n", ctx->base.pc_next); 4373 #endif 4374 gen_reserved_instruction(ctx); 4375 goto out; 4376 } 4377 4378 /* Load needed operands */ 4379 switch (opc) { 4380 case OPC_BEQ: 4381 case OPC_BEQL: 4382 case OPC_BNE: 4383 case OPC_BNEL: 4384 /* Compare two registers */ 4385 if (rs != rt) { 4386 gen_load_gpr(t0, rs); 4387 gen_load_gpr(t1, rt); 4388 bcond_compute = 1; 4389 } 4390 btgt = ctx->base.pc_next + insn_bytes + offset; 4391 break; 4392 case OPC_BGEZ: 4393 case OPC_BGEZAL: 4394 case OPC_BGEZALL: 4395 case OPC_BGEZL: 4396 case OPC_BGTZ: 4397 case OPC_BGTZL: 4398 case OPC_BLEZ: 4399 case OPC_BLEZL: 4400 case OPC_BLTZ: 4401 case OPC_BLTZAL: 4402 case OPC_BLTZALL: 4403 case OPC_BLTZL: 4404 /* Compare to zero */ 4405 if (rs != 0) { 4406 gen_load_gpr(t0, rs); 4407 bcond_compute = 1; 4408 } 4409 btgt = ctx->base.pc_next + insn_bytes + offset; 4410 break; 4411 case OPC_BPOSGE32: 4412 #if defined(TARGET_MIPS64) 4413 case OPC_BPOSGE64: 4414 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F); 4415 #else 4416 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 4417 #endif 4418 bcond_compute = 1; 4419 btgt = ctx->base.pc_next + insn_bytes + offset; 4420 break; 4421 case OPC_J: 4422 case OPC_JAL: 4423 { 4424 /* Jump to immediate */ 4425 int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000 4426 : 0xF0000000; 4427 btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask) 4428 | (uint32_t)offset; 4429 break; 4430 } 4431 case OPC_JALX: 4432 /* Jump to immediate */ 4433 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) | 4434 (uint32_t)offset; 4435 break; 4436 case OPC_JR: 4437 case OPC_JALR: 4438 /* Jump to register */ 4439 if (offset != 0 && offset != 16) { 4440 /* 4441 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 4442 * others are reserved. 4443 */ 4444 MIPS_INVAL("jump hint"); 4445 gen_reserved_instruction(ctx); 4446 goto out; 4447 } 4448 gen_load_gpr(btarget, rs); 4449 break; 4450 default: 4451 MIPS_INVAL("branch/jump"); 4452 gen_reserved_instruction(ctx); 4453 goto out; 4454 } 4455 if (bcond_compute == 0) { 4456 /* No condition to be computed */ 4457 switch (opc) { 4458 case OPC_BEQ: /* rx == rx */ 4459 case OPC_BEQL: /* rx == rx likely */ 4460 case OPC_BGEZ: /* 0 >= 0 */ 4461 case OPC_BGEZL: /* 0 >= 0 likely */ 4462 case OPC_BLEZ: /* 0 <= 0 */ 4463 case OPC_BLEZL: /* 0 <= 0 likely */ 4464 /* Always take */ 4465 ctx->hflags |= MIPS_HFLAG_B; 4466 break; 4467 case OPC_BGEZAL: /* 0 >= 0 */ 4468 case OPC_BGEZALL: /* 0 >= 0 likely */ 4469 /* Always take and link */ 4470 blink = 31; 4471 ctx->hflags |= MIPS_HFLAG_B; 4472 break; 4473 case OPC_BNE: /* rx != rx */ 4474 case OPC_BGTZ: /* 0 > 0 */ 4475 case OPC_BLTZ: /* 0 < 0 */ 4476 /* Treat as NOP. */ 4477 goto out; 4478 case OPC_BLTZAL: /* 0 < 0 */ 4479 /* 4480 * Handle as an unconditional branch to get correct delay 4481 * slot checking. 4482 */ 4483 blink = 31; 4484 btgt = ctx->base.pc_next + insn_bytes + delayslot_size; 4485 ctx->hflags |= MIPS_HFLAG_B; 4486 break; 4487 case OPC_BLTZALL: /* 0 < 0 likely */ 4488 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 4489 /* Skip the instruction in the delay slot */ 4490 ctx->base.pc_next += 4; 4491 goto out; 4492 case OPC_BNEL: /* rx != rx likely */ 4493 case OPC_BGTZL: /* 0 > 0 likely */ 4494 case OPC_BLTZL: /* 0 < 0 likely */ 4495 /* Skip the instruction in the delay slot */ 4496 ctx->base.pc_next += 4; 4497 goto out; 4498 case OPC_J: 4499 ctx->hflags |= MIPS_HFLAG_B; 4500 break; 4501 case OPC_JALX: 4502 ctx->hflags |= MIPS_HFLAG_BX; 4503 /* Fallthrough */ 4504 case OPC_JAL: 4505 blink = 31; 4506 ctx->hflags |= MIPS_HFLAG_B; 4507 break; 4508 case OPC_JR: 4509 ctx->hflags |= MIPS_HFLAG_BR; 4510 break; 4511 case OPC_JALR: 4512 blink = rt; 4513 ctx->hflags |= MIPS_HFLAG_BR; 4514 break; 4515 default: 4516 MIPS_INVAL("branch/jump"); 4517 gen_reserved_instruction(ctx); 4518 goto out; 4519 } 4520 } else { 4521 switch (opc) { 4522 case OPC_BEQ: 4523 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 4524 goto not_likely; 4525 case OPC_BEQL: 4526 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 4527 goto likely; 4528 case OPC_BNE: 4529 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 4530 goto not_likely; 4531 case OPC_BNEL: 4532 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 4533 goto likely; 4534 case OPC_BGEZ: 4535 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4536 goto not_likely; 4537 case OPC_BGEZL: 4538 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4539 goto likely; 4540 case OPC_BGEZAL: 4541 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4542 blink = 31; 4543 goto not_likely; 4544 case OPC_BGEZALL: 4545 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4546 blink = 31; 4547 goto likely; 4548 case OPC_BGTZ: 4549 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 4550 goto not_likely; 4551 case OPC_BGTZL: 4552 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 4553 goto likely; 4554 case OPC_BLEZ: 4555 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 4556 goto not_likely; 4557 case OPC_BLEZL: 4558 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 4559 goto likely; 4560 case OPC_BLTZ: 4561 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4562 goto not_likely; 4563 case OPC_BLTZL: 4564 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4565 goto likely; 4566 case OPC_BPOSGE32: 4567 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 4568 goto not_likely; 4569 #if defined(TARGET_MIPS64) 4570 case OPC_BPOSGE64: 4571 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64); 4572 goto not_likely; 4573 #endif 4574 case OPC_BLTZAL: 4575 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4576 blink = 31; 4577 not_likely: 4578 ctx->hflags |= MIPS_HFLAG_BC; 4579 break; 4580 case OPC_BLTZALL: 4581 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4582 blink = 31; 4583 likely: 4584 ctx->hflags |= MIPS_HFLAG_BL; 4585 break; 4586 default: 4587 MIPS_INVAL("conditional branch/jump"); 4588 gen_reserved_instruction(ctx); 4589 goto out; 4590 } 4591 } 4592 4593 ctx->btarget = btgt; 4594 4595 switch (delayslot_size) { 4596 case 2: 4597 ctx->hflags |= MIPS_HFLAG_BDS16; 4598 break; 4599 case 4: 4600 ctx->hflags |= MIPS_HFLAG_BDS32; 4601 break; 4602 } 4603 4604 if (blink > 0) { 4605 int post_delay = insn_bytes + delayslot_size; 4606 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); 4607 4608 tcg_gen_movi_tl(cpu_gpr[blink], 4609 ctx->base.pc_next + post_delay + lowbit); 4610 } 4611 4612 out: 4613 if (insn_bytes == 2) { 4614 ctx->hflags |= MIPS_HFLAG_B16; 4615 } 4616 } 4617 4618 4619 /* special3 bitfield operations */ 4620 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, 4621 int rs, int lsb, int msb) 4622 { 4623 TCGv t0 = tcg_temp_new(); 4624 TCGv t1 = tcg_temp_new(); 4625 4626 gen_load_gpr(t1, rs); 4627 switch (opc) { 4628 case OPC_EXT: 4629 if (lsb + msb > 31) { 4630 goto fail; 4631 } 4632 if (msb != 31) { 4633 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 4634 } else { 4635 /* 4636 * The two checks together imply that lsb == 0, 4637 * so this is a simple sign-extension. 4638 */ 4639 tcg_gen_ext32s_tl(t0, t1); 4640 } 4641 break; 4642 #if defined(TARGET_MIPS64) 4643 case OPC_DEXTU: 4644 lsb += 32; 4645 goto do_dext; 4646 case OPC_DEXTM: 4647 msb += 32; 4648 goto do_dext; 4649 case OPC_DEXT: 4650 do_dext: 4651 if (lsb + msb > 63) { 4652 goto fail; 4653 } 4654 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 4655 break; 4656 #endif 4657 case OPC_INS: 4658 if (lsb > msb) { 4659 goto fail; 4660 } 4661 gen_load_gpr(t0, rt); 4662 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 4663 tcg_gen_ext32s_tl(t0, t0); 4664 break; 4665 #if defined(TARGET_MIPS64) 4666 case OPC_DINSU: 4667 lsb += 32; 4668 /* FALLTHRU */ 4669 case OPC_DINSM: 4670 msb += 32; 4671 /* FALLTHRU */ 4672 case OPC_DINS: 4673 if (lsb > msb) { 4674 goto fail; 4675 } 4676 gen_load_gpr(t0, rt); 4677 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 4678 break; 4679 #endif 4680 default: 4681 fail: 4682 MIPS_INVAL("bitops"); 4683 gen_reserved_instruction(ctx); 4684 return; 4685 } 4686 gen_store_gpr(t0, rt); 4687 } 4688 4689 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) 4690 { 4691 TCGv t0; 4692 4693 if (rd == 0) { 4694 /* If no destination, treat it as a NOP. */ 4695 return; 4696 } 4697 4698 t0 = tcg_temp_new(); 4699 gen_load_gpr(t0, rt); 4700 switch (op2) { 4701 case OPC_WSBH: 4702 { 4703 TCGv t1 = tcg_temp_new(); 4704 TCGv t2 = tcg_constant_tl(0x00FF00FF); 4705 4706 tcg_gen_shri_tl(t1, t0, 8); 4707 tcg_gen_and_tl(t1, t1, t2); 4708 tcg_gen_and_tl(t0, t0, t2); 4709 tcg_gen_shli_tl(t0, t0, 8); 4710 tcg_gen_or_tl(t0, t0, t1); 4711 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 4712 } 4713 break; 4714 case OPC_SEB: 4715 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 4716 break; 4717 case OPC_SEH: 4718 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 4719 break; 4720 #if defined(TARGET_MIPS64) 4721 case OPC_DSBH: 4722 { 4723 TCGv t1 = tcg_temp_new(); 4724 TCGv t2 = tcg_constant_tl(0x00FF00FF00FF00FFULL); 4725 4726 tcg_gen_shri_tl(t1, t0, 8); 4727 tcg_gen_and_tl(t1, t1, t2); 4728 tcg_gen_and_tl(t0, t0, t2); 4729 tcg_gen_shli_tl(t0, t0, 8); 4730 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 4731 } 4732 break; 4733 case OPC_DSHD: 4734 { 4735 TCGv t1 = tcg_temp_new(); 4736 TCGv t2 = tcg_constant_tl(0x0000FFFF0000FFFFULL); 4737 4738 tcg_gen_shri_tl(t1, t0, 16); 4739 tcg_gen_and_tl(t1, t1, t2); 4740 tcg_gen_and_tl(t0, t0, t2); 4741 tcg_gen_shli_tl(t0, t0, 16); 4742 tcg_gen_or_tl(t0, t0, t1); 4743 tcg_gen_shri_tl(t1, t0, 32); 4744 tcg_gen_shli_tl(t0, t0, 32); 4745 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 4746 } 4747 break; 4748 #endif 4749 default: 4750 MIPS_INVAL("bsfhl"); 4751 gen_reserved_instruction(ctx); 4752 return; 4753 } 4754 } 4755 4756 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, 4757 int rt, int bits) 4758 { 4759 TCGv t0; 4760 if (rd == 0) { 4761 /* Treat as NOP. */ 4762 return; 4763 } 4764 t0 = tcg_temp_new(); 4765 if (bits == 0 || bits == wordsz) { 4766 if (bits == 0) { 4767 gen_load_gpr(t0, rt); 4768 } else { 4769 gen_load_gpr(t0, rs); 4770 } 4771 switch (wordsz) { 4772 case 32: 4773 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 4774 break; 4775 #if defined(TARGET_MIPS64) 4776 case 64: 4777 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4778 break; 4779 #endif 4780 } 4781 } else { 4782 TCGv t1 = tcg_temp_new(); 4783 gen_load_gpr(t0, rt); 4784 gen_load_gpr(t1, rs); 4785 switch (wordsz) { 4786 case 32: 4787 { 4788 TCGv_i64 t2 = tcg_temp_new_i64(); 4789 tcg_gen_concat_tl_i64(t2, t1, t0); 4790 tcg_gen_shri_i64(t2, t2, 32 - bits); 4791 gen_move_low32(cpu_gpr[rd], t2); 4792 } 4793 break; 4794 #if defined(TARGET_MIPS64) 4795 case 64: 4796 tcg_gen_shli_tl(t0, t0, bits); 4797 tcg_gen_shri_tl(t1, t1, 64 - bits); 4798 tcg_gen_or_tl(cpu_gpr[rd], t1, t0); 4799 break; 4800 #endif 4801 } 4802 } 4803 } 4804 4805 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp) 4806 { 4807 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); 4808 } 4809 4810 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) 4811 { 4812 TCGv t0; 4813 if (rd == 0) { 4814 /* Treat as NOP. */ 4815 return; 4816 } 4817 t0 = tcg_temp_new(); 4818 gen_load_gpr(t0, rt); 4819 switch (opc) { 4820 case OPC_BITSWAP: 4821 gen_helper_bitswap(cpu_gpr[rd], t0); 4822 break; 4823 #if defined(TARGET_MIPS64) 4824 case OPC_DBITSWAP: 4825 gen_helper_dbitswap(cpu_gpr[rd], t0); 4826 break; 4827 #endif 4828 } 4829 } 4830 4831 #ifndef CONFIG_USER_ONLY 4832 /* CP0 (MMU and control) */ 4833 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off) 4834 { 4835 TCGv_i64 t0 = tcg_temp_new_i64(); 4836 TCGv_i64 t1 = tcg_temp_new_i64(); 4837 4838 tcg_gen_ext_tl_i64(t0, arg); 4839 tcg_gen_ld_i64(t1, tcg_env, off); 4840 #if defined(TARGET_MIPS64) 4841 tcg_gen_deposit_i64(t1, t1, t0, 30, 32); 4842 #else 4843 tcg_gen_concat32_i64(t1, t1, t0); 4844 #endif 4845 tcg_gen_st_i64(t1, tcg_env, off); 4846 } 4847 4848 static inline void gen_mthc0_store64(TCGv arg, target_ulong off) 4849 { 4850 TCGv_i64 t0 = tcg_temp_new_i64(); 4851 TCGv_i64 t1 = tcg_temp_new_i64(); 4852 4853 tcg_gen_ext_tl_i64(t0, arg); 4854 tcg_gen_ld_i64(t1, tcg_env, off); 4855 tcg_gen_concat32_i64(t1, t1, t0); 4856 tcg_gen_st_i64(t1, tcg_env, off); 4857 } 4858 4859 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off) 4860 { 4861 TCGv_i64 t0 = tcg_temp_new_i64(); 4862 4863 tcg_gen_ld_i64(t0, tcg_env, off); 4864 #if defined(TARGET_MIPS64) 4865 tcg_gen_shri_i64(t0, t0, 30); 4866 #else 4867 tcg_gen_shri_i64(t0, t0, 32); 4868 #endif 4869 gen_move_low32(arg, t0); 4870 } 4871 4872 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift) 4873 { 4874 TCGv_i64 t0 = tcg_temp_new_i64(); 4875 4876 tcg_gen_ld_i64(t0, tcg_env, off); 4877 tcg_gen_shri_i64(t0, t0, 32 + shift); 4878 gen_move_low32(arg, t0); 4879 } 4880 4881 static inline void gen_mfc0_load32(TCGv arg, target_ulong off) 4882 { 4883 TCGv_i32 t0 = tcg_temp_new_i32(); 4884 4885 tcg_gen_ld_i32(t0, tcg_env, off); 4886 tcg_gen_ext_i32_tl(arg, t0); 4887 } 4888 4889 static inline void gen_mfc0_load64(TCGv arg, target_ulong off) 4890 { 4891 tcg_gen_ld_tl(arg, tcg_env, off); 4892 tcg_gen_ext32s_tl(arg, arg); 4893 } 4894 4895 static inline void gen_mtc0_store32(TCGv arg, target_ulong off) 4896 { 4897 TCGv_i32 t0 = tcg_temp_new_i32(); 4898 4899 tcg_gen_trunc_tl_i32(t0, arg); 4900 tcg_gen_st_i32(t0, tcg_env, off); 4901 } 4902 4903 #define CP0_CHECK(c) \ 4904 do { \ 4905 if (!(c)) { \ 4906 goto cp0_unimplemented; \ 4907 } \ 4908 } while (0) 4909 4910 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) 4911 { 4912 const char *register_name = "invalid"; 4913 4914 switch (reg) { 4915 case CP0_REGISTER_02: 4916 switch (sel) { 4917 case 0: 4918 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 4919 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 4920 register_name = "EntryLo0"; 4921 break; 4922 default: 4923 goto cp0_unimplemented; 4924 } 4925 break; 4926 case CP0_REGISTER_03: 4927 switch (sel) { 4928 case CP0_REG03__ENTRYLO1: 4929 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 4930 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 4931 register_name = "EntryLo1"; 4932 break; 4933 default: 4934 goto cp0_unimplemented; 4935 } 4936 break; 4937 case CP0_REGISTER_17: 4938 switch (sel) { 4939 case CP0_REG17__LLADDR: 4940 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr), 4941 ctx->CP0_LLAddr_shift); 4942 register_name = "LLAddr"; 4943 break; 4944 case CP0_REG17__MAAR: 4945 CP0_CHECK(ctx->mrp); 4946 gen_helper_mfhc0_maar(arg, tcg_env); 4947 register_name = "MAAR"; 4948 break; 4949 default: 4950 goto cp0_unimplemented; 4951 } 4952 break; 4953 case CP0_REGISTER_19: 4954 switch (sel) { 4955 case CP0_REG19__WATCHHI0: 4956 case CP0_REG19__WATCHHI1: 4957 case CP0_REG19__WATCHHI2: 4958 case CP0_REG19__WATCHHI3: 4959 case CP0_REG19__WATCHHI4: 4960 case CP0_REG19__WATCHHI5: 4961 case CP0_REG19__WATCHHI6: 4962 case CP0_REG19__WATCHHI7: 4963 /* upper 32 bits are only available when Config5MI != 0 */ 4964 CP0_CHECK(ctx->mi); 4965 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0); 4966 register_name = "WatchHi"; 4967 break; 4968 default: 4969 goto cp0_unimplemented; 4970 } 4971 break; 4972 case CP0_REGISTER_28: 4973 switch (sel) { 4974 case 0: 4975 case 2: 4976 case 4: 4977 case 6: 4978 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0); 4979 register_name = "TagLo"; 4980 break; 4981 default: 4982 goto cp0_unimplemented; 4983 } 4984 break; 4985 default: 4986 goto cp0_unimplemented; 4987 } 4988 trace_mips_translate_c0("mfhc0", register_name, reg, sel); 4989 return; 4990 4991 cp0_unimplemented: 4992 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", 4993 register_name, reg, sel); 4994 tcg_gen_movi_tl(arg, 0); 4995 } 4996 4997 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) 4998 { 4999 const char *register_name = "invalid"; 5000 uint64_t mask = ctx->PAMask >> 36; 5001 5002 switch (reg) { 5003 case CP0_REGISTER_02: 5004 switch (sel) { 5005 case 0: 5006 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5007 tcg_gen_andi_tl(arg, arg, mask); 5008 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5009 register_name = "EntryLo0"; 5010 break; 5011 default: 5012 goto cp0_unimplemented; 5013 } 5014 break; 5015 case CP0_REGISTER_03: 5016 switch (sel) { 5017 case CP0_REG03__ENTRYLO1: 5018 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5019 tcg_gen_andi_tl(arg, arg, mask); 5020 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5021 register_name = "EntryLo1"; 5022 break; 5023 default: 5024 goto cp0_unimplemented; 5025 } 5026 break; 5027 case CP0_REGISTER_17: 5028 switch (sel) { 5029 case CP0_REG17__LLADDR: 5030 /* 5031 * LLAddr is read-only (the only exception is bit 0 if LLB is 5032 * supported); the CP0_LLAddr_rw_bitmask does not seem to be 5033 * relevant for modern MIPS cores supporting MTHC0, therefore 5034 * treating MTHC0 to LLAddr as NOP. 5035 */ 5036 register_name = "LLAddr"; 5037 break; 5038 case CP0_REG17__MAAR: 5039 CP0_CHECK(ctx->mrp); 5040 gen_helper_mthc0_maar(tcg_env, arg); 5041 register_name = "MAAR"; 5042 break; 5043 default: 5044 goto cp0_unimplemented; 5045 } 5046 break; 5047 case CP0_REGISTER_19: 5048 switch (sel) { 5049 case CP0_REG19__WATCHHI0: 5050 case CP0_REG19__WATCHHI1: 5051 case CP0_REG19__WATCHHI2: 5052 case CP0_REG19__WATCHHI3: 5053 case CP0_REG19__WATCHHI4: 5054 case CP0_REG19__WATCHHI5: 5055 case CP0_REG19__WATCHHI6: 5056 case CP0_REG19__WATCHHI7: 5057 /* upper 32 bits are only available when Config5MI != 0 */ 5058 CP0_CHECK(ctx->mi); 5059 gen_helper_0e1i(mthc0_watchhi, arg, sel); 5060 register_name = "WatchHi"; 5061 break; 5062 default: 5063 goto cp0_unimplemented; 5064 } 5065 break; 5066 case CP0_REGISTER_28: 5067 switch (sel) { 5068 case 0: 5069 case 2: 5070 case 4: 5071 case 6: 5072 tcg_gen_andi_tl(arg, arg, mask); 5073 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo)); 5074 register_name = "TagLo"; 5075 break; 5076 default: 5077 goto cp0_unimplemented; 5078 } 5079 break; 5080 default: 5081 goto cp0_unimplemented; 5082 } 5083 trace_mips_translate_c0("mthc0", register_name, reg, sel); 5084 return; 5085 5086 cp0_unimplemented: 5087 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", 5088 register_name, reg, sel); 5089 } 5090 5091 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg) 5092 { 5093 if (ctx->insn_flags & ISA_MIPS_R6) { 5094 tcg_gen_movi_tl(arg, 0); 5095 } else { 5096 tcg_gen_movi_tl(arg, ~0); 5097 } 5098 } 5099 5100 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5101 { 5102 const char *register_name = "invalid"; 5103 5104 if (sel != 0) { 5105 check_insn(ctx, ISA_MIPS_R1); 5106 } 5107 5108 switch (reg) { 5109 case CP0_REGISTER_00: 5110 switch (sel) { 5111 case CP0_REG00__INDEX: 5112 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 5113 register_name = "Index"; 5114 break; 5115 case CP0_REG00__MVPCONTROL: 5116 CP0_CHECK(disas_mt_available(ctx)); 5117 gen_helper_mfc0_mvpcontrol(arg, tcg_env); 5118 register_name = "MVPControl"; 5119 break; 5120 case CP0_REG00__MVPCONF0: 5121 CP0_CHECK(disas_mt_available(ctx)); 5122 gen_helper_mfc0_mvpconf0(arg, tcg_env); 5123 register_name = "MVPConf0"; 5124 break; 5125 case CP0_REG00__MVPCONF1: 5126 CP0_CHECK(disas_mt_available(ctx)); 5127 gen_helper_mfc0_mvpconf1(arg, tcg_env); 5128 register_name = "MVPConf1"; 5129 break; 5130 case CP0_REG00__VPCONTROL: 5131 CP0_CHECK(ctx->vp); 5132 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 5133 register_name = "VPControl"; 5134 break; 5135 default: 5136 goto cp0_unimplemented; 5137 } 5138 break; 5139 case CP0_REGISTER_01: 5140 switch (sel) { 5141 case CP0_REG01__RANDOM: 5142 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5143 gen_helper_mfc0_random(arg, tcg_env); 5144 register_name = "Random"; 5145 break; 5146 case CP0_REG01__VPECONTROL: 5147 CP0_CHECK(disas_mt_available(ctx)); 5148 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 5149 register_name = "VPEControl"; 5150 break; 5151 case CP0_REG01__VPECONF0: 5152 CP0_CHECK(disas_mt_available(ctx)); 5153 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 5154 register_name = "VPEConf0"; 5155 break; 5156 case CP0_REG01__VPECONF1: 5157 CP0_CHECK(disas_mt_available(ctx)); 5158 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 5159 register_name = "VPEConf1"; 5160 break; 5161 case CP0_REG01__YQMASK: 5162 CP0_CHECK(disas_mt_available(ctx)); 5163 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 5164 register_name = "YQMask"; 5165 break; 5166 case CP0_REG01__VPESCHEDULE: 5167 CP0_CHECK(disas_mt_available(ctx)); 5168 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 5169 register_name = "VPESchedule"; 5170 break; 5171 case CP0_REG01__VPESCHEFBACK: 5172 CP0_CHECK(disas_mt_available(ctx)); 5173 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5174 register_name = "VPEScheFBack"; 5175 break; 5176 case CP0_REG01__VPEOPT: 5177 CP0_CHECK(disas_mt_available(ctx)); 5178 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 5179 register_name = "VPEOpt"; 5180 break; 5181 default: 5182 goto cp0_unimplemented; 5183 } 5184 break; 5185 case CP0_REGISTER_02: 5186 switch (sel) { 5187 case CP0_REG02__ENTRYLO0: 5188 { 5189 TCGv_i64 tmp = tcg_temp_new_i64(); 5190 tcg_gen_ld_i64(tmp, tcg_env, 5191 offsetof(CPUMIPSState, CP0_EntryLo0)); 5192 #if defined(TARGET_MIPS64) 5193 if (ctx->rxi) { 5194 /* Move RI/XI fields to bits 31:30 */ 5195 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5196 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5197 } 5198 #endif 5199 gen_move_low32(arg, tmp); 5200 } 5201 register_name = "EntryLo0"; 5202 break; 5203 case CP0_REG02__TCSTATUS: 5204 CP0_CHECK(disas_mt_available(ctx)); 5205 gen_helper_mfc0_tcstatus(arg, tcg_env); 5206 register_name = "TCStatus"; 5207 break; 5208 case CP0_REG02__TCBIND: 5209 CP0_CHECK(disas_mt_available(ctx)); 5210 gen_helper_mfc0_tcbind(arg, tcg_env); 5211 register_name = "TCBind"; 5212 break; 5213 case CP0_REG02__TCRESTART: 5214 CP0_CHECK(disas_mt_available(ctx)); 5215 gen_helper_mfc0_tcrestart(arg, tcg_env); 5216 register_name = "TCRestart"; 5217 break; 5218 case CP0_REG02__TCHALT: 5219 CP0_CHECK(disas_mt_available(ctx)); 5220 gen_helper_mfc0_tchalt(arg, tcg_env); 5221 register_name = "TCHalt"; 5222 break; 5223 case CP0_REG02__TCCONTEXT: 5224 CP0_CHECK(disas_mt_available(ctx)); 5225 gen_helper_mfc0_tccontext(arg, tcg_env); 5226 register_name = "TCContext"; 5227 break; 5228 case CP0_REG02__TCSCHEDULE: 5229 CP0_CHECK(disas_mt_available(ctx)); 5230 gen_helper_mfc0_tcschedule(arg, tcg_env); 5231 register_name = "TCSchedule"; 5232 break; 5233 case CP0_REG02__TCSCHEFBACK: 5234 CP0_CHECK(disas_mt_available(ctx)); 5235 gen_helper_mfc0_tcschefback(arg, tcg_env); 5236 register_name = "TCScheFBack"; 5237 break; 5238 default: 5239 goto cp0_unimplemented; 5240 } 5241 break; 5242 case CP0_REGISTER_03: 5243 switch (sel) { 5244 case CP0_REG03__ENTRYLO1: 5245 { 5246 TCGv_i64 tmp = tcg_temp_new_i64(); 5247 tcg_gen_ld_i64(tmp, tcg_env, 5248 offsetof(CPUMIPSState, CP0_EntryLo1)); 5249 #if defined(TARGET_MIPS64) 5250 if (ctx->rxi) { 5251 /* Move RI/XI fields to bits 31:30 */ 5252 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5253 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5254 } 5255 #endif 5256 gen_move_low32(arg, tmp); 5257 } 5258 register_name = "EntryLo1"; 5259 break; 5260 case CP0_REG03__GLOBALNUM: 5261 CP0_CHECK(ctx->vp); 5262 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 5263 register_name = "GlobalNumber"; 5264 break; 5265 default: 5266 goto cp0_unimplemented; 5267 } 5268 break; 5269 case CP0_REGISTER_04: 5270 switch (sel) { 5271 case CP0_REG04__CONTEXT: 5272 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context)); 5273 tcg_gen_ext32s_tl(arg, arg); 5274 register_name = "Context"; 5275 break; 5276 case CP0_REG04__CONTEXTCONFIG: 5277 /* SmartMIPS ASE */ 5278 /* gen_helper_mfc0_contextconfig(arg); */ 5279 register_name = "ContextConfig"; 5280 goto cp0_unimplemented; 5281 case CP0_REG04__USERLOCAL: 5282 CP0_CHECK(ctx->ulri); 5283 tcg_gen_ld_tl(arg, tcg_env, 5284 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 5285 tcg_gen_ext32s_tl(arg, arg); 5286 register_name = "UserLocal"; 5287 break; 5288 case CP0_REG04__MMID: 5289 CP0_CHECK(ctx->mi); 5290 gen_helper_mtc0_memorymapid(tcg_env, arg); 5291 register_name = "MMID"; 5292 break; 5293 default: 5294 goto cp0_unimplemented; 5295 } 5296 break; 5297 case CP0_REGISTER_05: 5298 switch (sel) { 5299 case CP0_REG05__PAGEMASK: 5300 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 5301 register_name = "PageMask"; 5302 break; 5303 case CP0_REG05__PAGEGRAIN: 5304 check_insn(ctx, ISA_MIPS_R2); 5305 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 5306 register_name = "PageGrain"; 5307 break; 5308 case CP0_REG05__SEGCTL0: 5309 CP0_CHECK(ctx->sc); 5310 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 5311 tcg_gen_ext32s_tl(arg, arg); 5312 register_name = "SegCtl0"; 5313 break; 5314 case CP0_REG05__SEGCTL1: 5315 CP0_CHECK(ctx->sc); 5316 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 5317 tcg_gen_ext32s_tl(arg, arg); 5318 register_name = "SegCtl1"; 5319 break; 5320 case CP0_REG05__SEGCTL2: 5321 CP0_CHECK(ctx->sc); 5322 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 5323 tcg_gen_ext32s_tl(arg, arg); 5324 register_name = "SegCtl2"; 5325 break; 5326 case CP0_REG05__PWBASE: 5327 check_pw(ctx); 5328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 5329 register_name = "PWBase"; 5330 break; 5331 case CP0_REG05__PWFIELD: 5332 check_pw(ctx); 5333 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField)); 5334 register_name = "PWField"; 5335 break; 5336 case CP0_REG05__PWSIZE: 5337 check_pw(ctx); 5338 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize)); 5339 register_name = "PWSize"; 5340 break; 5341 default: 5342 goto cp0_unimplemented; 5343 } 5344 break; 5345 case CP0_REGISTER_06: 5346 switch (sel) { 5347 case CP0_REG06__WIRED: 5348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 5349 register_name = "Wired"; 5350 break; 5351 case CP0_REG06__SRSCONF0: 5352 check_insn(ctx, ISA_MIPS_R2); 5353 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 5354 register_name = "SRSConf0"; 5355 break; 5356 case CP0_REG06__SRSCONF1: 5357 check_insn(ctx, ISA_MIPS_R2); 5358 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 5359 register_name = "SRSConf1"; 5360 break; 5361 case CP0_REG06__SRSCONF2: 5362 check_insn(ctx, ISA_MIPS_R2); 5363 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 5364 register_name = "SRSConf2"; 5365 break; 5366 case CP0_REG06__SRSCONF3: 5367 check_insn(ctx, ISA_MIPS_R2); 5368 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 5369 register_name = "SRSConf3"; 5370 break; 5371 case CP0_REG06__SRSCONF4: 5372 check_insn(ctx, ISA_MIPS_R2); 5373 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 5374 register_name = "SRSConf4"; 5375 break; 5376 case CP0_REG06__PWCTL: 5377 check_pw(ctx); 5378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 5379 register_name = "PWCtl"; 5380 break; 5381 default: 5382 goto cp0_unimplemented; 5383 } 5384 break; 5385 case CP0_REGISTER_07: 5386 switch (sel) { 5387 case CP0_REG07__HWRENA: 5388 check_insn(ctx, ISA_MIPS_R2); 5389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 5390 register_name = "HWREna"; 5391 break; 5392 default: 5393 goto cp0_unimplemented; 5394 } 5395 break; 5396 case CP0_REGISTER_08: 5397 switch (sel) { 5398 case CP0_REG08__BADVADDR: 5399 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 5400 tcg_gen_ext32s_tl(arg, arg); 5401 register_name = "BadVAddr"; 5402 break; 5403 case CP0_REG08__BADINSTR: 5404 CP0_CHECK(ctx->bi); 5405 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 5406 register_name = "BadInstr"; 5407 break; 5408 case CP0_REG08__BADINSTRP: 5409 CP0_CHECK(ctx->bp); 5410 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 5411 register_name = "BadInstrP"; 5412 break; 5413 case CP0_REG08__BADINSTRX: 5414 CP0_CHECK(ctx->bi); 5415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 5416 tcg_gen_andi_tl(arg, arg, ~0xffff); 5417 register_name = "BadInstrX"; 5418 break; 5419 default: 5420 goto cp0_unimplemented; 5421 } 5422 break; 5423 case CP0_REGISTER_09: 5424 switch (sel) { 5425 case CP0_REG09__COUNT: 5426 /* Mark as an IO operation because we read the time. */ 5427 translator_io_start(&ctx->base); 5428 5429 gen_helper_mfc0_count(arg, tcg_env); 5430 /* 5431 * Break the TB to be able to take timer interrupts immediately 5432 * after reading count. DISAS_STOP isn't sufficient, we need to 5433 * ensure we break completely out of translated code. 5434 */ 5435 gen_save_pc(ctx->base.pc_next + 4); 5436 ctx->base.is_jmp = DISAS_EXIT; 5437 register_name = "Count"; 5438 break; 5439 default: 5440 goto cp0_unimplemented; 5441 } 5442 break; 5443 case CP0_REGISTER_10: 5444 switch (sel) { 5445 case CP0_REG10__ENTRYHI: 5446 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi)); 5447 tcg_gen_ext32s_tl(arg, arg); 5448 register_name = "EntryHi"; 5449 break; 5450 default: 5451 goto cp0_unimplemented; 5452 } 5453 break; 5454 case CP0_REGISTER_11: 5455 switch (sel) { 5456 case CP0_REG11__COMPARE: 5457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 5458 register_name = "Compare"; 5459 break; 5460 /* 6,7 are implementation dependent */ 5461 default: 5462 goto cp0_unimplemented; 5463 } 5464 break; 5465 case CP0_REGISTER_12: 5466 switch (sel) { 5467 case CP0_REG12__STATUS: 5468 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 5469 register_name = "Status"; 5470 break; 5471 case CP0_REG12__INTCTL: 5472 check_insn(ctx, ISA_MIPS_R2); 5473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 5474 register_name = "IntCtl"; 5475 break; 5476 case CP0_REG12__SRSCTL: 5477 check_insn(ctx, ISA_MIPS_R2); 5478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 5479 register_name = "SRSCtl"; 5480 break; 5481 case CP0_REG12__SRSMAP: 5482 check_insn(ctx, ISA_MIPS_R2); 5483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 5484 register_name = "SRSMap"; 5485 break; 5486 default: 5487 goto cp0_unimplemented; 5488 } 5489 break; 5490 case CP0_REGISTER_13: 5491 switch (sel) { 5492 case CP0_REG13__CAUSE: 5493 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 5494 register_name = "Cause"; 5495 break; 5496 default: 5497 goto cp0_unimplemented; 5498 } 5499 break; 5500 case CP0_REGISTER_14: 5501 switch (sel) { 5502 case CP0_REG14__EPC: 5503 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 5504 tcg_gen_ext32s_tl(arg, arg); 5505 register_name = "EPC"; 5506 break; 5507 default: 5508 goto cp0_unimplemented; 5509 } 5510 break; 5511 case CP0_REGISTER_15: 5512 switch (sel) { 5513 case CP0_REG15__PRID: 5514 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 5515 register_name = "PRid"; 5516 break; 5517 case CP0_REG15__EBASE: 5518 check_insn(ctx, ISA_MIPS_R2); 5519 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase)); 5520 tcg_gen_ext32s_tl(arg, arg); 5521 register_name = "EBase"; 5522 break; 5523 case CP0_REG15__CMGCRBASE: 5524 check_insn(ctx, ISA_MIPS_R2); 5525 CP0_CHECK(ctx->cmgcr); 5526 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 5527 tcg_gen_ext32s_tl(arg, arg); 5528 register_name = "CMGCRBase"; 5529 break; 5530 default: 5531 goto cp0_unimplemented; 5532 } 5533 break; 5534 case CP0_REGISTER_16: 5535 switch (sel) { 5536 case CP0_REG16__CONFIG: 5537 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 5538 register_name = "Config"; 5539 break; 5540 case CP0_REG16__CONFIG1: 5541 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 5542 register_name = "Config1"; 5543 break; 5544 case CP0_REG16__CONFIG2: 5545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 5546 register_name = "Config2"; 5547 break; 5548 case CP0_REG16__CONFIG3: 5549 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 5550 register_name = "Config3"; 5551 break; 5552 case CP0_REG16__CONFIG4: 5553 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 5554 register_name = "Config4"; 5555 break; 5556 case CP0_REG16__CONFIG5: 5557 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 5558 register_name = "Config5"; 5559 break; 5560 /* 6,7 are implementation dependent */ 5561 case CP0_REG16__CONFIG6: 5562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 5563 register_name = "Config6"; 5564 break; 5565 case CP0_REG16__CONFIG7: 5566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 5567 register_name = "Config7"; 5568 break; 5569 default: 5570 goto cp0_unimplemented; 5571 } 5572 break; 5573 case CP0_REGISTER_17: 5574 switch (sel) { 5575 case CP0_REG17__LLADDR: 5576 gen_helper_mfc0_lladdr(arg, tcg_env); 5577 register_name = "LLAddr"; 5578 break; 5579 case CP0_REG17__MAAR: 5580 CP0_CHECK(ctx->mrp); 5581 gen_helper_mfc0_maar(arg, tcg_env); 5582 register_name = "MAAR"; 5583 break; 5584 case CP0_REG17__MAARI: 5585 CP0_CHECK(ctx->mrp); 5586 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 5587 register_name = "MAARI"; 5588 break; 5589 default: 5590 goto cp0_unimplemented; 5591 } 5592 break; 5593 case CP0_REGISTER_18: 5594 switch (sel) { 5595 case CP0_REG18__WATCHLO0: 5596 case CP0_REG18__WATCHLO1: 5597 case CP0_REG18__WATCHLO2: 5598 case CP0_REG18__WATCHLO3: 5599 case CP0_REG18__WATCHLO4: 5600 case CP0_REG18__WATCHLO5: 5601 case CP0_REG18__WATCHLO6: 5602 case CP0_REG18__WATCHLO7: 5603 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 5604 gen_helper_1e0i(mfc0_watchlo, arg, sel); 5605 register_name = "WatchLo"; 5606 break; 5607 default: 5608 goto cp0_unimplemented; 5609 } 5610 break; 5611 case CP0_REGISTER_19: 5612 switch (sel) { 5613 case CP0_REG19__WATCHHI0: 5614 case CP0_REG19__WATCHHI1: 5615 case CP0_REG19__WATCHHI2: 5616 case CP0_REG19__WATCHHI3: 5617 case CP0_REG19__WATCHHI4: 5618 case CP0_REG19__WATCHHI5: 5619 case CP0_REG19__WATCHHI6: 5620 case CP0_REG19__WATCHHI7: 5621 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 5622 gen_helper_1e0i(mfc0_watchhi, arg, sel); 5623 register_name = "WatchHi"; 5624 break; 5625 default: 5626 goto cp0_unimplemented; 5627 } 5628 break; 5629 case CP0_REGISTER_20: 5630 switch (sel) { 5631 case CP0_REG20__XCONTEXT: 5632 #if defined(TARGET_MIPS64) 5633 check_insn(ctx, ISA_MIPS3); 5634 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext)); 5635 tcg_gen_ext32s_tl(arg, arg); 5636 register_name = "XContext"; 5637 break; 5638 #endif 5639 default: 5640 goto cp0_unimplemented; 5641 } 5642 break; 5643 case CP0_REGISTER_21: 5644 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 5645 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5646 switch (sel) { 5647 case 0: 5648 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 5649 register_name = "Framemask"; 5650 break; 5651 default: 5652 goto cp0_unimplemented; 5653 } 5654 break; 5655 case CP0_REGISTER_22: 5656 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 5657 register_name = "'Diagnostic"; /* implementation dependent */ 5658 break; 5659 case CP0_REGISTER_23: 5660 switch (sel) { 5661 case CP0_REG23__DEBUG: 5662 gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */ 5663 register_name = "Debug"; 5664 break; 5665 case CP0_REG23__TRACECONTROL: 5666 /* PDtrace support */ 5667 /* gen_helper_mfc0_tracecontrol(arg); */ 5668 register_name = "TraceControl"; 5669 goto cp0_unimplemented; 5670 case CP0_REG23__TRACECONTROL2: 5671 /* PDtrace support */ 5672 /* gen_helper_mfc0_tracecontrol2(arg); */ 5673 register_name = "TraceControl2"; 5674 goto cp0_unimplemented; 5675 case CP0_REG23__USERTRACEDATA1: 5676 /* PDtrace support */ 5677 /* gen_helper_mfc0_usertracedata1(arg);*/ 5678 register_name = "UserTraceData1"; 5679 goto cp0_unimplemented; 5680 case CP0_REG23__TRACEIBPC: 5681 /* PDtrace support */ 5682 /* gen_helper_mfc0_traceibpc(arg); */ 5683 register_name = "TraceIBPC"; 5684 goto cp0_unimplemented; 5685 case CP0_REG23__TRACEDBPC: 5686 /* PDtrace support */ 5687 /* gen_helper_mfc0_tracedbpc(arg); */ 5688 register_name = "TraceDBPC"; 5689 goto cp0_unimplemented; 5690 default: 5691 goto cp0_unimplemented; 5692 } 5693 break; 5694 case CP0_REGISTER_24: 5695 switch (sel) { 5696 case CP0_REG24__DEPC: 5697 /* EJTAG support */ 5698 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 5699 tcg_gen_ext32s_tl(arg, arg); 5700 register_name = "DEPC"; 5701 break; 5702 default: 5703 goto cp0_unimplemented; 5704 } 5705 break; 5706 case CP0_REGISTER_25: 5707 switch (sel) { 5708 case CP0_REG25__PERFCTL0: 5709 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 5710 register_name = "Performance0"; 5711 break; 5712 case CP0_REG25__PERFCNT0: 5713 /* gen_helper_mfc0_performance1(arg); */ 5714 register_name = "Performance1"; 5715 goto cp0_unimplemented; 5716 case CP0_REG25__PERFCTL1: 5717 /* gen_helper_mfc0_performance2(arg); */ 5718 register_name = "Performance2"; 5719 goto cp0_unimplemented; 5720 case CP0_REG25__PERFCNT1: 5721 /* gen_helper_mfc0_performance3(arg); */ 5722 register_name = "Performance3"; 5723 goto cp0_unimplemented; 5724 case CP0_REG25__PERFCTL2: 5725 /* gen_helper_mfc0_performance4(arg); */ 5726 register_name = "Performance4"; 5727 goto cp0_unimplemented; 5728 case CP0_REG25__PERFCNT2: 5729 /* gen_helper_mfc0_performance5(arg); */ 5730 register_name = "Performance5"; 5731 goto cp0_unimplemented; 5732 case CP0_REG25__PERFCTL3: 5733 /* gen_helper_mfc0_performance6(arg); */ 5734 register_name = "Performance6"; 5735 goto cp0_unimplemented; 5736 case CP0_REG25__PERFCNT3: 5737 /* gen_helper_mfc0_performance7(arg); */ 5738 register_name = "Performance7"; 5739 goto cp0_unimplemented; 5740 default: 5741 goto cp0_unimplemented; 5742 } 5743 break; 5744 case CP0_REGISTER_26: 5745 switch (sel) { 5746 case CP0_REG26__ERRCTL: 5747 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 5748 register_name = "ErrCtl"; 5749 break; 5750 default: 5751 goto cp0_unimplemented; 5752 } 5753 break; 5754 case CP0_REGISTER_27: 5755 switch (sel) { 5756 case CP0_REG27__CACHERR: 5757 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 5758 register_name = "CacheErr"; 5759 break; 5760 default: 5761 goto cp0_unimplemented; 5762 } 5763 break; 5764 case CP0_REGISTER_28: 5765 switch (sel) { 5766 case CP0_REG28__TAGLO: 5767 case CP0_REG28__TAGLO1: 5768 case CP0_REG28__TAGLO2: 5769 case CP0_REG28__TAGLO3: 5770 { 5771 TCGv_i64 tmp = tcg_temp_new_i64(); 5772 tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPUMIPSState, CP0_TagLo)); 5773 gen_move_low32(arg, tmp); 5774 } 5775 register_name = "TagLo"; 5776 break; 5777 case CP0_REG28__DATALO: 5778 case CP0_REG28__DATALO1: 5779 case CP0_REG28__DATALO2: 5780 case CP0_REG28__DATALO3: 5781 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 5782 register_name = "DataLo"; 5783 break; 5784 default: 5785 goto cp0_unimplemented; 5786 } 5787 break; 5788 case CP0_REGISTER_29: 5789 switch (sel) { 5790 case CP0_REG29__TAGHI: 5791 case CP0_REG29__TAGHI1: 5792 case CP0_REG29__TAGHI2: 5793 case CP0_REG29__TAGHI3: 5794 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 5795 register_name = "TagHi"; 5796 break; 5797 case CP0_REG29__DATAHI: 5798 case CP0_REG29__DATAHI1: 5799 case CP0_REG29__DATAHI2: 5800 case CP0_REG29__DATAHI3: 5801 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 5802 register_name = "DataHi"; 5803 break; 5804 default: 5805 goto cp0_unimplemented; 5806 } 5807 break; 5808 case CP0_REGISTER_30: 5809 switch (sel) { 5810 case CP0_REG30__ERROREPC: 5811 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 5812 tcg_gen_ext32s_tl(arg, arg); 5813 register_name = "ErrorEPC"; 5814 break; 5815 default: 5816 goto cp0_unimplemented; 5817 } 5818 break; 5819 case CP0_REGISTER_31: 5820 switch (sel) { 5821 case CP0_REG31__DESAVE: 5822 /* EJTAG support */ 5823 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 5824 register_name = "DESAVE"; 5825 break; 5826 case CP0_REG31__KSCRATCH1: 5827 case CP0_REG31__KSCRATCH2: 5828 case CP0_REG31__KSCRATCH3: 5829 case CP0_REG31__KSCRATCH4: 5830 case CP0_REG31__KSCRATCH5: 5831 case CP0_REG31__KSCRATCH6: 5832 CP0_CHECK(ctx->kscrexist & (1 << sel)); 5833 tcg_gen_ld_tl(arg, tcg_env, 5834 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 5835 tcg_gen_ext32s_tl(arg, arg); 5836 register_name = "KScratch"; 5837 break; 5838 default: 5839 goto cp0_unimplemented; 5840 } 5841 break; 5842 default: 5843 goto cp0_unimplemented; 5844 } 5845 trace_mips_translate_c0("mfc0", register_name, reg, sel); 5846 return; 5847 5848 cp0_unimplemented: 5849 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", 5850 register_name, reg, sel); 5851 gen_mfc0_unimplemented(ctx, arg); 5852 } 5853 5854 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5855 { 5856 const char *register_name = "invalid"; 5857 bool icount; 5858 5859 if (sel != 0) { 5860 check_insn(ctx, ISA_MIPS_R1); 5861 } 5862 5863 icount = translator_io_start(&ctx->base); 5864 5865 switch (reg) { 5866 case CP0_REGISTER_00: 5867 switch (sel) { 5868 case CP0_REG00__INDEX: 5869 gen_helper_mtc0_index(tcg_env, arg); 5870 register_name = "Index"; 5871 break; 5872 case CP0_REG00__MVPCONTROL: 5873 CP0_CHECK(disas_mt_available(ctx)); 5874 gen_helper_mtc0_mvpcontrol(tcg_env, arg); 5875 register_name = "MVPControl"; 5876 break; 5877 case CP0_REG00__MVPCONF0: 5878 CP0_CHECK(disas_mt_available(ctx)); 5879 /* ignored */ 5880 register_name = "MVPConf0"; 5881 break; 5882 case CP0_REG00__MVPCONF1: 5883 CP0_CHECK(disas_mt_available(ctx)); 5884 /* ignored */ 5885 register_name = "MVPConf1"; 5886 break; 5887 case CP0_REG00__VPCONTROL: 5888 CP0_CHECK(ctx->vp); 5889 /* ignored */ 5890 register_name = "VPControl"; 5891 break; 5892 default: 5893 goto cp0_unimplemented; 5894 } 5895 break; 5896 case CP0_REGISTER_01: 5897 switch (sel) { 5898 case CP0_REG01__RANDOM: 5899 /* ignored */ 5900 register_name = "Random"; 5901 break; 5902 case CP0_REG01__VPECONTROL: 5903 CP0_CHECK(disas_mt_available(ctx)); 5904 gen_helper_mtc0_vpecontrol(tcg_env, arg); 5905 register_name = "VPEControl"; 5906 break; 5907 case CP0_REG01__VPECONF0: 5908 CP0_CHECK(disas_mt_available(ctx)); 5909 gen_helper_mtc0_vpeconf0(tcg_env, arg); 5910 register_name = "VPEConf0"; 5911 break; 5912 case CP0_REG01__VPECONF1: 5913 CP0_CHECK(disas_mt_available(ctx)); 5914 gen_helper_mtc0_vpeconf1(tcg_env, arg); 5915 register_name = "VPEConf1"; 5916 break; 5917 case CP0_REG01__YQMASK: 5918 CP0_CHECK(disas_mt_available(ctx)); 5919 gen_helper_mtc0_yqmask(tcg_env, arg); 5920 register_name = "YQMask"; 5921 break; 5922 case CP0_REG01__VPESCHEDULE: 5923 CP0_CHECK(disas_mt_available(ctx)); 5924 tcg_gen_st_tl(arg, tcg_env, 5925 offsetof(CPUMIPSState, CP0_VPESchedule)); 5926 register_name = "VPESchedule"; 5927 break; 5928 case CP0_REG01__VPESCHEFBACK: 5929 CP0_CHECK(disas_mt_available(ctx)); 5930 tcg_gen_st_tl(arg, tcg_env, 5931 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5932 register_name = "VPEScheFBack"; 5933 break; 5934 case CP0_REG01__VPEOPT: 5935 CP0_CHECK(disas_mt_available(ctx)); 5936 gen_helper_mtc0_vpeopt(tcg_env, arg); 5937 register_name = "VPEOpt"; 5938 break; 5939 default: 5940 goto cp0_unimplemented; 5941 } 5942 break; 5943 case CP0_REGISTER_02: 5944 switch (sel) { 5945 case CP0_REG02__ENTRYLO0: 5946 gen_helper_mtc0_entrylo0(tcg_env, arg); 5947 register_name = "EntryLo0"; 5948 break; 5949 case CP0_REG02__TCSTATUS: 5950 CP0_CHECK(disas_mt_available(ctx)); 5951 gen_helper_mtc0_tcstatus(tcg_env, arg); 5952 register_name = "TCStatus"; 5953 break; 5954 case CP0_REG02__TCBIND: 5955 CP0_CHECK(disas_mt_available(ctx)); 5956 gen_helper_mtc0_tcbind(tcg_env, arg); 5957 register_name = "TCBind"; 5958 break; 5959 case CP0_REG02__TCRESTART: 5960 CP0_CHECK(disas_mt_available(ctx)); 5961 gen_helper_mtc0_tcrestart(tcg_env, arg); 5962 register_name = "TCRestart"; 5963 break; 5964 case CP0_REG02__TCHALT: 5965 CP0_CHECK(disas_mt_available(ctx)); 5966 gen_helper_mtc0_tchalt(tcg_env, arg); 5967 register_name = "TCHalt"; 5968 break; 5969 case CP0_REG02__TCCONTEXT: 5970 CP0_CHECK(disas_mt_available(ctx)); 5971 gen_helper_mtc0_tccontext(tcg_env, arg); 5972 register_name = "TCContext"; 5973 break; 5974 case CP0_REG02__TCSCHEDULE: 5975 CP0_CHECK(disas_mt_available(ctx)); 5976 gen_helper_mtc0_tcschedule(tcg_env, arg); 5977 register_name = "TCSchedule"; 5978 break; 5979 case CP0_REG02__TCSCHEFBACK: 5980 CP0_CHECK(disas_mt_available(ctx)); 5981 gen_helper_mtc0_tcschefback(tcg_env, arg); 5982 register_name = "TCScheFBack"; 5983 break; 5984 default: 5985 goto cp0_unimplemented; 5986 } 5987 break; 5988 case CP0_REGISTER_03: 5989 switch (sel) { 5990 case CP0_REG03__ENTRYLO1: 5991 gen_helper_mtc0_entrylo1(tcg_env, arg); 5992 register_name = "EntryLo1"; 5993 break; 5994 case CP0_REG03__GLOBALNUM: 5995 CP0_CHECK(ctx->vp); 5996 /* ignored */ 5997 register_name = "GlobalNumber"; 5998 break; 5999 default: 6000 goto cp0_unimplemented; 6001 } 6002 break; 6003 case CP0_REGISTER_04: 6004 switch (sel) { 6005 case CP0_REG04__CONTEXT: 6006 gen_helper_mtc0_context(tcg_env, arg); 6007 register_name = "Context"; 6008 break; 6009 case CP0_REG04__CONTEXTCONFIG: 6010 /* SmartMIPS ASE */ 6011 /* gen_helper_mtc0_contextconfig(arg); */ 6012 register_name = "ContextConfig"; 6013 goto cp0_unimplemented; 6014 case CP0_REG04__USERLOCAL: 6015 CP0_CHECK(ctx->ulri); 6016 tcg_gen_st_tl(arg, tcg_env, 6017 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6018 register_name = "UserLocal"; 6019 break; 6020 case CP0_REG04__MMID: 6021 CP0_CHECK(ctx->mi); 6022 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 6023 register_name = "MMID"; 6024 break; 6025 default: 6026 goto cp0_unimplemented; 6027 } 6028 break; 6029 case CP0_REGISTER_05: 6030 switch (sel) { 6031 case CP0_REG05__PAGEMASK: 6032 gen_helper_mtc0_pagemask(tcg_env, arg); 6033 register_name = "PageMask"; 6034 break; 6035 case CP0_REG05__PAGEGRAIN: 6036 check_insn(ctx, ISA_MIPS_R2); 6037 gen_helper_mtc0_pagegrain(tcg_env, arg); 6038 register_name = "PageGrain"; 6039 ctx->base.is_jmp = DISAS_STOP; 6040 break; 6041 case CP0_REG05__SEGCTL0: 6042 CP0_CHECK(ctx->sc); 6043 gen_helper_mtc0_segctl0(tcg_env, arg); 6044 register_name = "SegCtl0"; 6045 break; 6046 case CP0_REG05__SEGCTL1: 6047 CP0_CHECK(ctx->sc); 6048 gen_helper_mtc0_segctl1(tcg_env, arg); 6049 register_name = "SegCtl1"; 6050 break; 6051 case CP0_REG05__SEGCTL2: 6052 CP0_CHECK(ctx->sc); 6053 gen_helper_mtc0_segctl2(tcg_env, arg); 6054 register_name = "SegCtl2"; 6055 break; 6056 case CP0_REG05__PWBASE: 6057 check_pw(ctx); 6058 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 6059 register_name = "PWBase"; 6060 break; 6061 case CP0_REG05__PWFIELD: 6062 check_pw(ctx); 6063 gen_helper_mtc0_pwfield(tcg_env, arg); 6064 register_name = "PWField"; 6065 break; 6066 case CP0_REG05__PWSIZE: 6067 check_pw(ctx); 6068 gen_helper_mtc0_pwsize(tcg_env, arg); 6069 register_name = "PWSize"; 6070 break; 6071 default: 6072 goto cp0_unimplemented; 6073 } 6074 break; 6075 case CP0_REGISTER_06: 6076 switch (sel) { 6077 case CP0_REG06__WIRED: 6078 gen_helper_mtc0_wired(tcg_env, arg); 6079 register_name = "Wired"; 6080 break; 6081 case CP0_REG06__SRSCONF0: 6082 check_insn(ctx, ISA_MIPS_R2); 6083 gen_helper_mtc0_srsconf0(tcg_env, arg); 6084 register_name = "SRSConf0"; 6085 break; 6086 case CP0_REG06__SRSCONF1: 6087 check_insn(ctx, ISA_MIPS_R2); 6088 gen_helper_mtc0_srsconf1(tcg_env, arg); 6089 register_name = "SRSConf1"; 6090 break; 6091 case CP0_REG06__SRSCONF2: 6092 check_insn(ctx, ISA_MIPS_R2); 6093 gen_helper_mtc0_srsconf2(tcg_env, arg); 6094 register_name = "SRSConf2"; 6095 break; 6096 case CP0_REG06__SRSCONF3: 6097 check_insn(ctx, ISA_MIPS_R2); 6098 gen_helper_mtc0_srsconf3(tcg_env, arg); 6099 register_name = "SRSConf3"; 6100 break; 6101 case CP0_REG06__SRSCONF4: 6102 check_insn(ctx, ISA_MIPS_R2); 6103 gen_helper_mtc0_srsconf4(tcg_env, arg); 6104 register_name = "SRSConf4"; 6105 break; 6106 case CP0_REG06__PWCTL: 6107 check_pw(ctx); 6108 gen_helper_mtc0_pwctl(tcg_env, arg); 6109 register_name = "PWCtl"; 6110 break; 6111 default: 6112 goto cp0_unimplemented; 6113 } 6114 break; 6115 case CP0_REGISTER_07: 6116 switch (sel) { 6117 case CP0_REG07__HWRENA: 6118 check_insn(ctx, ISA_MIPS_R2); 6119 gen_helper_mtc0_hwrena(tcg_env, arg); 6120 ctx->base.is_jmp = DISAS_STOP; 6121 register_name = "HWREna"; 6122 break; 6123 default: 6124 goto cp0_unimplemented; 6125 } 6126 break; 6127 case CP0_REGISTER_08: 6128 switch (sel) { 6129 case CP0_REG08__BADVADDR: 6130 /* ignored */ 6131 register_name = "BadVAddr"; 6132 break; 6133 case CP0_REG08__BADINSTR: 6134 /* ignored */ 6135 register_name = "BadInstr"; 6136 break; 6137 case CP0_REG08__BADINSTRP: 6138 /* ignored */ 6139 register_name = "BadInstrP"; 6140 break; 6141 case CP0_REG08__BADINSTRX: 6142 /* ignored */ 6143 register_name = "BadInstrX"; 6144 break; 6145 default: 6146 goto cp0_unimplemented; 6147 } 6148 break; 6149 case CP0_REGISTER_09: 6150 switch (sel) { 6151 case CP0_REG09__COUNT: 6152 gen_helper_mtc0_count(tcg_env, arg); 6153 register_name = "Count"; 6154 break; 6155 default: 6156 goto cp0_unimplemented; 6157 } 6158 break; 6159 case CP0_REGISTER_10: 6160 switch (sel) { 6161 case CP0_REG10__ENTRYHI: 6162 gen_helper_mtc0_entryhi(tcg_env, arg); 6163 register_name = "EntryHi"; 6164 break; 6165 default: 6166 goto cp0_unimplemented; 6167 } 6168 break; 6169 case CP0_REGISTER_11: 6170 switch (sel) { 6171 case CP0_REG11__COMPARE: 6172 gen_helper_mtc0_compare(tcg_env, arg); 6173 register_name = "Compare"; 6174 break; 6175 /* 6,7 are implementation dependent */ 6176 default: 6177 goto cp0_unimplemented; 6178 } 6179 break; 6180 case CP0_REGISTER_12: 6181 switch (sel) { 6182 case CP0_REG12__STATUS: 6183 save_cpu_state(ctx, 1); 6184 gen_helper_mtc0_status(tcg_env, arg); 6185 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6186 gen_save_pc(ctx->base.pc_next + 4); 6187 ctx->base.is_jmp = DISAS_EXIT; 6188 register_name = "Status"; 6189 break; 6190 case CP0_REG12__INTCTL: 6191 check_insn(ctx, ISA_MIPS_R2); 6192 gen_helper_mtc0_intctl(tcg_env, arg); 6193 /* Stop translation as we may have switched the execution mode */ 6194 ctx->base.is_jmp = DISAS_STOP; 6195 register_name = "IntCtl"; 6196 break; 6197 case CP0_REG12__SRSCTL: 6198 check_insn(ctx, ISA_MIPS_R2); 6199 gen_helper_mtc0_srsctl(tcg_env, arg); 6200 /* Stop translation as we may have switched the execution mode */ 6201 ctx->base.is_jmp = DISAS_STOP; 6202 register_name = "SRSCtl"; 6203 break; 6204 case CP0_REG12__SRSMAP: 6205 check_insn(ctx, ISA_MIPS_R2); 6206 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6207 /* Stop translation as we may have switched the execution mode */ 6208 ctx->base.is_jmp = DISAS_STOP; 6209 register_name = "SRSMap"; 6210 break; 6211 default: 6212 goto cp0_unimplemented; 6213 } 6214 break; 6215 case CP0_REGISTER_13: 6216 switch (sel) { 6217 case CP0_REG13__CAUSE: 6218 save_cpu_state(ctx, 1); 6219 gen_helper_mtc0_cause(tcg_env, arg); 6220 /* 6221 * Stop translation as we may have triggered an interrupt. 6222 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6223 * translated code to check for pending interrupts. 6224 */ 6225 gen_save_pc(ctx->base.pc_next + 4); 6226 ctx->base.is_jmp = DISAS_EXIT; 6227 register_name = "Cause"; 6228 break; 6229 default: 6230 goto cp0_unimplemented; 6231 } 6232 break; 6233 case CP0_REGISTER_14: 6234 switch (sel) { 6235 case CP0_REG14__EPC: 6236 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 6237 register_name = "EPC"; 6238 break; 6239 default: 6240 goto cp0_unimplemented; 6241 } 6242 break; 6243 case CP0_REGISTER_15: 6244 switch (sel) { 6245 case CP0_REG15__PRID: 6246 /* ignored */ 6247 register_name = "PRid"; 6248 break; 6249 case CP0_REG15__EBASE: 6250 check_insn(ctx, ISA_MIPS_R2); 6251 gen_helper_mtc0_ebase(tcg_env, arg); 6252 register_name = "EBase"; 6253 break; 6254 default: 6255 goto cp0_unimplemented; 6256 } 6257 break; 6258 case CP0_REGISTER_16: 6259 switch (sel) { 6260 case CP0_REG16__CONFIG: 6261 gen_helper_mtc0_config0(tcg_env, arg); 6262 register_name = "Config"; 6263 /* Stop translation as we may have switched the execution mode */ 6264 ctx->base.is_jmp = DISAS_STOP; 6265 break; 6266 case CP0_REG16__CONFIG1: 6267 /* ignored, read only */ 6268 register_name = "Config1"; 6269 break; 6270 case CP0_REG16__CONFIG2: 6271 gen_helper_mtc0_config2(tcg_env, arg); 6272 register_name = "Config2"; 6273 /* Stop translation as we may have switched the execution mode */ 6274 ctx->base.is_jmp = DISAS_STOP; 6275 break; 6276 case CP0_REG16__CONFIG3: 6277 gen_helper_mtc0_config3(tcg_env, arg); 6278 register_name = "Config3"; 6279 /* Stop translation as we may have switched the execution mode */ 6280 ctx->base.is_jmp = DISAS_STOP; 6281 break; 6282 case CP0_REG16__CONFIG4: 6283 gen_helper_mtc0_config4(tcg_env, arg); 6284 register_name = "Config4"; 6285 ctx->base.is_jmp = DISAS_STOP; 6286 break; 6287 case CP0_REG16__CONFIG5: 6288 gen_helper_mtc0_config5(tcg_env, arg); 6289 register_name = "Config5"; 6290 /* Stop translation as we may have switched the execution mode */ 6291 ctx->base.is_jmp = DISAS_STOP; 6292 break; 6293 /* 6,7 are implementation dependent */ 6294 case CP0_REG16__CONFIG6: 6295 /* ignored */ 6296 register_name = "Config6"; 6297 break; 6298 case CP0_REG16__CONFIG7: 6299 /* ignored */ 6300 register_name = "Config7"; 6301 break; 6302 default: 6303 register_name = "Invalid config selector"; 6304 goto cp0_unimplemented; 6305 } 6306 break; 6307 case CP0_REGISTER_17: 6308 switch (sel) { 6309 case CP0_REG17__LLADDR: 6310 gen_helper_mtc0_lladdr(tcg_env, arg); 6311 register_name = "LLAddr"; 6312 break; 6313 case CP0_REG17__MAAR: 6314 CP0_CHECK(ctx->mrp); 6315 gen_helper_mtc0_maar(tcg_env, arg); 6316 register_name = "MAAR"; 6317 break; 6318 case CP0_REG17__MAARI: 6319 CP0_CHECK(ctx->mrp); 6320 gen_helper_mtc0_maari(tcg_env, arg); 6321 register_name = "MAARI"; 6322 break; 6323 default: 6324 goto cp0_unimplemented; 6325 } 6326 break; 6327 case CP0_REGISTER_18: 6328 switch (sel) { 6329 case CP0_REG18__WATCHLO0: 6330 case CP0_REG18__WATCHLO1: 6331 case CP0_REG18__WATCHLO2: 6332 case CP0_REG18__WATCHLO3: 6333 case CP0_REG18__WATCHLO4: 6334 case CP0_REG18__WATCHLO5: 6335 case CP0_REG18__WATCHLO6: 6336 case CP0_REG18__WATCHLO7: 6337 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6338 gen_helper_0e1i(mtc0_watchlo, arg, sel); 6339 register_name = "WatchLo"; 6340 break; 6341 default: 6342 goto cp0_unimplemented; 6343 } 6344 break; 6345 case CP0_REGISTER_19: 6346 switch (sel) { 6347 case CP0_REG19__WATCHHI0: 6348 case CP0_REG19__WATCHHI1: 6349 case CP0_REG19__WATCHHI2: 6350 case CP0_REG19__WATCHHI3: 6351 case CP0_REG19__WATCHHI4: 6352 case CP0_REG19__WATCHHI5: 6353 case CP0_REG19__WATCHHI6: 6354 case CP0_REG19__WATCHHI7: 6355 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6356 gen_helper_0e1i(mtc0_watchhi, arg, sel); 6357 register_name = "WatchHi"; 6358 break; 6359 default: 6360 goto cp0_unimplemented; 6361 } 6362 break; 6363 case CP0_REGISTER_20: 6364 switch (sel) { 6365 case CP0_REG20__XCONTEXT: 6366 #if defined(TARGET_MIPS64) 6367 check_insn(ctx, ISA_MIPS3); 6368 gen_helper_mtc0_xcontext(tcg_env, arg); 6369 register_name = "XContext"; 6370 break; 6371 #endif 6372 default: 6373 goto cp0_unimplemented; 6374 } 6375 break; 6376 case CP0_REGISTER_21: 6377 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6378 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6379 switch (sel) { 6380 case 0: 6381 gen_helper_mtc0_framemask(tcg_env, arg); 6382 register_name = "Framemask"; 6383 break; 6384 default: 6385 goto cp0_unimplemented; 6386 } 6387 break; 6388 case CP0_REGISTER_22: 6389 /* ignored */ 6390 register_name = "Diagnostic"; /* implementation dependent */ 6391 break; 6392 case CP0_REGISTER_23: 6393 switch (sel) { 6394 case CP0_REG23__DEBUG: 6395 gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */ 6396 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6397 gen_save_pc(ctx->base.pc_next + 4); 6398 ctx->base.is_jmp = DISAS_EXIT; 6399 register_name = "Debug"; 6400 break; 6401 case CP0_REG23__TRACECONTROL: 6402 /* PDtrace support */ 6403 /* gen_helper_mtc0_tracecontrol(tcg_env, arg); */ 6404 register_name = "TraceControl"; 6405 /* Stop translation as we may have switched the execution mode */ 6406 ctx->base.is_jmp = DISAS_STOP; 6407 goto cp0_unimplemented; 6408 case CP0_REG23__TRACECONTROL2: 6409 /* PDtrace support */ 6410 /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */ 6411 register_name = "TraceControl2"; 6412 /* Stop translation as we may have switched the execution mode */ 6413 ctx->base.is_jmp = DISAS_STOP; 6414 goto cp0_unimplemented; 6415 case CP0_REG23__USERTRACEDATA1: 6416 /* Stop translation as we may have switched the execution mode */ 6417 ctx->base.is_jmp = DISAS_STOP; 6418 /* PDtrace support */ 6419 /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/ 6420 register_name = "UserTraceData"; 6421 /* Stop translation as we may have switched the execution mode */ 6422 ctx->base.is_jmp = DISAS_STOP; 6423 goto cp0_unimplemented; 6424 case CP0_REG23__TRACEIBPC: 6425 /* PDtrace support */ 6426 /* gen_helper_mtc0_traceibpc(tcg_env, arg); */ 6427 /* Stop translation as we may have switched the execution mode */ 6428 ctx->base.is_jmp = DISAS_STOP; 6429 register_name = "TraceIBPC"; 6430 goto cp0_unimplemented; 6431 case CP0_REG23__TRACEDBPC: 6432 /* PDtrace support */ 6433 /* gen_helper_mtc0_tracedbpc(tcg_env, arg); */ 6434 /* Stop translation as we may have switched the execution mode */ 6435 ctx->base.is_jmp = DISAS_STOP; 6436 register_name = "TraceDBPC"; 6437 goto cp0_unimplemented; 6438 default: 6439 goto cp0_unimplemented; 6440 } 6441 break; 6442 case CP0_REGISTER_24: 6443 switch (sel) { 6444 case CP0_REG24__DEPC: 6445 /* EJTAG support */ 6446 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 6447 register_name = "DEPC"; 6448 break; 6449 default: 6450 goto cp0_unimplemented; 6451 } 6452 break; 6453 case CP0_REGISTER_25: 6454 switch (sel) { 6455 case CP0_REG25__PERFCTL0: 6456 gen_helper_mtc0_performance0(tcg_env, arg); 6457 register_name = "Performance0"; 6458 break; 6459 case CP0_REG25__PERFCNT0: 6460 /* gen_helper_mtc0_performance1(arg); */ 6461 register_name = "Performance1"; 6462 goto cp0_unimplemented; 6463 case CP0_REG25__PERFCTL1: 6464 /* gen_helper_mtc0_performance2(arg); */ 6465 register_name = "Performance2"; 6466 goto cp0_unimplemented; 6467 case CP0_REG25__PERFCNT1: 6468 /* gen_helper_mtc0_performance3(arg); */ 6469 register_name = "Performance3"; 6470 goto cp0_unimplemented; 6471 case CP0_REG25__PERFCTL2: 6472 /* gen_helper_mtc0_performance4(arg); */ 6473 register_name = "Performance4"; 6474 goto cp0_unimplemented; 6475 case CP0_REG25__PERFCNT2: 6476 /* gen_helper_mtc0_performance5(arg); */ 6477 register_name = "Performance5"; 6478 goto cp0_unimplemented; 6479 case CP0_REG25__PERFCTL3: 6480 /* gen_helper_mtc0_performance6(arg); */ 6481 register_name = "Performance6"; 6482 goto cp0_unimplemented; 6483 case CP0_REG25__PERFCNT3: 6484 /* gen_helper_mtc0_performance7(arg); */ 6485 register_name = "Performance7"; 6486 goto cp0_unimplemented; 6487 default: 6488 goto cp0_unimplemented; 6489 } 6490 break; 6491 case CP0_REGISTER_26: 6492 switch (sel) { 6493 case CP0_REG26__ERRCTL: 6494 gen_helper_mtc0_errctl(tcg_env, arg); 6495 ctx->base.is_jmp = DISAS_STOP; 6496 register_name = "ErrCtl"; 6497 break; 6498 default: 6499 goto cp0_unimplemented; 6500 } 6501 break; 6502 case CP0_REGISTER_27: 6503 switch (sel) { 6504 case CP0_REG27__CACHERR: 6505 /* ignored */ 6506 register_name = "CacheErr"; 6507 break; 6508 default: 6509 goto cp0_unimplemented; 6510 } 6511 break; 6512 case CP0_REGISTER_28: 6513 switch (sel) { 6514 case CP0_REG28__TAGLO: 6515 case CP0_REG28__TAGLO1: 6516 case CP0_REG28__TAGLO2: 6517 case CP0_REG28__TAGLO3: 6518 gen_helper_mtc0_taglo(tcg_env, arg); 6519 register_name = "TagLo"; 6520 break; 6521 case CP0_REG28__DATALO: 6522 case CP0_REG28__DATALO1: 6523 case CP0_REG28__DATALO2: 6524 case CP0_REG28__DATALO3: 6525 gen_helper_mtc0_datalo(tcg_env, arg); 6526 register_name = "DataLo"; 6527 break; 6528 default: 6529 goto cp0_unimplemented; 6530 } 6531 break; 6532 case CP0_REGISTER_29: 6533 switch (sel) { 6534 case CP0_REG29__TAGHI: 6535 case CP0_REG29__TAGHI1: 6536 case CP0_REG29__TAGHI2: 6537 case CP0_REG29__TAGHI3: 6538 gen_helper_mtc0_taghi(tcg_env, arg); 6539 register_name = "TagHi"; 6540 break; 6541 case CP0_REG29__DATAHI: 6542 case CP0_REG29__DATAHI1: 6543 case CP0_REG29__DATAHI2: 6544 case CP0_REG29__DATAHI3: 6545 gen_helper_mtc0_datahi(tcg_env, arg); 6546 register_name = "DataHi"; 6547 break; 6548 default: 6549 register_name = "invalid sel"; 6550 goto cp0_unimplemented; 6551 } 6552 break; 6553 case CP0_REGISTER_30: 6554 switch (sel) { 6555 case CP0_REG30__ERROREPC: 6556 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 6557 register_name = "ErrorEPC"; 6558 break; 6559 default: 6560 goto cp0_unimplemented; 6561 } 6562 break; 6563 case CP0_REGISTER_31: 6564 switch (sel) { 6565 case CP0_REG31__DESAVE: 6566 /* EJTAG support */ 6567 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 6568 register_name = "DESAVE"; 6569 break; 6570 case CP0_REG31__KSCRATCH1: 6571 case CP0_REG31__KSCRATCH2: 6572 case CP0_REG31__KSCRATCH3: 6573 case CP0_REG31__KSCRATCH4: 6574 case CP0_REG31__KSCRATCH5: 6575 case CP0_REG31__KSCRATCH6: 6576 CP0_CHECK(ctx->kscrexist & (1 << sel)); 6577 tcg_gen_st_tl(arg, tcg_env, 6578 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 6579 register_name = "KScratch"; 6580 break; 6581 default: 6582 goto cp0_unimplemented; 6583 } 6584 break; 6585 default: 6586 goto cp0_unimplemented; 6587 } 6588 trace_mips_translate_c0("mtc0", register_name, reg, sel); 6589 6590 /* For simplicity assume that all writes can cause interrupts. */ 6591 if (icount) { 6592 /* 6593 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6594 * translated code to check for pending interrupts. 6595 */ 6596 gen_save_pc(ctx->base.pc_next + 4); 6597 ctx->base.is_jmp = DISAS_EXIT; 6598 } 6599 return; 6600 6601 cp0_unimplemented: 6602 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", 6603 register_name, reg, sel); 6604 } 6605 6606 #if defined(TARGET_MIPS64) 6607 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 6608 { 6609 const char *register_name = "invalid"; 6610 6611 if (sel != 0) { 6612 check_insn(ctx, ISA_MIPS_R1); 6613 } 6614 6615 switch (reg) { 6616 case CP0_REGISTER_00: 6617 switch (sel) { 6618 case CP0_REG00__INDEX: 6619 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 6620 register_name = "Index"; 6621 break; 6622 case CP0_REG00__MVPCONTROL: 6623 CP0_CHECK(disas_mt_available(ctx)); 6624 gen_helper_mfc0_mvpcontrol(arg, tcg_env); 6625 register_name = "MVPControl"; 6626 break; 6627 case CP0_REG00__MVPCONF0: 6628 CP0_CHECK(disas_mt_available(ctx)); 6629 gen_helper_mfc0_mvpconf0(arg, tcg_env); 6630 register_name = "MVPConf0"; 6631 break; 6632 case CP0_REG00__MVPCONF1: 6633 CP0_CHECK(disas_mt_available(ctx)); 6634 gen_helper_mfc0_mvpconf1(arg, tcg_env); 6635 register_name = "MVPConf1"; 6636 break; 6637 case CP0_REG00__VPCONTROL: 6638 CP0_CHECK(ctx->vp); 6639 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 6640 register_name = "VPControl"; 6641 break; 6642 default: 6643 goto cp0_unimplemented; 6644 } 6645 break; 6646 case CP0_REGISTER_01: 6647 switch (sel) { 6648 case CP0_REG01__RANDOM: 6649 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6650 gen_helper_mfc0_random(arg, tcg_env); 6651 register_name = "Random"; 6652 break; 6653 case CP0_REG01__VPECONTROL: 6654 CP0_CHECK(disas_mt_available(ctx)); 6655 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 6656 register_name = "VPEControl"; 6657 break; 6658 case CP0_REG01__VPECONF0: 6659 CP0_CHECK(disas_mt_available(ctx)); 6660 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 6661 register_name = "VPEConf0"; 6662 break; 6663 case CP0_REG01__VPECONF1: 6664 CP0_CHECK(disas_mt_available(ctx)); 6665 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 6666 register_name = "VPEConf1"; 6667 break; 6668 case CP0_REG01__YQMASK: 6669 CP0_CHECK(disas_mt_available(ctx)); 6670 tcg_gen_ld_tl(arg, tcg_env, 6671 offsetof(CPUMIPSState, CP0_YQMask)); 6672 register_name = "YQMask"; 6673 break; 6674 case CP0_REG01__VPESCHEDULE: 6675 CP0_CHECK(disas_mt_available(ctx)); 6676 tcg_gen_ld_tl(arg, tcg_env, 6677 offsetof(CPUMIPSState, CP0_VPESchedule)); 6678 register_name = "VPESchedule"; 6679 break; 6680 case CP0_REG01__VPESCHEFBACK: 6681 CP0_CHECK(disas_mt_available(ctx)); 6682 tcg_gen_ld_tl(arg, tcg_env, 6683 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6684 register_name = "VPEScheFBack"; 6685 break; 6686 case CP0_REG01__VPEOPT: 6687 CP0_CHECK(disas_mt_available(ctx)); 6688 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 6689 register_name = "VPEOpt"; 6690 break; 6691 default: 6692 goto cp0_unimplemented; 6693 } 6694 break; 6695 case CP0_REGISTER_02: 6696 switch (sel) { 6697 case CP0_REG02__ENTRYLO0: 6698 tcg_gen_ld_tl(arg, tcg_env, 6699 offsetof(CPUMIPSState, CP0_EntryLo0)); 6700 register_name = "EntryLo0"; 6701 break; 6702 case CP0_REG02__TCSTATUS: 6703 CP0_CHECK(disas_mt_available(ctx)); 6704 gen_helper_mfc0_tcstatus(arg, tcg_env); 6705 register_name = "TCStatus"; 6706 break; 6707 case CP0_REG02__TCBIND: 6708 CP0_CHECK(disas_mt_available(ctx)); 6709 gen_helper_mfc0_tcbind(arg, tcg_env); 6710 register_name = "TCBind"; 6711 break; 6712 case CP0_REG02__TCRESTART: 6713 CP0_CHECK(disas_mt_available(ctx)); 6714 gen_helper_dmfc0_tcrestart(arg, tcg_env); 6715 register_name = "TCRestart"; 6716 break; 6717 case CP0_REG02__TCHALT: 6718 CP0_CHECK(disas_mt_available(ctx)); 6719 gen_helper_dmfc0_tchalt(arg, tcg_env); 6720 register_name = "TCHalt"; 6721 break; 6722 case CP0_REG02__TCCONTEXT: 6723 CP0_CHECK(disas_mt_available(ctx)); 6724 gen_helper_dmfc0_tccontext(arg, tcg_env); 6725 register_name = "TCContext"; 6726 break; 6727 case CP0_REG02__TCSCHEDULE: 6728 CP0_CHECK(disas_mt_available(ctx)); 6729 gen_helper_dmfc0_tcschedule(arg, tcg_env); 6730 register_name = "TCSchedule"; 6731 break; 6732 case CP0_REG02__TCSCHEFBACK: 6733 CP0_CHECK(disas_mt_available(ctx)); 6734 gen_helper_dmfc0_tcschefback(arg, tcg_env); 6735 register_name = "TCScheFBack"; 6736 break; 6737 default: 6738 goto cp0_unimplemented; 6739 } 6740 break; 6741 case CP0_REGISTER_03: 6742 switch (sel) { 6743 case CP0_REG03__ENTRYLO1: 6744 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 6745 register_name = "EntryLo1"; 6746 break; 6747 case CP0_REG03__GLOBALNUM: 6748 CP0_CHECK(ctx->vp); 6749 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 6750 register_name = "GlobalNumber"; 6751 break; 6752 default: 6753 goto cp0_unimplemented; 6754 } 6755 break; 6756 case CP0_REGISTER_04: 6757 switch (sel) { 6758 case CP0_REG04__CONTEXT: 6759 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context)); 6760 register_name = "Context"; 6761 break; 6762 case CP0_REG04__CONTEXTCONFIG: 6763 /* SmartMIPS ASE */ 6764 /* gen_helper_dmfc0_contextconfig(arg); */ 6765 register_name = "ContextConfig"; 6766 goto cp0_unimplemented; 6767 case CP0_REG04__USERLOCAL: 6768 CP0_CHECK(ctx->ulri); 6769 tcg_gen_ld_tl(arg, tcg_env, 6770 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6771 register_name = "UserLocal"; 6772 break; 6773 case CP0_REG04__MMID: 6774 CP0_CHECK(ctx->mi); 6775 gen_helper_mtc0_memorymapid(tcg_env, arg); 6776 register_name = "MMID"; 6777 break; 6778 default: 6779 goto cp0_unimplemented; 6780 } 6781 break; 6782 case CP0_REGISTER_05: 6783 switch (sel) { 6784 case CP0_REG05__PAGEMASK: 6785 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 6786 register_name = "PageMask"; 6787 break; 6788 case CP0_REG05__PAGEGRAIN: 6789 check_insn(ctx, ISA_MIPS_R2); 6790 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 6791 register_name = "PageGrain"; 6792 break; 6793 case CP0_REG05__SEGCTL0: 6794 CP0_CHECK(ctx->sc); 6795 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 6796 register_name = "SegCtl0"; 6797 break; 6798 case CP0_REG05__SEGCTL1: 6799 CP0_CHECK(ctx->sc); 6800 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 6801 register_name = "SegCtl1"; 6802 break; 6803 case CP0_REG05__SEGCTL2: 6804 CP0_CHECK(ctx->sc); 6805 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 6806 register_name = "SegCtl2"; 6807 break; 6808 case CP0_REG05__PWBASE: 6809 check_pw(ctx); 6810 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase)); 6811 register_name = "PWBase"; 6812 break; 6813 case CP0_REG05__PWFIELD: 6814 check_pw(ctx); 6815 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWField)); 6816 register_name = "PWField"; 6817 break; 6818 case CP0_REG05__PWSIZE: 6819 check_pw(ctx); 6820 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWSize)); 6821 register_name = "PWSize"; 6822 break; 6823 default: 6824 goto cp0_unimplemented; 6825 } 6826 break; 6827 case CP0_REGISTER_06: 6828 switch (sel) { 6829 case CP0_REG06__WIRED: 6830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 6831 register_name = "Wired"; 6832 break; 6833 case CP0_REG06__SRSCONF0: 6834 check_insn(ctx, ISA_MIPS_R2); 6835 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 6836 register_name = "SRSConf0"; 6837 break; 6838 case CP0_REG06__SRSCONF1: 6839 check_insn(ctx, ISA_MIPS_R2); 6840 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 6841 register_name = "SRSConf1"; 6842 break; 6843 case CP0_REG06__SRSCONF2: 6844 check_insn(ctx, ISA_MIPS_R2); 6845 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 6846 register_name = "SRSConf2"; 6847 break; 6848 case CP0_REG06__SRSCONF3: 6849 check_insn(ctx, ISA_MIPS_R2); 6850 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 6851 register_name = "SRSConf3"; 6852 break; 6853 case CP0_REG06__SRSCONF4: 6854 check_insn(ctx, ISA_MIPS_R2); 6855 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 6856 register_name = "SRSConf4"; 6857 break; 6858 case CP0_REG06__PWCTL: 6859 check_pw(ctx); 6860 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 6861 register_name = "PWCtl"; 6862 break; 6863 default: 6864 goto cp0_unimplemented; 6865 } 6866 break; 6867 case CP0_REGISTER_07: 6868 switch (sel) { 6869 case CP0_REG07__HWRENA: 6870 check_insn(ctx, ISA_MIPS_R2); 6871 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 6872 register_name = "HWREna"; 6873 break; 6874 default: 6875 goto cp0_unimplemented; 6876 } 6877 break; 6878 case CP0_REGISTER_08: 6879 switch (sel) { 6880 case CP0_REG08__BADVADDR: 6881 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 6882 register_name = "BadVAddr"; 6883 break; 6884 case CP0_REG08__BADINSTR: 6885 CP0_CHECK(ctx->bi); 6886 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 6887 register_name = "BadInstr"; 6888 break; 6889 case CP0_REG08__BADINSTRP: 6890 CP0_CHECK(ctx->bp); 6891 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 6892 register_name = "BadInstrP"; 6893 break; 6894 case CP0_REG08__BADINSTRX: 6895 CP0_CHECK(ctx->bi); 6896 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 6897 tcg_gen_andi_tl(arg, arg, ~0xffff); 6898 register_name = "BadInstrX"; 6899 break; 6900 default: 6901 goto cp0_unimplemented; 6902 } 6903 break; 6904 case CP0_REGISTER_09: 6905 switch (sel) { 6906 case CP0_REG09__COUNT: 6907 /* Mark as an IO operation because we read the time. */ 6908 translator_io_start(&ctx->base); 6909 gen_helper_mfc0_count(arg, tcg_env); 6910 /* 6911 * Break the TB to be able to take timer interrupts immediately 6912 * after reading count. DISAS_STOP isn't sufficient, we need to 6913 * ensure we break completely out of translated code. 6914 */ 6915 gen_save_pc(ctx->base.pc_next + 4); 6916 ctx->base.is_jmp = DISAS_EXIT; 6917 register_name = "Count"; 6918 break; 6919 default: 6920 goto cp0_unimplemented; 6921 } 6922 break; 6923 case CP0_REGISTER_10: 6924 switch (sel) { 6925 case CP0_REG10__ENTRYHI: 6926 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi)); 6927 register_name = "EntryHi"; 6928 break; 6929 default: 6930 goto cp0_unimplemented; 6931 } 6932 break; 6933 case CP0_REGISTER_11: 6934 switch (sel) { 6935 case CP0_REG11__COMPARE: 6936 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 6937 register_name = "Compare"; 6938 break; 6939 /* 6,7 are implementation dependent */ 6940 default: 6941 goto cp0_unimplemented; 6942 } 6943 break; 6944 case CP0_REGISTER_12: 6945 switch (sel) { 6946 case CP0_REG12__STATUS: 6947 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 6948 register_name = "Status"; 6949 break; 6950 case CP0_REG12__INTCTL: 6951 check_insn(ctx, ISA_MIPS_R2); 6952 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 6953 register_name = "IntCtl"; 6954 break; 6955 case CP0_REG12__SRSCTL: 6956 check_insn(ctx, ISA_MIPS_R2); 6957 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 6958 register_name = "SRSCtl"; 6959 break; 6960 case CP0_REG12__SRSMAP: 6961 check_insn(ctx, ISA_MIPS_R2); 6962 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6963 register_name = "SRSMap"; 6964 break; 6965 default: 6966 goto cp0_unimplemented; 6967 } 6968 break; 6969 case CP0_REGISTER_13: 6970 switch (sel) { 6971 case CP0_REG13__CAUSE: 6972 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 6973 register_name = "Cause"; 6974 break; 6975 default: 6976 goto cp0_unimplemented; 6977 } 6978 break; 6979 case CP0_REGISTER_14: 6980 switch (sel) { 6981 case CP0_REG14__EPC: 6982 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 6983 register_name = "EPC"; 6984 break; 6985 default: 6986 goto cp0_unimplemented; 6987 } 6988 break; 6989 case CP0_REGISTER_15: 6990 switch (sel) { 6991 case CP0_REG15__PRID: 6992 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 6993 register_name = "PRid"; 6994 break; 6995 case CP0_REG15__EBASE: 6996 check_insn(ctx, ISA_MIPS_R2); 6997 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase)); 6998 register_name = "EBase"; 6999 break; 7000 case CP0_REG15__CMGCRBASE: 7001 check_insn(ctx, ISA_MIPS_R2); 7002 CP0_CHECK(ctx->cmgcr); 7003 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 7004 register_name = "CMGCRBase"; 7005 break; 7006 default: 7007 goto cp0_unimplemented; 7008 } 7009 break; 7010 case CP0_REGISTER_16: 7011 switch (sel) { 7012 case CP0_REG16__CONFIG: 7013 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 7014 register_name = "Config"; 7015 break; 7016 case CP0_REG16__CONFIG1: 7017 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 7018 register_name = "Config1"; 7019 break; 7020 case CP0_REG16__CONFIG2: 7021 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 7022 register_name = "Config2"; 7023 break; 7024 case CP0_REG16__CONFIG3: 7025 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 7026 register_name = "Config3"; 7027 break; 7028 case CP0_REG16__CONFIG4: 7029 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 7030 register_name = "Config4"; 7031 break; 7032 case CP0_REG16__CONFIG5: 7033 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 7034 register_name = "Config5"; 7035 break; 7036 /* 6,7 are implementation dependent */ 7037 case CP0_REG16__CONFIG6: 7038 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 7039 register_name = "Config6"; 7040 break; 7041 case CP0_REG16__CONFIG7: 7042 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 7043 register_name = "Config7"; 7044 break; 7045 default: 7046 goto cp0_unimplemented; 7047 } 7048 break; 7049 case CP0_REGISTER_17: 7050 switch (sel) { 7051 case CP0_REG17__LLADDR: 7052 gen_helper_dmfc0_lladdr(arg, tcg_env); 7053 register_name = "LLAddr"; 7054 break; 7055 case CP0_REG17__MAAR: 7056 CP0_CHECK(ctx->mrp); 7057 gen_helper_dmfc0_maar(arg, tcg_env); 7058 register_name = "MAAR"; 7059 break; 7060 case CP0_REG17__MAARI: 7061 CP0_CHECK(ctx->mrp); 7062 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 7063 register_name = "MAARI"; 7064 break; 7065 default: 7066 goto cp0_unimplemented; 7067 } 7068 break; 7069 case CP0_REGISTER_18: 7070 switch (sel) { 7071 case CP0_REG18__WATCHLO0: 7072 case CP0_REG18__WATCHLO1: 7073 case CP0_REG18__WATCHLO2: 7074 case CP0_REG18__WATCHLO3: 7075 case CP0_REG18__WATCHLO4: 7076 case CP0_REG18__WATCHLO5: 7077 case CP0_REG18__WATCHLO6: 7078 case CP0_REG18__WATCHLO7: 7079 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7080 gen_helper_1e0i(dmfc0_watchlo, arg, sel); 7081 register_name = "WatchLo"; 7082 break; 7083 default: 7084 goto cp0_unimplemented; 7085 } 7086 break; 7087 case CP0_REGISTER_19: 7088 switch (sel) { 7089 case CP0_REG19__WATCHHI0: 7090 case CP0_REG19__WATCHHI1: 7091 case CP0_REG19__WATCHHI2: 7092 case CP0_REG19__WATCHHI3: 7093 case CP0_REG19__WATCHHI4: 7094 case CP0_REG19__WATCHHI5: 7095 case CP0_REG19__WATCHHI6: 7096 case CP0_REG19__WATCHHI7: 7097 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7098 gen_helper_1e0i(dmfc0_watchhi, arg, sel); 7099 register_name = "WatchHi"; 7100 break; 7101 default: 7102 goto cp0_unimplemented; 7103 } 7104 break; 7105 case CP0_REGISTER_20: 7106 switch (sel) { 7107 case CP0_REG20__XCONTEXT: 7108 check_insn(ctx, ISA_MIPS3); 7109 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext)); 7110 register_name = "XContext"; 7111 break; 7112 default: 7113 goto cp0_unimplemented; 7114 } 7115 break; 7116 case CP0_REGISTER_21: 7117 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7118 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7119 switch (sel) { 7120 case 0: 7121 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 7122 register_name = "Framemask"; 7123 break; 7124 default: 7125 goto cp0_unimplemented; 7126 } 7127 break; 7128 case CP0_REGISTER_22: 7129 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7130 register_name = "'Diagnostic"; /* implementation dependent */ 7131 break; 7132 case CP0_REGISTER_23: 7133 switch (sel) { 7134 case CP0_REG23__DEBUG: 7135 gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */ 7136 register_name = "Debug"; 7137 break; 7138 case CP0_REG23__TRACECONTROL: 7139 /* PDtrace support */ 7140 /* gen_helper_dmfc0_tracecontrol(arg, tcg_env); */ 7141 register_name = "TraceControl"; 7142 goto cp0_unimplemented; 7143 case CP0_REG23__TRACECONTROL2: 7144 /* PDtrace support */ 7145 /* gen_helper_dmfc0_tracecontrol2(arg, tcg_env); */ 7146 register_name = "TraceControl2"; 7147 goto cp0_unimplemented; 7148 case CP0_REG23__USERTRACEDATA1: 7149 /* PDtrace support */ 7150 /* gen_helper_dmfc0_usertracedata1(arg, tcg_env);*/ 7151 register_name = "UserTraceData1"; 7152 goto cp0_unimplemented; 7153 case CP0_REG23__TRACEIBPC: 7154 /* PDtrace support */ 7155 /* gen_helper_dmfc0_traceibpc(arg, tcg_env); */ 7156 register_name = "TraceIBPC"; 7157 goto cp0_unimplemented; 7158 case CP0_REG23__TRACEDBPC: 7159 /* PDtrace support */ 7160 /* gen_helper_dmfc0_tracedbpc(arg, tcg_env); */ 7161 register_name = "TraceDBPC"; 7162 goto cp0_unimplemented; 7163 default: 7164 goto cp0_unimplemented; 7165 } 7166 break; 7167 case CP0_REGISTER_24: 7168 switch (sel) { 7169 case CP0_REG24__DEPC: 7170 /* EJTAG support */ 7171 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 7172 register_name = "DEPC"; 7173 break; 7174 default: 7175 goto cp0_unimplemented; 7176 } 7177 break; 7178 case CP0_REGISTER_25: 7179 switch (sel) { 7180 case CP0_REG25__PERFCTL0: 7181 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 7182 register_name = "Performance0"; 7183 break; 7184 case CP0_REG25__PERFCNT0: 7185 /* gen_helper_dmfc0_performance1(arg); */ 7186 register_name = "Performance1"; 7187 goto cp0_unimplemented; 7188 case CP0_REG25__PERFCTL1: 7189 /* gen_helper_dmfc0_performance2(arg); */ 7190 register_name = "Performance2"; 7191 goto cp0_unimplemented; 7192 case CP0_REG25__PERFCNT1: 7193 /* gen_helper_dmfc0_performance3(arg); */ 7194 register_name = "Performance3"; 7195 goto cp0_unimplemented; 7196 case CP0_REG25__PERFCTL2: 7197 /* gen_helper_dmfc0_performance4(arg); */ 7198 register_name = "Performance4"; 7199 goto cp0_unimplemented; 7200 case CP0_REG25__PERFCNT2: 7201 /* gen_helper_dmfc0_performance5(arg); */ 7202 register_name = "Performance5"; 7203 goto cp0_unimplemented; 7204 case CP0_REG25__PERFCTL3: 7205 /* gen_helper_dmfc0_performance6(arg); */ 7206 register_name = "Performance6"; 7207 goto cp0_unimplemented; 7208 case CP0_REG25__PERFCNT3: 7209 /* gen_helper_dmfc0_performance7(arg); */ 7210 register_name = "Performance7"; 7211 goto cp0_unimplemented; 7212 default: 7213 goto cp0_unimplemented; 7214 } 7215 break; 7216 case CP0_REGISTER_26: 7217 switch (sel) { 7218 case CP0_REG26__ERRCTL: 7219 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 7220 register_name = "ErrCtl"; 7221 break; 7222 default: 7223 goto cp0_unimplemented; 7224 } 7225 break; 7226 case CP0_REGISTER_27: 7227 switch (sel) { 7228 /* ignored */ 7229 case CP0_REG27__CACHERR: 7230 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7231 register_name = "CacheErr"; 7232 break; 7233 default: 7234 goto cp0_unimplemented; 7235 } 7236 break; 7237 case CP0_REGISTER_28: 7238 switch (sel) { 7239 case CP0_REG28__TAGLO: 7240 case CP0_REG28__TAGLO1: 7241 case CP0_REG28__TAGLO2: 7242 case CP0_REG28__TAGLO3: 7243 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 7244 register_name = "TagLo"; 7245 break; 7246 case CP0_REG28__DATALO: 7247 case CP0_REG28__DATALO1: 7248 case CP0_REG28__DATALO2: 7249 case CP0_REG28__DATALO3: 7250 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 7251 register_name = "DataLo"; 7252 break; 7253 default: 7254 goto cp0_unimplemented; 7255 } 7256 break; 7257 case CP0_REGISTER_29: 7258 switch (sel) { 7259 case CP0_REG29__TAGHI: 7260 case CP0_REG29__TAGHI1: 7261 case CP0_REG29__TAGHI2: 7262 case CP0_REG29__TAGHI3: 7263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 7264 register_name = "TagHi"; 7265 break; 7266 case CP0_REG29__DATAHI: 7267 case CP0_REG29__DATAHI1: 7268 case CP0_REG29__DATAHI2: 7269 case CP0_REG29__DATAHI3: 7270 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 7271 register_name = "DataHi"; 7272 break; 7273 default: 7274 goto cp0_unimplemented; 7275 } 7276 break; 7277 case CP0_REGISTER_30: 7278 switch (sel) { 7279 case CP0_REG30__ERROREPC: 7280 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7281 register_name = "ErrorEPC"; 7282 break; 7283 default: 7284 goto cp0_unimplemented; 7285 } 7286 break; 7287 case CP0_REGISTER_31: 7288 switch (sel) { 7289 case CP0_REG31__DESAVE: 7290 /* EJTAG support */ 7291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7292 register_name = "DESAVE"; 7293 break; 7294 case CP0_REG31__KSCRATCH1: 7295 case CP0_REG31__KSCRATCH2: 7296 case CP0_REG31__KSCRATCH3: 7297 case CP0_REG31__KSCRATCH4: 7298 case CP0_REG31__KSCRATCH5: 7299 case CP0_REG31__KSCRATCH6: 7300 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7301 tcg_gen_ld_tl(arg, tcg_env, 7302 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7303 register_name = "KScratch"; 7304 break; 7305 default: 7306 goto cp0_unimplemented; 7307 } 7308 break; 7309 default: 7310 goto cp0_unimplemented; 7311 } 7312 trace_mips_translate_c0("dmfc0", register_name, reg, sel); 7313 return; 7314 7315 cp0_unimplemented: 7316 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", 7317 register_name, reg, sel); 7318 gen_mfc0_unimplemented(ctx, arg); 7319 } 7320 7321 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7322 { 7323 const char *register_name = "invalid"; 7324 bool icount; 7325 7326 if (sel != 0) { 7327 check_insn(ctx, ISA_MIPS_R1); 7328 } 7329 7330 icount = translator_io_start(&ctx->base); 7331 7332 switch (reg) { 7333 case CP0_REGISTER_00: 7334 switch (sel) { 7335 case CP0_REG00__INDEX: 7336 gen_helper_mtc0_index(tcg_env, arg); 7337 register_name = "Index"; 7338 break; 7339 case CP0_REG00__MVPCONTROL: 7340 CP0_CHECK(disas_mt_available(ctx)); 7341 gen_helper_mtc0_mvpcontrol(tcg_env, arg); 7342 register_name = "MVPControl"; 7343 break; 7344 case CP0_REG00__MVPCONF0: 7345 CP0_CHECK(disas_mt_available(ctx)); 7346 /* ignored */ 7347 register_name = "MVPConf0"; 7348 break; 7349 case CP0_REG00__MVPCONF1: 7350 CP0_CHECK(disas_mt_available(ctx)); 7351 /* ignored */ 7352 register_name = "MVPConf1"; 7353 break; 7354 case CP0_REG00__VPCONTROL: 7355 CP0_CHECK(ctx->vp); 7356 /* ignored */ 7357 register_name = "VPControl"; 7358 break; 7359 default: 7360 goto cp0_unimplemented; 7361 } 7362 break; 7363 case CP0_REGISTER_01: 7364 switch (sel) { 7365 case CP0_REG01__RANDOM: 7366 /* ignored */ 7367 register_name = "Random"; 7368 break; 7369 case CP0_REG01__VPECONTROL: 7370 CP0_CHECK(disas_mt_available(ctx)); 7371 gen_helper_mtc0_vpecontrol(tcg_env, arg); 7372 register_name = "VPEControl"; 7373 break; 7374 case CP0_REG01__VPECONF0: 7375 CP0_CHECK(disas_mt_available(ctx)); 7376 gen_helper_mtc0_vpeconf0(tcg_env, arg); 7377 register_name = "VPEConf0"; 7378 break; 7379 case CP0_REG01__VPECONF1: 7380 CP0_CHECK(disas_mt_available(ctx)); 7381 gen_helper_mtc0_vpeconf1(tcg_env, arg); 7382 register_name = "VPEConf1"; 7383 break; 7384 case CP0_REG01__YQMASK: 7385 CP0_CHECK(disas_mt_available(ctx)); 7386 gen_helper_mtc0_yqmask(tcg_env, arg); 7387 register_name = "YQMask"; 7388 break; 7389 case CP0_REG01__VPESCHEDULE: 7390 CP0_CHECK(disas_mt_available(ctx)); 7391 tcg_gen_st_tl(arg, tcg_env, 7392 offsetof(CPUMIPSState, CP0_VPESchedule)); 7393 register_name = "VPESchedule"; 7394 break; 7395 case CP0_REG01__VPESCHEFBACK: 7396 CP0_CHECK(disas_mt_available(ctx)); 7397 tcg_gen_st_tl(arg, tcg_env, 7398 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7399 register_name = "VPEScheFBack"; 7400 break; 7401 case CP0_REG01__VPEOPT: 7402 CP0_CHECK(disas_mt_available(ctx)); 7403 gen_helper_mtc0_vpeopt(tcg_env, arg); 7404 register_name = "VPEOpt"; 7405 break; 7406 default: 7407 goto cp0_unimplemented; 7408 } 7409 break; 7410 case CP0_REGISTER_02: 7411 switch (sel) { 7412 case CP0_REG02__ENTRYLO0: 7413 gen_helper_dmtc0_entrylo0(tcg_env, arg); 7414 register_name = "EntryLo0"; 7415 break; 7416 case CP0_REG02__TCSTATUS: 7417 CP0_CHECK(disas_mt_available(ctx)); 7418 gen_helper_mtc0_tcstatus(tcg_env, arg); 7419 register_name = "TCStatus"; 7420 break; 7421 case CP0_REG02__TCBIND: 7422 CP0_CHECK(disas_mt_available(ctx)); 7423 gen_helper_mtc0_tcbind(tcg_env, arg); 7424 register_name = "TCBind"; 7425 break; 7426 case CP0_REG02__TCRESTART: 7427 CP0_CHECK(disas_mt_available(ctx)); 7428 gen_helper_mtc0_tcrestart(tcg_env, arg); 7429 register_name = "TCRestart"; 7430 break; 7431 case CP0_REG02__TCHALT: 7432 CP0_CHECK(disas_mt_available(ctx)); 7433 gen_helper_mtc0_tchalt(tcg_env, arg); 7434 register_name = "TCHalt"; 7435 break; 7436 case CP0_REG02__TCCONTEXT: 7437 CP0_CHECK(disas_mt_available(ctx)); 7438 gen_helper_mtc0_tccontext(tcg_env, arg); 7439 register_name = "TCContext"; 7440 break; 7441 case CP0_REG02__TCSCHEDULE: 7442 CP0_CHECK(disas_mt_available(ctx)); 7443 gen_helper_mtc0_tcschedule(tcg_env, arg); 7444 register_name = "TCSchedule"; 7445 break; 7446 case CP0_REG02__TCSCHEFBACK: 7447 CP0_CHECK(disas_mt_available(ctx)); 7448 gen_helper_mtc0_tcschefback(tcg_env, arg); 7449 register_name = "TCScheFBack"; 7450 break; 7451 default: 7452 goto cp0_unimplemented; 7453 } 7454 break; 7455 case CP0_REGISTER_03: 7456 switch (sel) { 7457 case CP0_REG03__ENTRYLO1: 7458 gen_helper_dmtc0_entrylo1(tcg_env, arg); 7459 register_name = "EntryLo1"; 7460 break; 7461 case CP0_REG03__GLOBALNUM: 7462 CP0_CHECK(ctx->vp); 7463 /* ignored */ 7464 register_name = "GlobalNumber"; 7465 break; 7466 default: 7467 goto cp0_unimplemented; 7468 } 7469 break; 7470 case CP0_REGISTER_04: 7471 switch (sel) { 7472 case CP0_REG04__CONTEXT: 7473 gen_helper_mtc0_context(tcg_env, arg); 7474 register_name = "Context"; 7475 break; 7476 case CP0_REG04__CONTEXTCONFIG: 7477 /* SmartMIPS ASE */ 7478 /* gen_helper_dmtc0_contextconfig(arg); */ 7479 register_name = "ContextConfig"; 7480 goto cp0_unimplemented; 7481 case CP0_REG04__USERLOCAL: 7482 CP0_CHECK(ctx->ulri); 7483 tcg_gen_st_tl(arg, tcg_env, 7484 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 7485 register_name = "UserLocal"; 7486 break; 7487 case CP0_REG04__MMID: 7488 CP0_CHECK(ctx->mi); 7489 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 7490 register_name = "MMID"; 7491 break; 7492 default: 7493 goto cp0_unimplemented; 7494 } 7495 break; 7496 case CP0_REGISTER_05: 7497 switch (sel) { 7498 case CP0_REG05__PAGEMASK: 7499 gen_helper_mtc0_pagemask(tcg_env, arg); 7500 register_name = "PageMask"; 7501 break; 7502 case CP0_REG05__PAGEGRAIN: 7503 check_insn(ctx, ISA_MIPS_R2); 7504 gen_helper_mtc0_pagegrain(tcg_env, arg); 7505 register_name = "PageGrain"; 7506 break; 7507 case CP0_REG05__SEGCTL0: 7508 CP0_CHECK(ctx->sc); 7509 gen_helper_mtc0_segctl0(tcg_env, arg); 7510 register_name = "SegCtl0"; 7511 break; 7512 case CP0_REG05__SEGCTL1: 7513 CP0_CHECK(ctx->sc); 7514 gen_helper_mtc0_segctl1(tcg_env, arg); 7515 register_name = "SegCtl1"; 7516 break; 7517 case CP0_REG05__SEGCTL2: 7518 CP0_CHECK(ctx->sc); 7519 gen_helper_mtc0_segctl2(tcg_env, arg); 7520 register_name = "SegCtl2"; 7521 break; 7522 case CP0_REG05__PWBASE: 7523 check_pw(ctx); 7524 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase)); 7525 register_name = "PWBase"; 7526 break; 7527 case CP0_REG05__PWFIELD: 7528 check_pw(ctx); 7529 gen_helper_mtc0_pwfield(tcg_env, arg); 7530 register_name = "PWField"; 7531 break; 7532 case CP0_REG05__PWSIZE: 7533 check_pw(ctx); 7534 gen_helper_mtc0_pwsize(tcg_env, arg); 7535 register_name = "PWSize"; 7536 break; 7537 default: 7538 goto cp0_unimplemented; 7539 } 7540 break; 7541 case CP0_REGISTER_06: 7542 switch (sel) { 7543 case CP0_REG06__WIRED: 7544 gen_helper_mtc0_wired(tcg_env, arg); 7545 register_name = "Wired"; 7546 break; 7547 case CP0_REG06__SRSCONF0: 7548 check_insn(ctx, ISA_MIPS_R2); 7549 gen_helper_mtc0_srsconf0(tcg_env, arg); 7550 register_name = "SRSConf0"; 7551 break; 7552 case CP0_REG06__SRSCONF1: 7553 check_insn(ctx, ISA_MIPS_R2); 7554 gen_helper_mtc0_srsconf1(tcg_env, arg); 7555 register_name = "SRSConf1"; 7556 break; 7557 case CP0_REG06__SRSCONF2: 7558 check_insn(ctx, ISA_MIPS_R2); 7559 gen_helper_mtc0_srsconf2(tcg_env, arg); 7560 register_name = "SRSConf2"; 7561 break; 7562 case CP0_REG06__SRSCONF3: 7563 check_insn(ctx, ISA_MIPS_R2); 7564 gen_helper_mtc0_srsconf3(tcg_env, arg); 7565 register_name = "SRSConf3"; 7566 break; 7567 case CP0_REG06__SRSCONF4: 7568 check_insn(ctx, ISA_MIPS_R2); 7569 gen_helper_mtc0_srsconf4(tcg_env, arg); 7570 register_name = "SRSConf4"; 7571 break; 7572 case CP0_REG06__PWCTL: 7573 check_pw(ctx); 7574 gen_helper_mtc0_pwctl(tcg_env, arg); 7575 register_name = "PWCtl"; 7576 break; 7577 default: 7578 goto cp0_unimplemented; 7579 } 7580 break; 7581 case CP0_REGISTER_07: 7582 switch (sel) { 7583 case CP0_REG07__HWRENA: 7584 check_insn(ctx, ISA_MIPS_R2); 7585 gen_helper_mtc0_hwrena(tcg_env, arg); 7586 ctx->base.is_jmp = DISAS_STOP; 7587 register_name = "HWREna"; 7588 break; 7589 default: 7590 goto cp0_unimplemented; 7591 } 7592 break; 7593 case CP0_REGISTER_08: 7594 switch (sel) { 7595 case CP0_REG08__BADVADDR: 7596 /* ignored */ 7597 register_name = "BadVAddr"; 7598 break; 7599 case CP0_REG08__BADINSTR: 7600 /* ignored */ 7601 register_name = "BadInstr"; 7602 break; 7603 case CP0_REG08__BADINSTRP: 7604 /* ignored */ 7605 register_name = "BadInstrP"; 7606 break; 7607 case CP0_REG08__BADINSTRX: 7608 /* ignored */ 7609 register_name = "BadInstrX"; 7610 break; 7611 default: 7612 goto cp0_unimplemented; 7613 } 7614 break; 7615 case CP0_REGISTER_09: 7616 switch (sel) { 7617 case CP0_REG09__COUNT: 7618 gen_helper_mtc0_count(tcg_env, arg); 7619 register_name = "Count"; 7620 break; 7621 default: 7622 goto cp0_unimplemented; 7623 } 7624 /* Stop translation as we may have switched the execution mode */ 7625 ctx->base.is_jmp = DISAS_STOP; 7626 break; 7627 case CP0_REGISTER_10: 7628 switch (sel) { 7629 case CP0_REG10__ENTRYHI: 7630 gen_helper_mtc0_entryhi(tcg_env, arg); 7631 register_name = "EntryHi"; 7632 break; 7633 default: 7634 goto cp0_unimplemented; 7635 } 7636 break; 7637 case CP0_REGISTER_11: 7638 switch (sel) { 7639 case CP0_REG11__COMPARE: 7640 gen_helper_mtc0_compare(tcg_env, arg); 7641 register_name = "Compare"; 7642 break; 7643 /* 6,7 are implementation dependent */ 7644 default: 7645 goto cp0_unimplemented; 7646 } 7647 /* Stop translation as we may have switched the execution mode */ 7648 ctx->base.is_jmp = DISAS_STOP; 7649 break; 7650 case CP0_REGISTER_12: 7651 switch (sel) { 7652 case CP0_REG12__STATUS: 7653 save_cpu_state(ctx, 1); 7654 gen_helper_mtc0_status(tcg_env, arg); 7655 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7656 gen_save_pc(ctx->base.pc_next + 4); 7657 ctx->base.is_jmp = DISAS_EXIT; 7658 register_name = "Status"; 7659 break; 7660 case CP0_REG12__INTCTL: 7661 check_insn(ctx, ISA_MIPS_R2); 7662 gen_helper_mtc0_intctl(tcg_env, arg); 7663 /* Stop translation as we may have switched the execution mode */ 7664 ctx->base.is_jmp = DISAS_STOP; 7665 register_name = "IntCtl"; 7666 break; 7667 case CP0_REG12__SRSCTL: 7668 check_insn(ctx, ISA_MIPS_R2); 7669 gen_helper_mtc0_srsctl(tcg_env, arg); 7670 /* Stop translation as we may have switched the execution mode */ 7671 ctx->base.is_jmp = DISAS_STOP; 7672 register_name = "SRSCtl"; 7673 break; 7674 case CP0_REG12__SRSMAP: 7675 check_insn(ctx, ISA_MIPS_R2); 7676 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7677 /* Stop translation as we may have switched the execution mode */ 7678 ctx->base.is_jmp = DISAS_STOP; 7679 register_name = "SRSMap"; 7680 break; 7681 default: 7682 goto cp0_unimplemented; 7683 } 7684 break; 7685 case CP0_REGISTER_13: 7686 switch (sel) { 7687 case CP0_REG13__CAUSE: 7688 save_cpu_state(ctx, 1); 7689 gen_helper_mtc0_cause(tcg_env, arg); 7690 /* 7691 * Stop translation as we may have triggered an interrupt. 7692 * DISAS_STOP isn't sufficient, we need to ensure we break out of 7693 * translated code to check for pending interrupts. 7694 */ 7695 gen_save_pc(ctx->base.pc_next + 4); 7696 ctx->base.is_jmp = DISAS_EXIT; 7697 register_name = "Cause"; 7698 break; 7699 default: 7700 goto cp0_unimplemented; 7701 } 7702 break; 7703 case CP0_REGISTER_14: 7704 switch (sel) { 7705 case CP0_REG14__EPC: 7706 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 7707 register_name = "EPC"; 7708 break; 7709 default: 7710 goto cp0_unimplemented; 7711 } 7712 break; 7713 case CP0_REGISTER_15: 7714 switch (sel) { 7715 case CP0_REG15__PRID: 7716 /* ignored */ 7717 register_name = "PRid"; 7718 break; 7719 case CP0_REG15__EBASE: 7720 check_insn(ctx, ISA_MIPS_R2); 7721 gen_helper_mtc0_ebase(tcg_env, arg); 7722 register_name = "EBase"; 7723 break; 7724 default: 7725 goto cp0_unimplemented; 7726 } 7727 break; 7728 case CP0_REGISTER_16: 7729 switch (sel) { 7730 case CP0_REG16__CONFIG: 7731 gen_helper_mtc0_config0(tcg_env, arg); 7732 register_name = "Config"; 7733 /* Stop translation as we may have switched the execution mode */ 7734 ctx->base.is_jmp = DISAS_STOP; 7735 break; 7736 case CP0_REG16__CONFIG1: 7737 /* ignored, read only */ 7738 register_name = "Config1"; 7739 break; 7740 case CP0_REG16__CONFIG2: 7741 gen_helper_mtc0_config2(tcg_env, arg); 7742 register_name = "Config2"; 7743 /* Stop translation as we may have switched the execution mode */ 7744 ctx->base.is_jmp = DISAS_STOP; 7745 break; 7746 case CP0_REG16__CONFIG3: 7747 gen_helper_mtc0_config3(tcg_env, arg); 7748 register_name = "Config3"; 7749 /* Stop translation as we may have switched the execution mode */ 7750 ctx->base.is_jmp = DISAS_STOP; 7751 break; 7752 case CP0_REG16__CONFIG4: 7753 /* currently ignored */ 7754 register_name = "Config4"; 7755 break; 7756 case CP0_REG16__CONFIG5: 7757 gen_helper_mtc0_config5(tcg_env, arg); 7758 register_name = "Config5"; 7759 /* Stop translation as we may have switched the execution mode */ 7760 ctx->base.is_jmp = DISAS_STOP; 7761 break; 7762 /* 6,7 are implementation dependent */ 7763 default: 7764 register_name = "Invalid config selector"; 7765 goto cp0_unimplemented; 7766 } 7767 break; 7768 case CP0_REGISTER_17: 7769 switch (sel) { 7770 case CP0_REG17__LLADDR: 7771 gen_helper_mtc0_lladdr(tcg_env, arg); 7772 register_name = "LLAddr"; 7773 break; 7774 case CP0_REG17__MAAR: 7775 CP0_CHECK(ctx->mrp); 7776 gen_helper_mtc0_maar(tcg_env, arg); 7777 register_name = "MAAR"; 7778 break; 7779 case CP0_REG17__MAARI: 7780 CP0_CHECK(ctx->mrp); 7781 gen_helper_mtc0_maari(tcg_env, arg); 7782 register_name = "MAARI"; 7783 break; 7784 default: 7785 goto cp0_unimplemented; 7786 } 7787 break; 7788 case CP0_REGISTER_18: 7789 switch (sel) { 7790 case CP0_REG18__WATCHLO0: 7791 case CP0_REG18__WATCHLO1: 7792 case CP0_REG18__WATCHLO2: 7793 case CP0_REG18__WATCHLO3: 7794 case CP0_REG18__WATCHLO4: 7795 case CP0_REG18__WATCHLO5: 7796 case CP0_REG18__WATCHLO6: 7797 case CP0_REG18__WATCHLO7: 7798 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7799 gen_helper_0e1i(mtc0_watchlo, arg, sel); 7800 register_name = "WatchLo"; 7801 break; 7802 default: 7803 goto cp0_unimplemented; 7804 } 7805 break; 7806 case CP0_REGISTER_19: 7807 switch (sel) { 7808 case CP0_REG19__WATCHHI0: 7809 case CP0_REG19__WATCHHI1: 7810 case CP0_REG19__WATCHHI2: 7811 case CP0_REG19__WATCHHI3: 7812 case CP0_REG19__WATCHHI4: 7813 case CP0_REG19__WATCHHI5: 7814 case CP0_REG19__WATCHHI6: 7815 case CP0_REG19__WATCHHI7: 7816 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7817 gen_helper_0e1i(mtc0_watchhi, arg, sel); 7818 register_name = "WatchHi"; 7819 break; 7820 default: 7821 goto cp0_unimplemented; 7822 } 7823 break; 7824 case CP0_REGISTER_20: 7825 switch (sel) { 7826 case CP0_REG20__XCONTEXT: 7827 check_insn(ctx, ISA_MIPS3); 7828 gen_helper_mtc0_xcontext(tcg_env, arg); 7829 register_name = "XContext"; 7830 break; 7831 default: 7832 goto cp0_unimplemented; 7833 } 7834 break; 7835 case CP0_REGISTER_21: 7836 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7837 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7838 switch (sel) { 7839 case 0: 7840 gen_helper_mtc0_framemask(tcg_env, arg); 7841 register_name = "Framemask"; 7842 break; 7843 default: 7844 goto cp0_unimplemented; 7845 } 7846 break; 7847 case CP0_REGISTER_22: 7848 /* ignored */ 7849 register_name = "Diagnostic"; /* implementation dependent */ 7850 break; 7851 case CP0_REGISTER_23: 7852 switch (sel) { 7853 case CP0_REG23__DEBUG: 7854 gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */ 7855 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7856 gen_save_pc(ctx->base.pc_next + 4); 7857 ctx->base.is_jmp = DISAS_EXIT; 7858 register_name = "Debug"; 7859 break; 7860 case CP0_REG23__TRACECONTROL: 7861 /* PDtrace support */ 7862 /* gen_helper_mtc0_tracecontrol(tcg_env, arg); */ 7863 /* Stop translation as we may have switched the execution mode */ 7864 ctx->base.is_jmp = DISAS_STOP; 7865 register_name = "TraceControl"; 7866 goto cp0_unimplemented; 7867 case CP0_REG23__TRACECONTROL2: 7868 /* PDtrace support */ 7869 /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */ 7870 /* Stop translation as we may have switched the execution mode */ 7871 ctx->base.is_jmp = DISAS_STOP; 7872 register_name = "TraceControl2"; 7873 goto cp0_unimplemented; 7874 case CP0_REG23__USERTRACEDATA1: 7875 /* PDtrace support */ 7876 /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/ 7877 /* Stop translation as we may have switched the execution mode */ 7878 ctx->base.is_jmp = DISAS_STOP; 7879 register_name = "UserTraceData1"; 7880 goto cp0_unimplemented; 7881 case CP0_REG23__TRACEIBPC: 7882 /* PDtrace support */ 7883 /* gen_helper_mtc0_traceibpc(tcg_env, arg); */ 7884 /* Stop translation as we may have switched the execution mode */ 7885 ctx->base.is_jmp = DISAS_STOP; 7886 register_name = "TraceIBPC"; 7887 goto cp0_unimplemented; 7888 case CP0_REG23__TRACEDBPC: 7889 /* PDtrace support */ 7890 /* gen_helper_mtc0_tracedbpc(tcg_env, arg); */ 7891 /* Stop translation as we may have switched the execution mode */ 7892 ctx->base.is_jmp = DISAS_STOP; 7893 register_name = "TraceDBPC"; 7894 goto cp0_unimplemented; 7895 default: 7896 goto cp0_unimplemented; 7897 } 7898 break; 7899 case CP0_REGISTER_24: 7900 switch (sel) { 7901 case CP0_REG24__DEPC: 7902 /* EJTAG support */ 7903 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 7904 register_name = "DEPC"; 7905 break; 7906 default: 7907 goto cp0_unimplemented; 7908 } 7909 break; 7910 case CP0_REGISTER_25: 7911 switch (sel) { 7912 case CP0_REG25__PERFCTL0: 7913 gen_helper_mtc0_performance0(tcg_env, arg); 7914 register_name = "Performance0"; 7915 break; 7916 case CP0_REG25__PERFCNT0: 7917 /* gen_helper_mtc0_performance1(tcg_env, arg); */ 7918 register_name = "Performance1"; 7919 goto cp0_unimplemented; 7920 case CP0_REG25__PERFCTL1: 7921 /* gen_helper_mtc0_performance2(tcg_env, arg); */ 7922 register_name = "Performance2"; 7923 goto cp0_unimplemented; 7924 case CP0_REG25__PERFCNT1: 7925 /* gen_helper_mtc0_performance3(tcg_env, arg); */ 7926 register_name = "Performance3"; 7927 goto cp0_unimplemented; 7928 case CP0_REG25__PERFCTL2: 7929 /* gen_helper_mtc0_performance4(tcg_env, arg); */ 7930 register_name = "Performance4"; 7931 goto cp0_unimplemented; 7932 case CP0_REG25__PERFCNT2: 7933 /* gen_helper_mtc0_performance5(tcg_env, arg); */ 7934 register_name = "Performance5"; 7935 goto cp0_unimplemented; 7936 case CP0_REG25__PERFCTL3: 7937 /* gen_helper_mtc0_performance6(tcg_env, arg); */ 7938 register_name = "Performance6"; 7939 goto cp0_unimplemented; 7940 case CP0_REG25__PERFCNT3: 7941 /* gen_helper_mtc0_performance7(tcg_env, arg); */ 7942 register_name = "Performance7"; 7943 goto cp0_unimplemented; 7944 default: 7945 goto cp0_unimplemented; 7946 } 7947 break; 7948 case CP0_REGISTER_26: 7949 switch (sel) { 7950 case CP0_REG26__ERRCTL: 7951 gen_helper_mtc0_errctl(tcg_env, arg); 7952 ctx->base.is_jmp = DISAS_STOP; 7953 register_name = "ErrCtl"; 7954 break; 7955 default: 7956 goto cp0_unimplemented; 7957 } 7958 break; 7959 case CP0_REGISTER_27: 7960 switch (sel) { 7961 case CP0_REG27__CACHERR: 7962 /* ignored */ 7963 register_name = "CacheErr"; 7964 break; 7965 default: 7966 goto cp0_unimplemented; 7967 } 7968 break; 7969 case CP0_REGISTER_28: 7970 switch (sel) { 7971 case CP0_REG28__TAGLO: 7972 case CP0_REG28__TAGLO1: 7973 case CP0_REG28__TAGLO2: 7974 case CP0_REG28__TAGLO3: 7975 gen_helper_mtc0_taglo(tcg_env, arg); 7976 register_name = "TagLo"; 7977 break; 7978 case CP0_REG28__DATALO: 7979 case CP0_REG28__DATALO1: 7980 case CP0_REG28__DATALO2: 7981 case CP0_REG28__DATALO3: 7982 gen_helper_mtc0_datalo(tcg_env, arg); 7983 register_name = "DataLo"; 7984 break; 7985 default: 7986 goto cp0_unimplemented; 7987 } 7988 break; 7989 case CP0_REGISTER_29: 7990 switch (sel) { 7991 case CP0_REG29__TAGHI: 7992 case CP0_REG29__TAGHI1: 7993 case CP0_REG29__TAGHI2: 7994 case CP0_REG29__TAGHI3: 7995 gen_helper_mtc0_taghi(tcg_env, arg); 7996 register_name = "TagHi"; 7997 break; 7998 case CP0_REG29__DATAHI: 7999 case CP0_REG29__DATAHI1: 8000 case CP0_REG29__DATAHI2: 8001 case CP0_REG29__DATAHI3: 8002 gen_helper_mtc0_datahi(tcg_env, arg); 8003 register_name = "DataHi"; 8004 break; 8005 default: 8006 register_name = "invalid sel"; 8007 goto cp0_unimplemented; 8008 } 8009 break; 8010 case CP0_REGISTER_30: 8011 switch (sel) { 8012 case CP0_REG30__ERROREPC: 8013 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 8014 register_name = "ErrorEPC"; 8015 break; 8016 default: 8017 goto cp0_unimplemented; 8018 } 8019 break; 8020 case CP0_REGISTER_31: 8021 switch (sel) { 8022 case CP0_REG31__DESAVE: 8023 /* EJTAG support */ 8024 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 8025 register_name = "DESAVE"; 8026 break; 8027 case CP0_REG31__KSCRATCH1: 8028 case CP0_REG31__KSCRATCH2: 8029 case CP0_REG31__KSCRATCH3: 8030 case CP0_REG31__KSCRATCH4: 8031 case CP0_REG31__KSCRATCH5: 8032 case CP0_REG31__KSCRATCH6: 8033 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8034 tcg_gen_st_tl(arg, tcg_env, 8035 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8036 register_name = "KScratch"; 8037 break; 8038 default: 8039 goto cp0_unimplemented; 8040 } 8041 break; 8042 default: 8043 goto cp0_unimplemented; 8044 } 8045 trace_mips_translate_c0("dmtc0", register_name, reg, sel); 8046 8047 /* For simplicity assume that all writes can cause interrupts. */ 8048 if (icount) { 8049 /* 8050 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8051 * translated code to check for pending interrupts. 8052 */ 8053 gen_save_pc(ctx->base.pc_next + 4); 8054 ctx->base.is_jmp = DISAS_EXIT; 8055 } 8056 return; 8057 8058 cp0_unimplemented: 8059 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", 8060 register_name, reg, sel); 8061 } 8062 #endif /* TARGET_MIPS64 */ 8063 8064 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 8065 int u, int sel, int h) 8066 { 8067 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8068 TCGv t0 = tcg_temp_new(); 8069 8070 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8071 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8072 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8073 tcg_gen_movi_tl(t0, -1); 8074 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8075 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8076 tcg_gen_movi_tl(t0, -1); 8077 } else if (u == 0) { 8078 switch (rt) { 8079 case 1: 8080 switch (sel) { 8081 case 1: 8082 gen_helper_mftc0_vpecontrol(t0, tcg_env); 8083 break; 8084 case 2: 8085 gen_helper_mftc0_vpeconf0(t0, tcg_env); 8086 break; 8087 default: 8088 goto die; 8089 break; 8090 } 8091 break; 8092 case 2: 8093 switch (sel) { 8094 case 1: 8095 gen_helper_mftc0_tcstatus(t0, tcg_env); 8096 break; 8097 case 2: 8098 gen_helper_mftc0_tcbind(t0, tcg_env); 8099 break; 8100 case 3: 8101 gen_helper_mftc0_tcrestart(t0, tcg_env); 8102 break; 8103 case 4: 8104 gen_helper_mftc0_tchalt(t0, tcg_env); 8105 break; 8106 case 5: 8107 gen_helper_mftc0_tccontext(t0, tcg_env); 8108 break; 8109 case 6: 8110 gen_helper_mftc0_tcschedule(t0, tcg_env); 8111 break; 8112 case 7: 8113 gen_helper_mftc0_tcschefback(t0, tcg_env); 8114 break; 8115 default: 8116 gen_mfc0(ctx, t0, rt, sel); 8117 break; 8118 } 8119 break; 8120 case 10: 8121 switch (sel) { 8122 case 0: 8123 gen_helper_mftc0_entryhi(t0, tcg_env); 8124 break; 8125 default: 8126 gen_mfc0(ctx, t0, rt, sel); 8127 break; 8128 } 8129 break; 8130 case 12: 8131 switch (sel) { 8132 case 0: 8133 gen_helper_mftc0_status(t0, tcg_env); 8134 break; 8135 default: 8136 gen_mfc0(ctx, t0, rt, sel); 8137 break; 8138 } 8139 break; 8140 case 13: 8141 switch (sel) { 8142 case 0: 8143 gen_helper_mftc0_cause(t0, tcg_env); 8144 break; 8145 default: 8146 goto die; 8147 break; 8148 } 8149 break; 8150 case 14: 8151 switch (sel) { 8152 case 0: 8153 gen_helper_mftc0_epc(t0, tcg_env); 8154 break; 8155 default: 8156 goto die; 8157 break; 8158 } 8159 break; 8160 case 15: 8161 switch (sel) { 8162 case 1: 8163 gen_helper_mftc0_ebase(t0, tcg_env); 8164 break; 8165 default: 8166 goto die; 8167 break; 8168 } 8169 break; 8170 case 16: 8171 switch (sel) { 8172 case 0: 8173 case 1: 8174 case 2: 8175 case 3: 8176 case 4: 8177 case 5: 8178 case 6: 8179 case 7: 8180 gen_helper_mftc0_configx(t0, tcg_env, tcg_constant_tl(sel)); 8181 break; 8182 default: 8183 goto die; 8184 break; 8185 } 8186 break; 8187 case 23: 8188 switch (sel) { 8189 case 0: 8190 gen_helper_mftc0_debug(t0, tcg_env); 8191 break; 8192 default: 8193 gen_mfc0(ctx, t0, rt, sel); 8194 break; 8195 } 8196 break; 8197 default: 8198 gen_mfc0(ctx, t0, rt, sel); 8199 } 8200 } else { 8201 switch (sel) { 8202 /* GPR registers. */ 8203 case 0: 8204 gen_helper_1e0i(mftgpr, t0, rt); 8205 break; 8206 /* Auxiliary CPU registers */ 8207 case 1: 8208 switch (rt) { 8209 case 0: 8210 gen_helper_1e0i(mftlo, t0, 0); 8211 break; 8212 case 1: 8213 gen_helper_1e0i(mfthi, t0, 0); 8214 break; 8215 case 2: 8216 gen_helper_1e0i(mftacx, t0, 0); 8217 break; 8218 case 4: 8219 gen_helper_1e0i(mftlo, t0, 1); 8220 break; 8221 case 5: 8222 gen_helper_1e0i(mfthi, t0, 1); 8223 break; 8224 case 6: 8225 gen_helper_1e0i(mftacx, t0, 1); 8226 break; 8227 case 8: 8228 gen_helper_1e0i(mftlo, t0, 2); 8229 break; 8230 case 9: 8231 gen_helper_1e0i(mfthi, t0, 2); 8232 break; 8233 case 10: 8234 gen_helper_1e0i(mftacx, t0, 2); 8235 break; 8236 case 12: 8237 gen_helper_1e0i(mftlo, t0, 3); 8238 break; 8239 case 13: 8240 gen_helper_1e0i(mfthi, t0, 3); 8241 break; 8242 case 14: 8243 gen_helper_1e0i(mftacx, t0, 3); 8244 break; 8245 case 16: 8246 gen_helper_mftdsp(t0, tcg_env); 8247 break; 8248 default: 8249 goto die; 8250 } 8251 break; 8252 /* Floating point (COP1). */ 8253 case 2: 8254 /* XXX: For now we support only a single FPU context. */ 8255 if (h == 0) { 8256 TCGv_i32 fp0 = tcg_temp_new_i32(); 8257 8258 gen_load_fpr32(ctx, fp0, rt); 8259 tcg_gen_ext_i32_tl(t0, fp0); 8260 } else { 8261 TCGv_i32 fp0 = tcg_temp_new_i32(); 8262 8263 gen_load_fpr32h(ctx, fp0, rt); 8264 tcg_gen_ext_i32_tl(t0, fp0); 8265 } 8266 break; 8267 case 3: 8268 /* XXX: For now we support only a single FPU context. */ 8269 gen_helper_1e0i(cfc1, t0, rt); 8270 break; 8271 /* COP2: Not implemented. */ 8272 case 4: 8273 case 5: 8274 /* fall through */ 8275 default: 8276 goto die; 8277 } 8278 } 8279 trace_mips_translate_tr("mftr", rt, u, sel, h); 8280 gen_store_gpr(t0, rd); 8281 return; 8282 8283 die: 8284 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 8285 gen_reserved_instruction(ctx); 8286 } 8287 8288 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 8289 int u, int sel, int h) 8290 { 8291 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8292 TCGv t0 = tcg_temp_new(); 8293 8294 gen_load_gpr(t0, rt); 8295 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8296 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8297 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8298 /* NOP */ 8299 ; 8300 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8301 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8302 /* NOP */ 8303 ; 8304 } else if (u == 0) { 8305 switch (rd) { 8306 case 1: 8307 switch (sel) { 8308 case 1: 8309 gen_helper_mttc0_vpecontrol(tcg_env, t0); 8310 break; 8311 case 2: 8312 gen_helper_mttc0_vpeconf0(tcg_env, t0); 8313 break; 8314 default: 8315 goto die; 8316 break; 8317 } 8318 break; 8319 case 2: 8320 switch (sel) { 8321 case 1: 8322 gen_helper_mttc0_tcstatus(tcg_env, t0); 8323 break; 8324 case 2: 8325 gen_helper_mttc0_tcbind(tcg_env, t0); 8326 break; 8327 case 3: 8328 gen_helper_mttc0_tcrestart(tcg_env, t0); 8329 break; 8330 case 4: 8331 gen_helper_mttc0_tchalt(tcg_env, t0); 8332 break; 8333 case 5: 8334 gen_helper_mttc0_tccontext(tcg_env, t0); 8335 break; 8336 case 6: 8337 gen_helper_mttc0_tcschedule(tcg_env, t0); 8338 break; 8339 case 7: 8340 gen_helper_mttc0_tcschefback(tcg_env, t0); 8341 break; 8342 default: 8343 gen_mtc0(ctx, t0, rd, sel); 8344 break; 8345 } 8346 break; 8347 case 10: 8348 switch (sel) { 8349 case 0: 8350 gen_helper_mttc0_entryhi(tcg_env, t0); 8351 break; 8352 default: 8353 gen_mtc0(ctx, t0, rd, sel); 8354 break; 8355 } 8356 break; 8357 case 12: 8358 switch (sel) { 8359 case 0: 8360 gen_helper_mttc0_status(tcg_env, t0); 8361 break; 8362 default: 8363 gen_mtc0(ctx, t0, rd, sel); 8364 break; 8365 } 8366 break; 8367 case 13: 8368 switch (sel) { 8369 case 0: 8370 gen_helper_mttc0_cause(tcg_env, t0); 8371 break; 8372 default: 8373 goto die; 8374 break; 8375 } 8376 break; 8377 case 15: 8378 switch (sel) { 8379 case 1: 8380 gen_helper_mttc0_ebase(tcg_env, t0); 8381 break; 8382 default: 8383 goto die; 8384 break; 8385 } 8386 break; 8387 case 23: 8388 switch (sel) { 8389 case 0: 8390 gen_helper_mttc0_debug(tcg_env, t0); 8391 break; 8392 default: 8393 gen_mtc0(ctx, t0, rd, sel); 8394 break; 8395 } 8396 break; 8397 default: 8398 gen_mtc0(ctx, t0, rd, sel); 8399 } 8400 } else { 8401 switch (sel) { 8402 /* GPR registers. */ 8403 case 0: 8404 gen_helper_0e1i(mttgpr, t0, rd); 8405 break; 8406 /* Auxiliary CPU registers */ 8407 case 1: 8408 switch (rd) { 8409 case 0: 8410 gen_helper_0e1i(mttlo, t0, 0); 8411 break; 8412 case 1: 8413 gen_helper_0e1i(mtthi, t0, 0); 8414 break; 8415 case 2: 8416 gen_helper_0e1i(mttacx, t0, 0); 8417 break; 8418 case 4: 8419 gen_helper_0e1i(mttlo, t0, 1); 8420 break; 8421 case 5: 8422 gen_helper_0e1i(mtthi, t0, 1); 8423 break; 8424 case 6: 8425 gen_helper_0e1i(mttacx, t0, 1); 8426 break; 8427 case 8: 8428 gen_helper_0e1i(mttlo, t0, 2); 8429 break; 8430 case 9: 8431 gen_helper_0e1i(mtthi, t0, 2); 8432 break; 8433 case 10: 8434 gen_helper_0e1i(mttacx, t0, 2); 8435 break; 8436 case 12: 8437 gen_helper_0e1i(mttlo, t0, 3); 8438 break; 8439 case 13: 8440 gen_helper_0e1i(mtthi, t0, 3); 8441 break; 8442 case 14: 8443 gen_helper_0e1i(mttacx, t0, 3); 8444 break; 8445 case 16: 8446 gen_helper_mttdsp(tcg_env, t0); 8447 break; 8448 default: 8449 goto die; 8450 } 8451 break; 8452 /* Floating point (COP1). */ 8453 case 2: 8454 /* XXX: For now we support only a single FPU context. */ 8455 if (h == 0) { 8456 TCGv_i32 fp0 = tcg_temp_new_i32(); 8457 8458 tcg_gen_trunc_tl_i32(fp0, t0); 8459 gen_store_fpr32(ctx, fp0, rd); 8460 } else { 8461 TCGv_i32 fp0 = tcg_temp_new_i32(); 8462 8463 tcg_gen_trunc_tl_i32(fp0, t0); 8464 gen_store_fpr32h(ctx, fp0, rd); 8465 } 8466 break; 8467 case 3: 8468 /* XXX: For now we support only a single FPU context. */ 8469 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt); 8470 /* Stop translation as we may have changed hflags */ 8471 ctx->base.is_jmp = DISAS_STOP; 8472 break; 8473 /* COP2: Not implemented. */ 8474 case 4: 8475 case 5: 8476 /* fall through */ 8477 default: 8478 goto die; 8479 } 8480 } 8481 trace_mips_translate_tr("mttr", rd, u, sel, h); 8482 return; 8483 8484 die: 8485 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 8486 gen_reserved_instruction(ctx); 8487 } 8488 8489 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 8490 int rt, int rd) 8491 { 8492 const char *opn = "ldst"; 8493 8494 check_cp0_enabled(ctx); 8495 switch (opc) { 8496 case OPC_MFC0: 8497 if (rt == 0) { 8498 /* Treat as NOP. */ 8499 return; 8500 } 8501 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8502 opn = "mfc0"; 8503 break; 8504 case OPC_MTC0: 8505 { 8506 TCGv t0 = tcg_temp_new(); 8507 8508 gen_load_gpr(t0, rt); 8509 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7); 8510 } 8511 opn = "mtc0"; 8512 break; 8513 #if defined(TARGET_MIPS64) 8514 case OPC_DMFC0: 8515 check_insn(ctx, ISA_MIPS3); 8516 if (rt == 0) { 8517 /* Treat as NOP. */ 8518 return; 8519 } 8520 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8521 opn = "dmfc0"; 8522 break; 8523 case OPC_DMTC0: 8524 check_insn(ctx, ISA_MIPS3); 8525 { 8526 TCGv t0 = tcg_temp_new(); 8527 8528 gen_load_gpr(t0, rt); 8529 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7); 8530 } 8531 opn = "dmtc0"; 8532 break; 8533 #endif 8534 case OPC_MFHC0: 8535 check_mvh(ctx); 8536 if (rt == 0) { 8537 /* Treat as NOP. */ 8538 return; 8539 } 8540 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8541 opn = "mfhc0"; 8542 break; 8543 case OPC_MTHC0: 8544 check_mvh(ctx); 8545 { 8546 TCGv t0 = tcg_temp_new(); 8547 gen_load_gpr(t0, rt); 8548 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7); 8549 } 8550 opn = "mthc0"; 8551 break; 8552 case OPC_MFTR: 8553 check_cp0_enabled(ctx); 8554 if (rd == 0) { 8555 /* Treat as NOP. */ 8556 return; 8557 } 8558 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 8559 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 8560 opn = "mftr"; 8561 break; 8562 case OPC_MTTR: 8563 check_cp0_enabled(ctx); 8564 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 8565 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 8566 opn = "mttr"; 8567 break; 8568 case OPC_TLBWI: 8569 opn = "tlbwi"; 8570 if (!env->tlb->helper_tlbwi) { 8571 goto die; 8572 } 8573 gen_helper_tlbwi(tcg_env); 8574 break; 8575 case OPC_TLBINV: 8576 opn = "tlbinv"; 8577 if (ctx->ie >= 2) { 8578 if (!env->tlb->helper_tlbinv) { 8579 goto die; 8580 } 8581 gen_helper_tlbinv(tcg_env); 8582 } /* treat as nop if TLBINV not supported */ 8583 break; 8584 case OPC_TLBINVF: 8585 opn = "tlbinvf"; 8586 if (ctx->ie >= 2) { 8587 if (!env->tlb->helper_tlbinvf) { 8588 goto die; 8589 } 8590 gen_helper_tlbinvf(tcg_env); 8591 } /* treat as nop if TLBINV not supported */ 8592 break; 8593 case OPC_TLBWR: 8594 opn = "tlbwr"; 8595 if (!env->tlb->helper_tlbwr) { 8596 goto die; 8597 } 8598 gen_helper_tlbwr(tcg_env); 8599 break; 8600 case OPC_TLBP: 8601 opn = "tlbp"; 8602 if (!env->tlb->helper_tlbp) { 8603 goto die; 8604 } 8605 gen_helper_tlbp(tcg_env); 8606 break; 8607 case OPC_TLBR: 8608 opn = "tlbr"; 8609 if (!env->tlb->helper_tlbr) { 8610 goto die; 8611 } 8612 gen_helper_tlbr(tcg_env); 8613 break; 8614 case OPC_ERET: /* OPC_ERETNC */ 8615 if ((ctx->insn_flags & ISA_MIPS_R6) && 8616 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8617 goto die; 8618 } else { 8619 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6; 8620 if (ctx->opcode & (1 << bit_shift)) { 8621 /* OPC_ERETNC */ 8622 opn = "eretnc"; 8623 check_insn(ctx, ISA_MIPS_R5); 8624 gen_helper_eretnc(tcg_env); 8625 } else { 8626 /* OPC_ERET */ 8627 opn = "eret"; 8628 check_insn(ctx, ISA_MIPS2); 8629 gen_helper_eret(tcg_env); 8630 } 8631 ctx->base.is_jmp = DISAS_EXIT; 8632 } 8633 break; 8634 case OPC_DERET: 8635 opn = "deret"; 8636 check_insn(ctx, ISA_MIPS_R1); 8637 if ((ctx->insn_flags & ISA_MIPS_R6) && 8638 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8639 goto die; 8640 } 8641 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 8642 MIPS_INVAL(opn); 8643 gen_reserved_instruction(ctx); 8644 } else { 8645 gen_helper_deret(tcg_env); 8646 ctx->base.is_jmp = DISAS_EXIT; 8647 } 8648 break; 8649 case OPC_WAIT: 8650 opn = "wait"; 8651 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 8652 if ((ctx->insn_flags & ISA_MIPS_R6) && 8653 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8654 goto die; 8655 } 8656 /* If we get an exception, we want to restart at next instruction */ 8657 ctx->base.pc_next += 4; 8658 save_cpu_state(ctx, 1); 8659 ctx->base.pc_next -= 4; 8660 gen_helper_wait(tcg_env); 8661 ctx->base.is_jmp = DISAS_NORETURN; 8662 break; 8663 default: 8664 die: 8665 MIPS_INVAL(opn); 8666 gen_reserved_instruction(ctx); 8667 return; 8668 } 8669 (void)opn; /* avoid a compiler warning */ 8670 } 8671 #endif /* !CONFIG_USER_ONLY */ 8672 8673 /* CP1 Branches (before delay slot) */ 8674 static void gen_compute_branch1(DisasContext *ctx, uint32_t op, 8675 int32_t cc, int32_t offset) 8676 { 8677 target_ulong btarget; 8678 TCGv_i32 t0 = tcg_temp_new_i32(); 8679 8680 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { 8681 gen_reserved_instruction(ctx); 8682 return; 8683 } 8684 8685 if (cc != 0) { 8686 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 8687 } 8688 8689 btarget = ctx->base.pc_next + 4 + offset; 8690 8691 switch (op) { 8692 case OPC_BC1F: 8693 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8694 tcg_gen_not_i32(t0, t0); 8695 tcg_gen_andi_i32(t0, t0, 1); 8696 tcg_gen_extu_i32_tl(bcond, t0); 8697 goto not_likely; 8698 case OPC_BC1FL: 8699 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8700 tcg_gen_not_i32(t0, t0); 8701 tcg_gen_andi_i32(t0, t0, 1); 8702 tcg_gen_extu_i32_tl(bcond, t0); 8703 goto likely; 8704 case OPC_BC1T: 8705 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8706 tcg_gen_andi_i32(t0, t0, 1); 8707 tcg_gen_extu_i32_tl(bcond, t0); 8708 goto not_likely; 8709 case OPC_BC1TL: 8710 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8711 tcg_gen_andi_i32(t0, t0, 1); 8712 tcg_gen_extu_i32_tl(bcond, t0); 8713 likely: 8714 ctx->hflags |= MIPS_HFLAG_BL; 8715 break; 8716 case OPC_BC1FANY2: 8717 { 8718 TCGv_i32 t1 = tcg_temp_new_i32(); 8719 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8720 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8721 tcg_gen_nand_i32(t0, t0, t1); 8722 tcg_gen_andi_i32(t0, t0, 1); 8723 tcg_gen_extu_i32_tl(bcond, t0); 8724 } 8725 goto not_likely; 8726 case OPC_BC1TANY2: 8727 { 8728 TCGv_i32 t1 = tcg_temp_new_i32(); 8729 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8730 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8731 tcg_gen_or_i32(t0, t0, t1); 8732 tcg_gen_andi_i32(t0, t0, 1); 8733 tcg_gen_extu_i32_tl(bcond, t0); 8734 } 8735 goto not_likely; 8736 case OPC_BC1FANY4: 8737 { 8738 TCGv_i32 t1 = tcg_temp_new_i32(); 8739 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8740 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8741 tcg_gen_and_i32(t0, t0, t1); 8742 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 8743 tcg_gen_and_i32(t0, t0, t1); 8744 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 8745 tcg_gen_nand_i32(t0, t0, t1); 8746 tcg_gen_andi_i32(t0, t0, 1); 8747 tcg_gen_extu_i32_tl(bcond, t0); 8748 } 8749 goto not_likely; 8750 case OPC_BC1TANY4: 8751 { 8752 TCGv_i32 t1 = tcg_temp_new_i32(); 8753 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8754 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8755 tcg_gen_or_i32(t0, t0, t1); 8756 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 8757 tcg_gen_or_i32(t0, t0, t1); 8758 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 8759 tcg_gen_or_i32(t0, t0, t1); 8760 tcg_gen_andi_i32(t0, t0, 1); 8761 tcg_gen_extu_i32_tl(bcond, t0); 8762 } 8763 not_likely: 8764 ctx->hflags |= MIPS_HFLAG_BC; 8765 break; 8766 default: 8767 MIPS_INVAL("cp1 cond branch"); 8768 gen_reserved_instruction(ctx); 8769 return; 8770 } 8771 ctx->btarget = btarget; 8772 ctx->hflags |= MIPS_HFLAG_BDS32; 8773 } 8774 8775 /* R6 CP1 Branches */ 8776 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, 8777 int32_t ft, int32_t offset, 8778 int delayslot_size) 8779 { 8780 target_ulong btarget; 8781 TCGv_i64 t0 = tcg_temp_new_i64(); 8782 8783 if (ctx->hflags & MIPS_HFLAG_BMASK) { 8784 #ifdef MIPS_DEBUG_DISAS 8785 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 8786 VADDR_PRIx "\n", ctx->base.pc_next); 8787 #endif 8788 gen_reserved_instruction(ctx); 8789 return; 8790 } 8791 8792 gen_load_fpr64(ctx, t0, ft); 8793 tcg_gen_andi_i64(t0, t0, 1); 8794 8795 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 8796 8797 switch (op) { 8798 case OPC_BC1EQZ: 8799 tcg_gen_xori_i64(t0, t0, 1); 8800 ctx->hflags |= MIPS_HFLAG_BC; 8801 break; 8802 case OPC_BC1NEZ: 8803 /* t0 already set */ 8804 ctx->hflags |= MIPS_HFLAG_BC; 8805 break; 8806 default: 8807 MIPS_INVAL("cp1 cond branch"); 8808 gen_reserved_instruction(ctx); 8809 return; 8810 } 8811 8812 tcg_gen_trunc_i64_tl(bcond, t0); 8813 8814 ctx->btarget = btarget; 8815 8816 switch (delayslot_size) { 8817 case 2: 8818 ctx->hflags |= MIPS_HFLAG_BDS16; 8819 break; 8820 case 4: 8821 ctx->hflags |= MIPS_HFLAG_BDS32; 8822 break; 8823 } 8824 } 8825 8826 /* Coprocessor 1 (FPU) */ 8827 8828 #define FOP(func, fmt) (((fmt) << 21) | (func)) 8829 8830 enum fopcode { 8831 OPC_ADD_S = FOP(0, FMT_S), 8832 OPC_SUB_S = FOP(1, FMT_S), 8833 OPC_MUL_S = FOP(2, FMT_S), 8834 OPC_DIV_S = FOP(3, FMT_S), 8835 OPC_SQRT_S = FOP(4, FMT_S), 8836 OPC_ABS_S = FOP(5, FMT_S), 8837 OPC_MOV_S = FOP(6, FMT_S), 8838 OPC_NEG_S = FOP(7, FMT_S), 8839 OPC_ROUND_L_S = FOP(8, FMT_S), 8840 OPC_TRUNC_L_S = FOP(9, FMT_S), 8841 OPC_CEIL_L_S = FOP(10, FMT_S), 8842 OPC_FLOOR_L_S = FOP(11, FMT_S), 8843 OPC_ROUND_W_S = FOP(12, FMT_S), 8844 OPC_TRUNC_W_S = FOP(13, FMT_S), 8845 OPC_CEIL_W_S = FOP(14, FMT_S), 8846 OPC_FLOOR_W_S = FOP(15, FMT_S), 8847 OPC_SEL_S = FOP(16, FMT_S), 8848 OPC_MOVCF_S = FOP(17, FMT_S), 8849 OPC_MOVZ_S = FOP(18, FMT_S), 8850 OPC_MOVN_S = FOP(19, FMT_S), 8851 OPC_SELEQZ_S = FOP(20, FMT_S), 8852 OPC_RECIP_S = FOP(21, FMT_S), 8853 OPC_RSQRT_S = FOP(22, FMT_S), 8854 OPC_SELNEZ_S = FOP(23, FMT_S), 8855 OPC_MADDF_S = FOP(24, FMT_S), 8856 OPC_MSUBF_S = FOP(25, FMT_S), 8857 OPC_RINT_S = FOP(26, FMT_S), 8858 OPC_CLASS_S = FOP(27, FMT_S), 8859 OPC_MIN_S = FOP(28, FMT_S), 8860 OPC_RECIP2_S = FOP(28, FMT_S), 8861 OPC_MINA_S = FOP(29, FMT_S), 8862 OPC_RECIP1_S = FOP(29, FMT_S), 8863 OPC_MAX_S = FOP(30, FMT_S), 8864 OPC_RSQRT1_S = FOP(30, FMT_S), 8865 OPC_MAXA_S = FOP(31, FMT_S), 8866 OPC_RSQRT2_S = FOP(31, FMT_S), 8867 OPC_CVT_D_S = FOP(33, FMT_S), 8868 OPC_CVT_W_S = FOP(36, FMT_S), 8869 OPC_CVT_L_S = FOP(37, FMT_S), 8870 OPC_CVT_PS_S = FOP(38, FMT_S), 8871 OPC_CMP_F_S = FOP(48, FMT_S), 8872 OPC_CMP_UN_S = FOP(49, FMT_S), 8873 OPC_CMP_EQ_S = FOP(50, FMT_S), 8874 OPC_CMP_UEQ_S = FOP(51, FMT_S), 8875 OPC_CMP_OLT_S = FOP(52, FMT_S), 8876 OPC_CMP_ULT_S = FOP(53, FMT_S), 8877 OPC_CMP_OLE_S = FOP(54, FMT_S), 8878 OPC_CMP_ULE_S = FOP(55, FMT_S), 8879 OPC_CMP_SF_S = FOP(56, FMT_S), 8880 OPC_CMP_NGLE_S = FOP(57, FMT_S), 8881 OPC_CMP_SEQ_S = FOP(58, FMT_S), 8882 OPC_CMP_NGL_S = FOP(59, FMT_S), 8883 OPC_CMP_LT_S = FOP(60, FMT_S), 8884 OPC_CMP_NGE_S = FOP(61, FMT_S), 8885 OPC_CMP_LE_S = FOP(62, FMT_S), 8886 OPC_CMP_NGT_S = FOP(63, FMT_S), 8887 8888 OPC_ADD_D = FOP(0, FMT_D), 8889 OPC_SUB_D = FOP(1, FMT_D), 8890 OPC_MUL_D = FOP(2, FMT_D), 8891 OPC_DIV_D = FOP(3, FMT_D), 8892 OPC_SQRT_D = FOP(4, FMT_D), 8893 OPC_ABS_D = FOP(5, FMT_D), 8894 OPC_MOV_D = FOP(6, FMT_D), 8895 OPC_NEG_D = FOP(7, FMT_D), 8896 OPC_ROUND_L_D = FOP(8, FMT_D), 8897 OPC_TRUNC_L_D = FOP(9, FMT_D), 8898 OPC_CEIL_L_D = FOP(10, FMT_D), 8899 OPC_FLOOR_L_D = FOP(11, FMT_D), 8900 OPC_ROUND_W_D = FOP(12, FMT_D), 8901 OPC_TRUNC_W_D = FOP(13, FMT_D), 8902 OPC_CEIL_W_D = FOP(14, FMT_D), 8903 OPC_FLOOR_W_D = FOP(15, FMT_D), 8904 OPC_SEL_D = FOP(16, FMT_D), 8905 OPC_MOVCF_D = FOP(17, FMT_D), 8906 OPC_MOVZ_D = FOP(18, FMT_D), 8907 OPC_MOVN_D = FOP(19, FMT_D), 8908 OPC_SELEQZ_D = FOP(20, FMT_D), 8909 OPC_RECIP_D = FOP(21, FMT_D), 8910 OPC_RSQRT_D = FOP(22, FMT_D), 8911 OPC_SELNEZ_D = FOP(23, FMT_D), 8912 OPC_MADDF_D = FOP(24, FMT_D), 8913 OPC_MSUBF_D = FOP(25, FMT_D), 8914 OPC_RINT_D = FOP(26, FMT_D), 8915 OPC_CLASS_D = FOP(27, FMT_D), 8916 OPC_MIN_D = FOP(28, FMT_D), 8917 OPC_RECIP2_D = FOP(28, FMT_D), 8918 OPC_MINA_D = FOP(29, FMT_D), 8919 OPC_RECIP1_D = FOP(29, FMT_D), 8920 OPC_MAX_D = FOP(30, FMT_D), 8921 OPC_RSQRT1_D = FOP(30, FMT_D), 8922 OPC_MAXA_D = FOP(31, FMT_D), 8923 OPC_RSQRT2_D = FOP(31, FMT_D), 8924 OPC_CVT_S_D = FOP(32, FMT_D), 8925 OPC_CVT_W_D = FOP(36, FMT_D), 8926 OPC_CVT_L_D = FOP(37, FMT_D), 8927 OPC_CMP_F_D = FOP(48, FMT_D), 8928 OPC_CMP_UN_D = FOP(49, FMT_D), 8929 OPC_CMP_EQ_D = FOP(50, FMT_D), 8930 OPC_CMP_UEQ_D = FOP(51, FMT_D), 8931 OPC_CMP_OLT_D = FOP(52, FMT_D), 8932 OPC_CMP_ULT_D = FOP(53, FMT_D), 8933 OPC_CMP_OLE_D = FOP(54, FMT_D), 8934 OPC_CMP_ULE_D = FOP(55, FMT_D), 8935 OPC_CMP_SF_D = FOP(56, FMT_D), 8936 OPC_CMP_NGLE_D = FOP(57, FMT_D), 8937 OPC_CMP_SEQ_D = FOP(58, FMT_D), 8938 OPC_CMP_NGL_D = FOP(59, FMT_D), 8939 OPC_CMP_LT_D = FOP(60, FMT_D), 8940 OPC_CMP_NGE_D = FOP(61, FMT_D), 8941 OPC_CMP_LE_D = FOP(62, FMT_D), 8942 OPC_CMP_NGT_D = FOP(63, FMT_D), 8943 8944 OPC_CVT_S_W = FOP(32, FMT_W), 8945 OPC_CVT_D_W = FOP(33, FMT_W), 8946 OPC_CVT_S_L = FOP(32, FMT_L), 8947 OPC_CVT_D_L = FOP(33, FMT_L), 8948 OPC_CVT_PS_PW = FOP(38, FMT_W), 8949 8950 OPC_ADD_PS = FOP(0, FMT_PS), 8951 OPC_SUB_PS = FOP(1, FMT_PS), 8952 OPC_MUL_PS = FOP(2, FMT_PS), 8953 OPC_DIV_PS = FOP(3, FMT_PS), 8954 OPC_ABS_PS = FOP(5, FMT_PS), 8955 OPC_MOV_PS = FOP(6, FMT_PS), 8956 OPC_NEG_PS = FOP(7, FMT_PS), 8957 OPC_MOVCF_PS = FOP(17, FMT_PS), 8958 OPC_MOVZ_PS = FOP(18, FMT_PS), 8959 OPC_MOVN_PS = FOP(19, FMT_PS), 8960 OPC_ADDR_PS = FOP(24, FMT_PS), 8961 OPC_MULR_PS = FOP(26, FMT_PS), 8962 OPC_RECIP2_PS = FOP(28, FMT_PS), 8963 OPC_RECIP1_PS = FOP(29, FMT_PS), 8964 OPC_RSQRT1_PS = FOP(30, FMT_PS), 8965 OPC_RSQRT2_PS = FOP(31, FMT_PS), 8966 8967 OPC_CVT_S_PU = FOP(32, FMT_PS), 8968 OPC_CVT_PW_PS = FOP(36, FMT_PS), 8969 OPC_CVT_S_PL = FOP(40, FMT_PS), 8970 OPC_PLL_PS = FOP(44, FMT_PS), 8971 OPC_PLU_PS = FOP(45, FMT_PS), 8972 OPC_PUL_PS = FOP(46, FMT_PS), 8973 OPC_PUU_PS = FOP(47, FMT_PS), 8974 OPC_CMP_F_PS = FOP(48, FMT_PS), 8975 OPC_CMP_UN_PS = FOP(49, FMT_PS), 8976 OPC_CMP_EQ_PS = FOP(50, FMT_PS), 8977 OPC_CMP_UEQ_PS = FOP(51, FMT_PS), 8978 OPC_CMP_OLT_PS = FOP(52, FMT_PS), 8979 OPC_CMP_ULT_PS = FOP(53, FMT_PS), 8980 OPC_CMP_OLE_PS = FOP(54, FMT_PS), 8981 OPC_CMP_ULE_PS = FOP(55, FMT_PS), 8982 OPC_CMP_SF_PS = FOP(56, FMT_PS), 8983 OPC_CMP_NGLE_PS = FOP(57, FMT_PS), 8984 OPC_CMP_SEQ_PS = FOP(58, FMT_PS), 8985 OPC_CMP_NGL_PS = FOP(59, FMT_PS), 8986 OPC_CMP_LT_PS = FOP(60, FMT_PS), 8987 OPC_CMP_NGE_PS = FOP(61, FMT_PS), 8988 OPC_CMP_LE_PS = FOP(62, FMT_PS), 8989 OPC_CMP_NGT_PS = FOP(63, FMT_PS), 8990 }; 8991 8992 enum r6_f_cmp_op { 8993 R6_OPC_CMP_AF_S = FOP(0, FMT_W), 8994 R6_OPC_CMP_UN_S = FOP(1, FMT_W), 8995 R6_OPC_CMP_EQ_S = FOP(2, FMT_W), 8996 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W), 8997 R6_OPC_CMP_LT_S = FOP(4, FMT_W), 8998 R6_OPC_CMP_ULT_S = FOP(5, FMT_W), 8999 R6_OPC_CMP_LE_S = FOP(6, FMT_W), 9000 R6_OPC_CMP_ULE_S = FOP(7, FMT_W), 9001 R6_OPC_CMP_SAF_S = FOP(8, FMT_W), 9002 R6_OPC_CMP_SUN_S = FOP(9, FMT_W), 9003 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W), 9004 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W), 9005 R6_OPC_CMP_SLT_S = FOP(12, FMT_W), 9006 R6_OPC_CMP_SULT_S = FOP(13, FMT_W), 9007 R6_OPC_CMP_SLE_S = FOP(14, FMT_W), 9008 R6_OPC_CMP_SULE_S = FOP(15, FMT_W), 9009 R6_OPC_CMP_OR_S = FOP(17, FMT_W), 9010 R6_OPC_CMP_UNE_S = FOP(18, FMT_W), 9011 R6_OPC_CMP_NE_S = FOP(19, FMT_W), 9012 R6_OPC_CMP_SOR_S = FOP(25, FMT_W), 9013 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W), 9014 R6_OPC_CMP_SNE_S = FOP(27, FMT_W), 9015 9016 R6_OPC_CMP_AF_D = FOP(0, FMT_L), 9017 R6_OPC_CMP_UN_D = FOP(1, FMT_L), 9018 R6_OPC_CMP_EQ_D = FOP(2, FMT_L), 9019 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L), 9020 R6_OPC_CMP_LT_D = FOP(4, FMT_L), 9021 R6_OPC_CMP_ULT_D = FOP(5, FMT_L), 9022 R6_OPC_CMP_LE_D = FOP(6, FMT_L), 9023 R6_OPC_CMP_ULE_D = FOP(7, FMT_L), 9024 R6_OPC_CMP_SAF_D = FOP(8, FMT_L), 9025 R6_OPC_CMP_SUN_D = FOP(9, FMT_L), 9026 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L), 9027 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L), 9028 R6_OPC_CMP_SLT_D = FOP(12, FMT_L), 9029 R6_OPC_CMP_SULT_D = FOP(13, FMT_L), 9030 R6_OPC_CMP_SLE_D = FOP(14, FMT_L), 9031 R6_OPC_CMP_SULE_D = FOP(15, FMT_L), 9032 R6_OPC_CMP_OR_D = FOP(17, FMT_L), 9033 R6_OPC_CMP_UNE_D = FOP(18, FMT_L), 9034 R6_OPC_CMP_NE_D = FOP(19, FMT_L), 9035 R6_OPC_CMP_SOR_D = FOP(25, FMT_L), 9036 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L), 9037 R6_OPC_CMP_SNE_D = FOP(27, FMT_L), 9038 }; 9039 9040 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) 9041 { 9042 TCGv t0 = tcg_temp_new(); 9043 9044 switch (opc) { 9045 case OPC_MFC1: 9046 { 9047 TCGv_i32 fp0 = tcg_temp_new_i32(); 9048 9049 gen_load_fpr32(ctx, fp0, fs); 9050 tcg_gen_ext_i32_tl(t0, fp0); 9051 } 9052 gen_store_gpr(t0, rt); 9053 break; 9054 case OPC_MTC1: 9055 gen_load_gpr(t0, rt); 9056 { 9057 TCGv_i32 fp0 = tcg_temp_new_i32(); 9058 9059 tcg_gen_trunc_tl_i32(fp0, t0); 9060 gen_store_fpr32(ctx, fp0, fs); 9061 } 9062 break; 9063 case OPC_CFC1: 9064 gen_helper_1e0i(cfc1, t0, fs); 9065 gen_store_gpr(t0, rt); 9066 break; 9067 case OPC_CTC1: 9068 gen_load_gpr(t0, rt); 9069 save_cpu_state(ctx, 0); 9070 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt); 9071 /* Stop translation as we may have changed hflags */ 9072 ctx->base.is_jmp = DISAS_STOP; 9073 break; 9074 #if defined(TARGET_MIPS64) 9075 case OPC_DMFC1: 9076 gen_load_fpr64(ctx, t0, fs); 9077 gen_store_gpr(t0, rt); 9078 break; 9079 case OPC_DMTC1: 9080 gen_load_gpr(t0, rt); 9081 gen_store_fpr64(ctx, t0, fs); 9082 break; 9083 #endif 9084 case OPC_MFHC1: 9085 { 9086 TCGv_i32 fp0 = tcg_temp_new_i32(); 9087 9088 gen_load_fpr32h(ctx, fp0, fs); 9089 tcg_gen_ext_i32_tl(t0, fp0); 9090 } 9091 gen_store_gpr(t0, rt); 9092 break; 9093 case OPC_MTHC1: 9094 gen_load_gpr(t0, rt); 9095 { 9096 TCGv_i32 fp0 = tcg_temp_new_i32(); 9097 9098 tcg_gen_trunc_tl_i32(fp0, t0); 9099 gen_store_fpr32h(ctx, fp0, fs); 9100 } 9101 break; 9102 default: 9103 MIPS_INVAL("cp1 move"); 9104 gen_reserved_instruction(ctx); 9105 return; 9106 } 9107 } 9108 9109 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf) 9110 { 9111 TCGLabel *l1; 9112 TCGCond cond; 9113 TCGv_i32 t0; 9114 9115 if (rd == 0) { 9116 /* Treat as NOP. */ 9117 return; 9118 } 9119 9120 if (tf) { 9121 cond = TCG_COND_EQ; 9122 } else { 9123 cond = TCG_COND_NE; 9124 } 9125 9126 l1 = gen_new_label(); 9127 t0 = tcg_temp_new_i32(); 9128 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9129 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9130 gen_load_gpr(cpu_gpr[rd], rs); 9131 gen_set_label(l1); 9132 } 9133 9134 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, 9135 int tf) 9136 { 9137 int cond; 9138 TCGv_i32 t0 = tcg_temp_new_i32(); 9139 TCGLabel *l1 = gen_new_label(); 9140 9141 if (tf) { 9142 cond = TCG_COND_EQ; 9143 } else { 9144 cond = TCG_COND_NE; 9145 } 9146 9147 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9148 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9149 gen_load_fpr32(ctx, t0, fs); 9150 gen_store_fpr32(ctx, t0, fd); 9151 gen_set_label(l1); 9152 } 9153 9154 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, 9155 int tf) 9156 { 9157 int cond; 9158 TCGv_i32 t0 = tcg_temp_new_i32(); 9159 TCGv_i64 fp0; 9160 TCGLabel *l1 = gen_new_label(); 9161 9162 if (tf) { 9163 cond = TCG_COND_EQ; 9164 } else { 9165 cond = TCG_COND_NE; 9166 } 9167 9168 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9169 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9170 fp0 = tcg_temp_new_i64(); 9171 gen_load_fpr64(ctx, fp0, fs); 9172 gen_store_fpr64(ctx, fp0, fd); 9173 gen_set_label(l1); 9174 } 9175 9176 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, 9177 int cc, int tf) 9178 { 9179 int cond; 9180 TCGv_i32 t0 = tcg_temp_new_i32(); 9181 TCGLabel *l1 = gen_new_label(); 9182 TCGLabel *l2 = gen_new_label(); 9183 9184 if (tf) { 9185 cond = TCG_COND_EQ; 9186 } else { 9187 cond = TCG_COND_NE; 9188 } 9189 9190 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9191 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9192 gen_load_fpr32(ctx, t0, fs); 9193 gen_store_fpr32(ctx, t0, fd); 9194 gen_set_label(l1); 9195 9196 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1)); 9197 tcg_gen_brcondi_i32(cond, t0, 0, l2); 9198 gen_load_fpr32h(ctx, t0, fs); 9199 gen_store_fpr32h(ctx, t0, fd); 9200 gen_set_label(l2); 9201 } 9202 9203 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9204 int fs) 9205 { 9206 TCGv_i32 t1 = tcg_constant_i32(0); 9207 TCGv_i32 fp0 = tcg_temp_new_i32(); 9208 TCGv_i32 fp1 = tcg_temp_new_i32(); 9209 TCGv_i32 fp2 = tcg_temp_new_i32(); 9210 gen_load_fpr32(ctx, fp0, fd); 9211 gen_load_fpr32(ctx, fp1, ft); 9212 gen_load_fpr32(ctx, fp2, fs); 9213 9214 switch (op1) { 9215 case OPC_SEL_S: 9216 tcg_gen_andi_i32(fp0, fp0, 1); 9217 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9218 break; 9219 case OPC_SELEQZ_S: 9220 tcg_gen_andi_i32(fp1, fp1, 1); 9221 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9222 break; 9223 case OPC_SELNEZ_S: 9224 tcg_gen_andi_i32(fp1, fp1, 1); 9225 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9226 break; 9227 default: 9228 MIPS_INVAL("gen_sel_s"); 9229 gen_reserved_instruction(ctx); 9230 break; 9231 } 9232 9233 gen_store_fpr32(ctx, fp0, fd); 9234 } 9235 9236 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9237 int fs) 9238 { 9239 TCGv_i64 t1 = tcg_constant_i64(0); 9240 TCGv_i64 fp0 = tcg_temp_new_i64(); 9241 TCGv_i64 fp1 = tcg_temp_new_i64(); 9242 TCGv_i64 fp2 = tcg_temp_new_i64(); 9243 gen_load_fpr64(ctx, fp0, fd); 9244 gen_load_fpr64(ctx, fp1, ft); 9245 gen_load_fpr64(ctx, fp2, fs); 9246 9247 switch (op1) { 9248 case OPC_SEL_D: 9249 tcg_gen_andi_i64(fp0, fp0, 1); 9250 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9251 break; 9252 case OPC_SELEQZ_D: 9253 tcg_gen_andi_i64(fp1, fp1, 1); 9254 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9255 break; 9256 case OPC_SELNEZ_D: 9257 tcg_gen_andi_i64(fp1, fp1, 1); 9258 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9259 break; 9260 default: 9261 MIPS_INVAL("gen_sel_d"); 9262 gen_reserved_instruction(ctx); 9263 break; 9264 } 9265 9266 gen_store_fpr64(ctx, fp0, fd); 9267 } 9268 9269 static void gen_farith(DisasContext *ctx, enum fopcode op1, 9270 int ft, int fs, int fd, int cc) 9271 { 9272 uint32_t func = ctx->opcode & 0x3f; 9273 switch (op1) { 9274 case OPC_ADD_S: 9275 { 9276 TCGv_i32 fp0 = tcg_temp_new_i32(); 9277 TCGv_i32 fp1 = tcg_temp_new_i32(); 9278 9279 gen_load_fpr32(ctx, fp0, fs); 9280 gen_load_fpr32(ctx, fp1, ft); 9281 gen_helper_float_add_s(fp0, tcg_env, fp0, fp1); 9282 gen_store_fpr32(ctx, fp0, fd); 9283 } 9284 break; 9285 case OPC_SUB_S: 9286 { 9287 TCGv_i32 fp0 = tcg_temp_new_i32(); 9288 TCGv_i32 fp1 = tcg_temp_new_i32(); 9289 9290 gen_load_fpr32(ctx, fp0, fs); 9291 gen_load_fpr32(ctx, fp1, ft); 9292 gen_helper_float_sub_s(fp0, tcg_env, fp0, fp1); 9293 gen_store_fpr32(ctx, fp0, fd); 9294 } 9295 break; 9296 case OPC_MUL_S: 9297 { 9298 TCGv_i32 fp0 = tcg_temp_new_i32(); 9299 TCGv_i32 fp1 = tcg_temp_new_i32(); 9300 9301 gen_load_fpr32(ctx, fp0, fs); 9302 gen_load_fpr32(ctx, fp1, ft); 9303 gen_helper_float_mul_s(fp0, tcg_env, fp0, fp1); 9304 gen_store_fpr32(ctx, fp0, fd); 9305 } 9306 break; 9307 case OPC_DIV_S: 9308 { 9309 TCGv_i32 fp0 = tcg_temp_new_i32(); 9310 TCGv_i32 fp1 = tcg_temp_new_i32(); 9311 9312 gen_load_fpr32(ctx, fp0, fs); 9313 gen_load_fpr32(ctx, fp1, ft); 9314 gen_helper_float_div_s(fp0, tcg_env, fp0, fp1); 9315 gen_store_fpr32(ctx, fp0, fd); 9316 } 9317 break; 9318 case OPC_SQRT_S: 9319 { 9320 TCGv_i32 fp0 = tcg_temp_new_i32(); 9321 9322 gen_load_fpr32(ctx, fp0, fs); 9323 gen_helper_float_sqrt_s(fp0, tcg_env, fp0); 9324 gen_store_fpr32(ctx, fp0, fd); 9325 } 9326 break; 9327 case OPC_ABS_S: 9328 { 9329 TCGv_i32 fp0 = tcg_temp_new_i32(); 9330 9331 gen_load_fpr32(ctx, fp0, fs); 9332 if (ctx->abs2008) { 9333 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL); 9334 } else { 9335 gen_helper_float_abs_s(fp0, fp0); 9336 } 9337 gen_store_fpr32(ctx, fp0, fd); 9338 } 9339 break; 9340 case OPC_MOV_S: 9341 { 9342 TCGv_i32 fp0 = tcg_temp_new_i32(); 9343 9344 gen_load_fpr32(ctx, fp0, fs); 9345 gen_store_fpr32(ctx, fp0, fd); 9346 } 9347 break; 9348 case OPC_NEG_S: 9349 { 9350 TCGv_i32 fp0 = tcg_temp_new_i32(); 9351 9352 gen_load_fpr32(ctx, fp0, fs); 9353 if (ctx->abs2008) { 9354 tcg_gen_xori_i32(fp0, fp0, 1UL << 31); 9355 } else { 9356 gen_helper_float_chs_s(fp0, fp0); 9357 } 9358 gen_store_fpr32(ctx, fp0, fd); 9359 } 9360 break; 9361 case OPC_ROUND_L_S: 9362 check_cp1_64bitmode(ctx); 9363 { 9364 TCGv_i32 fp32 = tcg_temp_new_i32(); 9365 TCGv_i64 fp64 = tcg_temp_new_i64(); 9366 9367 gen_load_fpr32(ctx, fp32, fs); 9368 if (ctx->nan2008) { 9369 gen_helper_float_round_2008_l_s(fp64, tcg_env, fp32); 9370 } else { 9371 gen_helper_float_round_l_s(fp64, tcg_env, fp32); 9372 } 9373 gen_store_fpr64(ctx, fp64, fd); 9374 } 9375 break; 9376 case OPC_TRUNC_L_S: 9377 check_cp1_64bitmode(ctx); 9378 { 9379 TCGv_i32 fp32 = tcg_temp_new_i32(); 9380 TCGv_i64 fp64 = tcg_temp_new_i64(); 9381 9382 gen_load_fpr32(ctx, fp32, fs); 9383 if (ctx->nan2008) { 9384 gen_helper_float_trunc_2008_l_s(fp64, tcg_env, fp32); 9385 } else { 9386 gen_helper_float_trunc_l_s(fp64, tcg_env, fp32); 9387 } 9388 gen_store_fpr64(ctx, fp64, fd); 9389 } 9390 break; 9391 case OPC_CEIL_L_S: 9392 check_cp1_64bitmode(ctx); 9393 { 9394 TCGv_i32 fp32 = tcg_temp_new_i32(); 9395 TCGv_i64 fp64 = tcg_temp_new_i64(); 9396 9397 gen_load_fpr32(ctx, fp32, fs); 9398 if (ctx->nan2008) { 9399 gen_helper_float_ceil_2008_l_s(fp64, tcg_env, fp32); 9400 } else { 9401 gen_helper_float_ceil_l_s(fp64, tcg_env, fp32); 9402 } 9403 gen_store_fpr64(ctx, fp64, fd); 9404 } 9405 break; 9406 case OPC_FLOOR_L_S: 9407 check_cp1_64bitmode(ctx); 9408 { 9409 TCGv_i32 fp32 = tcg_temp_new_i32(); 9410 TCGv_i64 fp64 = tcg_temp_new_i64(); 9411 9412 gen_load_fpr32(ctx, fp32, fs); 9413 if (ctx->nan2008) { 9414 gen_helper_float_floor_2008_l_s(fp64, tcg_env, fp32); 9415 } else { 9416 gen_helper_float_floor_l_s(fp64, tcg_env, fp32); 9417 } 9418 gen_store_fpr64(ctx, fp64, fd); 9419 } 9420 break; 9421 case OPC_ROUND_W_S: 9422 { 9423 TCGv_i32 fp0 = tcg_temp_new_i32(); 9424 9425 gen_load_fpr32(ctx, fp0, fs); 9426 if (ctx->nan2008) { 9427 gen_helper_float_round_2008_w_s(fp0, tcg_env, fp0); 9428 } else { 9429 gen_helper_float_round_w_s(fp0, tcg_env, fp0); 9430 } 9431 gen_store_fpr32(ctx, fp0, fd); 9432 } 9433 break; 9434 case OPC_TRUNC_W_S: 9435 { 9436 TCGv_i32 fp0 = tcg_temp_new_i32(); 9437 9438 gen_load_fpr32(ctx, fp0, fs); 9439 if (ctx->nan2008) { 9440 gen_helper_float_trunc_2008_w_s(fp0, tcg_env, fp0); 9441 } else { 9442 gen_helper_float_trunc_w_s(fp0, tcg_env, fp0); 9443 } 9444 gen_store_fpr32(ctx, fp0, fd); 9445 } 9446 break; 9447 case OPC_CEIL_W_S: 9448 { 9449 TCGv_i32 fp0 = tcg_temp_new_i32(); 9450 9451 gen_load_fpr32(ctx, fp0, fs); 9452 if (ctx->nan2008) { 9453 gen_helper_float_ceil_2008_w_s(fp0, tcg_env, fp0); 9454 } else { 9455 gen_helper_float_ceil_w_s(fp0, tcg_env, fp0); 9456 } 9457 gen_store_fpr32(ctx, fp0, fd); 9458 } 9459 break; 9460 case OPC_FLOOR_W_S: 9461 { 9462 TCGv_i32 fp0 = tcg_temp_new_i32(); 9463 9464 gen_load_fpr32(ctx, fp0, fs); 9465 if (ctx->nan2008) { 9466 gen_helper_float_floor_2008_w_s(fp0, tcg_env, fp0); 9467 } else { 9468 gen_helper_float_floor_w_s(fp0, tcg_env, fp0); 9469 } 9470 gen_store_fpr32(ctx, fp0, fd); 9471 } 9472 break; 9473 case OPC_SEL_S: 9474 check_insn(ctx, ISA_MIPS_R6); 9475 gen_sel_s(ctx, op1, fd, ft, fs); 9476 break; 9477 case OPC_SELEQZ_S: 9478 check_insn(ctx, ISA_MIPS_R6); 9479 gen_sel_s(ctx, op1, fd, ft, fs); 9480 break; 9481 case OPC_SELNEZ_S: 9482 check_insn(ctx, ISA_MIPS_R6); 9483 gen_sel_s(ctx, op1, fd, ft, fs); 9484 break; 9485 case OPC_MOVCF_S: 9486 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9487 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 9488 break; 9489 case OPC_MOVZ_S: 9490 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9491 { 9492 TCGLabel *l1 = gen_new_label(); 9493 TCGv_i32 fp0; 9494 9495 if (ft != 0) { 9496 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 9497 } 9498 fp0 = tcg_temp_new_i32(); 9499 gen_load_fpr32(ctx, fp0, fs); 9500 gen_store_fpr32(ctx, fp0, fd); 9501 gen_set_label(l1); 9502 } 9503 break; 9504 case OPC_MOVN_S: 9505 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9506 { 9507 TCGLabel *l1 = gen_new_label(); 9508 TCGv_i32 fp0; 9509 9510 if (ft != 0) { 9511 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 9512 fp0 = tcg_temp_new_i32(); 9513 gen_load_fpr32(ctx, fp0, fs); 9514 gen_store_fpr32(ctx, fp0, fd); 9515 gen_set_label(l1); 9516 } 9517 } 9518 break; 9519 case OPC_RECIP_S: 9520 { 9521 TCGv_i32 fp0 = tcg_temp_new_i32(); 9522 9523 gen_load_fpr32(ctx, fp0, fs); 9524 gen_helper_float_recip_s(fp0, tcg_env, fp0); 9525 gen_store_fpr32(ctx, fp0, fd); 9526 } 9527 break; 9528 case OPC_RSQRT_S: 9529 { 9530 TCGv_i32 fp0 = tcg_temp_new_i32(); 9531 9532 gen_load_fpr32(ctx, fp0, fs); 9533 gen_helper_float_rsqrt_s(fp0, tcg_env, fp0); 9534 gen_store_fpr32(ctx, fp0, fd); 9535 } 9536 break; 9537 case OPC_MADDF_S: 9538 check_insn(ctx, ISA_MIPS_R6); 9539 { 9540 TCGv_i32 fp0 = tcg_temp_new_i32(); 9541 TCGv_i32 fp1 = tcg_temp_new_i32(); 9542 TCGv_i32 fp2 = tcg_temp_new_i32(); 9543 gen_load_fpr32(ctx, fp0, fs); 9544 gen_load_fpr32(ctx, fp1, ft); 9545 gen_load_fpr32(ctx, fp2, fd); 9546 gen_helper_float_maddf_s(fp2, tcg_env, fp0, fp1, fp2); 9547 gen_store_fpr32(ctx, fp2, fd); 9548 } 9549 break; 9550 case OPC_MSUBF_S: 9551 check_insn(ctx, ISA_MIPS_R6); 9552 { 9553 TCGv_i32 fp0 = tcg_temp_new_i32(); 9554 TCGv_i32 fp1 = tcg_temp_new_i32(); 9555 TCGv_i32 fp2 = tcg_temp_new_i32(); 9556 gen_load_fpr32(ctx, fp0, fs); 9557 gen_load_fpr32(ctx, fp1, ft); 9558 gen_load_fpr32(ctx, fp2, fd); 9559 gen_helper_float_msubf_s(fp2, tcg_env, fp0, fp1, fp2); 9560 gen_store_fpr32(ctx, fp2, fd); 9561 } 9562 break; 9563 case OPC_RINT_S: 9564 check_insn(ctx, ISA_MIPS_R6); 9565 { 9566 TCGv_i32 fp0 = tcg_temp_new_i32(); 9567 gen_load_fpr32(ctx, fp0, fs); 9568 gen_helper_float_rint_s(fp0, tcg_env, fp0); 9569 gen_store_fpr32(ctx, fp0, fd); 9570 } 9571 break; 9572 case OPC_CLASS_S: 9573 check_insn(ctx, ISA_MIPS_R6); 9574 { 9575 TCGv_i32 fp0 = tcg_temp_new_i32(); 9576 gen_load_fpr32(ctx, fp0, fs); 9577 gen_helper_float_class_s(fp0, tcg_env, fp0); 9578 gen_store_fpr32(ctx, fp0, fd); 9579 } 9580 break; 9581 case OPC_MIN_S: /* OPC_RECIP2_S */ 9582 if (ctx->insn_flags & ISA_MIPS_R6) { 9583 /* OPC_MIN_S */ 9584 TCGv_i32 fp0 = tcg_temp_new_i32(); 9585 TCGv_i32 fp1 = tcg_temp_new_i32(); 9586 TCGv_i32 fp2 = tcg_temp_new_i32(); 9587 gen_load_fpr32(ctx, fp0, fs); 9588 gen_load_fpr32(ctx, fp1, ft); 9589 gen_helper_float_min_s(fp2, tcg_env, fp0, fp1); 9590 gen_store_fpr32(ctx, fp2, fd); 9591 } else { 9592 /* OPC_RECIP2_S */ 9593 check_cp1_64bitmode(ctx); 9594 { 9595 TCGv_i32 fp0 = tcg_temp_new_i32(); 9596 TCGv_i32 fp1 = tcg_temp_new_i32(); 9597 9598 gen_load_fpr32(ctx, fp0, fs); 9599 gen_load_fpr32(ctx, fp1, ft); 9600 gen_helper_float_recip2_s(fp0, tcg_env, fp0, fp1); 9601 gen_store_fpr32(ctx, fp0, fd); 9602 } 9603 } 9604 break; 9605 case OPC_MINA_S: /* OPC_RECIP1_S */ 9606 if (ctx->insn_flags & ISA_MIPS_R6) { 9607 /* OPC_MINA_S */ 9608 TCGv_i32 fp0 = tcg_temp_new_i32(); 9609 TCGv_i32 fp1 = tcg_temp_new_i32(); 9610 TCGv_i32 fp2 = tcg_temp_new_i32(); 9611 gen_load_fpr32(ctx, fp0, fs); 9612 gen_load_fpr32(ctx, fp1, ft); 9613 gen_helper_float_mina_s(fp2, tcg_env, fp0, fp1); 9614 gen_store_fpr32(ctx, fp2, fd); 9615 } else { 9616 /* OPC_RECIP1_S */ 9617 check_cp1_64bitmode(ctx); 9618 { 9619 TCGv_i32 fp0 = tcg_temp_new_i32(); 9620 9621 gen_load_fpr32(ctx, fp0, fs); 9622 gen_helper_float_recip1_s(fp0, tcg_env, fp0); 9623 gen_store_fpr32(ctx, fp0, fd); 9624 } 9625 } 9626 break; 9627 case OPC_MAX_S: /* OPC_RSQRT1_S */ 9628 if (ctx->insn_flags & ISA_MIPS_R6) { 9629 /* OPC_MAX_S */ 9630 TCGv_i32 fp0 = tcg_temp_new_i32(); 9631 TCGv_i32 fp1 = tcg_temp_new_i32(); 9632 gen_load_fpr32(ctx, fp0, fs); 9633 gen_load_fpr32(ctx, fp1, ft); 9634 gen_helper_float_max_s(fp1, tcg_env, fp0, fp1); 9635 gen_store_fpr32(ctx, fp1, fd); 9636 } else { 9637 /* OPC_RSQRT1_S */ 9638 check_cp1_64bitmode(ctx); 9639 { 9640 TCGv_i32 fp0 = tcg_temp_new_i32(); 9641 9642 gen_load_fpr32(ctx, fp0, fs); 9643 gen_helper_float_rsqrt1_s(fp0, tcg_env, fp0); 9644 gen_store_fpr32(ctx, fp0, fd); 9645 } 9646 } 9647 break; 9648 case OPC_MAXA_S: /* OPC_RSQRT2_S */ 9649 if (ctx->insn_flags & ISA_MIPS_R6) { 9650 /* OPC_MAXA_S */ 9651 TCGv_i32 fp0 = tcg_temp_new_i32(); 9652 TCGv_i32 fp1 = tcg_temp_new_i32(); 9653 gen_load_fpr32(ctx, fp0, fs); 9654 gen_load_fpr32(ctx, fp1, ft); 9655 gen_helper_float_maxa_s(fp1, tcg_env, fp0, fp1); 9656 gen_store_fpr32(ctx, fp1, fd); 9657 } else { 9658 /* OPC_RSQRT2_S */ 9659 check_cp1_64bitmode(ctx); 9660 { 9661 TCGv_i32 fp0 = tcg_temp_new_i32(); 9662 TCGv_i32 fp1 = tcg_temp_new_i32(); 9663 9664 gen_load_fpr32(ctx, fp0, fs); 9665 gen_load_fpr32(ctx, fp1, ft); 9666 gen_helper_float_rsqrt2_s(fp0, tcg_env, fp0, fp1); 9667 gen_store_fpr32(ctx, fp0, fd); 9668 } 9669 } 9670 break; 9671 case OPC_CVT_D_S: 9672 check_cp1_registers(ctx, fd); 9673 { 9674 TCGv_i32 fp32 = tcg_temp_new_i32(); 9675 TCGv_i64 fp64 = tcg_temp_new_i64(); 9676 9677 gen_load_fpr32(ctx, fp32, fs); 9678 gen_helper_float_cvtd_s(fp64, tcg_env, fp32); 9679 gen_store_fpr64(ctx, fp64, fd); 9680 } 9681 break; 9682 case OPC_CVT_W_S: 9683 { 9684 TCGv_i32 fp0 = tcg_temp_new_i32(); 9685 9686 gen_load_fpr32(ctx, fp0, fs); 9687 if (ctx->nan2008) { 9688 gen_helper_float_cvt_2008_w_s(fp0, tcg_env, fp0); 9689 } else { 9690 gen_helper_float_cvt_w_s(fp0, tcg_env, fp0); 9691 } 9692 gen_store_fpr32(ctx, fp0, fd); 9693 } 9694 break; 9695 case OPC_CVT_L_S: 9696 check_cp1_64bitmode(ctx); 9697 { 9698 TCGv_i32 fp32 = tcg_temp_new_i32(); 9699 TCGv_i64 fp64 = tcg_temp_new_i64(); 9700 9701 gen_load_fpr32(ctx, fp32, fs); 9702 if (ctx->nan2008) { 9703 gen_helper_float_cvt_2008_l_s(fp64, tcg_env, fp32); 9704 } else { 9705 gen_helper_float_cvt_l_s(fp64, tcg_env, fp32); 9706 } 9707 gen_store_fpr64(ctx, fp64, fd); 9708 } 9709 break; 9710 case OPC_CVT_PS_S: 9711 check_ps(ctx); 9712 { 9713 TCGv_i64 fp64 = tcg_temp_new_i64(); 9714 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 9715 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 9716 9717 gen_load_fpr32(ctx, fp32_0, fs); 9718 gen_load_fpr32(ctx, fp32_1, ft); 9719 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); 9720 gen_store_fpr64(ctx, fp64, fd); 9721 } 9722 break; 9723 case OPC_CMP_F_S: 9724 case OPC_CMP_UN_S: 9725 case OPC_CMP_EQ_S: 9726 case OPC_CMP_UEQ_S: 9727 case OPC_CMP_OLT_S: 9728 case OPC_CMP_ULT_S: 9729 case OPC_CMP_OLE_S: 9730 case OPC_CMP_ULE_S: 9731 case OPC_CMP_SF_S: 9732 case OPC_CMP_NGLE_S: 9733 case OPC_CMP_SEQ_S: 9734 case OPC_CMP_NGL_S: 9735 case OPC_CMP_LT_S: 9736 case OPC_CMP_NGE_S: 9737 case OPC_CMP_LE_S: 9738 case OPC_CMP_NGT_S: 9739 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9740 if (ctx->opcode & (1 << 6)) { 9741 gen_cmpabs_s(ctx, func - 48, ft, fs, cc); 9742 } else { 9743 gen_cmp_s(ctx, func - 48, ft, fs, cc); 9744 } 9745 break; 9746 case OPC_ADD_D: 9747 check_cp1_registers(ctx, fs | ft | fd); 9748 { 9749 TCGv_i64 fp0 = tcg_temp_new_i64(); 9750 TCGv_i64 fp1 = tcg_temp_new_i64(); 9751 9752 gen_load_fpr64(ctx, fp0, fs); 9753 gen_load_fpr64(ctx, fp1, ft); 9754 gen_helper_float_add_d(fp0, tcg_env, fp0, fp1); 9755 gen_store_fpr64(ctx, fp0, fd); 9756 } 9757 break; 9758 case OPC_SUB_D: 9759 check_cp1_registers(ctx, fs | ft | fd); 9760 { 9761 TCGv_i64 fp0 = tcg_temp_new_i64(); 9762 TCGv_i64 fp1 = tcg_temp_new_i64(); 9763 9764 gen_load_fpr64(ctx, fp0, fs); 9765 gen_load_fpr64(ctx, fp1, ft); 9766 gen_helper_float_sub_d(fp0, tcg_env, fp0, fp1); 9767 gen_store_fpr64(ctx, fp0, fd); 9768 } 9769 break; 9770 case OPC_MUL_D: 9771 check_cp1_registers(ctx, fs | ft | fd); 9772 { 9773 TCGv_i64 fp0 = tcg_temp_new_i64(); 9774 TCGv_i64 fp1 = tcg_temp_new_i64(); 9775 9776 gen_load_fpr64(ctx, fp0, fs); 9777 gen_load_fpr64(ctx, fp1, ft); 9778 gen_helper_float_mul_d(fp0, tcg_env, fp0, fp1); 9779 gen_store_fpr64(ctx, fp0, fd); 9780 } 9781 break; 9782 case OPC_DIV_D: 9783 check_cp1_registers(ctx, fs | ft | fd); 9784 { 9785 TCGv_i64 fp0 = tcg_temp_new_i64(); 9786 TCGv_i64 fp1 = tcg_temp_new_i64(); 9787 9788 gen_load_fpr64(ctx, fp0, fs); 9789 gen_load_fpr64(ctx, fp1, ft); 9790 gen_helper_float_div_d(fp0, tcg_env, fp0, fp1); 9791 gen_store_fpr64(ctx, fp0, fd); 9792 } 9793 break; 9794 case OPC_SQRT_D: 9795 check_cp1_registers(ctx, fs | fd); 9796 { 9797 TCGv_i64 fp0 = tcg_temp_new_i64(); 9798 9799 gen_load_fpr64(ctx, fp0, fs); 9800 gen_helper_float_sqrt_d(fp0, tcg_env, fp0); 9801 gen_store_fpr64(ctx, fp0, fd); 9802 } 9803 break; 9804 case OPC_ABS_D: 9805 check_cp1_registers(ctx, fs | fd); 9806 { 9807 TCGv_i64 fp0 = tcg_temp_new_i64(); 9808 9809 gen_load_fpr64(ctx, fp0, fs); 9810 if (ctx->abs2008) { 9811 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL); 9812 } else { 9813 gen_helper_float_abs_d(fp0, fp0); 9814 } 9815 gen_store_fpr64(ctx, fp0, fd); 9816 } 9817 break; 9818 case OPC_MOV_D: 9819 check_cp1_registers(ctx, fs | fd); 9820 { 9821 TCGv_i64 fp0 = tcg_temp_new_i64(); 9822 9823 gen_load_fpr64(ctx, fp0, fs); 9824 gen_store_fpr64(ctx, fp0, fd); 9825 } 9826 break; 9827 case OPC_NEG_D: 9828 check_cp1_registers(ctx, fs | fd); 9829 { 9830 TCGv_i64 fp0 = tcg_temp_new_i64(); 9831 9832 gen_load_fpr64(ctx, fp0, fs); 9833 if (ctx->abs2008) { 9834 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63); 9835 } else { 9836 gen_helper_float_chs_d(fp0, fp0); 9837 } 9838 gen_store_fpr64(ctx, fp0, fd); 9839 } 9840 break; 9841 case OPC_ROUND_L_D: 9842 check_cp1_64bitmode(ctx); 9843 { 9844 TCGv_i64 fp0 = tcg_temp_new_i64(); 9845 9846 gen_load_fpr64(ctx, fp0, fs); 9847 if (ctx->nan2008) { 9848 gen_helper_float_round_2008_l_d(fp0, tcg_env, fp0); 9849 } else { 9850 gen_helper_float_round_l_d(fp0, tcg_env, fp0); 9851 } 9852 gen_store_fpr64(ctx, fp0, fd); 9853 } 9854 break; 9855 case OPC_TRUNC_L_D: 9856 check_cp1_64bitmode(ctx); 9857 { 9858 TCGv_i64 fp0 = tcg_temp_new_i64(); 9859 9860 gen_load_fpr64(ctx, fp0, fs); 9861 if (ctx->nan2008) { 9862 gen_helper_float_trunc_2008_l_d(fp0, tcg_env, fp0); 9863 } else { 9864 gen_helper_float_trunc_l_d(fp0, tcg_env, fp0); 9865 } 9866 gen_store_fpr64(ctx, fp0, fd); 9867 } 9868 break; 9869 case OPC_CEIL_L_D: 9870 check_cp1_64bitmode(ctx); 9871 { 9872 TCGv_i64 fp0 = tcg_temp_new_i64(); 9873 9874 gen_load_fpr64(ctx, fp0, fs); 9875 if (ctx->nan2008) { 9876 gen_helper_float_ceil_2008_l_d(fp0, tcg_env, fp0); 9877 } else { 9878 gen_helper_float_ceil_l_d(fp0, tcg_env, fp0); 9879 } 9880 gen_store_fpr64(ctx, fp0, fd); 9881 } 9882 break; 9883 case OPC_FLOOR_L_D: 9884 check_cp1_64bitmode(ctx); 9885 { 9886 TCGv_i64 fp0 = tcg_temp_new_i64(); 9887 9888 gen_load_fpr64(ctx, fp0, fs); 9889 if (ctx->nan2008) { 9890 gen_helper_float_floor_2008_l_d(fp0, tcg_env, fp0); 9891 } else { 9892 gen_helper_float_floor_l_d(fp0, tcg_env, fp0); 9893 } 9894 gen_store_fpr64(ctx, fp0, fd); 9895 } 9896 break; 9897 case OPC_ROUND_W_D: 9898 check_cp1_registers(ctx, fs); 9899 { 9900 TCGv_i32 fp32 = tcg_temp_new_i32(); 9901 TCGv_i64 fp64 = tcg_temp_new_i64(); 9902 9903 gen_load_fpr64(ctx, fp64, fs); 9904 if (ctx->nan2008) { 9905 gen_helper_float_round_2008_w_d(fp32, tcg_env, fp64); 9906 } else { 9907 gen_helper_float_round_w_d(fp32, tcg_env, fp64); 9908 } 9909 gen_store_fpr32(ctx, fp32, fd); 9910 } 9911 break; 9912 case OPC_TRUNC_W_D: 9913 check_cp1_registers(ctx, fs); 9914 { 9915 TCGv_i32 fp32 = tcg_temp_new_i32(); 9916 TCGv_i64 fp64 = tcg_temp_new_i64(); 9917 9918 gen_load_fpr64(ctx, fp64, fs); 9919 if (ctx->nan2008) { 9920 gen_helper_float_trunc_2008_w_d(fp32, tcg_env, fp64); 9921 } else { 9922 gen_helper_float_trunc_w_d(fp32, tcg_env, fp64); 9923 } 9924 gen_store_fpr32(ctx, fp32, fd); 9925 } 9926 break; 9927 case OPC_CEIL_W_D: 9928 check_cp1_registers(ctx, fs); 9929 { 9930 TCGv_i32 fp32 = tcg_temp_new_i32(); 9931 TCGv_i64 fp64 = tcg_temp_new_i64(); 9932 9933 gen_load_fpr64(ctx, fp64, fs); 9934 if (ctx->nan2008) { 9935 gen_helper_float_ceil_2008_w_d(fp32, tcg_env, fp64); 9936 } else { 9937 gen_helper_float_ceil_w_d(fp32, tcg_env, fp64); 9938 } 9939 gen_store_fpr32(ctx, fp32, fd); 9940 } 9941 break; 9942 case OPC_FLOOR_W_D: 9943 check_cp1_registers(ctx, fs); 9944 { 9945 TCGv_i32 fp32 = tcg_temp_new_i32(); 9946 TCGv_i64 fp64 = tcg_temp_new_i64(); 9947 9948 gen_load_fpr64(ctx, fp64, fs); 9949 if (ctx->nan2008) { 9950 gen_helper_float_floor_2008_w_d(fp32, tcg_env, fp64); 9951 } else { 9952 gen_helper_float_floor_w_d(fp32, tcg_env, fp64); 9953 } 9954 gen_store_fpr32(ctx, fp32, fd); 9955 } 9956 break; 9957 case OPC_SEL_D: 9958 check_insn(ctx, ISA_MIPS_R6); 9959 gen_sel_d(ctx, op1, fd, ft, fs); 9960 break; 9961 case OPC_SELEQZ_D: 9962 check_insn(ctx, ISA_MIPS_R6); 9963 gen_sel_d(ctx, op1, fd, ft, fs); 9964 break; 9965 case OPC_SELNEZ_D: 9966 check_insn(ctx, ISA_MIPS_R6); 9967 gen_sel_d(ctx, op1, fd, ft, fs); 9968 break; 9969 case OPC_MOVCF_D: 9970 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9971 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 9972 break; 9973 case OPC_MOVZ_D: 9974 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9975 { 9976 TCGLabel *l1 = gen_new_label(); 9977 TCGv_i64 fp0; 9978 9979 if (ft != 0) { 9980 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 9981 } 9982 fp0 = tcg_temp_new_i64(); 9983 gen_load_fpr64(ctx, fp0, fs); 9984 gen_store_fpr64(ctx, fp0, fd); 9985 gen_set_label(l1); 9986 } 9987 break; 9988 case OPC_MOVN_D: 9989 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9990 { 9991 TCGLabel *l1 = gen_new_label(); 9992 TCGv_i64 fp0; 9993 9994 if (ft != 0) { 9995 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 9996 fp0 = tcg_temp_new_i64(); 9997 gen_load_fpr64(ctx, fp0, fs); 9998 gen_store_fpr64(ctx, fp0, fd); 9999 gen_set_label(l1); 10000 } 10001 } 10002 break; 10003 case OPC_RECIP_D: 10004 check_cp1_registers(ctx, fs | fd); 10005 { 10006 TCGv_i64 fp0 = tcg_temp_new_i64(); 10007 10008 gen_load_fpr64(ctx, fp0, fs); 10009 gen_helper_float_recip_d(fp0, tcg_env, fp0); 10010 gen_store_fpr64(ctx, fp0, fd); 10011 } 10012 break; 10013 case OPC_RSQRT_D: 10014 check_cp1_registers(ctx, fs | fd); 10015 { 10016 TCGv_i64 fp0 = tcg_temp_new_i64(); 10017 10018 gen_load_fpr64(ctx, fp0, fs); 10019 gen_helper_float_rsqrt_d(fp0, tcg_env, fp0); 10020 gen_store_fpr64(ctx, fp0, fd); 10021 } 10022 break; 10023 case OPC_MADDF_D: 10024 check_insn(ctx, ISA_MIPS_R6); 10025 { 10026 TCGv_i64 fp0 = tcg_temp_new_i64(); 10027 TCGv_i64 fp1 = tcg_temp_new_i64(); 10028 TCGv_i64 fp2 = tcg_temp_new_i64(); 10029 gen_load_fpr64(ctx, fp0, fs); 10030 gen_load_fpr64(ctx, fp1, ft); 10031 gen_load_fpr64(ctx, fp2, fd); 10032 gen_helper_float_maddf_d(fp2, tcg_env, fp0, fp1, fp2); 10033 gen_store_fpr64(ctx, fp2, fd); 10034 } 10035 break; 10036 case OPC_MSUBF_D: 10037 check_insn(ctx, ISA_MIPS_R6); 10038 { 10039 TCGv_i64 fp0 = tcg_temp_new_i64(); 10040 TCGv_i64 fp1 = tcg_temp_new_i64(); 10041 TCGv_i64 fp2 = tcg_temp_new_i64(); 10042 gen_load_fpr64(ctx, fp0, fs); 10043 gen_load_fpr64(ctx, fp1, ft); 10044 gen_load_fpr64(ctx, fp2, fd); 10045 gen_helper_float_msubf_d(fp2, tcg_env, fp0, fp1, fp2); 10046 gen_store_fpr64(ctx, fp2, fd); 10047 } 10048 break; 10049 case OPC_RINT_D: 10050 check_insn(ctx, ISA_MIPS_R6); 10051 { 10052 TCGv_i64 fp0 = tcg_temp_new_i64(); 10053 gen_load_fpr64(ctx, fp0, fs); 10054 gen_helper_float_rint_d(fp0, tcg_env, fp0); 10055 gen_store_fpr64(ctx, fp0, fd); 10056 } 10057 break; 10058 case OPC_CLASS_D: 10059 check_insn(ctx, ISA_MIPS_R6); 10060 { 10061 TCGv_i64 fp0 = tcg_temp_new_i64(); 10062 gen_load_fpr64(ctx, fp0, fs); 10063 gen_helper_float_class_d(fp0, tcg_env, fp0); 10064 gen_store_fpr64(ctx, fp0, fd); 10065 } 10066 break; 10067 case OPC_MIN_D: /* OPC_RECIP2_D */ 10068 if (ctx->insn_flags & ISA_MIPS_R6) { 10069 /* OPC_MIN_D */ 10070 TCGv_i64 fp0 = tcg_temp_new_i64(); 10071 TCGv_i64 fp1 = tcg_temp_new_i64(); 10072 gen_load_fpr64(ctx, fp0, fs); 10073 gen_load_fpr64(ctx, fp1, ft); 10074 gen_helper_float_min_d(fp1, tcg_env, fp0, fp1); 10075 gen_store_fpr64(ctx, fp1, fd); 10076 } else { 10077 /* OPC_RECIP2_D */ 10078 check_cp1_64bitmode(ctx); 10079 { 10080 TCGv_i64 fp0 = tcg_temp_new_i64(); 10081 TCGv_i64 fp1 = tcg_temp_new_i64(); 10082 10083 gen_load_fpr64(ctx, fp0, fs); 10084 gen_load_fpr64(ctx, fp1, ft); 10085 gen_helper_float_recip2_d(fp0, tcg_env, fp0, fp1); 10086 gen_store_fpr64(ctx, fp0, fd); 10087 } 10088 } 10089 break; 10090 case OPC_MINA_D: /* OPC_RECIP1_D */ 10091 if (ctx->insn_flags & ISA_MIPS_R6) { 10092 /* OPC_MINA_D */ 10093 TCGv_i64 fp0 = tcg_temp_new_i64(); 10094 TCGv_i64 fp1 = tcg_temp_new_i64(); 10095 gen_load_fpr64(ctx, fp0, fs); 10096 gen_load_fpr64(ctx, fp1, ft); 10097 gen_helper_float_mina_d(fp1, tcg_env, fp0, fp1); 10098 gen_store_fpr64(ctx, fp1, fd); 10099 } else { 10100 /* OPC_RECIP1_D */ 10101 check_cp1_64bitmode(ctx); 10102 { 10103 TCGv_i64 fp0 = tcg_temp_new_i64(); 10104 10105 gen_load_fpr64(ctx, fp0, fs); 10106 gen_helper_float_recip1_d(fp0, tcg_env, fp0); 10107 gen_store_fpr64(ctx, fp0, fd); 10108 } 10109 } 10110 break; 10111 case OPC_MAX_D: /* OPC_RSQRT1_D */ 10112 if (ctx->insn_flags & ISA_MIPS_R6) { 10113 /* OPC_MAX_D */ 10114 TCGv_i64 fp0 = tcg_temp_new_i64(); 10115 TCGv_i64 fp1 = tcg_temp_new_i64(); 10116 gen_load_fpr64(ctx, fp0, fs); 10117 gen_load_fpr64(ctx, fp1, ft); 10118 gen_helper_float_max_d(fp1, tcg_env, fp0, fp1); 10119 gen_store_fpr64(ctx, fp1, fd); 10120 } else { 10121 /* OPC_RSQRT1_D */ 10122 check_cp1_64bitmode(ctx); 10123 { 10124 TCGv_i64 fp0 = tcg_temp_new_i64(); 10125 10126 gen_load_fpr64(ctx, fp0, fs); 10127 gen_helper_float_rsqrt1_d(fp0, tcg_env, fp0); 10128 gen_store_fpr64(ctx, fp0, fd); 10129 } 10130 } 10131 break; 10132 case OPC_MAXA_D: /* OPC_RSQRT2_D */ 10133 if (ctx->insn_flags & ISA_MIPS_R6) { 10134 /* OPC_MAXA_D */ 10135 TCGv_i64 fp0 = tcg_temp_new_i64(); 10136 TCGv_i64 fp1 = tcg_temp_new_i64(); 10137 gen_load_fpr64(ctx, fp0, fs); 10138 gen_load_fpr64(ctx, fp1, ft); 10139 gen_helper_float_maxa_d(fp1, tcg_env, fp0, fp1); 10140 gen_store_fpr64(ctx, fp1, fd); 10141 } else { 10142 /* OPC_RSQRT2_D */ 10143 check_cp1_64bitmode(ctx); 10144 { 10145 TCGv_i64 fp0 = tcg_temp_new_i64(); 10146 TCGv_i64 fp1 = tcg_temp_new_i64(); 10147 10148 gen_load_fpr64(ctx, fp0, fs); 10149 gen_load_fpr64(ctx, fp1, ft); 10150 gen_helper_float_rsqrt2_d(fp0, tcg_env, fp0, fp1); 10151 gen_store_fpr64(ctx, fp0, fd); 10152 } 10153 } 10154 break; 10155 case OPC_CMP_F_D: 10156 case OPC_CMP_UN_D: 10157 case OPC_CMP_EQ_D: 10158 case OPC_CMP_UEQ_D: 10159 case OPC_CMP_OLT_D: 10160 case OPC_CMP_ULT_D: 10161 case OPC_CMP_OLE_D: 10162 case OPC_CMP_ULE_D: 10163 case OPC_CMP_SF_D: 10164 case OPC_CMP_NGLE_D: 10165 case OPC_CMP_SEQ_D: 10166 case OPC_CMP_NGL_D: 10167 case OPC_CMP_LT_D: 10168 case OPC_CMP_NGE_D: 10169 case OPC_CMP_LE_D: 10170 case OPC_CMP_NGT_D: 10171 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10172 if (ctx->opcode & (1 << 6)) { 10173 gen_cmpabs_d(ctx, func - 48, ft, fs, cc); 10174 } else { 10175 gen_cmp_d(ctx, func - 48, ft, fs, cc); 10176 } 10177 break; 10178 case OPC_CVT_S_D: 10179 check_cp1_registers(ctx, fs); 10180 { 10181 TCGv_i32 fp32 = tcg_temp_new_i32(); 10182 TCGv_i64 fp64 = tcg_temp_new_i64(); 10183 10184 gen_load_fpr64(ctx, fp64, fs); 10185 gen_helper_float_cvts_d(fp32, tcg_env, fp64); 10186 gen_store_fpr32(ctx, fp32, fd); 10187 } 10188 break; 10189 case OPC_CVT_W_D: 10190 check_cp1_registers(ctx, fs); 10191 { 10192 TCGv_i32 fp32 = tcg_temp_new_i32(); 10193 TCGv_i64 fp64 = tcg_temp_new_i64(); 10194 10195 gen_load_fpr64(ctx, fp64, fs); 10196 if (ctx->nan2008) { 10197 gen_helper_float_cvt_2008_w_d(fp32, tcg_env, fp64); 10198 } else { 10199 gen_helper_float_cvt_w_d(fp32, tcg_env, fp64); 10200 } 10201 gen_store_fpr32(ctx, fp32, fd); 10202 } 10203 break; 10204 case OPC_CVT_L_D: 10205 check_cp1_64bitmode(ctx); 10206 { 10207 TCGv_i64 fp0 = tcg_temp_new_i64(); 10208 10209 gen_load_fpr64(ctx, fp0, fs); 10210 if (ctx->nan2008) { 10211 gen_helper_float_cvt_2008_l_d(fp0, tcg_env, fp0); 10212 } else { 10213 gen_helper_float_cvt_l_d(fp0, tcg_env, fp0); 10214 } 10215 gen_store_fpr64(ctx, fp0, fd); 10216 } 10217 break; 10218 case OPC_CVT_S_W: 10219 { 10220 TCGv_i32 fp0 = tcg_temp_new_i32(); 10221 10222 gen_load_fpr32(ctx, fp0, fs); 10223 gen_helper_float_cvts_w(fp0, tcg_env, fp0); 10224 gen_store_fpr32(ctx, fp0, fd); 10225 } 10226 break; 10227 case OPC_CVT_D_W: 10228 check_cp1_registers(ctx, fd); 10229 { 10230 TCGv_i32 fp32 = tcg_temp_new_i32(); 10231 TCGv_i64 fp64 = tcg_temp_new_i64(); 10232 10233 gen_load_fpr32(ctx, fp32, fs); 10234 gen_helper_float_cvtd_w(fp64, tcg_env, fp32); 10235 gen_store_fpr64(ctx, fp64, fd); 10236 } 10237 break; 10238 case OPC_CVT_S_L: 10239 check_cp1_64bitmode(ctx); 10240 { 10241 TCGv_i32 fp32 = tcg_temp_new_i32(); 10242 TCGv_i64 fp64 = tcg_temp_new_i64(); 10243 10244 gen_load_fpr64(ctx, fp64, fs); 10245 gen_helper_float_cvts_l(fp32, tcg_env, fp64); 10246 gen_store_fpr32(ctx, fp32, fd); 10247 } 10248 break; 10249 case OPC_CVT_D_L: 10250 check_cp1_64bitmode(ctx); 10251 { 10252 TCGv_i64 fp0 = tcg_temp_new_i64(); 10253 10254 gen_load_fpr64(ctx, fp0, fs); 10255 gen_helper_float_cvtd_l(fp0, tcg_env, fp0); 10256 gen_store_fpr64(ctx, fp0, fd); 10257 } 10258 break; 10259 case OPC_CVT_PS_PW: 10260 check_ps(ctx); 10261 { 10262 TCGv_i64 fp0 = tcg_temp_new_i64(); 10263 10264 gen_load_fpr64(ctx, fp0, fs); 10265 gen_helper_float_cvtps_pw(fp0, tcg_env, fp0); 10266 gen_store_fpr64(ctx, fp0, fd); 10267 } 10268 break; 10269 case OPC_ADD_PS: 10270 check_ps(ctx); 10271 { 10272 TCGv_i64 fp0 = tcg_temp_new_i64(); 10273 TCGv_i64 fp1 = tcg_temp_new_i64(); 10274 10275 gen_load_fpr64(ctx, fp0, fs); 10276 gen_load_fpr64(ctx, fp1, ft); 10277 gen_helper_float_add_ps(fp0, tcg_env, fp0, fp1); 10278 gen_store_fpr64(ctx, fp0, fd); 10279 } 10280 break; 10281 case OPC_SUB_PS: 10282 check_ps(ctx); 10283 { 10284 TCGv_i64 fp0 = tcg_temp_new_i64(); 10285 TCGv_i64 fp1 = tcg_temp_new_i64(); 10286 10287 gen_load_fpr64(ctx, fp0, fs); 10288 gen_load_fpr64(ctx, fp1, ft); 10289 gen_helper_float_sub_ps(fp0, tcg_env, fp0, fp1); 10290 gen_store_fpr64(ctx, fp0, fd); 10291 } 10292 break; 10293 case OPC_MUL_PS: 10294 check_ps(ctx); 10295 { 10296 TCGv_i64 fp0 = tcg_temp_new_i64(); 10297 TCGv_i64 fp1 = tcg_temp_new_i64(); 10298 10299 gen_load_fpr64(ctx, fp0, fs); 10300 gen_load_fpr64(ctx, fp1, ft); 10301 gen_helper_float_mul_ps(fp0, tcg_env, fp0, fp1); 10302 gen_store_fpr64(ctx, fp0, fd); 10303 } 10304 break; 10305 case OPC_ABS_PS: 10306 check_ps(ctx); 10307 { 10308 TCGv_i64 fp0 = tcg_temp_new_i64(); 10309 10310 gen_load_fpr64(ctx, fp0, fs); 10311 gen_helper_float_abs_ps(fp0, fp0); 10312 gen_store_fpr64(ctx, fp0, fd); 10313 } 10314 break; 10315 case OPC_MOV_PS: 10316 check_ps(ctx); 10317 { 10318 TCGv_i64 fp0 = tcg_temp_new_i64(); 10319 10320 gen_load_fpr64(ctx, fp0, fs); 10321 gen_store_fpr64(ctx, fp0, fd); 10322 } 10323 break; 10324 case OPC_NEG_PS: 10325 check_ps(ctx); 10326 { 10327 TCGv_i64 fp0 = tcg_temp_new_i64(); 10328 10329 gen_load_fpr64(ctx, fp0, fs); 10330 gen_helper_float_chs_ps(fp0, fp0); 10331 gen_store_fpr64(ctx, fp0, fd); 10332 } 10333 break; 10334 case OPC_MOVCF_PS: 10335 check_ps(ctx); 10336 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10337 break; 10338 case OPC_MOVZ_PS: 10339 check_ps(ctx); 10340 { 10341 TCGLabel *l1 = gen_new_label(); 10342 TCGv_i64 fp0; 10343 10344 if (ft != 0) { 10345 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10346 } 10347 fp0 = tcg_temp_new_i64(); 10348 gen_load_fpr64(ctx, fp0, fs); 10349 gen_store_fpr64(ctx, fp0, fd); 10350 gen_set_label(l1); 10351 } 10352 break; 10353 case OPC_MOVN_PS: 10354 check_ps(ctx); 10355 { 10356 TCGLabel *l1 = gen_new_label(); 10357 TCGv_i64 fp0; 10358 10359 if (ft != 0) { 10360 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10361 fp0 = tcg_temp_new_i64(); 10362 gen_load_fpr64(ctx, fp0, fs); 10363 gen_store_fpr64(ctx, fp0, fd); 10364 gen_set_label(l1); 10365 } 10366 } 10367 break; 10368 case OPC_ADDR_PS: 10369 check_ps(ctx); 10370 { 10371 TCGv_i64 fp0 = tcg_temp_new_i64(); 10372 TCGv_i64 fp1 = tcg_temp_new_i64(); 10373 10374 gen_load_fpr64(ctx, fp0, ft); 10375 gen_load_fpr64(ctx, fp1, fs); 10376 gen_helper_float_addr_ps(fp0, tcg_env, fp0, fp1); 10377 gen_store_fpr64(ctx, fp0, fd); 10378 } 10379 break; 10380 case OPC_MULR_PS: 10381 check_ps(ctx); 10382 { 10383 TCGv_i64 fp0 = tcg_temp_new_i64(); 10384 TCGv_i64 fp1 = tcg_temp_new_i64(); 10385 10386 gen_load_fpr64(ctx, fp0, ft); 10387 gen_load_fpr64(ctx, fp1, fs); 10388 gen_helper_float_mulr_ps(fp0, tcg_env, fp0, fp1); 10389 gen_store_fpr64(ctx, fp0, fd); 10390 } 10391 break; 10392 case OPC_RECIP2_PS: 10393 check_ps(ctx); 10394 { 10395 TCGv_i64 fp0 = tcg_temp_new_i64(); 10396 TCGv_i64 fp1 = tcg_temp_new_i64(); 10397 10398 gen_load_fpr64(ctx, fp0, fs); 10399 gen_load_fpr64(ctx, fp1, ft); 10400 gen_helper_float_recip2_ps(fp0, tcg_env, fp0, fp1); 10401 gen_store_fpr64(ctx, fp0, fd); 10402 } 10403 break; 10404 case OPC_RECIP1_PS: 10405 check_ps(ctx); 10406 { 10407 TCGv_i64 fp0 = tcg_temp_new_i64(); 10408 10409 gen_load_fpr64(ctx, fp0, fs); 10410 gen_helper_float_recip1_ps(fp0, tcg_env, fp0); 10411 gen_store_fpr64(ctx, fp0, fd); 10412 } 10413 break; 10414 case OPC_RSQRT1_PS: 10415 check_ps(ctx); 10416 { 10417 TCGv_i64 fp0 = tcg_temp_new_i64(); 10418 10419 gen_load_fpr64(ctx, fp0, fs); 10420 gen_helper_float_rsqrt1_ps(fp0, tcg_env, fp0); 10421 gen_store_fpr64(ctx, fp0, fd); 10422 } 10423 break; 10424 case OPC_RSQRT2_PS: 10425 check_ps(ctx); 10426 { 10427 TCGv_i64 fp0 = tcg_temp_new_i64(); 10428 TCGv_i64 fp1 = tcg_temp_new_i64(); 10429 10430 gen_load_fpr64(ctx, fp0, fs); 10431 gen_load_fpr64(ctx, fp1, ft); 10432 gen_helper_float_rsqrt2_ps(fp0, tcg_env, fp0, fp1); 10433 gen_store_fpr64(ctx, fp0, fd); 10434 } 10435 break; 10436 case OPC_CVT_S_PU: 10437 check_cp1_64bitmode(ctx); 10438 { 10439 TCGv_i32 fp0 = tcg_temp_new_i32(); 10440 10441 gen_load_fpr32h(ctx, fp0, fs); 10442 gen_helper_float_cvts_pu(fp0, tcg_env, fp0); 10443 gen_store_fpr32(ctx, fp0, fd); 10444 } 10445 break; 10446 case OPC_CVT_PW_PS: 10447 check_ps(ctx); 10448 { 10449 TCGv_i64 fp0 = tcg_temp_new_i64(); 10450 10451 gen_load_fpr64(ctx, fp0, fs); 10452 gen_helper_float_cvtpw_ps(fp0, tcg_env, fp0); 10453 gen_store_fpr64(ctx, fp0, fd); 10454 } 10455 break; 10456 case OPC_CVT_S_PL: 10457 check_cp1_64bitmode(ctx); 10458 { 10459 TCGv_i32 fp0 = tcg_temp_new_i32(); 10460 10461 gen_load_fpr32(ctx, fp0, fs); 10462 gen_helper_float_cvts_pl(fp0, tcg_env, fp0); 10463 gen_store_fpr32(ctx, fp0, fd); 10464 } 10465 break; 10466 case OPC_PLL_PS: 10467 check_ps(ctx); 10468 { 10469 TCGv_i32 fp0 = tcg_temp_new_i32(); 10470 TCGv_i32 fp1 = tcg_temp_new_i32(); 10471 10472 gen_load_fpr32(ctx, fp0, fs); 10473 gen_load_fpr32(ctx, fp1, ft); 10474 gen_store_fpr32h(ctx, fp0, fd); 10475 gen_store_fpr32(ctx, fp1, fd); 10476 } 10477 break; 10478 case OPC_PLU_PS: 10479 check_ps(ctx); 10480 { 10481 TCGv_i32 fp0 = tcg_temp_new_i32(); 10482 TCGv_i32 fp1 = tcg_temp_new_i32(); 10483 10484 gen_load_fpr32(ctx, fp0, fs); 10485 gen_load_fpr32h(ctx, fp1, ft); 10486 gen_store_fpr32(ctx, fp1, fd); 10487 gen_store_fpr32h(ctx, fp0, fd); 10488 } 10489 break; 10490 case OPC_PUL_PS: 10491 check_ps(ctx); 10492 { 10493 TCGv_i32 fp0 = tcg_temp_new_i32(); 10494 TCGv_i32 fp1 = tcg_temp_new_i32(); 10495 10496 gen_load_fpr32h(ctx, fp0, fs); 10497 gen_load_fpr32(ctx, fp1, ft); 10498 gen_store_fpr32(ctx, fp1, fd); 10499 gen_store_fpr32h(ctx, fp0, fd); 10500 } 10501 break; 10502 case OPC_PUU_PS: 10503 check_ps(ctx); 10504 { 10505 TCGv_i32 fp0 = tcg_temp_new_i32(); 10506 TCGv_i32 fp1 = tcg_temp_new_i32(); 10507 10508 gen_load_fpr32h(ctx, fp0, fs); 10509 gen_load_fpr32h(ctx, fp1, ft); 10510 gen_store_fpr32(ctx, fp1, fd); 10511 gen_store_fpr32h(ctx, fp0, fd); 10512 } 10513 break; 10514 case OPC_CMP_F_PS: 10515 case OPC_CMP_UN_PS: 10516 case OPC_CMP_EQ_PS: 10517 case OPC_CMP_UEQ_PS: 10518 case OPC_CMP_OLT_PS: 10519 case OPC_CMP_ULT_PS: 10520 case OPC_CMP_OLE_PS: 10521 case OPC_CMP_ULE_PS: 10522 case OPC_CMP_SF_PS: 10523 case OPC_CMP_NGLE_PS: 10524 case OPC_CMP_SEQ_PS: 10525 case OPC_CMP_NGL_PS: 10526 case OPC_CMP_LT_PS: 10527 case OPC_CMP_NGE_PS: 10528 case OPC_CMP_LE_PS: 10529 case OPC_CMP_NGT_PS: 10530 if (ctx->opcode & (1 << 6)) { 10531 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc); 10532 } else { 10533 gen_cmp_ps(ctx, func - 48, ft, fs, cc); 10534 } 10535 break; 10536 default: 10537 MIPS_INVAL("farith"); 10538 gen_reserved_instruction(ctx); 10539 return; 10540 } 10541 } 10542 10543 /* Coprocessor 3 (FPU) */ 10544 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, 10545 int fd, int fs, int base, int index) 10546 { 10547 TCGv t0 = tcg_temp_new(); 10548 10549 if (base == 0) { 10550 gen_load_gpr(t0, index); 10551 } else if (index == 0) { 10552 gen_load_gpr(t0, base); 10553 } else { 10554 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); 10555 } 10556 /* 10557 * Don't do NOP if destination is zero: we must perform the actual 10558 * memory access. 10559 */ 10560 switch (opc) { 10561 case OPC_LWXC1: 10562 check_cop1x(ctx); 10563 { 10564 TCGv_i32 fp0 = tcg_temp_new_i32(); 10565 10566 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 10567 tcg_gen_trunc_tl_i32(fp0, t0); 10568 gen_store_fpr32(ctx, fp0, fd); 10569 } 10570 break; 10571 case OPC_LDXC1: 10572 check_cop1x(ctx); 10573 check_cp1_registers(ctx, fd); 10574 { 10575 TCGv_i64 fp0 = tcg_temp_new_i64(); 10576 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10577 gen_store_fpr64(ctx, fp0, fd); 10578 } 10579 break; 10580 case OPC_LUXC1: 10581 check_cp1_64bitmode(ctx); 10582 tcg_gen_andi_tl(t0, t0, ~0x7); 10583 { 10584 TCGv_i64 fp0 = tcg_temp_new_i64(); 10585 10586 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10587 gen_store_fpr64(ctx, fp0, fd); 10588 } 10589 break; 10590 case OPC_SWXC1: 10591 check_cop1x(ctx); 10592 { 10593 TCGv_i32 fp0 = tcg_temp_new_i32(); 10594 gen_load_fpr32(ctx, fp0, fs); 10595 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 10596 } 10597 break; 10598 case OPC_SDXC1: 10599 check_cop1x(ctx); 10600 check_cp1_registers(ctx, fs); 10601 { 10602 TCGv_i64 fp0 = tcg_temp_new_i64(); 10603 gen_load_fpr64(ctx, fp0, fs); 10604 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10605 } 10606 break; 10607 case OPC_SUXC1: 10608 check_cp1_64bitmode(ctx); 10609 tcg_gen_andi_tl(t0, t0, ~0x7); 10610 { 10611 TCGv_i64 fp0 = tcg_temp_new_i64(); 10612 gen_load_fpr64(ctx, fp0, fs); 10613 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10614 } 10615 break; 10616 } 10617 } 10618 10619 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, 10620 int fd, int fr, int fs, int ft) 10621 { 10622 switch (opc) { 10623 case OPC_ALNV_PS: 10624 check_ps(ctx); 10625 { 10626 TCGv t0 = tcg_temp_new(); 10627 TCGv_i32 fp = tcg_temp_new_i32(); 10628 TCGv_i32 fph = tcg_temp_new_i32(); 10629 TCGLabel *l1 = gen_new_label(); 10630 TCGLabel *l2 = gen_new_label(); 10631 10632 gen_load_gpr(t0, fr); 10633 tcg_gen_andi_tl(t0, t0, 0x7); 10634 10635 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 10636 gen_load_fpr32(ctx, fp, fs); 10637 gen_load_fpr32h(ctx, fph, fs); 10638 gen_store_fpr32(ctx, fp, fd); 10639 gen_store_fpr32h(ctx, fph, fd); 10640 tcg_gen_br(l2); 10641 gen_set_label(l1); 10642 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 10643 if (disas_is_bigendian(ctx)) { 10644 gen_load_fpr32(ctx, fp, fs); 10645 gen_load_fpr32h(ctx, fph, ft); 10646 gen_store_fpr32h(ctx, fp, fd); 10647 gen_store_fpr32(ctx, fph, fd); 10648 } else { 10649 gen_load_fpr32h(ctx, fph, fs); 10650 gen_load_fpr32(ctx, fp, ft); 10651 gen_store_fpr32(ctx, fph, fd); 10652 gen_store_fpr32h(ctx, fp, fd); 10653 } 10654 gen_set_label(l2); 10655 } 10656 break; 10657 case OPC_MADD_S: 10658 check_cop1x(ctx); 10659 { 10660 TCGv_i32 fp0 = tcg_temp_new_i32(); 10661 TCGv_i32 fp1 = tcg_temp_new_i32(); 10662 TCGv_i32 fp2 = tcg_temp_new_i32(); 10663 10664 gen_load_fpr32(ctx, fp0, fs); 10665 gen_load_fpr32(ctx, fp1, ft); 10666 gen_load_fpr32(ctx, fp2, fr); 10667 gen_helper_float_madd_s(fp2, tcg_env, fp0, fp1, fp2); 10668 gen_store_fpr32(ctx, fp2, fd); 10669 } 10670 break; 10671 case OPC_MADD_D: 10672 check_cop1x(ctx); 10673 check_cp1_registers(ctx, fd | fs | ft | fr); 10674 { 10675 TCGv_i64 fp0 = tcg_temp_new_i64(); 10676 TCGv_i64 fp1 = tcg_temp_new_i64(); 10677 TCGv_i64 fp2 = tcg_temp_new_i64(); 10678 10679 gen_load_fpr64(ctx, fp0, fs); 10680 gen_load_fpr64(ctx, fp1, ft); 10681 gen_load_fpr64(ctx, fp2, fr); 10682 gen_helper_float_madd_d(fp2, tcg_env, fp0, fp1, fp2); 10683 gen_store_fpr64(ctx, fp2, fd); 10684 } 10685 break; 10686 case OPC_MADD_PS: 10687 check_ps(ctx); 10688 { 10689 TCGv_i64 fp0 = tcg_temp_new_i64(); 10690 TCGv_i64 fp1 = tcg_temp_new_i64(); 10691 TCGv_i64 fp2 = tcg_temp_new_i64(); 10692 10693 gen_load_fpr64(ctx, fp0, fs); 10694 gen_load_fpr64(ctx, fp1, ft); 10695 gen_load_fpr64(ctx, fp2, fr); 10696 gen_helper_float_madd_ps(fp2, tcg_env, fp0, fp1, fp2); 10697 gen_store_fpr64(ctx, fp2, fd); 10698 } 10699 break; 10700 case OPC_MSUB_S: 10701 check_cop1x(ctx); 10702 { 10703 TCGv_i32 fp0 = tcg_temp_new_i32(); 10704 TCGv_i32 fp1 = tcg_temp_new_i32(); 10705 TCGv_i32 fp2 = tcg_temp_new_i32(); 10706 10707 gen_load_fpr32(ctx, fp0, fs); 10708 gen_load_fpr32(ctx, fp1, ft); 10709 gen_load_fpr32(ctx, fp2, fr); 10710 gen_helper_float_msub_s(fp2, tcg_env, fp0, fp1, fp2); 10711 gen_store_fpr32(ctx, fp2, fd); 10712 } 10713 break; 10714 case OPC_MSUB_D: 10715 check_cop1x(ctx); 10716 check_cp1_registers(ctx, fd | fs | ft | fr); 10717 { 10718 TCGv_i64 fp0 = tcg_temp_new_i64(); 10719 TCGv_i64 fp1 = tcg_temp_new_i64(); 10720 TCGv_i64 fp2 = tcg_temp_new_i64(); 10721 10722 gen_load_fpr64(ctx, fp0, fs); 10723 gen_load_fpr64(ctx, fp1, ft); 10724 gen_load_fpr64(ctx, fp2, fr); 10725 gen_helper_float_msub_d(fp2, tcg_env, fp0, fp1, fp2); 10726 gen_store_fpr64(ctx, fp2, fd); 10727 } 10728 break; 10729 case OPC_MSUB_PS: 10730 check_ps(ctx); 10731 { 10732 TCGv_i64 fp0 = tcg_temp_new_i64(); 10733 TCGv_i64 fp1 = tcg_temp_new_i64(); 10734 TCGv_i64 fp2 = tcg_temp_new_i64(); 10735 10736 gen_load_fpr64(ctx, fp0, fs); 10737 gen_load_fpr64(ctx, fp1, ft); 10738 gen_load_fpr64(ctx, fp2, fr); 10739 gen_helper_float_msub_ps(fp2, tcg_env, fp0, fp1, fp2); 10740 gen_store_fpr64(ctx, fp2, fd); 10741 } 10742 break; 10743 case OPC_NMADD_S: 10744 check_cop1x(ctx); 10745 { 10746 TCGv_i32 fp0 = tcg_temp_new_i32(); 10747 TCGv_i32 fp1 = tcg_temp_new_i32(); 10748 TCGv_i32 fp2 = tcg_temp_new_i32(); 10749 10750 gen_load_fpr32(ctx, fp0, fs); 10751 gen_load_fpr32(ctx, fp1, ft); 10752 gen_load_fpr32(ctx, fp2, fr); 10753 gen_helper_float_nmadd_s(fp2, tcg_env, fp0, fp1, fp2); 10754 gen_store_fpr32(ctx, fp2, fd); 10755 } 10756 break; 10757 case OPC_NMADD_D: 10758 check_cop1x(ctx); 10759 check_cp1_registers(ctx, fd | fs | ft | fr); 10760 { 10761 TCGv_i64 fp0 = tcg_temp_new_i64(); 10762 TCGv_i64 fp1 = tcg_temp_new_i64(); 10763 TCGv_i64 fp2 = tcg_temp_new_i64(); 10764 10765 gen_load_fpr64(ctx, fp0, fs); 10766 gen_load_fpr64(ctx, fp1, ft); 10767 gen_load_fpr64(ctx, fp2, fr); 10768 gen_helper_float_nmadd_d(fp2, tcg_env, fp0, fp1, fp2); 10769 gen_store_fpr64(ctx, fp2, fd); 10770 } 10771 break; 10772 case OPC_NMADD_PS: 10773 check_ps(ctx); 10774 { 10775 TCGv_i64 fp0 = tcg_temp_new_i64(); 10776 TCGv_i64 fp1 = tcg_temp_new_i64(); 10777 TCGv_i64 fp2 = tcg_temp_new_i64(); 10778 10779 gen_load_fpr64(ctx, fp0, fs); 10780 gen_load_fpr64(ctx, fp1, ft); 10781 gen_load_fpr64(ctx, fp2, fr); 10782 gen_helper_float_nmadd_ps(fp2, tcg_env, fp0, fp1, fp2); 10783 gen_store_fpr64(ctx, fp2, fd); 10784 } 10785 break; 10786 case OPC_NMSUB_S: 10787 check_cop1x(ctx); 10788 { 10789 TCGv_i32 fp0 = tcg_temp_new_i32(); 10790 TCGv_i32 fp1 = tcg_temp_new_i32(); 10791 TCGv_i32 fp2 = tcg_temp_new_i32(); 10792 10793 gen_load_fpr32(ctx, fp0, fs); 10794 gen_load_fpr32(ctx, fp1, ft); 10795 gen_load_fpr32(ctx, fp2, fr); 10796 gen_helper_float_nmsub_s(fp2, tcg_env, fp0, fp1, fp2); 10797 gen_store_fpr32(ctx, fp2, fd); 10798 } 10799 break; 10800 case OPC_NMSUB_D: 10801 check_cop1x(ctx); 10802 check_cp1_registers(ctx, fd | fs | ft | fr); 10803 { 10804 TCGv_i64 fp0 = tcg_temp_new_i64(); 10805 TCGv_i64 fp1 = tcg_temp_new_i64(); 10806 TCGv_i64 fp2 = tcg_temp_new_i64(); 10807 10808 gen_load_fpr64(ctx, fp0, fs); 10809 gen_load_fpr64(ctx, fp1, ft); 10810 gen_load_fpr64(ctx, fp2, fr); 10811 gen_helper_float_nmsub_d(fp2, tcg_env, fp0, fp1, fp2); 10812 gen_store_fpr64(ctx, fp2, fd); 10813 } 10814 break; 10815 case OPC_NMSUB_PS: 10816 check_ps(ctx); 10817 { 10818 TCGv_i64 fp0 = tcg_temp_new_i64(); 10819 TCGv_i64 fp1 = tcg_temp_new_i64(); 10820 TCGv_i64 fp2 = tcg_temp_new_i64(); 10821 10822 gen_load_fpr64(ctx, fp0, fs); 10823 gen_load_fpr64(ctx, fp1, ft); 10824 gen_load_fpr64(ctx, fp2, fr); 10825 gen_helper_float_nmsub_ps(fp2, tcg_env, fp0, fp1, fp2); 10826 gen_store_fpr64(ctx, fp2, fd); 10827 } 10828 break; 10829 default: 10830 MIPS_INVAL("flt3_arith"); 10831 gen_reserved_instruction(ctx); 10832 return; 10833 } 10834 } 10835 10836 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) 10837 { 10838 TCGv t0; 10839 10840 #if !defined(CONFIG_USER_ONLY) 10841 /* 10842 * The Linux kernel will emulate rdhwr if it's not supported natively. 10843 * Therefore only check the ISA in system mode. 10844 */ 10845 check_insn(ctx, ISA_MIPS_R2); 10846 #endif 10847 t0 = tcg_temp_new(); 10848 10849 switch (rd) { 10850 case 0: 10851 gen_helper_rdhwr_cpunum(t0, tcg_env); 10852 gen_store_gpr(t0, rt); 10853 break; 10854 case 1: 10855 gen_helper_rdhwr_synci_step(t0, tcg_env); 10856 gen_store_gpr(t0, rt); 10857 break; 10858 case 2: 10859 translator_io_start(&ctx->base); 10860 gen_helper_rdhwr_cc(t0, tcg_env); 10861 gen_store_gpr(t0, rt); 10862 /* 10863 * Break the TB to be able to take timer interrupts immediately 10864 * after reading count. DISAS_STOP isn't sufficient, we need to ensure 10865 * we break completely out of translated code. 10866 */ 10867 gen_save_pc(ctx->base.pc_next + 4); 10868 ctx->base.is_jmp = DISAS_EXIT; 10869 break; 10870 case 3: 10871 gen_helper_rdhwr_ccres(t0, tcg_env); 10872 gen_store_gpr(t0, rt); 10873 break; 10874 case 4: 10875 check_insn(ctx, ISA_MIPS_R6); 10876 if (sel != 0) { 10877 /* 10878 * Performance counter registers are not implemented other than 10879 * control register 0. 10880 */ 10881 generate_exception(ctx, EXCP_RI); 10882 } 10883 gen_helper_rdhwr_performance(t0, tcg_env); 10884 gen_store_gpr(t0, rt); 10885 break; 10886 case 5: 10887 check_insn(ctx, ISA_MIPS_R6); 10888 gen_helper_rdhwr_xnp(t0, tcg_env); 10889 gen_store_gpr(t0, rt); 10890 break; 10891 case 29: 10892 #if defined(CONFIG_USER_ONLY) 10893 tcg_gen_ld_tl(t0, tcg_env, 10894 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 10895 gen_store_gpr(t0, rt); 10896 break; 10897 #else 10898 if ((ctx->hflags & MIPS_HFLAG_CP0) || 10899 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) { 10900 tcg_gen_ld_tl(t0, tcg_env, 10901 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 10902 gen_store_gpr(t0, rt); 10903 } else { 10904 gen_reserved_instruction(ctx); 10905 } 10906 break; 10907 #endif 10908 default: /* Invalid */ 10909 MIPS_INVAL("rdhwr"); 10910 gen_reserved_instruction(ctx); 10911 break; 10912 } 10913 } 10914 10915 static inline void clear_branch_hflags(DisasContext *ctx) 10916 { 10917 ctx->hflags &= ~MIPS_HFLAG_BMASK; 10918 if (ctx->base.is_jmp == DISAS_NEXT) { 10919 save_cpu_state(ctx, 0); 10920 } else { 10921 /* 10922 * It is not safe to save ctx->hflags as hflags may be changed 10923 * in execution time by the instruction in delay / forbidden slot. 10924 */ 10925 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK); 10926 } 10927 } 10928 10929 static void gen_branch(DisasContext *ctx, int insn_bytes) 10930 { 10931 if (ctx->hflags & MIPS_HFLAG_BMASK) { 10932 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK; 10933 /* Branches completion */ 10934 clear_branch_hflags(ctx); 10935 ctx->base.is_jmp = DISAS_NORETURN; 10936 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) { 10937 case MIPS_HFLAG_FBNSLOT: 10938 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes); 10939 break; 10940 case MIPS_HFLAG_B: 10941 /* unconditional branch */ 10942 if (proc_hflags & MIPS_HFLAG_BX) { 10943 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16); 10944 } 10945 gen_goto_tb(ctx, 0, ctx->btarget); 10946 break; 10947 case MIPS_HFLAG_BL: 10948 /* blikely taken case */ 10949 gen_goto_tb(ctx, 0, ctx->btarget); 10950 break; 10951 case MIPS_HFLAG_BC: 10952 /* Conditional branch */ 10953 { 10954 TCGLabel *l1 = gen_new_label(); 10955 10956 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 10957 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); 10958 gen_set_label(l1); 10959 gen_goto_tb(ctx, 0, ctx->btarget); 10960 } 10961 break; 10962 case MIPS_HFLAG_BR: 10963 /* unconditional branch to register */ 10964 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) { 10965 TCGv t0 = tcg_temp_new(); 10966 TCGv_i32 t1 = tcg_temp_new_i32(); 10967 10968 tcg_gen_andi_tl(t0, btarget, 0x1); 10969 tcg_gen_trunc_tl_i32(t1, t0); 10970 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16); 10971 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT); 10972 tcg_gen_or_i32(hflags, hflags, t1); 10973 10974 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1); 10975 } else { 10976 tcg_gen_mov_tl(cpu_PC, btarget); 10977 } 10978 tcg_gen_lookup_and_goto_ptr(); 10979 break; 10980 default: 10981 LOG_DISAS("unknown branch 0x%x\n", proc_hflags); 10982 gen_reserved_instruction(ctx); 10983 } 10984 } 10985 } 10986 10987 /* Compact Branches */ 10988 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, 10989 int rs, int rt, int32_t offset) 10990 { 10991 int bcond_compute = 0; 10992 TCGv t0 = tcg_temp_new(); 10993 TCGv t1 = tcg_temp_new(); 10994 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; 10995 10996 if (ctx->hflags & MIPS_HFLAG_BMASK) { 10997 #ifdef MIPS_DEBUG_DISAS 10998 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 10999 VADDR_PRIx "\n", ctx->base.pc_next); 11000 #endif 11001 gen_reserved_instruction(ctx); 11002 return; 11003 } 11004 11005 /* Load needed operands and calculate btarget */ 11006 switch (opc) { 11007 /* compact branch */ 11008 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11009 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11010 gen_load_gpr(t0, rs); 11011 gen_load_gpr(t1, rt); 11012 bcond_compute = 1; 11013 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11014 if (rs <= rt && rs == 0) { 11015 /* OPC_BEQZALC, OPC_BNEZALC */ 11016 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11017 } 11018 break; 11019 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11020 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11021 gen_load_gpr(t0, rs); 11022 gen_load_gpr(t1, rt); 11023 bcond_compute = 1; 11024 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11025 break; 11026 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11027 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11028 if (rs == 0 || rs == rt) { 11029 /* OPC_BLEZALC, OPC_BGEZALC */ 11030 /* OPC_BGTZALC, OPC_BLTZALC */ 11031 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11032 } 11033 gen_load_gpr(t0, rs); 11034 gen_load_gpr(t1, rt); 11035 bcond_compute = 1; 11036 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11037 break; 11038 case OPC_BC: 11039 case OPC_BALC: 11040 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11041 break; 11042 case OPC_BEQZC: 11043 case OPC_BNEZC: 11044 if (rs != 0) { 11045 /* OPC_BEQZC, OPC_BNEZC */ 11046 gen_load_gpr(t0, rs); 11047 bcond_compute = 1; 11048 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11049 } else { 11050 /* OPC_JIC, OPC_JIALC */ 11051 TCGv tbase = tcg_temp_new(); 11052 11053 gen_load_gpr(tbase, rt); 11054 gen_op_addr_addi(ctx, btarget, tbase, offset); 11055 } 11056 break; 11057 default: 11058 MIPS_INVAL("Compact branch/jump"); 11059 gen_reserved_instruction(ctx); 11060 return; 11061 } 11062 11063 if (bcond_compute == 0) { 11064 /* Unconditional compact branch */ 11065 switch (opc) { 11066 case OPC_JIALC: 11067 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11068 /* Fallthrough */ 11069 case OPC_JIC: 11070 ctx->hflags |= MIPS_HFLAG_BR; 11071 break; 11072 case OPC_BALC: 11073 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11074 /* Fallthrough */ 11075 case OPC_BC: 11076 ctx->hflags |= MIPS_HFLAG_B; 11077 break; 11078 default: 11079 MIPS_INVAL("Compact branch/jump"); 11080 gen_reserved_instruction(ctx); 11081 return; 11082 } 11083 11084 /* Generating branch here as compact branches don't have delay slot */ 11085 gen_branch(ctx, 4); 11086 } else { 11087 /* Conditional compact branch */ 11088 TCGLabel *fs = gen_new_label(); 11089 save_cpu_state(ctx, 0); 11090 11091 switch (opc) { 11092 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11093 if (rs == 0 && rt != 0) { 11094 /* OPC_BLEZALC */ 11095 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11096 } else if (rs != 0 && rt != 0 && rs == rt) { 11097 /* OPC_BGEZALC */ 11098 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11099 } else { 11100 /* OPC_BGEUC */ 11101 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 11102 } 11103 break; 11104 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11105 if (rs == 0 && rt != 0) { 11106 /* OPC_BGTZALC */ 11107 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11108 } else if (rs != 0 && rt != 0 && rs == rt) { 11109 /* OPC_BLTZALC */ 11110 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11111 } else { 11112 /* OPC_BLTUC */ 11113 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 11114 } 11115 break; 11116 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11117 if (rs == 0 && rt != 0) { 11118 /* OPC_BLEZC */ 11119 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11120 } else if (rs != 0 && rt != 0 && rs == rt) { 11121 /* OPC_BGEZC */ 11122 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11123 } else { 11124 /* OPC_BGEC */ 11125 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 11126 } 11127 break; 11128 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11129 if (rs == 0 && rt != 0) { 11130 /* OPC_BGTZC */ 11131 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11132 } else if (rs != 0 && rt != 0 && rs == rt) { 11133 /* OPC_BLTZC */ 11134 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11135 } else { 11136 /* OPC_BLTC */ 11137 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 11138 } 11139 break; 11140 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11141 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11142 if (rs >= rt) { 11143 /* OPC_BOVC, OPC_BNVC */ 11144 TCGv t2 = tcg_temp_new(); 11145 TCGv t3 = tcg_temp_new(); 11146 TCGv t4 = tcg_temp_new(); 11147 TCGv input_overflow = tcg_temp_new(); 11148 11149 gen_load_gpr(t0, rs); 11150 gen_load_gpr(t1, rt); 11151 tcg_gen_ext32s_tl(t2, t0); 11152 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0); 11153 tcg_gen_ext32s_tl(t3, t1); 11154 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1); 11155 tcg_gen_or_tl(input_overflow, input_overflow, t4); 11156 11157 tcg_gen_add_tl(t4, t2, t3); 11158 tcg_gen_ext32s_tl(t4, t4); 11159 tcg_gen_xor_tl(t2, t2, t3); 11160 tcg_gen_xor_tl(t3, t4, t3); 11161 tcg_gen_andc_tl(t2, t3, t2); 11162 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0); 11163 tcg_gen_or_tl(t4, t4, input_overflow); 11164 if (opc == OPC_BOVC) { 11165 /* OPC_BOVC */ 11166 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs); 11167 } else { 11168 /* OPC_BNVC */ 11169 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs); 11170 } 11171 } else if (rs < rt && rs == 0) { 11172 /* OPC_BEQZALC, OPC_BNEZALC */ 11173 if (opc == OPC_BEQZALC) { 11174 /* OPC_BEQZALC */ 11175 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs); 11176 } else { 11177 /* OPC_BNEZALC */ 11178 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs); 11179 } 11180 } else { 11181 /* OPC_BEQC, OPC_BNEC */ 11182 if (opc == OPC_BEQC) { 11183 /* OPC_BEQC */ 11184 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); 11185 } else { 11186 /* OPC_BNEC */ 11187 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); 11188 } 11189 } 11190 break; 11191 case OPC_BEQZC: 11192 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 11193 break; 11194 case OPC_BNEZC: 11195 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs); 11196 break; 11197 default: 11198 MIPS_INVAL("Compact conditional branch/jump"); 11199 gen_reserved_instruction(ctx); 11200 return; 11201 } 11202 11203 /* Generating branch here as compact branches don't have delay slot */ 11204 gen_goto_tb(ctx, 1, ctx->btarget); 11205 gen_set_label(fs); 11206 11207 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 11208 } 11209 } 11210 11211 void gen_addiupc(DisasContext *ctx, int rx, int imm, 11212 int is_64_bit, int extended) 11213 { 11214 target_ulong npc; 11215 11216 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { 11217 gen_reserved_instruction(ctx); 11218 return; 11219 } 11220 11221 npc = pc_relative_pc(ctx) + imm; 11222 if (!is_64_bit) { 11223 npc = (int32_t)npc; 11224 } 11225 tcg_gen_movi_tl(cpu_gpr[rx], npc); 11226 } 11227 11228 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, 11229 int16_t offset) 11230 { 11231 TCGv_i32 t0 = tcg_constant_i32(op); 11232 TCGv t1 = tcg_temp_new(); 11233 gen_base_offset_addr(ctx, t1, base, offset); 11234 gen_helper_cache(tcg_env, t1, t0); 11235 } 11236 11237 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code) 11238 { 11239 #ifdef CONFIG_USER_ONLY 11240 return false; 11241 #else 11242 bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM; 11243 return semihosting_enabled(is_user) && sdbbp_code == 1; 11244 #endif 11245 } 11246 11247 void gen_ldxs(DisasContext *ctx, int base, int index, int rd) 11248 { 11249 TCGv t0 = tcg_temp_new(); 11250 TCGv t1 = tcg_temp_new(); 11251 11252 gen_load_gpr(t0, base); 11253 11254 if (index != 0) { 11255 gen_load_gpr(t1, index); 11256 tcg_gen_shli_tl(t1, t1, 2); 11257 gen_op_addr_add(ctx, t0, t1, t0); 11258 } 11259 11260 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 11261 gen_store_gpr(t1, rd); 11262 } 11263 11264 static void gen_sync(int stype) 11265 { 11266 TCGBar tcg_mo = TCG_BAR_SC; 11267 11268 switch (stype) { 11269 case 0x4: /* SYNC_WMB */ 11270 tcg_mo |= TCG_MO_ST_ST; 11271 break; 11272 case 0x10: /* SYNC_MB */ 11273 tcg_mo |= TCG_MO_ALL; 11274 break; 11275 case 0x11: /* SYNC_ACQUIRE */ 11276 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; 11277 break; 11278 case 0x12: /* SYNC_RELEASE */ 11279 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; 11280 break; 11281 case 0x13: /* SYNC_RMB */ 11282 tcg_mo |= TCG_MO_LD_LD; 11283 break; 11284 default: 11285 tcg_mo |= TCG_MO_ALL; 11286 break; 11287 } 11288 11289 tcg_gen_mb(tcg_mo); 11290 } 11291 11292 /* ISA extensions (ASEs) */ 11293 11294 /* MIPS16 extension to MIPS32 */ 11295 #include "mips16e_translate.c.inc" 11296 11297 /* microMIPS extension to MIPS32/MIPS64 */ 11298 11299 /* 11300 * Values for microMIPS fmt field. Variable-width, depending on which 11301 * formats the instruction supports. 11302 */ 11303 enum { 11304 FMT_SD_S = 0, 11305 FMT_SD_D = 1, 11306 11307 FMT_SDPS_S = 0, 11308 FMT_SDPS_D = 1, 11309 FMT_SDPS_PS = 2, 11310 11311 FMT_SWL_S = 0, 11312 FMT_SWL_W = 1, 11313 FMT_SWL_L = 2, 11314 11315 FMT_DWL_D = 0, 11316 FMT_DWL_W = 1, 11317 FMT_DWL_L = 2 11318 }; 11319 11320 #include "micromips_translate.c.inc" 11321 11322 #include "nanomips_translate.c.inc" 11323 11324 /* MIPSDSP functions. */ 11325 11326 /* Indexed load is not for DSP only */ 11327 static void gen_mips_lx(DisasContext *ctx, uint32_t opc, 11328 int rd, int base, int offset) 11329 { 11330 TCGv t0; 11331 11332 if (!(ctx->insn_flags & INSN_OCTEON)) { 11333 check_dsp(ctx); 11334 } 11335 t0 = tcg_temp_new(); 11336 11337 if (base == 0) { 11338 gen_load_gpr(t0, offset); 11339 } else if (offset == 0) { 11340 gen_load_gpr(t0, base); 11341 } else { 11342 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]); 11343 } 11344 11345 switch (opc) { 11346 case OPC_LBUX: 11347 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB); 11348 gen_store_gpr(t0, rd); 11349 break; 11350 case OPC_LHX: 11351 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW); 11352 gen_store_gpr(t0, rd); 11353 break; 11354 case OPC_LWX: 11355 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 11356 gen_store_gpr(t0, rd); 11357 break; 11358 #if defined(TARGET_MIPS64) 11359 case OPC_LDX: 11360 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 11361 gen_store_gpr(t0, rd); 11362 break; 11363 #endif 11364 } 11365 } 11366 11367 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2, 11368 int ret, int v1, int v2) 11369 { 11370 TCGv v1_t; 11371 TCGv v2_t; 11372 11373 if (ret == 0) { 11374 /* Treat as NOP. */ 11375 return; 11376 } 11377 11378 v1_t = tcg_temp_new(); 11379 v2_t = tcg_temp_new(); 11380 11381 gen_load_gpr(v1_t, v1); 11382 gen_load_gpr(v2_t, v2); 11383 11384 switch (op1) { 11385 case OPC_ADDUH_QB_DSP: 11386 check_dsp_r2(ctx); 11387 switch (op2) { 11388 case OPC_ADDUH_QB: 11389 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); 11390 break; 11391 case OPC_ADDUH_R_QB: 11392 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); 11393 break; 11394 case OPC_ADDQH_PH: 11395 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); 11396 break; 11397 case OPC_ADDQH_R_PH: 11398 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 11399 break; 11400 case OPC_ADDQH_W: 11401 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); 11402 break; 11403 case OPC_ADDQH_R_W: 11404 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); 11405 break; 11406 case OPC_SUBUH_QB: 11407 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); 11408 break; 11409 case OPC_SUBUH_R_QB: 11410 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); 11411 break; 11412 case OPC_SUBQH_PH: 11413 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); 11414 break; 11415 case OPC_SUBQH_R_PH: 11416 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 11417 break; 11418 case OPC_SUBQH_W: 11419 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); 11420 break; 11421 case OPC_SUBQH_R_W: 11422 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); 11423 break; 11424 } 11425 break; 11426 case OPC_ABSQ_S_PH_DSP: 11427 switch (op2) { 11428 case OPC_ABSQ_S_QB: 11429 check_dsp_r2(ctx); 11430 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, tcg_env); 11431 break; 11432 case OPC_ABSQ_S_PH: 11433 check_dsp(ctx); 11434 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, tcg_env); 11435 break; 11436 case OPC_ABSQ_S_W: 11437 check_dsp(ctx); 11438 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, tcg_env); 11439 break; 11440 case OPC_PRECEQ_W_PHL: 11441 check_dsp(ctx); 11442 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); 11443 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 11444 break; 11445 case OPC_PRECEQ_W_PHR: 11446 check_dsp(ctx); 11447 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); 11448 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); 11449 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 11450 break; 11451 case OPC_PRECEQU_PH_QBL: 11452 check_dsp(ctx); 11453 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); 11454 break; 11455 case OPC_PRECEQU_PH_QBR: 11456 check_dsp(ctx); 11457 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); 11458 break; 11459 case OPC_PRECEQU_PH_QBLA: 11460 check_dsp(ctx); 11461 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); 11462 break; 11463 case OPC_PRECEQU_PH_QBRA: 11464 check_dsp(ctx); 11465 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); 11466 break; 11467 case OPC_PRECEU_PH_QBL: 11468 check_dsp(ctx); 11469 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); 11470 break; 11471 case OPC_PRECEU_PH_QBR: 11472 check_dsp(ctx); 11473 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); 11474 break; 11475 case OPC_PRECEU_PH_QBLA: 11476 check_dsp(ctx); 11477 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); 11478 break; 11479 case OPC_PRECEU_PH_QBRA: 11480 check_dsp(ctx); 11481 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); 11482 break; 11483 } 11484 break; 11485 case OPC_ADDU_QB_DSP: 11486 switch (op2) { 11487 case OPC_ADDQ_PH: 11488 check_dsp(ctx); 11489 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11490 break; 11491 case OPC_ADDQ_S_PH: 11492 check_dsp(ctx); 11493 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11494 break; 11495 case OPC_ADDQ_S_W: 11496 check_dsp(ctx); 11497 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11498 break; 11499 case OPC_ADDU_QB: 11500 check_dsp(ctx); 11501 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11502 break; 11503 case OPC_ADDU_S_QB: 11504 check_dsp(ctx); 11505 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11506 break; 11507 case OPC_ADDU_PH: 11508 check_dsp_r2(ctx); 11509 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11510 break; 11511 case OPC_ADDU_S_PH: 11512 check_dsp_r2(ctx); 11513 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11514 break; 11515 case OPC_SUBQ_PH: 11516 check_dsp(ctx); 11517 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11518 break; 11519 case OPC_SUBQ_S_PH: 11520 check_dsp(ctx); 11521 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11522 break; 11523 case OPC_SUBQ_S_W: 11524 check_dsp(ctx); 11525 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11526 break; 11527 case OPC_SUBU_QB: 11528 check_dsp(ctx); 11529 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11530 break; 11531 case OPC_SUBU_S_QB: 11532 check_dsp(ctx); 11533 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11534 break; 11535 case OPC_SUBU_PH: 11536 check_dsp_r2(ctx); 11537 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11538 break; 11539 case OPC_SUBU_S_PH: 11540 check_dsp_r2(ctx); 11541 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11542 break; 11543 case OPC_ADDSC: 11544 check_dsp(ctx); 11545 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11546 break; 11547 case OPC_ADDWC: 11548 check_dsp(ctx); 11549 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11550 break; 11551 case OPC_MODSUB: 11552 check_dsp(ctx); 11553 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); 11554 break; 11555 case OPC_RADDU_W_QB: 11556 check_dsp(ctx); 11557 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); 11558 break; 11559 } 11560 break; 11561 case OPC_CMPU_EQ_QB_DSP: 11562 switch (op2) { 11563 case OPC_PRECR_QB_PH: 11564 check_dsp_r2(ctx); 11565 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); 11566 break; 11567 case OPC_PRECRQ_QB_PH: 11568 check_dsp(ctx); 11569 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); 11570 break; 11571 case OPC_PRECR_SRA_PH_W: 11572 check_dsp_r2(ctx); 11573 { 11574 TCGv_i32 sa_t = tcg_constant_i32(v2); 11575 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, 11576 cpu_gpr[ret]); 11577 break; 11578 } 11579 case OPC_PRECR_SRA_R_PH_W: 11580 check_dsp_r2(ctx); 11581 { 11582 TCGv_i32 sa_t = tcg_constant_i32(v2); 11583 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, 11584 cpu_gpr[ret]); 11585 break; 11586 } 11587 case OPC_PRECRQ_PH_W: 11588 check_dsp(ctx); 11589 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); 11590 break; 11591 case OPC_PRECRQ_RS_PH_W: 11592 check_dsp(ctx); 11593 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11594 break; 11595 case OPC_PRECRQU_S_QB_PH: 11596 check_dsp(ctx); 11597 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11598 break; 11599 } 11600 break; 11601 #ifdef TARGET_MIPS64 11602 case OPC_ABSQ_S_QH_DSP: 11603 switch (op2) { 11604 case OPC_PRECEQ_L_PWL: 11605 check_dsp(ctx); 11606 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); 11607 break; 11608 case OPC_PRECEQ_L_PWR: 11609 check_dsp(ctx); 11610 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); 11611 break; 11612 case OPC_PRECEQ_PW_QHL: 11613 check_dsp(ctx); 11614 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); 11615 break; 11616 case OPC_PRECEQ_PW_QHR: 11617 check_dsp(ctx); 11618 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); 11619 break; 11620 case OPC_PRECEQ_PW_QHLA: 11621 check_dsp(ctx); 11622 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); 11623 break; 11624 case OPC_PRECEQ_PW_QHRA: 11625 check_dsp(ctx); 11626 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); 11627 break; 11628 case OPC_PRECEQU_QH_OBL: 11629 check_dsp(ctx); 11630 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); 11631 break; 11632 case OPC_PRECEQU_QH_OBR: 11633 check_dsp(ctx); 11634 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); 11635 break; 11636 case OPC_PRECEQU_QH_OBLA: 11637 check_dsp(ctx); 11638 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); 11639 break; 11640 case OPC_PRECEQU_QH_OBRA: 11641 check_dsp(ctx); 11642 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); 11643 break; 11644 case OPC_PRECEU_QH_OBL: 11645 check_dsp(ctx); 11646 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); 11647 break; 11648 case OPC_PRECEU_QH_OBR: 11649 check_dsp(ctx); 11650 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); 11651 break; 11652 case OPC_PRECEU_QH_OBLA: 11653 check_dsp(ctx); 11654 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); 11655 break; 11656 case OPC_PRECEU_QH_OBRA: 11657 check_dsp(ctx); 11658 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); 11659 break; 11660 case OPC_ABSQ_S_OB: 11661 check_dsp_r2(ctx); 11662 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, tcg_env); 11663 break; 11664 case OPC_ABSQ_S_PW: 11665 check_dsp(ctx); 11666 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, tcg_env); 11667 break; 11668 case OPC_ABSQ_S_QH: 11669 check_dsp(ctx); 11670 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, tcg_env); 11671 break; 11672 } 11673 break; 11674 case OPC_ADDU_OB_DSP: 11675 switch (op2) { 11676 case OPC_RADDU_L_OB: 11677 check_dsp(ctx); 11678 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); 11679 break; 11680 case OPC_SUBQ_PW: 11681 check_dsp(ctx); 11682 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11683 break; 11684 case OPC_SUBQ_S_PW: 11685 check_dsp(ctx); 11686 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11687 break; 11688 case OPC_SUBQ_QH: 11689 check_dsp(ctx); 11690 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11691 break; 11692 case OPC_SUBQ_S_QH: 11693 check_dsp(ctx); 11694 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11695 break; 11696 case OPC_SUBU_OB: 11697 check_dsp(ctx); 11698 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11699 break; 11700 case OPC_SUBU_S_OB: 11701 check_dsp(ctx); 11702 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11703 break; 11704 case OPC_SUBU_QH: 11705 check_dsp_r2(ctx); 11706 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11707 break; 11708 case OPC_SUBU_S_QH: 11709 check_dsp_r2(ctx); 11710 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11711 break; 11712 case OPC_SUBUH_OB: 11713 check_dsp_r2(ctx); 11714 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); 11715 break; 11716 case OPC_SUBUH_R_OB: 11717 check_dsp_r2(ctx); 11718 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); 11719 break; 11720 case OPC_ADDQ_PW: 11721 check_dsp(ctx); 11722 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11723 break; 11724 case OPC_ADDQ_S_PW: 11725 check_dsp(ctx); 11726 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11727 break; 11728 case OPC_ADDQ_QH: 11729 check_dsp(ctx); 11730 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11731 break; 11732 case OPC_ADDQ_S_QH: 11733 check_dsp(ctx); 11734 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11735 break; 11736 case OPC_ADDU_OB: 11737 check_dsp(ctx); 11738 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11739 break; 11740 case OPC_ADDU_S_OB: 11741 check_dsp(ctx); 11742 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11743 break; 11744 case OPC_ADDU_QH: 11745 check_dsp_r2(ctx); 11746 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11747 break; 11748 case OPC_ADDU_S_QH: 11749 check_dsp_r2(ctx); 11750 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11751 break; 11752 case OPC_ADDUH_OB: 11753 check_dsp_r2(ctx); 11754 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); 11755 break; 11756 case OPC_ADDUH_R_OB: 11757 check_dsp_r2(ctx); 11758 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); 11759 break; 11760 } 11761 break; 11762 case OPC_CMPU_EQ_OB_DSP: 11763 switch (op2) { 11764 case OPC_PRECR_OB_QH: 11765 check_dsp_r2(ctx); 11766 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); 11767 break; 11768 case OPC_PRECR_SRA_QH_PW: 11769 check_dsp_r2(ctx); 11770 { 11771 TCGv_i32 ret_t = tcg_constant_i32(ret); 11772 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); 11773 break; 11774 } 11775 case OPC_PRECR_SRA_R_QH_PW: 11776 check_dsp_r2(ctx); 11777 { 11778 TCGv_i32 sa_v = tcg_constant_i32(ret); 11779 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); 11780 break; 11781 } 11782 case OPC_PRECRQ_OB_QH: 11783 check_dsp(ctx); 11784 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); 11785 break; 11786 case OPC_PRECRQ_PW_L: 11787 check_dsp(ctx); 11788 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); 11789 break; 11790 case OPC_PRECRQ_QH_PW: 11791 check_dsp(ctx); 11792 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); 11793 break; 11794 case OPC_PRECRQ_RS_QH_PW: 11795 check_dsp(ctx); 11796 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11797 break; 11798 case OPC_PRECRQU_S_OB_QH: 11799 check_dsp(ctx); 11800 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11801 break; 11802 } 11803 break; 11804 #endif 11805 } 11806 } 11807 11808 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, 11809 int ret, int v1, int v2) 11810 { 11811 uint32_t op2; 11812 TCGv t0; 11813 TCGv v1_t; 11814 TCGv v2_t; 11815 11816 if (ret == 0) { 11817 /* Treat as NOP. */ 11818 return; 11819 } 11820 11821 t0 = tcg_temp_new(); 11822 v1_t = tcg_temp_new(); 11823 v2_t = tcg_temp_new(); 11824 11825 tcg_gen_movi_tl(t0, v1); 11826 gen_load_gpr(v1_t, v1); 11827 gen_load_gpr(v2_t, v2); 11828 11829 switch (opc) { 11830 case OPC_SHLL_QB_DSP: 11831 { 11832 op2 = MASK_SHLL_QB(ctx->opcode); 11833 switch (op2) { 11834 case OPC_SHLL_QB: 11835 check_dsp(ctx); 11836 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, tcg_env); 11837 break; 11838 case OPC_SHLLV_QB: 11839 check_dsp(ctx); 11840 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11841 break; 11842 case OPC_SHLL_PH: 11843 check_dsp(ctx); 11844 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, tcg_env); 11845 break; 11846 case OPC_SHLLV_PH: 11847 check_dsp(ctx); 11848 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11849 break; 11850 case OPC_SHLL_S_PH: 11851 check_dsp(ctx); 11852 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, tcg_env); 11853 break; 11854 case OPC_SHLLV_S_PH: 11855 check_dsp(ctx); 11856 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11857 break; 11858 case OPC_SHLL_S_W: 11859 check_dsp(ctx); 11860 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, tcg_env); 11861 break; 11862 case OPC_SHLLV_S_W: 11863 check_dsp(ctx); 11864 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11865 break; 11866 case OPC_SHRL_QB: 11867 check_dsp(ctx); 11868 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); 11869 break; 11870 case OPC_SHRLV_QB: 11871 check_dsp(ctx); 11872 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); 11873 break; 11874 case OPC_SHRL_PH: 11875 check_dsp_r2(ctx); 11876 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); 11877 break; 11878 case OPC_SHRLV_PH: 11879 check_dsp_r2(ctx); 11880 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); 11881 break; 11882 case OPC_SHRA_QB: 11883 check_dsp_r2(ctx); 11884 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); 11885 break; 11886 case OPC_SHRA_R_QB: 11887 check_dsp_r2(ctx); 11888 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); 11889 break; 11890 case OPC_SHRAV_QB: 11891 check_dsp_r2(ctx); 11892 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); 11893 break; 11894 case OPC_SHRAV_R_QB: 11895 check_dsp_r2(ctx); 11896 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); 11897 break; 11898 case OPC_SHRA_PH: 11899 check_dsp(ctx); 11900 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); 11901 break; 11902 case OPC_SHRA_R_PH: 11903 check_dsp(ctx); 11904 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); 11905 break; 11906 case OPC_SHRAV_PH: 11907 check_dsp(ctx); 11908 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); 11909 break; 11910 case OPC_SHRAV_R_PH: 11911 check_dsp(ctx); 11912 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); 11913 break; 11914 case OPC_SHRA_R_W: 11915 check_dsp(ctx); 11916 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); 11917 break; 11918 case OPC_SHRAV_R_W: 11919 check_dsp(ctx); 11920 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); 11921 break; 11922 default: /* Invalid */ 11923 MIPS_INVAL("MASK SHLL.QB"); 11924 gen_reserved_instruction(ctx); 11925 break; 11926 } 11927 break; 11928 } 11929 #ifdef TARGET_MIPS64 11930 case OPC_SHLL_OB_DSP: 11931 op2 = MASK_SHLL_OB(ctx->opcode); 11932 switch (op2) { 11933 case OPC_SHLL_PW: 11934 check_dsp(ctx); 11935 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, tcg_env); 11936 break; 11937 case OPC_SHLLV_PW: 11938 check_dsp(ctx); 11939 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11940 break; 11941 case OPC_SHLL_S_PW: 11942 check_dsp(ctx); 11943 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, tcg_env); 11944 break; 11945 case OPC_SHLLV_S_PW: 11946 check_dsp(ctx); 11947 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11948 break; 11949 case OPC_SHLL_OB: 11950 check_dsp(ctx); 11951 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, tcg_env); 11952 break; 11953 case OPC_SHLLV_OB: 11954 check_dsp(ctx); 11955 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11956 break; 11957 case OPC_SHLL_QH: 11958 check_dsp(ctx); 11959 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, tcg_env); 11960 break; 11961 case OPC_SHLLV_QH: 11962 check_dsp(ctx); 11963 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11964 break; 11965 case OPC_SHLL_S_QH: 11966 check_dsp(ctx); 11967 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, tcg_env); 11968 break; 11969 case OPC_SHLLV_S_QH: 11970 check_dsp(ctx); 11971 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11972 break; 11973 case OPC_SHRA_OB: 11974 check_dsp_r2(ctx); 11975 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); 11976 break; 11977 case OPC_SHRAV_OB: 11978 check_dsp_r2(ctx); 11979 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); 11980 break; 11981 case OPC_SHRA_R_OB: 11982 check_dsp_r2(ctx); 11983 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); 11984 break; 11985 case OPC_SHRAV_R_OB: 11986 check_dsp_r2(ctx); 11987 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); 11988 break; 11989 case OPC_SHRA_PW: 11990 check_dsp(ctx); 11991 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); 11992 break; 11993 case OPC_SHRAV_PW: 11994 check_dsp(ctx); 11995 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); 11996 break; 11997 case OPC_SHRA_R_PW: 11998 check_dsp(ctx); 11999 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); 12000 break; 12001 case OPC_SHRAV_R_PW: 12002 check_dsp(ctx); 12003 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); 12004 break; 12005 case OPC_SHRA_QH: 12006 check_dsp(ctx); 12007 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); 12008 break; 12009 case OPC_SHRAV_QH: 12010 check_dsp(ctx); 12011 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); 12012 break; 12013 case OPC_SHRA_R_QH: 12014 check_dsp(ctx); 12015 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); 12016 break; 12017 case OPC_SHRAV_R_QH: 12018 check_dsp(ctx); 12019 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); 12020 break; 12021 case OPC_SHRL_OB: 12022 check_dsp(ctx); 12023 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); 12024 break; 12025 case OPC_SHRLV_OB: 12026 check_dsp(ctx); 12027 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); 12028 break; 12029 case OPC_SHRL_QH: 12030 check_dsp_r2(ctx); 12031 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); 12032 break; 12033 case OPC_SHRLV_QH: 12034 check_dsp_r2(ctx); 12035 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); 12036 break; 12037 default: /* Invalid */ 12038 MIPS_INVAL("MASK SHLL.OB"); 12039 gen_reserved_instruction(ctx); 12040 break; 12041 } 12042 break; 12043 #endif 12044 } 12045 } 12046 12047 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2, 12048 int ret, int v1, int v2, int check_ret) 12049 { 12050 TCGv_i32 t0; 12051 TCGv v1_t; 12052 TCGv v2_t; 12053 12054 if ((ret == 0) && (check_ret == 1)) { 12055 /* Treat as NOP. */ 12056 return; 12057 } 12058 12059 t0 = tcg_temp_new_i32(); 12060 v1_t = tcg_temp_new(); 12061 v2_t = tcg_temp_new(); 12062 12063 tcg_gen_movi_i32(t0, ret); 12064 gen_load_gpr(v1_t, v1); 12065 gen_load_gpr(v2_t, v2); 12066 12067 switch (op1) { 12068 case OPC_MUL_PH_DSP: 12069 check_dsp_r2(ctx); 12070 switch (op2) { 12071 case OPC_MUL_PH: 12072 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12073 break; 12074 case OPC_MUL_S_PH: 12075 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12076 break; 12077 case OPC_MULQ_S_W: 12078 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12079 break; 12080 case OPC_MULQ_RS_W: 12081 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12082 break; 12083 } 12084 break; 12085 case OPC_DPA_W_PH_DSP: 12086 switch (op2) { 12087 case OPC_DPAU_H_QBL: 12088 check_dsp(ctx); 12089 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, tcg_env); 12090 break; 12091 case OPC_DPAU_H_QBR: 12092 check_dsp(ctx); 12093 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, tcg_env); 12094 break; 12095 case OPC_DPSU_H_QBL: 12096 check_dsp(ctx); 12097 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, tcg_env); 12098 break; 12099 case OPC_DPSU_H_QBR: 12100 check_dsp(ctx); 12101 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, tcg_env); 12102 break; 12103 case OPC_DPA_W_PH: 12104 check_dsp_r2(ctx); 12105 gen_helper_dpa_w_ph(t0, v1_t, v2_t, tcg_env); 12106 break; 12107 case OPC_DPAX_W_PH: 12108 check_dsp_r2(ctx); 12109 gen_helper_dpax_w_ph(t0, v1_t, v2_t, tcg_env); 12110 break; 12111 case OPC_DPAQ_S_W_PH: 12112 check_dsp(ctx); 12113 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12114 break; 12115 case OPC_DPAQX_S_W_PH: 12116 check_dsp_r2(ctx); 12117 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, tcg_env); 12118 break; 12119 case OPC_DPAQX_SA_W_PH: 12120 check_dsp_r2(ctx); 12121 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, tcg_env); 12122 break; 12123 case OPC_DPS_W_PH: 12124 check_dsp_r2(ctx); 12125 gen_helper_dps_w_ph(t0, v1_t, v2_t, tcg_env); 12126 break; 12127 case OPC_DPSX_W_PH: 12128 check_dsp_r2(ctx); 12129 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, tcg_env); 12130 break; 12131 case OPC_DPSQ_S_W_PH: 12132 check_dsp(ctx); 12133 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12134 break; 12135 case OPC_DPSQX_S_W_PH: 12136 check_dsp_r2(ctx); 12137 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, tcg_env); 12138 break; 12139 case OPC_DPSQX_SA_W_PH: 12140 check_dsp_r2(ctx); 12141 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, tcg_env); 12142 break; 12143 case OPC_MULSAQ_S_W_PH: 12144 check_dsp(ctx); 12145 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12146 break; 12147 case OPC_DPAQ_SA_L_W: 12148 check_dsp(ctx); 12149 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, tcg_env); 12150 break; 12151 case OPC_DPSQ_SA_L_W: 12152 check_dsp(ctx); 12153 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, tcg_env); 12154 break; 12155 case OPC_MAQ_S_W_PHL: 12156 check_dsp(ctx); 12157 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, tcg_env); 12158 break; 12159 case OPC_MAQ_S_W_PHR: 12160 check_dsp(ctx); 12161 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, tcg_env); 12162 break; 12163 case OPC_MAQ_SA_W_PHL: 12164 check_dsp(ctx); 12165 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, tcg_env); 12166 break; 12167 case OPC_MAQ_SA_W_PHR: 12168 check_dsp(ctx); 12169 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, tcg_env); 12170 break; 12171 case OPC_MULSA_W_PH: 12172 check_dsp_r2(ctx); 12173 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, tcg_env); 12174 break; 12175 } 12176 break; 12177 #ifdef TARGET_MIPS64 12178 case OPC_DPAQ_W_QH_DSP: 12179 { 12180 int ac = ret & 0x03; 12181 tcg_gen_movi_i32(t0, ac); 12182 12183 switch (op2) { 12184 case OPC_DMADD: 12185 check_dsp(ctx); 12186 gen_helper_dmadd(v1_t, v2_t, t0, tcg_env); 12187 break; 12188 case OPC_DMADDU: 12189 check_dsp(ctx); 12190 gen_helper_dmaddu(v1_t, v2_t, t0, tcg_env); 12191 break; 12192 case OPC_DMSUB: 12193 check_dsp(ctx); 12194 gen_helper_dmsub(v1_t, v2_t, t0, tcg_env); 12195 break; 12196 case OPC_DMSUBU: 12197 check_dsp(ctx); 12198 gen_helper_dmsubu(v1_t, v2_t, t0, tcg_env); 12199 break; 12200 case OPC_DPA_W_QH: 12201 check_dsp_r2(ctx); 12202 gen_helper_dpa_w_qh(v1_t, v2_t, t0, tcg_env); 12203 break; 12204 case OPC_DPAQ_S_W_QH: 12205 check_dsp(ctx); 12206 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12207 break; 12208 case OPC_DPAQ_SA_L_PW: 12209 check_dsp(ctx); 12210 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, tcg_env); 12211 break; 12212 case OPC_DPAU_H_OBL: 12213 check_dsp(ctx); 12214 gen_helper_dpau_h_obl(v1_t, v2_t, t0, tcg_env); 12215 break; 12216 case OPC_DPAU_H_OBR: 12217 check_dsp(ctx); 12218 gen_helper_dpau_h_obr(v1_t, v2_t, t0, tcg_env); 12219 break; 12220 case OPC_DPS_W_QH: 12221 check_dsp_r2(ctx); 12222 gen_helper_dps_w_qh(v1_t, v2_t, t0, tcg_env); 12223 break; 12224 case OPC_DPSQ_S_W_QH: 12225 check_dsp(ctx); 12226 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12227 break; 12228 case OPC_DPSQ_SA_L_PW: 12229 check_dsp(ctx); 12230 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, tcg_env); 12231 break; 12232 case OPC_DPSU_H_OBL: 12233 check_dsp(ctx); 12234 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, tcg_env); 12235 break; 12236 case OPC_DPSU_H_OBR: 12237 check_dsp(ctx); 12238 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, tcg_env); 12239 break; 12240 case OPC_MAQ_S_L_PWL: 12241 check_dsp(ctx); 12242 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, tcg_env); 12243 break; 12244 case OPC_MAQ_S_L_PWR: 12245 check_dsp(ctx); 12246 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, tcg_env); 12247 break; 12248 case OPC_MAQ_S_W_QHLL: 12249 check_dsp(ctx); 12250 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, tcg_env); 12251 break; 12252 case OPC_MAQ_SA_W_QHLL: 12253 check_dsp(ctx); 12254 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, tcg_env); 12255 break; 12256 case OPC_MAQ_S_W_QHLR: 12257 check_dsp(ctx); 12258 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, tcg_env); 12259 break; 12260 case OPC_MAQ_SA_W_QHLR: 12261 check_dsp(ctx); 12262 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, tcg_env); 12263 break; 12264 case OPC_MAQ_S_W_QHRL: 12265 check_dsp(ctx); 12266 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, tcg_env); 12267 break; 12268 case OPC_MAQ_SA_W_QHRL: 12269 check_dsp(ctx); 12270 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, tcg_env); 12271 break; 12272 case OPC_MAQ_S_W_QHRR: 12273 check_dsp(ctx); 12274 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, tcg_env); 12275 break; 12276 case OPC_MAQ_SA_W_QHRR: 12277 check_dsp(ctx); 12278 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, tcg_env); 12279 break; 12280 case OPC_MULSAQ_S_L_PW: 12281 check_dsp(ctx); 12282 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, tcg_env); 12283 break; 12284 case OPC_MULSAQ_S_W_QH: 12285 check_dsp(ctx); 12286 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12287 break; 12288 } 12289 } 12290 break; 12291 #endif 12292 case OPC_ADDU_QB_DSP: 12293 switch (op2) { 12294 case OPC_MULEU_S_PH_QBL: 12295 check_dsp(ctx); 12296 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12297 break; 12298 case OPC_MULEU_S_PH_QBR: 12299 check_dsp(ctx); 12300 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12301 break; 12302 case OPC_MULQ_RS_PH: 12303 check_dsp(ctx); 12304 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12305 break; 12306 case OPC_MULEQ_S_W_PHL: 12307 check_dsp(ctx); 12308 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12309 break; 12310 case OPC_MULEQ_S_W_PHR: 12311 check_dsp(ctx); 12312 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12313 break; 12314 case OPC_MULQ_S_PH: 12315 check_dsp_r2(ctx); 12316 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12317 break; 12318 } 12319 break; 12320 #ifdef TARGET_MIPS64 12321 case OPC_ADDU_OB_DSP: 12322 switch (op2) { 12323 case OPC_MULEQ_S_PW_QHL: 12324 check_dsp(ctx); 12325 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12326 break; 12327 case OPC_MULEQ_S_PW_QHR: 12328 check_dsp(ctx); 12329 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12330 break; 12331 case OPC_MULEU_S_QH_OBL: 12332 check_dsp(ctx); 12333 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12334 break; 12335 case OPC_MULEU_S_QH_OBR: 12336 check_dsp(ctx); 12337 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12338 break; 12339 case OPC_MULQ_RS_QH: 12340 check_dsp(ctx); 12341 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12342 break; 12343 } 12344 break; 12345 #endif 12346 } 12347 } 12348 12349 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 12350 int ret, int val) 12351 { 12352 int16_t imm; 12353 TCGv t0; 12354 TCGv val_t; 12355 12356 if (ret == 0) { 12357 /* Treat as NOP. */ 12358 return; 12359 } 12360 12361 t0 = tcg_temp_new(); 12362 val_t = tcg_temp_new(); 12363 gen_load_gpr(val_t, val); 12364 12365 switch (op1) { 12366 case OPC_ABSQ_S_PH_DSP: 12367 switch (op2) { 12368 case OPC_BITREV: 12369 check_dsp(ctx); 12370 gen_helper_bitrev(cpu_gpr[ret], val_t); 12371 break; 12372 case OPC_REPL_QB: 12373 check_dsp(ctx); 12374 { 12375 target_long result; 12376 imm = (ctx->opcode >> 16) & 0xFF; 12377 result = (uint32_t)imm << 24 | 12378 (uint32_t)imm << 16 | 12379 (uint32_t)imm << 8 | 12380 (uint32_t)imm; 12381 result = (int32_t)result; 12382 tcg_gen_movi_tl(cpu_gpr[ret], result); 12383 } 12384 break; 12385 case OPC_REPLV_QB: 12386 check_dsp(ctx); 12387 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 12388 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 12389 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12390 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12391 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12392 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12393 break; 12394 case OPC_REPL_PH: 12395 check_dsp(ctx); 12396 { 12397 imm = (ctx->opcode >> 16) & 0x03FF; 12398 imm = (int16_t)(imm << 6) >> 6; 12399 tcg_gen_movi_tl(cpu_gpr[ret], \ 12400 (target_long)((int32_t)imm << 16 | \ 12401 (uint16_t)imm)); 12402 } 12403 break; 12404 case OPC_REPLV_PH: 12405 check_dsp(ctx); 12406 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 12407 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12408 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12409 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12410 break; 12411 } 12412 break; 12413 #ifdef TARGET_MIPS64 12414 case OPC_ABSQ_S_QH_DSP: 12415 switch (op2) { 12416 case OPC_REPL_OB: 12417 check_dsp(ctx); 12418 { 12419 target_long temp; 12420 12421 imm = (ctx->opcode >> 16) & 0xFF; 12422 temp = ((uint64_t)imm << 8) | (uint64_t)imm; 12423 temp = (temp << 16) | temp; 12424 temp = (temp << 32) | temp; 12425 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12426 break; 12427 } 12428 case OPC_REPL_PW: 12429 check_dsp(ctx); 12430 { 12431 target_long temp; 12432 12433 imm = (ctx->opcode >> 16) & 0x03FF; 12434 imm = (int16_t)(imm << 6) >> 6; 12435 temp = ((target_long)imm << 32) \ 12436 | ((target_long)imm & 0xFFFFFFFF); 12437 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12438 break; 12439 } 12440 case OPC_REPL_QH: 12441 check_dsp(ctx); 12442 { 12443 target_long temp; 12444 12445 imm = (ctx->opcode >> 16) & 0x03FF; 12446 imm = (int16_t)(imm << 6) >> 6; 12447 12448 temp = ((uint64_t)(uint16_t)imm << 48) | 12449 ((uint64_t)(uint16_t)imm << 32) | 12450 ((uint64_t)(uint16_t)imm << 16) | 12451 (uint64_t)(uint16_t)imm; 12452 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12453 break; 12454 } 12455 case OPC_REPLV_OB: 12456 check_dsp(ctx); 12457 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 12458 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 12459 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12460 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12461 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12462 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12463 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12464 break; 12465 case OPC_REPLV_PW: 12466 check_dsp(ctx); 12467 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); 12468 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12469 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12470 break; 12471 case OPC_REPLV_QH: 12472 check_dsp(ctx); 12473 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 12474 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12475 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12476 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12477 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12478 break; 12479 } 12480 break; 12481 #endif 12482 } 12483 } 12484 12485 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, 12486 uint32_t op1, uint32_t op2, 12487 int ret, int v1, int v2, int check_ret) 12488 { 12489 TCGv t1; 12490 TCGv v1_t; 12491 TCGv v2_t; 12492 12493 if ((ret == 0) && (check_ret == 1)) { 12494 /* Treat as NOP. */ 12495 return; 12496 } 12497 12498 t1 = tcg_temp_new(); 12499 v1_t = tcg_temp_new(); 12500 v2_t = tcg_temp_new(); 12501 12502 gen_load_gpr(v1_t, v1); 12503 gen_load_gpr(v2_t, v2); 12504 12505 switch (op1) { 12506 case OPC_CMPU_EQ_QB_DSP: 12507 switch (op2) { 12508 case OPC_CMPU_EQ_QB: 12509 check_dsp(ctx); 12510 gen_helper_cmpu_eq_qb(v1_t, v2_t, tcg_env); 12511 break; 12512 case OPC_CMPU_LT_QB: 12513 check_dsp(ctx); 12514 gen_helper_cmpu_lt_qb(v1_t, v2_t, tcg_env); 12515 break; 12516 case OPC_CMPU_LE_QB: 12517 check_dsp(ctx); 12518 gen_helper_cmpu_le_qb(v1_t, v2_t, tcg_env); 12519 break; 12520 case OPC_CMPGU_EQ_QB: 12521 check_dsp(ctx); 12522 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); 12523 break; 12524 case OPC_CMPGU_LT_QB: 12525 check_dsp(ctx); 12526 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); 12527 break; 12528 case OPC_CMPGU_LE_QB: 12529 check_dsp(ctx); 12530 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); 12531 break; 12532 case OPC_CMPGDU_EQ_QB: 12533 check_dsp_r2(ctx); 12534 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); 12535 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12536 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12537 tcg_gen_shli_tl(t1, t1, 24); 12538 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12539 break; 12540 case OPC_CMPGDU_LT_QB: 12541 check_dsp_r2(ctx); 12542 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); 12543 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12544 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12545 tcg_gen_shli_tl(t1, t1, 24); 12546 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12547 break; 12548 case OPC_CMPGDU_LE_QB: 12549 check_dsp_r2(ctx); 12550 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); 12551 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12552 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12553 tcg_gen_shli_tl(t1, t1, 24); 12554 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12555 break; 12556 case OPC_CMP_EQ_PH: 12557 check_dsp(ctx); 12558 gen_helper_cmp_eq_ph(v1_t, v2_t, tcg_env); 12559 break; 12560 case OPC_CMP_LT_PH: 12561 check_dsp(ctx); 12562 gen_helper_cmp_lt_ph(v1_t, v2_t, tcg_env); 12563 break; 12564 case OPC_CMP_LE_PH: 12565 check_dsp(ctx); 12566 gen_helper_cmp_le_ph(v1_t, v2_t, tcg_env); 12567 break; 12568 case OPC_PICK_QB: 12569 check_dsp(ctx); 12570 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12571 break; 12572 case OPC_PICK_PH: 12573 check_dsp(ctx); 12574 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12575 break; 12576 case OPC_PACKRL_PH: 12577 check_dsp(ctx); 12578 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); 12579 break; 12580 } 12581 break; 12582 #ifdef TARGET_MIPS64 12583 case OPC_CMPU_EQ_OB_DSP: 12584 switch (op2) { 12585 case OPC_CMP_EQ_PW: 12586 check_dsp(ctx); 12587 gen_helper_cmp_eq_pw(v1_t, v2_t, tcg_env); 12588 break; 12589 case OPC_CMP_LT_PW: 12590 check_dsp(ctx); 12591 gen_helper_cmp_lt_pw(v1_t, v2_t, tcg_env); 12592 break; 12593 case OPC_CMP_LE_PW: 12594 check_dsp(ctx); 12595 gen_helper_cmp_le_pw(v1_t, v2_t, tcg_env); 12596 break; 12597 case OPC_CMP_EQ_QH: 12598 check_dsp(ctx); 12599 gen_helper_cmp_eq_qh(v1_t, v2_t, tcg_env); 12600 break; 12601 case OPC_CMP_LT_QH: 12602 check_dsp(ctx); 12603 gen_helper_cmp_lt_qh(v1_t, v2_t, tcg_env); 12604 break; 12605 case OPC_CMP_LE_QH: 12606 check_dsp(ctx); 12607 gen_helper_cmp_le_qh(v1_t, v2_t, tcg_env); 12608 break; 12609 case OPC_CMPGDU_EQ_OB: 12610 check_dsp_r2(ctx); 12611 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12612 break; 12613 case OPC_CMPGDU_LT_OB: 12614 check_dsp_r2(ctx); 12615 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12616 break; 12617 case OPC_CMPGDU_LE_OB: 12618 check_dsp_r2(ctx); 12619 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12620 break; 12621 case OPC_CMPGU_EQ_OB: 12622 check_dsp(ctx); 12623 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); 12624 break; 12625 case OPC_CMPGU_LT_OB: 12626 check_dsp(ctx); 12627 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); 12628 break; 12629 case OPC_CMPGU_LE_OB: 12630 check_dsp(ctx); 12631 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); 12632 break; 12633 case OPC_CMPU_EQ_OB: 12634 check_dsp(ctx); 12635 gen_helper_cmpu_eq_ob(v1_t, v2_t, tcg_env); 12636 break; 12637 case OPC_CMPU_LT_OB: 12638 check_dsp(ctx); 12639 gen_helper_cmpu_lt_ob(v1_t, v2_t, tcg_env); 12640 break; 12641 case OPC_CMPU_LE_OB: 12642 check_dsp(ctx); 12643 gen_helper_cmpu_le_ob(v1_t, v2_t, tcg_env); 12644 break; 12645 case OPC_PACKRL_PW: 12646 check_dsp(ctx); 12647 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); 12648 break; 12649 case OPC_PICK_OB: 12650 check_dsp(ctx); 12651 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12652 break; 12653 case OPC_PICK_PW: 12654 check_dsp(ctx); 12655 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12656 break; 12657 case OPC_PICK_QH: 12658 check_dsp(ctx); 12659 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12660 break; 12661 } 12662 break; 12663 #endif 12664 } 12665 } 12666 12667 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, 12668 uint32_t op1, int rt, int rs, int sa) 12669 { 12670 TCGv t0; 12671 12672 check_dsp_r2(ctx); 12673 12674 if (rt == 0) { 12675 /* Treat as NOP. */ 12676 return; 12677 } 12678 12679 t0 = tcg_temp_new(); 12680 gen_load_gpr(t0, rs); 12681 12682 switch (op1) { 12683 case OPC_APPEND_DSP: 12684 switch (MASK_APPEND(ctx->opcode)) { 12685 case OPC_APPEND: 12686 if (sa != 0) { 12687 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa); 12688 } 12689 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12690 break; 12691 case OPC_PREPEND: 12692 if (sa != 0) { 12693 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); 12694 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 12695 tcg_gen_shli_tl(t0, t0, 32 - sa); 12696 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12697 } 12698 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12699 break; 12700 case OPC_BALIGN: 12701 sa &= 3; 12702 if (sa != 0 && sa != 2) { 12703 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 12704 tcg_gen_ext32u_tl(t0, t0); 12705 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); 12706 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12707 } 12708 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12709 break; 12710 default: /* Invalid */ 12711 MIPS_INVAL("MASK APPEND"); 12712 gen_reserved_instruction(ctx); 12713 break; 12714 } 12715 break; 12716 #ifdef TARGET_MIPS64 12717 case OPC_DAPPEND_DSP: 12718 switch (MASK_DAPPEND(ctx->opcode)) { 12719 case OPC_DAPPEND: 12720 if (sa != 0) { 12721 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa); 12722 } 12723 break; 12724 case OPC_PREPENDD: 12725 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); 12726 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); 12727 tcg_gen_or_tl(cpu_gpr[rt], t0, t0); 12728 break; 12729 case OPC_PREPENDW: 12730 if (sa != 0) { 12731 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 12732 tcg_gen_shli_tl(t0, t0, 64 - sa); 12733 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12734 } 12735 break; 12736 case OPC_DBALIGN: 12737 sa &= 7; 12738 if (sa != 0 && sa != 2 && sa != 4) { 12739 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 12740 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); 12741 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12742 } 12743 break; 12744 default: /* Invalid */ 12745 MIPS_INVAL("MASK DAPPEND"); 12746 gen_reserved_instruction(ctx); 12747 break; 12748 } 12749 break; 12750 #endif 12751 } 12752 } 12753 12754 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 12755 int ret, int v1, int v2, int check_ret) 12756 12757 { 12758 TCGv t0; 12759 TCGv t1; 12760 TCGv v1_t; 12761 int16_t imm; 12762 12763 if ((ret == 0) && (check_ret == 1)) { 12764 /* Treat as NOP. */ 12765 return; 12766 } 12767 12768 t0 = tcg_temp_new(); 12769 t1 = tcg_temp_new(); 12770 v1_t = tcg_temp_new(); 12771 12772 gen_load_gpr(v1_t, v1); 12773 12774 switch (op1) { 12775 case OPC_EXTR_W_DSP: 12776 check_dsp(ctx); 12777 switch (op2) { 12778 case OPC_EXTR_W: 12779 tcg_gen_movi_tl(t0, v2); 12780 tcg_gen_movi_tl(t1, v1); 12781 gen_helper_extr_w(cpu_gpr[ret], t0, t1, tcg_env); 12782 break; 12783 case OPC_EXTR_R_W: 12784 tcg_gen_movi_tl(t0, v2); 12785 tcg_gen_movi_tl(t1, v1); 12786 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, tcg_env); 12787 break; 12788 case OPC_EXTR_RS_W: 12789 tcg_gen_movi_tl(t0, v2); 12790 tcg_gen_movi_tl(t1, v1); 12791 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, tcg_env); 12792 break; 12793 case OPC_EXTR_S_H: 12794 tcg_gen_movi_tl(t0, v2); 12795 tcg_gen_movi_tl(t1, v1); 12796 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, tcg_env); 12797 break; 12798 case OPC_EXTRV_S_H: 12799 tcg_gen_movi_tl(t0, v2); 12800 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env); 12801 break; 12802 case OPC_EXTRV_W: 12803 tcg_gen_movi_tl(t0, v2); 12804 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12805 break; 12806 case OPC_EXTRV_R_W: 12807 tcg_gen_movi_tl(t0, v2); 12808 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12809 break; 12810 case OPC_EXTRV_RS_W: 12811 tcg_gen_movi_tl(t0, v2); 12812 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12813 break; 12814 case OPC_EXTP: 12815 tcg_gen_movi_tl(t0, v2); 12816 tcg_gen_movi_tl(t1, v1); 12817 gen_helper_extp(cpu_gpr[ret], t0, t1, tcg_env); 12818 break; 12819 case OPC_EXTPV: 12820 tcg_gen_movi_tl(t0, v2); 12821 gen_helper_extp(cpu_gpr[ret], t0, v1_t, tcg_env); 12822 break; 12823 case OPC_EXTPDP: 12824 tcg_gen_movi_tl(t0, v2); 12825 tcg_gen_movi_tl(t1, v1); 12826 gen_helper_extpdp(cpu_gpr[ret], t0, t1, tcg_env); 12827 break; 12828 case OPC_EXTPDPV: 12829 tcg_gen_movi_tl(t0, v2); 12830 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, tcg_env); 12831 break; 12832 case OPC_SHILO: 12833 imm = (ctx->opcode >> 20) & 0x3F; 12834 tcg_gen_movi_tl(t0, ret); 12835 tcg_gen_movi_tl(t1, imm); 12836 gen_helper_shilo(t0, t1, tcg_env); 12837 break; 12838 case OPC_SHILOV: 12839 tcg_gen_movi_tl(t0, ret); 12840 gen_helper_shilo(t0, v1_t, tcg_env); 12841 break; 12842 case OPC_MTHLIP: 12843 tcg_gen_movi_tl(t0, ret); 12844 gen_helper_mthlip(t0, v1_t, tcg_env); 12845 break; 12846 case OPC_WRDSP: 12847 imm = (ctx->opcode >> 11) & 0x3FF; 12848 tcg_gen_movi_tl(t0, imm); 12849 gen_helper_wrdsp(v1_t, t0, tcg_env); 12850 break; 12851 case OPC_RDDSP: 12852 imm = (ctx->opcode >> 16) & 0x03FF; 12853 tcg_gen_movi_tl(t0, imm); 12854 gen_helper_rddsp(cpu_gpr[ret], t0, tcg_env); 12855 break; 12856 } 12857 break; 12858 #ifdef TARGET_MIPS64 12859 case OPC_DEXTR_W_DSP: 12860 check_dsp(ctx); 12861 switch (op2) { 12862 case OPC_DMTHLIP: 12863 tcg_gen_movi_tl(t0, ret); 12864 gen_helper_dmthlip(v1_t, t0, tcg_env); 12865 break; 12866 case OPC_DSHILO: 12867 { 12868 int shift = (ctx->opcode >> 19) & 0x7F; 12869 int ac = (ctx->opcode >> 11) & 0x03; 12870 tcg_gen_movi_tl(t0, shift); 12871 tcg_gen_movi_tl(t1, ac); 12872 gen_helper_dshilo(t0, t1, tcg_env); 12873 break; 12874 } 12875 case OPC_DSHILOV: 12876 { 12877 int ac = (ctx->opcode >> 11) & 0x03; 12878 tcg_gen_movi_tl(t0, ac); 12879 gen_helper_dshilo(v1_t, t0, tcg_env); 12880 break; 12881 } 12882 case OPC_DEXTP: 12883 tcg_gen_movi_tl(t0, v2); 12884 tcg_gen_movi_tl(t1, v1); 12885 12886 gen_helper_dextp(cpu_gpr[ret], t0, t1, tcg_env); 12887 break; 12888 case OPC_DEXTPV: 12889 tcg_gen_movi_tl(t0, v2); 12890 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, tcg_env); 12891 break; 12892 case OPC_DEXTPDP: 12893 tcg_gen_movi_tl(t0, v2); 12894 tcg_gen_movi_tl(t1, v1); 12895 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, tcg_env); 12896 break; 12897 case OPC_DEXTPDPV: 12898 tcg_gen_movi_tl(t0, v2); 12899 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, tcg_env); 12900 break; 12901 case OPC_DEXTR_L: 12902 tcg_gen_movi_tl(t0, v2); 12903 tcg_gen_movi_tl(t1, v1); 12904 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, tcg_env); 12905 break; 12906 case OPC_DEXTR_R_L: 12907 tcg_gen_movi_tl(t0, v2); 12908 tcg_gen_movi_tl(t1, v1); 12909 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, tcg_env); 12910 break; 12911 case OPC_DEXTR_RS_L: 12912 tcg_gen_movi_tl(t0, v2); 12913 tcg_gen_movi_tl(t1, v1); 12914 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, tcg_env); 12915 break; 12916 case OPC_DEXTR_W: 12917 tcg_gen_movi_tl(t0, v2); 12918 tcg_gen_movi_tl(t1, v1); 12919 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, tcg_env); 12920 break; 12921 case OPC_DEXTR_R_W: 12922 tcg_gen_movi_tl(t0, v2); 12923 tcg_gen_movi_tl(t1, v1); 12924 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, tcg_env); 12925 break; 12926 case OPC_DEXTR_RS_W: 12927 tcg_gen_movi_tl(t0, v2); 12928 tcg_gen_movi_tl(t1, v1); 12929 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, tcg_env); 12930 break; 12931 case OPC_DEXTR_S_H: 12932 tcg_gen_movi_tl(t0, v2); 12933 tcg_gen_movi_tl(t1, v1); 12934 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, tcg_env); 12935 break; 12936 case OPC_DEXTRV_S_H: 12937 tcg_gen_movi_tl(t0, v2); 12938 gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env); 12939 break; 12940 case OPC_DEXTRV_L: 12941 tcg_gen_movi_tl(t0, v2); 12942 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, tcg_env); 12943 break; 12944 case OPC_DEXTRV_R_L: 12945 tcg_gen_movi_tl(t0, v2); 12946 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, tcg_env); 12947 break; 12948 case OPC_DEXTRV_RS_L: 12949 tcg_gen_movi_tl(t0, v2); 12950 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, tcg_env); 12951 break; 12952 case OPC_DEXTRV_W: 12953 tcg_gen_movi_tl(t0, v2); 12954 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12955 break; 12956 case OPC_DEXTRV_R_W: 12957 tcg_gen_movi_tl(t0, v2); 12958 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12959 break; 12960 case OPC_DEXTRV_RS_W: 12961 tcg_gen_movi_tl(t0, v2); 12962 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12963 break; 12964 } 12965 break; 12966 #endif 12967 } 12968 } 12969 12970 /* End MIPSDSP functions. */ 12971 12972 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) 12973 { 12974 int rs, rt, rd, sa; 12975 uint32_t op1, op2; 12976 12977 rs = (ctx->opcode >> 21) & 0x1f; 12978 rt = (ctx->opcode >> 16) & 0x1f; 12979 rd = (ctx->opcode >> 11) & 0x1f; 12980 sa = (ctx->opcode >> 6) & 0x1f; 12981 12982 op1 = MASK_SPECIAL(ctx->opcode); 12983 switch (op1) { 12984 case OPC_MULT: 12985 case OPC_MULTU: 12986 case OPC_DIV: 12987 case OPC_DIVU: 12988 op2 = MASK_R6_MULDIV(ctx->opcode); 12989 switch (op2) { 12990 case R6_OPC_MUL: 12991 case R6_OPC_MUH: 12992 case R6_OPC_MULU: 12993 case R6_OPC_MUHU: 12994 case R6_OPC_DIV: 12995 case R6_OPC_MOD: 12996 case R6_OPC_DIVU: 12997 case R6_OPC_MODU: 12998 gen_r6_muldiv(ctx, op2, rd, rs, rt); 12999 break; 13000 default: 13001 MIPS_INVAL("special_r6 muldiv"); 13002 gen_reserved_instruction(ctx); 13003 break; 13004 } 13005 break; 13006 case OPC_SELEQZ: 13007 case OPC_SELNEZ: 13008 gen_cond_move(ctx, op1, rd, rs, rt); 13009 break; 13010 case R6_OPC_CLO: 13011 case R6_OPC_CLZ: 13012 if (rt == 0 && sa == 1) { 13013 /* 13014 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13015 * We need additionally to check other fields. 13016 */ 13017 gen_cl(ctx, op1, rd, rs); 13018 } else { 13019 gen_reserved_instruction(ctx); 13020 } 13021 break; 13022 case R6_OPC_SDBBP: 13023 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 13024 ctx->base.is_jmp = DISAS_SEMIHOST; 13025 } else { 13026 if (ctx->hflags & MIPS_HFLAG_SBRI) { 13027 gen_reserved_instruction(ctx); 13028 } else { 13029 generate_exception_end(ctx, EXCP_DBp); 13030 } 13031 } 13032 break; 13033 #if defined(TARGET_MIPS64) 13034 case R6_OPC_DCLO: 13035 case R6_OPC_DCLZ: 13036 if (rt == 0 && sa == 1) { 13037 /* 13038 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13039 * We need additionally to check other fields. 13040 */ 13041 check_mips_64(ctx); 13042 gen_cl(ctx, op1, rd, rs); 13043 } else { 13044 gen_reserved_instruction(ctx); 13045 } 13046 break; 13047 case OPC_DMULT: 13048 case OPC_DMULTU: 13049 case OPC_DDIV: 13050 case OPC_DDIVU: 13051 13052 op2 = MASK_R6_MULDIV(ctx->opcode); 13053 switch (op2) { 13054 case R6_OPC_DMUL: 13055 case R6_OPC_DMUH: 13056 case R6_OPC_DMULU: 13057 case R6_OPC_DMUHU: 13058 case R6_OPC_DDIV: 13059 case R6_OPC_DMOD: 13060 case R6_OPC_DDIVU: 13061 case R6_OPC_DMODU: 13062 check_mips_64(ctx); 13063 gen_r6_muldiv(ctx, op2, rd, rs, rt); 13064 break; 13065 default: 13066 MIPS_INVAL("special_r6 muldiv"); 13067 gen_reserved_instruction(ctx); 13068 break; 13069 } 13070 break; 13071 #endif 13072 default: /* Invalid */ 13073 MIPS_INVAL("special_r6"); 13074 gen_reserved_instruction(ctx); 13075 break; 13076 } 13077 } 13078 13079 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) 13080 { 13081 int rs = extract32(ctx->opcode, 21, 5); 13082 int rt = extract32(ctx->opcode, 16, 5); 13083 int rd = extract32(ctx->opcode, 11, 5); 13084 uint32_t op1 = MASK_SPECIAL(ctx->opcode); 13085 13086 switch (op1) { 13087 case OPC_MOVN: /* Conditional move */ 13088 case OPC_MOVZ: 13089 gen_cond_move(ctx, op1, rd, rs, rt); 13090 break; 13091 case OPC_MFHI: /* Move from HI/LO */ 13092 case OPC_MFLO: 13093 gen_HILO(ctx, op1, 0, rd); 13094 break; 13095 case OPC_MTHI: 13096 case OPC_MTLO: /* Move to HI/LO */ 13097 gen_HILO(ctx, op1, 0, rs); 13098 break; 13099 case OPC_MULT: 13100 case OPC_MULTU: 13101 gen_mul_txx9(ctx, op1, rd, rs, rt); 13102 break; 13103 case OPC_DIV: 13104 case OPC_DIVU: 13105 gen_muldiv(ctx, op1, 0, rs, rt); 13106 break; 13107 #if defined(TARGET_MIPS64) 13108 case OPC_DMULT: 13109 case OPC_DMULTU: 13110 case OPC_DDIV: 13111 case OPC_DDIVU: 13112 check_insn_opc_user_only(ctx, INSN_R5900); 13113 gen_muldiv(ctx, op1, 0, rs, rt); 13114 break; 13115 #endif 13116 case OPC_JR: 13117 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13118 break; 13119 default: /* Invalid */ 13120 MIPS_INVAL("special_tx79"); 13121 gen_reserved_instruction(ctx); 13122 break; 13123 } 13124 } 13125 13126 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) 13127 { 13128 int rs, rt, rd; 13129 uint32_t op1; 13130 13131 rs = (ctx->opcode >> 21) & 0x1f; 13132 rt = (ctx->opcode >> 16) & 0x1f; 13133 rd = (ctx->opcode >> 11) & 0x1f; 13134 13135 op1 = MASK_SPECIAL(ctx->opcode); 13136 switch (op1) { 13137 case OPC_MOVN: /* Conditional move */ 13138 case OPC_MOVZ: 13139 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | 13140 INSN_LOONGSON2E | INSN_LOONGSON2F); 13141 gen_cond_move(ctx, op1, rd, rs, rt); 13142 break; 13143 case OPC_MFHI: /* Move from HI/LO */ 13144 case OPC_MFLO: 13145 gen_HILO(ctx, op1, rs & 3, rd); 13146 break; 13147 case OPC_MTHI: 13148 case OPC_MTLO: /* Move to HI/LO */ 13149 gen_HILO(ctx, op1, rd & 3, rs); 13150 break; 13151 case OPC_MOVCI: 13152 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 13153 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 13154 check_cp1_enabled(ctx); 13155 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 13156 (ctx->opcode >> 16) & 1); 13157 } else { 13158 generate_exception_err(ctx, EXCP_CpU, 1); 13159 } 13160 break; 13161 case OPC_MULT: 13162 case OPC_MULTU: 13163 gen_muldiv(ctx, op1, rd & 3, rs, rt); 13164 break; 13165 case OPC_DIV: 13166 case OPC_DIVU: 13167 gen_muldiv(ctx, op1, 0, rs, rt); 13168 break; 13169 #if defined(TARGET_MIPS64) 13170 case OPC_DMULT: 13171 case OPC_DMULTU: 13172 case OPC_DDIV: 13173 case OPC_DDIVU: 13174 check_insn(ctx, ISA_MIPS3); 13175 check_mips_64(ctx); 13176 gen_muldiv(ctx, op1, 0, rs, rt); 13177 break; 13178 #endif 13179 case OPC_JR: 13180 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13181 break; 13182 case OPC_SPIM: 13183 #ifdef MIPS_STRICT_STANDARD 13184 MIPS_INVAL("SPIM"); 13185 gen_reserved_instruction(ctx); 13186 #else 13187 /* Implemented as RI exception for now. */ 13188 MIPS_INVAL("spim (unofficial)"); 13189 gen_reserved_instruction(ctx); 13190 #endif 13191 break; 13192 default: /* Invalid */ 13193 MIPS_INVAL("special_legacy"); 13194 gen_reserved_instruction(ctx); 13195 break; 13196 } 13197 } 13198 13199 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) 13200 { 13201 int rs, rt, rd, sa; 13202 uint32_t op1; 13203 13204 rs = (ctx->opcode >> 21) & 0x1f; 13205 rt = (ctx->opcode >> 16) & 0x1f; 13206 rd = (ctx->opcode >> 11) & 0x1f; 13207 sa = (ctx->opcode >> 6) & 0x1f; 13208 13209 op1 = MASK_SPECIAL(ctx->opcode); 13210 switch (op1) { 13211 case OPC_SLL: /* Shift with immediate */ 13212 if (sa == 5 && rd == 0 && 13213 rs == 0 && rt == 0) { /* PAUSE */ 13214 if ((ctx->insn_flags & ISA_MIPS_R6) && 13215 (ctx->hflags & MIPS_HFLAG_BMASK)) { 13216 gen_reserved_instruction(ctx); 13217 break; 13218 } 13219 } 13220 /* Fallthrough */ 13221 case OPC_SRA: 13222 gen_shift_imm(ctx, op1, rd, rt, sa); 13223 break; 13224 case OPC_SRL: 13225 switch ((ctx->opcode >> 21) & 0x1f) { 13226 case 1: 13227 /* rotr is decoded as srl on non-R2 CPUs */ 13228 if (ctx->insn_flags & ISA_MIPS_R2) { 13229 op1 = OPC_ROTR; 13230 } 13231 /* Fallthrough */ 13232 case 0: 13233 gen_shift_imm(ctx, op1, rd, rt, sa); 13234 break; 13235 default: 13236 gen_reserved_instruction(ctx); 13237 break; 13238 } 13239 break; 13240 case OPC_ADD: 13241 case OPC_ADDU: 13242 case OPC_SUB: 13243 case OPC_SUBU: 13244 gen_arith(ctx, op1, rd, rs, rt); 13245 break; 13246 case OPC_SLLV: /* Shifts */ 13247 case OPC_SRAV: 13248 gen_shift(ctx, op1, rd, rs, rt); 13249 break; 13250 case OPC_SRLV: 13251 switch ((ctx->opcode >> 6) & 0x1f) { 13252 case 1: 13253 /* rotrv is decoded as srlv on non-R2 CPUs */ 13254 if (ctx->insn_flags & ISA_MIPS_R2) { 13255 op1 = OPC_ROTRV; 13256 } 13257 /* Fallthrough */ 13258 case 0: 13259 gen_shift(ctx, op1, rd, rs, rt); 13260 break; 13261 default: 13262 gen_reserved_instruction(ctx); 13263 break; 13264 } 13265 break; 13266 case OPC_SLT: /* Set on less than */ 13267 case OPC_SLTU: 13268 gen_slt(ctx, op1, rd, rs, rt); 13269 break; 13270 case OPC_AND: /* Logic*/ 13271 case OPC_OR: 13272 case OPC_NOR: 13273 case OPC_XOR: 13274 gen_logic(ctx, op1, rd, rs, rt); 13275 break; 13276 case OPC_JALR: 13277 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 13278 break; 13279 case OPC_TGE: /* Traps */ 13280 case OPC_TGEU: 13281 case OPC_TLT: 13282 case OPC_TLTU: 13283 case OPC_TEQ: 13284 case OPC_TNE: 13285 check_insn(ctx, ISA_MIPS2); 13286 gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10)); 13287 break; 13288 case OPC_PMON: 13289 /* Pmon entry point, also R4010 selsl */ 13290 #ifdef MIPS_STRICT_STANDARD 13291 MIPS_INVAL("PMON / selsl"); 13292 gen_reserved_instruction(ctx); 13293 #else 13294 gen_helper_pmon(tcg_env, tcg_constant_i32(sa)); 13295 #endif 13296 break; 13297 case OPC_SYSCALL: 13298 generate_exception_end(ctx, EXCP_SYSCALL); 13299 break; 13300 case OPC_BREAK: 13301 generate_exception_break(ctx, extract32(ctx->opcode, 6, 20)); 13302 break; 13303 case OPC_SYNC: 13304 check_insn(ctx, ISA_MIPS2); 13305 gen_sync(extract32(ctx->opcode, 6, 5)); 13306 break; 13307 13308 #if defined(TARGET_MIPS64) 13309 /* MIPS64 specific opcodes */ 13310 case OPC_DSLL: 13311 case OPC_DSRA: 13312 case OPC_DSLL32: 13313 case OPC_DSRA32: 13314 check_insn(ctx, ISA_MIPS3); 13315 check_mips_64(ctx); 13316 gen_shift_imm(ctx, op1, rd, rt, sa); 13317 break; 13318 case OPC_DSRL: 13319 switch ((ctx->opcode >> 21) & 0x1f) { 13320 case 1: 13321 /* drotr is decoded as dsrl on non-R2 CPUs */ 13322 if (ctx->insn_flags & ISA_MIPS_R2) { 13323 op1 = OPC_DROTR; 13324 } 13325 /* Fallthrough */ 13326 case 0: 13327 check_insn(ctx, ISA_MIPS3); 13328 check_mips_64(ctx); 13329 gen_shift_imm(ctx, op1, rd, rt, sa); 13330 break; 13331 default: 13332 gen_reserved_instruction(ctx); 13333 break; 13334 } 13335 break; 13336 case OPC_DSRL32: 13337 switch ((ctx->opcode >> 21) & 0x1f) { 13338 case 1: 13339 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 13340 if (ctx->insn_flags & ISA_MIPS_R2) { 13341 op1 = OPC_DROTR32; 13342 } 13343 /* Fallthrough */ 13344 case 0: 13345 check_insn(ctx, ISA_MIPS3); 13346 check_mips_64(ctx); 13347 gen_shift_imm(ctx, op1, rd, rt, sa); 13348 break; 13349 default: 13350 gen_reserved_instruction(ctx); 13351 break; 13352 } 13353 break; 13354 case OPC_DADD: 13355 case OPC_DADDU: 13356 case OPC_DSUB: 13357 case OPC_DSUBU: 13358 check_insn(ctx, ISA_MIPS3); 13359 check_mips_64(ctx); 13360 gen_arith(ctx, op1, rd, rs, rt); 13361 break; 13362 case OPC_DSLLV: 13363 case OPC_DSRAV: 13364 check_insn(ctx, ISA_MIPS3); 13365 check_mips_64(ctx); 13366 gen_shift(ctx, op1, rd, rs, rt); 13367 break; 13368 case OPC_DSRLV: 13369 switch ((ctx->opcode >> 6) & 0x1f) { 13370 case 1: 13371 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 13372 if (ctx->insn_flags & ISA_MIPS_R2) { 13373 op1 = OPC_DROTRV; 13374 } 13375 /* Fallthrough */ 13376 case 0: 13377 check_insn(ctx, ISA_MIPS3); 13378 check_mips_64(ctx); 13379 gen_shift(ctx, op1, rd, rs, rt); 13380 break; 13381 default: 13382 gen_reserved_instruction(ctx); 13383 break; 13384 } 13385 break; 13386 #endif 13387 default: 13388 if (ctx->insn_flags & ISA_MIPS_R6) { 13389 decode_opc_special_r6(env, ctx); 13390 } else if (ctx->insn_flags & INSN_R5900) { 13391 decode_opc_special_tx79(env, ctx); 13392 } else { 13393 decode_opc_special_legacy(env, ctx); 13394 } 13395 } 13396 } 13397 13398 13399 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) 13400 { 13401 int rs, rt, rd; 13402 uint32_t op1; 13403 13404 rs = (ctx->opcode >> 21) & 0x1f; 13405 rt = (ctx->opcode >> 16) & 0x1f; 13406 rd = (ctx->opcode >> 11) & 0x1f; 13407 13408 op1 = MASK_SPECIAL2(ctx->opcode); 13409 switch (op1) { 13410 case OPC_MADD: /* Multiply and add/sub */ 13411 case OPC_MADDU: 13412 case OPC_MSUB: 13413 case OPC_MSUBU: 13414 check_insn(ctx, ISA_MIPS_R1); 13415 gen_muldiv(ctx, op1, rd & 3, rs, rt); 13416 break; 13417 case OPC_MUL: 13418 gen_arith(ctx, op1, rd, rs, rt); 13419 break; 13420 case OPC_CLO: 13421 case OPC_CLZ: 13422 check_insn(ctx, ISA_MIPS_R1); 13423 gen_cl(ctx, op1, rd, rs); 13424 break; 13425 case OPC_SDBBP: 13426 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 13427 ctx->base.is_jmp = DISAS_SEMIHOST; 13428 } else { 13429 /* 13430 * XXX: not clear which exception should be raised 13431 * when in debug mode... 13432 */ 13433 check_insn(ctx, ISA_MIPS_R1); 13434 generate_exception_end(ctx, EXCP_DBp); 13435 } 13436 break; 13437 #if defined(TARGET_MIPS64) 13438 case OPC_DCLO: 13439 case OPC_DCLZ: 13440 check_insn(ctx, ISA_MIPS_R1); 13441 check_mips_64(ctx); 13442 gen_cl(ctx, op1, rd, rs); 13443 break; 13444 #endif 13445 default: /* Invalid */ 13446 MIPS_INVAL("special2_legacy"); 13447 gen_reserved_instruction(ctx); 13448 break; 13449 } 13450 } 13451 13452 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) 13453 { 13454 int rs, rt, rd, sa; 13455 uint32_t op1, op2; 13456 int16_t imm; 13457 13458 rs = (ctx->opcode >> 21) & 0x1f; 13459 rt = (ctx->opcode >> 16) & 0x1f; 13460 rd = (ctx->opcode >> 11) & 0x1f; 13461 sa = (ctx->opcode >> 6) & 0x1f; 13462 imm = (int16_t)ctx->opcode >> 7; 13463 13464 op1 = MASK_SPECIAL3(ctx->opcode); 13465 switch (op1) { 13466 case R6_OPC_PREF: 13467 if (rt >= 24) { 13468 /* hint codes 24-31 are reserved and signal RI */ 13469 gen_reserved_instruction(ctx); 13470 } 13471 /* Treat as NOP. */ 13472 break; 13473 case R6_OPC_CACHE: 13474 check_cp0_enabled(ctx); 13475 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 13476 gen_cache_operation(ctx, rt, rs, imm); 13477 } 13478 break; 13479 case R6_OPC_SC: 13480 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false); 13481 break; 13482 case R6_OPC_LL: 13483 gen_ld(ctx, op1, rt, rs, imm); 13484 break; 13485 case OPC_BSHFL: 13486 { 13487 if (rd == 0) { 13488 /* Treat as NOP. */ 13489 break; 13490 } 13491 op2 = MASK_BSHFL(ctx->opcode); 13492 switch (op2) { 13493 case OPC_ALIGN: 13494 case OPC_ALIGN_1: 13495 case OPC_ALIGN_2: 13496 case OPC_ALIGN_3: 13497 gen_align(ctx, 32, rd, rs, rt, sa & 3); 13498 break; 13499 case OPC_BITSWAP: 13500 gen_bitswap(ctx, op2, rd, rt); 13501 break; 13502 } 13503 } 13504 break; 13505 #ifndef CONFIG_USER_ONLY 13506 case OPC_GINV: 13507 if (unlikely(ctx->gi <= 1)) { 13508 gen_reserved_instruction(ctx); 13509 } 13510 check_cp0_enabled(ctx); 13511 switch ((ctx->opcode >> 6) & 3) { 13512 case 0: /* GINVI */ 13513 /* Treat as NOP. */ 13514 break; 13515 case 2: /* GINVT */ 13516 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); 13517 break; 13518 default: 13519 gen_reserved_instruction(ctx); 13520 break; 13521 } 13522 break; 13523 #endif 13524 #if defined(TARGET_MIPS64) 13525 case R6_OPC_SCD: 13526 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false); 13527 break; 13528 case R6_OPC_LLD: 13529 gen_ld(ctx, op1, rt, rs, imm); 13530 break; 13531 case OPC_DBSHFL: 13532 check_mips_64(ctx); 13533 { 13534 if (rd == 0) { 13535 /* Treat as NOP. */ 13536 break; 13537 } 13538 op2 = MASK_DBSHFL(ctx->opcode); 13539 switch (op2) { 13540 case OPC_DALIGN: 13541 case OPC_DALIGN_1: 13542 case OPC_DALIGN_2: 13543 case OPC_DALIGN_3: 13544 case OPC_DALIGN_4: 13545 case OPC_DALIGN_5: 13546 case OPC_DALIGN_6: 13547 case OPC_DALIGN_7: 13548 gen_align(ctx, 64, rd, rs, rt, sa & 7); 13549 break; 13550 case OPC_DBITSWAP: 13551 gen_bitswap(ctx, op2, rd, rt); 13552 break; 13553 } 13554 13555 } 13556 break; 13557 #endif 13558 default: /* Invalid */ 13559 MIPS_INVAL("special3_r6"); 13560 gen_reserved_instruction(ctx); 13561 break; 13562 } 13563 } 13564 13565 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) 13566 { 13567 int rs, rt, rd; 13568 uint32_t op1, op2; 13569 13570 rs = (ctx->opcode >> 21) & 0x1f; 13571 rt = (ctx->opcode >> 16) & 0x1f; 13572 rd = (ctx->opcode >> 11) & 0x1f; 13573 13574 op1 = MASK_SPECIAL3(ctx->opcode); 13575 switch (op1) { 13576 case OPC_MUL_PH_DSP: 13577 /* 13578 * OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 13579 * the same mask and op1. 13580 */ 13581 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MUL_PH_DSP)) { 13582 op2 = MASK_ADDUH_QB(ctx->opcode); 13583 switch (op2) { 13584 case OPC_ADDUH_QB: 13585 case OPC_ADDUH_R_QB: 13586 case OPC_ADDQH_PH: 13587 case OPC_ADDQH_R_PH: 13588 case OPC_ADDQH_W: 13589 case OPC_ADDQH_R_W: 13590 case OPC_SUBUH_QB: 13591 case OPC_SUBUH_R_QB: 13592 case OPC_SUBQH_PH: 13593 case OPC_SUBQH_R_PH: 13594 case OPC_SUBQH_W: 13595 case OPC_SUBQH_R_W: 13596 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13597 break; 13598 case OPC_MUL_PH: 13599 case OPC_MUL_S_PH: 13600 case OPC_MULQ_S_W: 13601 case OPC_MULQ_RS_W: 13602 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13603 break; 13604 default: 13605 MIPS_INVAL("MASK ADDUH.QB"); 13606 gen_reserved_instruction(ctx); 13607 break; 13608 } 13609 } else { 13610 gen_reserved_instruction(ctx); 13611 } 13612 break; 13613 case OPC_LX_DSP: 13614 op2 = MASK_LX(ctx->opcode); 13615 switch (op2) { 13616 #if defined(TARGET_MIPS64) 13617 case OPC_LDX: 13618 #endif 13619 case OPC_LBUX: 13620 case OPC_LHX: 13621 case OPC_LWX: 13622 gen_mips_lx(ctx, op2, rd, rs, rt); 13623 break; 13624 default: /* Invalid */ 13625 MIPS_INVAL("MASK LX"); 13626 gen_reserved_instruction(ctx); 13627 break; 13628 } 13629 break; 13630 case OPC_ABSQ_S_PH_DSP: 13631 op2 = MASK_ABSQ_S_PH(ctx->opcode); 13632 switch (op2) { 13633 case OPC_ABSQ_S_QB: 13634 case OPC_ABSQ_S_PH: 13635 case OPC_ABSQ_S_W: 13636 case OPC_PRECEQ_W_PHL: 13637 case OPC_PRECEQ_W_PHR: 13638 case OPC_PRECEQU_PH_QBL: 13639 case OPC_PRECEQU_PH_QBR: 13640 case OPC_PRECEQU_PH_QBLA: 13641 case OPC_PRECEQU_PH_QBRA: 13642 case OPC_PRECEU_PH_QBL: 13643 case OPC_PRECEU_PH_QBR: 13644 case OPC_PRECEU_PH_QBLA: 13645 case OPC_PRECEU_PH_QBRA: 13646 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13647 break; 13648 case OPC_BITREV: 13649 case OPC_REPL_QB: 13650 case OPC_REPLV_QB: 13651 case OPC_REPL_PH: 13652 case OPC_REPLV_PH: 13653 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 13654 break; 13655 default: 13656 MIPS_INVAL("MASK ABSQ_S.PH"); 13657 gen_reserved_instruction(ctx); 13658 break; 13659 } 13660 break; 13661 case OPC_ADDU_QB_DSP: 13662 op2 = MASK_ADDU_QB(ctx->opcode); 13663 switch (op2) { 13664 case OPC_ADDQ_PH: 13665 case OPC_ADDQ_S_PH: 13666 case OPC_ADDQ_S_W: 13667 case OPC_ADDU_QB: 13668 case OPC_ADDU_S_QB: 13669 case OPC_ADDU_PH: 13670 case OPC_ADDU_S_PH: 13671 case OPC_SUBQ_PH: 13672 case OPC_SUBQ_S_PH: 13673 case OPC_SUBQ_S_W: 13674 case OPC_SUBU_QB: 13675 case OPC_SUBU_S_QB: 13676 case OPC_SUBU_PH: 13677 case OPC_SUBU_S_PH: 13678 case OPC_ADDSC: 13679 case OPC_ADDWC: 13680 case OPC_MODSUB: 13681 case OPC_RADDU_W_QB: 13682 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13683 break; 13684 case OPC_MULEU_S_PH_QBL: 13685 case OPC_MULEU_S_PH_QBR: 13686 case OPC_MULQ_RS_PH: 13687 case OPC_MULEQ_S_W_PHL: 13688 case OPC_MULEQ_S_W_PHR: 13689 case OPC_MULQ_S_PH: 13690 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13691 break; 13692 default: /* Invalid */ 13693 MIPS_INVAL("MASK ADDU.QB"); 13694 gen_reserved_instruction(ctx); 13695 break; 13696 13697 } 13698 break; 13699 case OPC_CMPU_EQ_QB_DSP: 13700 op2 = MASK_CMPU_EQ_QB(ctx->opcode); 13701 switch (op2) { 13702 case OPC_PRECR_SRA_PH_W: 13703 case OPC_PRECR_SRA_R_PH_W: 13704 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 13705 break; 13706 case OPC_PRECR_QB_PH: 13707 case OPC_PRECRQ_QB_PH: 13708 case OPC_PRECRQ_PH_W: 13709 case OPC_PRECRQ_RS_PH_W: 13710 case OPC_PRECRQU_S_QB_PH: 13711 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13712 break; 13713 case OPC_CMPU_EQ_QB: 13714 case OPC_CMPU_LT_QB: 13715 case OPC_CMPU_LE_QB: 13716 case OPC_CMP_EQ_PH: 13717 case OPC_CMP_LT_PH: 13718 case OPC_CMP_LE_PH: 13719 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 13720 break; 13721 case OPC_CMPGU_EQ_QB: 13722 case OPC_CMPGU_LT_QB: 13723 case OPC_CMPGU_LE_QB: 13724 case OPC_CMPGDU_EQ_QB: 13725 case OPC_CMPGDU_LT_QB: 13726 case OPC_CMPGDU_LE_QB: 13727 case OPC_PICK_QB: 13728 case OPC_PICK_PH: 13729 case OPC_PACKRL_PH: 13730 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 13731 break; 13732 default: /* Invalid */ 13733 MIPS_INVAL("MASK CMPU.EQ.QB"); 13734 gen_reserved_instruction(ctx); 13735 break; 13736 } 13737 break; 13738 case OPC_SHLL_QB_DSP: 13739 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 13740 break; 13741 case OPC_DPA_W_PH_DSP: 13742 op2 = MASK_DPA_W_PH(ctx->opcode); 13743 switch (op2) { 13744 case OPC_DPAU_H_QBL: 13745 case OPC_DPAU_H_QBR: 13746 case OPC_DPSU_H_QBL: 13747 case OPC_DPSU_H_QBR: 13748 case OPC_DPA_W_PH: 13749 case OPC_DPAX_W_PH: 13750 case OPC_DPAQ_S_W_PH: 13751 case OPC_DPAQX_S_W_PH: 13752 case OPC_DPAQX_SA_W_PH: 13753 case OPC_DPS_W_PH: 13754 case OPC_DPSX_W_PH: 13755 case OPC_DPSQ_S_W_PH: 13756 case OPC_DPSQX_S_W_PH: 13757 case OPC_DPSQX_SA_W_PH: 13758 case OPC_MULSAQ_S_W_PH: 13759 case OPC_DPAQ_SA_L_W: 13760 case OPC_DPSQ_SA_L_W: 13761 case OPC_MAQ_S_W_PHL: 13762 case OPC_MAQ_S_W_PHR: 13763 case OPC_MAQ_SA_W_PHL: 13764 case OPC_MAQ_SA_W_PHR: 13765 case OPC_MULSA_W_PH: 13766 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 13767 break; 13768 default: /* Invalid */ 13769 MIPS_INVAL("MASK DPAW.PH"); 13770 gen_reserved_instruction(ctx); 13771 break; 13772 } 13773 break; 13774 case OPC_INSV_DSP: 13775 op2 = MASK_INSV(ctx->opcode); 13776 switch (op2) { 13777 case OPC_INSV: 13778 check_dsp(ctx); 13779 { 13780 TCGv t0, t1; 13781 13782 if (rt == 0) { 13783 break; 13784 } 13785 13786 t0 = tcg_temp_new(); 13787 t1 = tcg_temp_new(); 13788 13789 gen_load_gpr(t0, rt); 13790 gen_load_gpr(t1, rs); 13791 13792 gen_helper_insv(cpu_gpr[rt], tcg_env, t1, t0); 13793 break; 13794 } 13795 default: /* Invalid */ 13796 MIPS_INVAL("MASK INSV"); 13797 gen_reserved_instruction(ctx); 13798 break; 13799 } 13800 break; 13801 case OPC_APPEND_DSP: 13802 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 13803 break; 13804 case OPC_EXTR_W_DSP: 13805 op2 = MASK_EXTR_W(ctx->opcode); 13806 switch (op2) { 13807 case OPC_EXTR_W: 13808 case OPC_EXTR_R_W: 13809 case OPC_EXTR_RS_W: 13810 case OPC_EXTR_S_H: 13811 case OPC_EXTRV_S_H: 13812 case OPC_EXTRV_W: 13813 case OPC_EXTRV_R_W: 13814 case OPC_EXTRV_RS_W: 13815 case OPC_EXTP: 13816 case OPC_EXTPV: 13817 case OPC_EXTPDP: 13818 case OPC_EXTPDPV: 13819 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 13820 break; 13821 case OPC_RDDSP: 13822 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1); 13823 break; 13824 case OPC_SHILO: 13825 case OPC_SHILOV: 13826 case OPC_MTHLIP: 13827 case OPC_WRDSP: 13828 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 13829 break; 13830 default: /* Invalid */ 13831 MIPS_INVAL("MASK EXTR.W"); 13832 gen_reserved_instruction(ctx); 13833 break; 13834 } 13835 break; 13836 #if defined(TARGET_MIPS64) 13837 case OPC_ABSQ_S_QH_DSP: 13838 op2 = MASK_ABSQ_S_QH(ctx->opcode); 13839 switch (op2) { 13840 case OPC_PRECEQ_L_PWL: 13841 case OPC_PRECEQ_L_PWR: 13842 case OPC_PRECEQ_PW_QHL: 13843 case OPC_PRECEQ_PW_QHR: 13844 case OPC_PRECEQ_PW_QHLA: 13845 case OPC_PRECEQ_PW_QHRA: 13846 case OPC_PRECEQU_QH_OBL: 13847 case OPC_PRECEQU_QH_OBR: 13848 case OPC_PRECEQU_QH_OBLA: 13849 case OPC_PRECEQU_QH_OBRA: 13850 case OPC_PRECEU_QH_OBL: 13851 case OPC_PRECEU_QH_OBR: 13852 case OPC_PRECEU_QH_OBLA: 13853 case OPC_PRECEU_QH_OBRA: 13854 case OPC_ABSQ_S_OB: 13855 case OPC_ABSQ_S_PW: 13856 case OPC_ABSQ_S_QH: 13857 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13858 break; 13859 case OPC_REPL_OB: 13860 case OPC_REPL_PW: 13861 case OPC_REPL_QH: 13862 case OPC_REPLV_OB: 13863 case OPC_REPLV_PW: 13864 case OPC_REPLV_QH: 13865 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 13866 break; 13867 default: /* Invalid */ 13868 MIPS_INVAL("MASK ABSQ_S.QH"); 13869 gen_reserved_instruction(ctx); 13870 break; 13871 } 13872 break; 13873 case OPC_ADDU_OB_DSP: 13874 op2 = MASK_ADDU_OB(ctx->opcode); 13875 switch (op2) { 13876 case OPC_RADDU_L_OB: 13877 case OPC_SUBQ_PW: 13878 case OPC_SUBQ_S_PW: 13879 case OPC_SUBQ_QH: 13880 case OPC_SUBQ_S_QH: 13881 case OPC_SUBU_OB: 13882 case OPC_SUBU_S_OB: 13883 case OPC_SUBU_QH: 13884 case OPC_SUBU_S_QH: 13885 case OPC_SUBUH_OB: 13886 case OPC_SUBUH_R_OB: 13887 case OPC_ADDQ_PW: 13888 case OPC_ADDQ_S_PW: 13889 case OPC_ADDQ_QH: 13890 case OPC_ADDQ_S_QH: 13891 case OPC_ADDU_OB: 13892 case OPC_ADDU_S_OB: 13893 case OPC_ADDU_QH: 13894 case OPC_ADDU_S_QH: 13895 case OPC_ADDUH_OB: 13896 case OPC_ADDUH_R_OB: 13897 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13898 break; 13899 case OPC_MULEQ_S_PW_QHL: 13900 case OPC_MULEQ_S_PW_QHR: 13901 case OPC_MULEU_S_QH_OBL: 13902 case OPC_MULEU_S_QH_OBR: 13903 case OPC_MULQ_RS_QH: 13904 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13905 break; 13906 default: /* Invalid */ 13907 MIPS_INVAL("MASK ADDU.OB"); 13908 gen_reserved_instruction(ctx); 13909 break; 13910 } 13911 break; 13912 case OPC_CMPU_EQ_OB_DSP: 13913 op2 = MASK_CMPU_EQ_OB(ctx->opcode); 13914 switch (op2) { 13915 case OPC_PRECR_SRA_QH_PW: 13916 case OPC_PRECR_SRA_R_QH_PW: 13917 /* Return value is rt. */ 13918 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 13919 break; 13920 case OPC_PRECR_OB_QH: 13921 case OPC_PRECRQ_OB_QH: 13922 case OPC_PRECRQ_PW_L: 13923 case OPC_PRECRQ_QH_PW: 13924 case OPC_PRECRQ_RS_QH_PW: 13925 case OPC_PRECRQU_S_OB_QH: 13926 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13927 break; 13928 case OPC_CMPU_EQ_OB: 13929 case OPC_CMPU_LT_OB: 13930 case OPC_CMPU_LE_OB: 13931 case OPC_CMP_EQ_QH: 13932 case OPC_CMP_LT_QH: 13933 case OPC_CMP_LE_QH: 13934 case OPC_CMP_EQ_PW: 13935 case OPC_CMP_LT_PW: 13936 case OPC_CMP_LE_PW: 13937 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 13938 break; 13939 case OPC_CMPGDU_EQ_OB: 13940 case OPC_CMPGDU_LT_OB: 13941 case OPC_CMPGDU_LE_OB: 13942 case OPC_CMPGU_EQ_OB: 13943 case OPC_CMPGU_LT_OB: 13944 case OPC_CMPGU_LE_OB: 13945 case OPC_PACKRL_PW: 13946 case OPC_PICK_OB: 13947 case OPC_PICK_PW: 13948 case OPC_PICK_QH: 13949 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 13950 break; 13951 default: /* Invalid */ 13952 MIPS_INVAL("MASK CMPU_EQ.OB"); 13953 gen_reserved_instruction(ctx); 13954 break; 13955 } 13956 break; 13957 case OPC_DAPPEND_DSP: 13958 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 13959 break; 13960 case OPC_DEXTR_W_DSP: 13961 op2 = MASK_DEXTR_W(ctx->opcode); 13962 switch (op2) { 13963 case OPC_DEXTP: 13964 case OPC_DEXTPDP: 13965 case OPC_DEXTPDPV: 13966 case OPC_DEXTPV: 13967 case OPC_DEXTR_L: 13968 case OPC_DEXTR_R_L: 13969 case OPC_DEXTR_RS_L: 13970 case OPC_DEXTR_W: 13971 case OPC_DEXTR_R_W: 13972 case OPC_DEXTR_RS_W: 13973 case OPC_DEXTR_S_H: 13974 case OPC_DEXTRV_L: 13975 case OPC_DEXTRV_R_L: 13976 case OPC_DEXTRV_RS_L: 13977 case OPC_DEXTRV_S_H: 13978 case OPC_DEXTRV_W: 13979 case OPC_DEXTRV_R_W: 13980 case OPC_DEXTRV_RS_W: 13981 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 13982 break; 13983 case OPC_DMTHLIP: 13984 case OPC_DSHILO: 13985 case OPC_DSHILOV: 13986 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 13987 break; 13988 default: /* Invalid */ 13989 MIPS_INVAL("MASK EXTR.W"); 13990 gen_reserved_instruction(ctx); 13991 break; 13992 } 13993 break; 13994 case OPC_DPAQ_W_QH_DSP: 13995 op2 = MASK_DPAQ_W_QH(ctx->opcode); 13996 switch (op2) { 13997 case OPC_DPAU_H_OBL: 13998 case OPC_DPAU_H_OBR: 13999 case OPC_DPSU_H_OBL: 14000 case OPC_DPSU_H_OBR: 14001 case OPC_DPA_W_QH: 14002 case OPC_DPAQ_S_W_QH: 14003 case OPC_DPS_W_QH: 14004 case OPC_DPSQ_S_W_QH: 14005 case OPC_MULSAQ_S_W_QH: 14006 case OPC_DPAQ_SA_L_PW: 14007 case OPC_DPSQ_SA_L_PW: 14008 case OPC_MULSAQ_S_L_PW: 14009 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14010 break; 14011 case OPC_MAQ_S_W_QHLL: 14012 case OPC_MAQ_S_W_QHLR: 14013 case OPC_MAQ_S_W_QHRL: 14014 case OPC_MAQ_S_W_QHRR: 14015 case OPC_MAQ_SA_W_QHLL: 14016 case OPC_MAQ_SA_W_QHLR: 14017 case OPC_MAQ_SA_W_QHRL: 14018 case OPC_MAQ_SA_W_QHRR: 14019 case OPC_MAQ_S_L_PWL: 14020 case OPC_MAQ_S_L_PWR: 14021 case OPC_DMADD: 14022 case OPC_DMADDU: 14023 case OPC_DMSUB: 14024 case OPC_DMSUBU: 14025 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14026 break; 14027 default: /* Invalid */ 14028 MIPS_INVAL("MASK DPAQ.W.QH"); 14029 gen_reserved_instruction(ctx); 14030 break; 14031 } 14032 break; 14033 case OPC_DINSV_DSP: 14034 op2 = MASK_INSV(ctx->opcode); 14035 switch (op2) { 14036 case OPC_DINSV: 14037 { 14038 TCGv t0, t1; 14039 14040 check_dsp(ctx); 14041 14042 if (rt == 0) { 14043 break; 14044 } 14045 14046 t0 = tcg_temp_new(); 14047 t1 = tcg_temp_new(); 14048 14049 gen_load_gpr(t0, rt); 14050 gen_load_gpr(t1, rs); 14051 14052 gen_helper_dinsv(cpu_gpr[rt], tcg_env, t1, t0); 14053 break; 14054 } 14055 default: /* Invalid */ 14056 MIPS_INVAL("MASK DINSV"); 14057 gen_reserved_instruction(ctx); 14058 break; 14059 } 14060 break; 14061 case OPC_SHLL_OB_DSP: 14062 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14063 break; 14064 #endif 14065 default: /* Invalid */ 14066 MIPS_INVAL("special3_legacy"); 14067 gen_reserved_instruction(ctx); 14068 break; 14069 } 14070 } 14071 14072 14073 #if defined(TARGET_MIPS64) 14074 14075 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) 14076 { 14077 uint32_t opc = MASK_MMI(ctx->opcode); 14078 int rs = extract32(ctx->opcode, 21, 5); 14079 int rt = extract32(ctx->opcode, 16, 5); 14080 int rd = extract32(ctx->opcode, 11, 5); 14081 14082 switch (opc) { 14083 case MMI_OPC_MULT1: 14084 case MMI_OPC_MULTU1: 14085 case MMI_OPC_MADD: 14086 case MMI_OPC_MADDU: 14087 case MMI_OPC_MADD1: 14088 case MMI_OPC_MADDU1: 14089 gen_mul_txx9(ctx, opc, rd, rs, rt); 14090 break; 14091 case MMI_OPC_DIV1: 14092 case MMI_OPC_DIVU1: 14093 gen_div1_tx79(ctx, opc, rs, rt); 14094 break; 14095 default: 14096 MIPS_INVAL("TX79 MMI class"); 14097 gen_reserved_instruction(ctx); 14098 break; 14099 } 14100 } 14101 14102 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset) 14103 { 14104 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */ 14105 } 14106 14107 /* 14108 * The TX79-specific instruction Store Quadword 14109 * 14110 * +--------+-------+-------+------------------------+ 14111 * | 011111 | base | rt | offset | SQ 14112 * +--------+-------+-------+------------------------+ 14113 * 6 5 5 16 14114 * 14115 * has the same opcode as the Read Hardware Register instruction 14116 * 14117 * +--------+-------+-------+-------+-------+--------+ 14118 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR 14119 * +--------+-------+-------+-------+-------+--------+ 14120 * 6 5 5 5 5 6 14121 * 14122 * that is required, trapped and emulated by the Linux kernel. However, all 14123 * RDHWR encodings yield address error exceptions on the TX79 since the SQ 14124 * offset is odd. Therefore all valid SQ instructions can execute normally. 14125 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish 14126 * between SQ and RDHWR, as the Linux kernel does. 14127 */ 14128 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx) 14129 { 14130 int base = extract32(ctx->opcode, 21, 5); 14131 int rt = extract32(ctx->opcode, 16, 5); 14132 int offset = extract32(ctx->opcode, 0, 16); 14133 14134 #ifdef CONFIG_USER_ONLY 14135 uint32_t op1 = MASK_SPECIAL3(ctx->opcode); 14136 uint32_t op2 = extract32(ctx->opcode, 6, 5); 14137 14138 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) { 14139 int rd = extract32(ctx->opcode, 11, 5); 14140 14141 gen_rdhwr(ctx, rt, rd, 0); 14142 return; 14143 } 14144 #endif 14145 14146 gen_mmi_sq(ctx, base, rt, offset); 14147 } 14148 14149 #endif 14150 14151 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) 14152 { 14153 int rs, rt, rd, sa; 14154 uint32_t op1, op2; 14155 int16_t imm; 14156 14157 rs = (ctx->opcode >> 21) & 0x1f; 14158 rt = (ctx->opcode >> 16) & 0x1f; 14159 rd = (ctx->opcode >> 11) & 0x1f; 14160 sa = (ctx->opcode >> 6) & 0x1f; 14161 imm = sextract32(ctx->opcode, 7, 9); 14162 14163 op1 = MASK_SPECIAL3(ctx->opcode); 14164 14165 /* 14166 * EVA loads and stores overlap Loongson 2E instructions decoded by 14167 * decode_opc_special3_legacy(), so be careful to allow their decoding when 14168 * EVA is absent. 14169 */ 14170 if (ctx->eva) { 14171 switch (op1) { 14172 case OPC_LWLE: 14173 case OPC_LWRE: 14174 case OPC_LBUE: 14175 case OPC_LHUE: 14176 case OPC_LBE: 14177 case OPC_LHE: 14178 case OPC_LLE: 14179 case OPC_LWE: 14180 check_cp0_enabled(ctx); 14181 gen_ld(ctx, op1, rt, rs, imm); 14182 return; 14183 case OPC_SWLE: 14184 case OPC_SWRE: 14185 case OPC_SBE: 14186 case OPC_SHE: 14187 case OPC_SWE: 14188 check_cp0_enabled(ctx); 14189 gen_st(ctx, op1, rt, rs, imm); 14190 return; 14191 case OPC_SCE: 14192 check_cp0_enabled(ctx); 14193 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, true); 14194 return; 14195 case OPC_CACHEE: 14196 check_eva(ctx); 14197 check_cp0_enabled(ctx); 14198 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14199 gen_cache_operation(ctx, rt, rs, imm); 14200 } 14201 return; 14202 case OPC_PREFE: 14203 check_cp0_enabled(ctx); 14204 /* Treat as NOP. */ 14205 return; 14206 } 14207 } 14208 14209 switch (op1) { 14210 case OPC_EXT: 14211 case OPC_INS: 14212 check_insn(ctx, ISA_MIPS_R2); 14213 gen_bitops(ctx, op1, rt, rs, sa, rd); 14214 break; 14215 case OPC_BSHFL: 14216 op2 = MASK_BSHFL(ctx->opcode); 14217 switch (op2) { 14218 case OPC_ALIGN: 14219 case OPC_ALIGN_1: 14220 case OPC_ALIGN_2: 14221 case OPC_ALIGN_3: 14222 case OPC_BITSWAP: 14223 check_insn(ctx, ISA_MIPS_R6); 14224 decode_opc_special3_r6(env, ctx); 14225 break; 14226 default: 14227 check_insn(ctx, ISA_MIPS_R2); 14228 gen_bshfl(ctx, op2, rt, rd); 14229 break; 14230 } 14231 break; 14232 #if defined(TARGET_MIPS64) 14233 case OPC_DEXTM: 14234 case OPC_DEXTU: 14235 case OPC_DEXT: 14236 case OPC_DINSM: 14237 case OPC_DINSU: 14238 case OPC_DINS: 14239 check_insn(ctx, ISA_MIPS_R2); 14240 check_mips_64(ctx); 14241 gen_bitops(ctx, op1, rt, rs, sa, rd); 14242 break; 14243 case OPC_DBSHFL: 14244 op2 = MASK_DBSHFL(ctx->opcode); 14245 switch (op2) { 14246 case OPC_DALIGN: 14247 case OPC_DALIGN_1: 14248 case OPC_DALIGN_2: 14249 case OPC_DALIGN_3: 14250 case OPC_DALIGN_4: 14251 case OPC_DALIGN_5: 14252 case OPC_DALIGN_6: 14253 case OPC_DALIGN_7: 14254 case OPC_DBITSWAP: 14255 check_insn(ctx, ISA_MIPS_R6); 14256 decode_opc_special3_r6(env, ctx); 14257 break; 14258 default: 14259 check_insn(ctx, ISA_MIPS_R2); 14260 check_mips_64(ctx); 14261 op2 = MASK_DBSHFL(ctx->opcode); 14262 gen_bshfl(ctx, op2, rt, rd); 14263 break; 14264 } 14265 break; 14266 #endif 14267 case OPC_RDHWR: 14268 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3)); 14269 break; 14270 case OPC_FORK: 14271 check_mt(ctx); 14272 { 14273 TCGv t0 = tcg_temp_new(); 14274 TCGv t1 = tcg_temp_new(); 14275 14276 gen_load_gpr(t0, rt); 14277 gen_load_gpr(t1, rs); 14278 gen_helper_fork(t0, t1); 14279 } 14280 break; 14281 case OPC_YIELD: 14282 check_mt(ctx); 14283 { 14284 TCGv t0 = tcg_temp_new(); 14285 14286 gen_load_gpr(t0, rs); 14287 gen_helper_yield(t0, tcg_env, t0); 14288 gen_store_gpr(t0, rd); 14289 } 14290 break; 14291 default: 14292 if (ctx->insn_flags & ISA_MIPS_R6) { 14293 decode_opc_special3_r6(env, ctx); 14294 } else { 14295 decode_opc_special3_legacy(env, ctx); 14296 } 14297 } 14298 } 14299 14300 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) 14301 { 14302 int32_t offset; 14303 int rs, rt, rd, sa; 14304 uint32_t op, op1; 14305 int16_t imm; 14306 14307 op = MASK_OP_MAJOR(ctx->opcode); 14308 rs = (ctx->opcode >> 21) & 0x1f; 14309 rt = (ctx->opcode >> 16) & 0x1f; 14310 rd = (ctx->opcode >> 11) & 0x1f; 14311 sa = (ctx->opcode >> 6) & 0x1f; 14312 imm = (int16_t)ctx->opcode; 14313 switch (op) { 14314 case OPC_SPECIAL: 14315 decode_opc_special(env, ctx); 14316 break; 14317 case OPC_SPECIAL2: 14318 #if defined(TARGET_MIPS64) 14319 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { 14320 decode_mmi(env, ctx); 14321 break; 14322 } 14323 #endif 14324 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) { 14325 if (decode_ase_mxu(ctx, ctx->opcode)) { 14326 break; 14327 } 14328 } 14329 decode_opc_special2_legacy(env, ctx); 14330 break; 14331 case OPC_SPECIAL3: 14332 #if defined(TARGET_MIPS64) 14333 if (ctx->insn_flags & INSN_R5900) { 14334 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ 14335 } else { 14336 decode_opc_special3(env, ctx); 14337 } 14338 #else 14339 decode_opc_special3(env, ctx); 14340 #endif 14341 break; 14342 case OPC_REGIMM: 14343 op1 = MASK_REGIMM(ctx->opcode); 14344 switch (op1) { 14345 case OPC_BLTZL: /* REGIMM branches */ 14346 case OPC_BGEZL: 14347 case OPC_BLTZALL: 14348 case OPC_BGEZALL: 14349 check_insn(ctx, ISA_MIPS2); 14350 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14351 /* Fallthrough */ 14352 case OPC_BLTZ: 14353 case OPC_BGEZ: 14354 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 14355 break; 14356 case OPC_BLTZAL: 14357 case OPC_BGEZAL: 14358 if (ctx->insn_flags & ISA_MIPS_R6) { 14359 if (rs == 0) { 14360 /* OPC_NAL, OPC_BAL */ 14361 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); 14362 } else { 14363 gen_reserved_instruction(ctx); 14364 } 14365 } else { 14366 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 14367 } 14368 break; 14369 case OPC_TGEI: /* REGIMM traps */ 14370 case OPC_TGEIU: 14371 case OPC_TLTI: 14372 case OPC_TLTIU: 14373 case OPC_TEQI: 14374 case OPC_TNEI: 14375 check_insn(ctx, ISA_MIPS2); 14376 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14377 gen_trap(ctx, op1, rs, -1, imm, 0); 14378 break; 14379 case OPC_SIGRIE: 14380 check_insn(ctx, ISA_MIPS_R6); 14381 gen_reserved_instruction(ctx); 14382 break; 14383 case OPC_SYNCI: 14384 check_insn(ctx, ISA_MIPS_R2); 14385 /* 14386 * Break the TB to be able to sync copied instructions 14387 * immediately. 14388 */ 14389 ctx->base.is_jmp = DISAS_STOP; 14390 break; 14391 case OPC_BPOSGE32: /* MIPS DSP branch */ 14392 #if defined(TARGET_MIPS64) 14393 case OPC_BPOSGE64: 14394 #endif 14395 check_dsp(ctx); 14396 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); 14397 break; 14398 #if defined(TARGET_MIPS64) 14399 case OPC_DAHI: 14400 check_insn(ctx, ISA_MIPS_R6); 14401 check_mips_64(ctx); 14402 if (rs != 0) { 14403 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); 14404 } 14405 break; 14406 case OPC_DATI: 14407 check_insn(ctx, ISA_MIPS_R6); 14408 check_mips_64(ctx); 14409 if (rs != 0) { 14410 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); 14411 } 14412 break; 14413 #endif 14414 default: /* Invalid */ 14415 MIPS_INVAL("regimm"); 14416 gen_reserved_instruction(ctx); 14417 break; 14418 } 14419 break; 14420 case OPC_CP0: 14421 check_cp0_enabled(ctx); 14422 op1 = MASK_CP0(ctx->opcode); 14423 switch (op1) { 14424 case OPC_MFC0: 14425 case OPC_MTC0: 14426 case OPC_MFTR: 14427 case OPC_MTTR: 14428 case OPC_MFHC0: 14429 case OPC_MTHC0: 14430 #if defined(TARGET_MIPS64) 14431 case OPC_DMFC0: 14432 case OPC_DMTC0: 14433 #endif 14434 #ifndef CONFIG_USER_ONLY 14435 gen_cp0(env, ctx, op1, rt, rd); 14436 #endif /* !CONFIG_USER_ONLY */ 14437 break; 14438 case OPC_C0: 14439 case OPC_C0_1: 14440 case OPC_C0_2: 14441 case OPC_C0_3: 14442 case OPC_C0_4: 14443 case OPC_C0_5: 14444 case OPC_C0_6: 14445 case OPC_C0_7: 14446 case OPC_C0_8: 14447 case OPC_C0_9: 14448 case OPC_C0_A: 14449 case OPC_C0_B: 14450 case OPC_C0_C: 14451 case OPC_C0_D: 14452 case OPC_C0_E: 14453 case OPC_C0_F: 14454 #ifndef CONFIG_USER_ONLY 14455 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 14456 #endif /* !CONFIG_USER_ONLY */ 14457 break; 14458 case OPC_MFMC0: 14459 #ifndef CONFIG_USER_ONLY 14460 { 14461 uint32_t op2; 14462 TCGv t0 = tcg_temp_new(); 14463 14464 op2 = MASK_MFMC0(ctx->opcode); 14465 switch (op2) { 14466 case OPC_DMT: 14467 check_cp0_mt(ctx); 14468 gen_helper_dmt(t0); 14469 gen_store_gpr(t0, rt); 14470 break; 14471 case OPC_EMT: 14472 check_cp0_mt(ctx); 14473 gen_helper_emt(t0); 14474 gen_store_gpr(t0, rt); 14475 break; 14476 case OPC_DVPE: 14477 check_cp0_mt(ctx); 14478 gen_helper_dvpe(t0, tcg_env); 14479 gen_store_gpr(t0, rt); 14480 break; 14481 case OPC_EVPE: 14482 check_cp0_mt(ctx); 14483 gen_helper_evpe(t0, tcg_env); 14484 gen_store_gpr(t0, rt); 14485 break; 14486 case OPC_DVP: 14487 check_insn(ctx, ISA_MIPS_R6); 14488 if (ctx->vp) { 14489 gen_helper_dvp(t0, tcg_env); 14490 gen_store_gpr(t0, rt); 14491 } 14492 break; 14493 case OPC_EVP: 14494 check_insn(ctx, ISA_MIPS_R6); 14495 if (ctx->vp) { 14496 gen_helper_evp(t0, tcg_env); 14497 gen_store_gpr(t0, rt); 14498 } 14499 break; 14500 case OPC_DI: 14501 check_insn(ctx, ISA_MIPS_R2); 14502 save_cpu_state(ctx, 1); 14503 gen_helper_di(t0, tcg_env); 14504 gen_store_gpr(t0, rt); 14505 /* 14506 * Stop translation as we may have switched 14507 * the execution mode. 14508 */ 14509 ctx->base.is_jmp = DISAS_STOP; 14510 break; 14511 case OPC_EI: 14512 check_insn(ctx, ISA_MIPS_R2); 14513 save_cpu_state(ctx, 1); 14514 gen_helper_ei(t0, tcg_env); 14515 gen_store_gpr(t0, rt); 14516 /* 14517 * DISAS_STOP isn't sufficient, we need to ensure we break 14518 * out of translated code to check for pending interrupts. 14519 */ 14520 gen_save_pc(ctx->base.pc_next + 4); 14521 ctx->base.is_jmp = DISAS_EXIT; 14522 break; 14523 default: /* Invalid */ 14524 MIPS_INVAL("mfmc0"); 14525 gen_reserved_instruction(ctx); 14526 break; 14527 } 14528 } 14529 #endif /* !CONFIG_USER_ONLY */ 14530 break; 14531 case OPC_RDPGPR: 14532 check_insn(ctx, ISA_MIPS_R2); 14533 gen_load_srsgpr(rt, rd); 14534 break; 14535 case OPC_WRPGPR: 14536 check_insn(ctx, ISA_MIPS_R2); 14537 gen_store_srsgpr(rt, rd); 14538 break; 14539 default: 14540 MIPS_INVAL("cp0"); 14541 gen_reserved_instruction(ctx); 14542 break; 14543 } 14544 break; 14545 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */ 14546 if (ctx->insn_flags & ISA_MIPS_R6) { 14547 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */ 14548 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14549 } else { 14550 /* OPC_ADDI */ 14551 /* Arithmetic with immediate opcode */ 14552 gen_arith_imm(ctx, op, rt, rs, imm); 14553 } 14554 break; 14555 case OPC_ADDIU: 14556 gen_arith_imm(ctx, op, rt, rs, imm); 14557 break; 14558 case OPC_SLTI: /* Set on less than with immediate opcode */ 14559 case OPC_SLTIU: 14560 gen_slt_imm(ctx, op, rt, rs, imm); 14561 break; 14562 case OPC_ANDI: /* Arithmetic with immediate opcode */ 14563 case OPC_LUI: /* OPC_AUI */ 14564 case OPC_ORI: 14565 case OPC_XORI: 14566 gen_logic_imm(ctx, op, rt, rs, imm); 14567 break; 14568 case OPC_J: /* Jump */ 14569 case OPC_JAL: 14570 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 14571 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 14572 break; 14573 /* Branch */ 14574 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ 14575 if (ctx->insn_flags & ISA_MIPS_R6) { 14576 if (rt == 0) { 14577 gen_reserved_instruction(ctx); 14578 break; 14579 } 14580 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */ 14581 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14582 } else { 14583 /* OPC_BLEZL */ 14584 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14585 } 14586 break; 14587 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ 14588 if (ctx->insn_flags & ISA_MIPS_R6) { 14589 if (rt == 0) { 14590 gen_reserved_instruction(ctx); 14591 break; 14592 } 14593 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */ 14594 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14595 } else { 14596 /* OPC_BGTZL */ 14597 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14598 } 14599 break; 14600 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */ 14601 if (rt == 0) { 14602 /* OPC_BLEZ */ 14603 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14604 } else { 14605 check_insn(ctx, ISA_MIPS_R6); 14606 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */ 14607 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14608 } 14609 break; 14610 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */ 14611 if (rt == 0) { 14612 /* OPC_BGTZ */ 14613 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14614 } else { 14615 check_insn(ctx, ISA_MIPS_R6); 14616 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */ 14617 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14618 } 14619 break; 14620 case OPC_BEQL: 14621 case OPC_BNEL: 14622 check_insn(ctx, ISA_MIPS2); 14623 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14624 /* Fallthrough */ 14625 case OPC_BEQ: 14626 case OPC_BNE: 14627 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14628 break; 14629 case OPC_LL: /* Load and stores */ 14630 check_insn(ctx, ISA_MIPS2); 14631 if (ctx->insn_flags & INSN_R5900) { 14632 check_insn_opc_user_only(ctx, INSN_R5900); 14633 } 14634 /* Fallthrough */ 14635 case OPC_LWL: 14636 case OPC_LWR: 14637 case OPC_LB: 14638 case OPC_LH: 14639 case OPC_LW: 14640 case OPC_LWPC: 14641 case OPC_LBU: 14642 case OPC_LHU: 14643 gen_ld(ctx, op, rt, rs, imm); 14644 break; 14645 case OPC_SWL: 14646 case OPC_SWR: 14647 case OPC_SB: 14648 case OPC_SH: 14649 case OPC_SW: 14650 gen_st(ctx, op, rt, rs, imm); 14651 break; 14652 case OPC_SC: 14653 check_insn(ctx, ISA_MIPS2); 14654 if (ctx->insn_flags & INSN_R5900) { 14655 check_insn_opc_user_only(ctx, INSN_R5900); 14656 } 14657 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false); 14658 break; 14659 case OPC_CACHE: 14660 check_cp0_enabled(ctx); 14661 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 14662 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14663 gen_cache_operation(ctx, rt, rs, imm); 14664 } 14665 /* Treat as NOP. */ 14666 break; 14667 case OPC_PREF: 14668 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900); 14669 /* Treat as NOP. */ 14670 break; 14671 14672 /* Floating point (COP1). */ 14673 case OPC_LWC1: 14674 case OPC_LDC1: 14675 case OPC_SWC1: 14676 case OPC_SDC1: 14677 gen_cop1_ldst(ctx, op, rt, rs, imm); 14678 break; 14679 14680 case OPC_CP1: 14681 op1 = MASK_CP1(ctx->opcode); 14682 14683 switch (op1) { 14684 case OPC_MFHC1: 14685 case OPC_MTHC1: 14686 check_cp1_enabled(ctx); 14687 check_insn(ctx, ISA_MIPS_R2); 14688 /* fall through */ 14689 case OPC_MFC1: 14690 case OPC_CFC1: 14691 case OPC_MTC1: 14692 case OPC_CTC1: 14693 check_cp1_enabled(ctx); 14694 gen_cp1(ctx, op1, rt, rd); 14695 break; 14696 #if defined(TARGET_MIPS64) 14697 case OPC_DMFC1: 14698 case OPC_DMTC1: 14699 check_cp1_enabled(ctx); 14700 check_insn(ctx, ISA_MIPS3); 14701 check_mips_64(ctx); 14702 gen_cp1(ctx, op1, rt, rd); 14703 break; 14704 #endif 14705 case OPC_BC1EQZ: /* OPC_BC1ANY2 */ 14706 check_cp1_enabled(ctx); 14707 if (ctx->insn_flags & ISA_MIPS_R6) { 14708 /* OPC_BC1EQZ */ 14709 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 14710 rt, imm << 2, 4); 14711 } else { 14712 /* OPC_BC1ANY2 */ 14713 check_cop1x(ctx); 14714 if (!ase_3d_available(env)) { 14715 return false; 14716 } 14717 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 14718 (rt >> 2) & 0x7, imm << 2); 14719 } 14720 break; 14721 case OPC_BC1NEZ: 14722 check_cp1_enabled(ctx); 14723 check_insn(ctx, ISA_MIPS_R6); 14724 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 14725 rt, imm << 2, 4); 14726 break; 14727 case OPC_BC1ANY4: 14728 check_cp1_enabled(ctx); 14729 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14730 check_cop1x(ctx); 14731 if (!ase_3d_available(env)) { 14732 return false; 14733 } 14734 /* fall through */ 14735 case OPC_BC1: 14736 check_cp1_enabled(ctx); 14737 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14738 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 14739 (rt >> 2) & 0x7, imm << 2); 14740 break; 14741 case OPC_PS_FMT: 14742 check_ps(ctx); 14743 /* fall through */ 14744 case OPC_S_FMT: 14745 case OPC_D_FMT: 14746 check_cp1_enabled(ctx); 14747 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 14748 (imm >> 8) & 0x7); 14749 break; 14750 case OPC_W_FMT: 14751 case OPC_L_FMT: 14752 { 14753 int r6_op = ctx->opcode & FOP(0x3f, 0x1f); 14754 check_cp1_enabled(ctx); 14755 if (ctx->insn_flags & ISA_MIPS_R6) { 14756 switch (r6_op) { 14757 case R6_OPC_CMP_AF_S: 14758 case R6_OPC_CMP_UN_S: 14759 case R6_OPC_CMP_EQ_S: 14760 case R6_OPC_CMP_UEQ_S: 14761 case R6_OPC_CMP_LT_S: 14762 case R6_OPC_CMP_ULT_S: 14763 case R6_OPC_CMP_LE_S: 14764 case R6_OPC_CMP_ULE_S: 14765 case R6_OPC_CMP_SAF_S: 14766 case R6_OPC_CMP_SUN_S: 14767 case R6_OPC_CMP_SEQ_S: 14768 case R6_OPC_CMP_SEUQ_S: 14769 case R6_OPC_CMP_SLT_S: 14770 case R6_OPC_CMP_SULT_S: 14771 case R6_OPC_CMP_SLE_S: 14772 case R6_OPC_CMP_SULE_S: 14773 case R6_OPC_CMP_OR_S: 14774 case R6_OPC_CMP_UNE_S: 14775 case R6_OPC_CMP_NE_S: 14776 case R6_OPC_CMP_SOR_S: 14777 case R6_OPC_CMP_SUNE_S: 14778 case R6_OPC_CMP_SNE_S: 14779 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa); 14780 break; 14781 case R6_OPC_CMP_AF_D: 14782 case R6_OPC_CMP_UN_D: 14783 case R6_OPC_CMP_EQ_D: 14784 case R6_OPC_CMP_UEQ_D: 14785 case R6_OPC_CMP_LT_D: 14786 case R6_OPC_CMP_ULT_D: 14787 case R6_OPC_CMP_LE_D: 14788 case R6_OPC_CMP_ULE_D: 14789 case R6_OPC_CMP_SAF_D: 14790 case R6_OPC_CMP_SUN_D: 14791 case R6_OPC_CMP_SEQ_D: 14792 case R6_OPC_CMP_SEUQ_D: 14793 case R6_OPC_CMP_SLT_D: 14794 case R6_OPC_CMP_SULT_D: 14795 case R6_OPC_CMP_SLE_D: 14796 case R6_OPC_CMP_SULE_D: 14797 case R6_OPC_CMP_OR_D: 14798 case R6_OPC_CMP_UNE_D: 14799 case R6_OPC_CMP_NE_D: 14800 case R6_OPC_CMP_SOR_D: 14801 case R6_OPC_CMP_SUNE_D: 14802 case R6_OPC_CMP_SNE_D: 14803 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa); 14804 break; 14805 default: 14806 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), 14807 rt, rd, sa, (imm >> 8) & 0x7); 14808 14809 break; 14810 } 14811 } else { 14812 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 14813 (imm >> 8) & 0x7); 14814 } 14815 break; 14816 } 14817 default: 14818 MIPS_INVAL("cp1"); 14819 gen_reserved_instruction(ctx); 14820 break; 14821 } 14822 break; 14823 14824 /* Compact branches [R6] and COP2 [non-R6] */ 14825 case OPC_BC: /* OPC_LWC2 */ 14826 case OPC_BALC: /* OPC_SWC2 */ 14827 if (ctx->insn_flags & ISA_MIPS_R6) { 14828 /* OPC_BC, OPC_BALC */ 14829 gen_compute_compact_branch(ctx, op, 0, 0, 14830 sextract32(ctx->opcode << 2, 0, 28)); 14831 } else if (ctx->insn_flags & ASE_LEXT) { 14832 gen_loongson_lswc2(ctx, rt, rs, rd); 14833 } else { 14834 /* OPC_LWC2, OPC_SWC2 */ 14835 /* COP2: Not implemented. */ 14836 generate_exception_err(ctx, EXCP_CpU, 2); 14837 } 14838 break; 14839 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */ 14840 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */ 14841 if (ctx->insn_flags & ISA_MIPS_R6) { 14842 if (rs != 0) { 14843 /* OPC_BEQZC, OPC_BNEZC */ 14844 gen_compute_compact_branch(ctx, op, rs, 0, 14845 sextract32(ctx->opcode << 2, 0, 23)); 14846 } else { 14847 /* OPC_JIC, OPC_JIALC */ 14848 gen_compute_compact_branch(ctx, op, 0, rt, imm); 14849 } 14850 } else if (ctx->insn_flags & ASE_LEXT) { 14851 gen_loongson_lsdc2(ctx, rt, rs, rd); 14852 } else { 14853 /* OPC_LWC2, OPC_SWC2 */ 14854 /* COP2: Not implemented. */ 14855 generate_exception_err(ctx, EXCP_CpU, 2); 14856 } 14857 break; 14858 case OPC_CP2: 14859 check_insn(ctx, ASE_LMMI); 14860 /* Note that these instructions use different fields. */ 14861 gen_loongson_multimedia(ctx, sa, rd, rt); 14862 break; 14863 14864 case OPC_CP3: 14865 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 14866 check_cp1_enabled(ctx); 14867 op1 = MASK_CP3(ctx->opcode); 14868 switch (op1) { 14869 case OPC_LUXC1: 14870 case OPC_SUXC1: 14871 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 14872 /* Fallthrough */ 14873 case OPC_LWXC1: 14874 case OPC_LDXC1: 14875 case OPC_SWXC1: 14876 case OPC_SDXC1: 14877 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14878 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 14879 break; 14880 case OPC_PREFX: 14881 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14882 /* Treat as NOP. */ 14883 break; 14884 case OPC_ALNV_PS: 14885 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 14886 /* Fallthrough */ 14887 case OPC_MADD_S: 14888 case OPC_MADD_D: 14889 case OPC_MADD_PS: 14890 case OPC_MSUB_S: 14891 case OPC_MSUB_D: 14892 case OPC_MSUB_PS: 14893 case OPC_NMADD_S: 14894 case OPC_NMADD_D: 14895 case OPC_NMADD_PS: 14896 case OPC_NMSUB_S: 14897 case OPC_NMSUB_D: 14898 case OPC_NMSUB_PS: 14899 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14900 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 14901 break; 14902 default: 14903 MIPS_INVAL("cp3"); 14904 gen_reserved_instruction(ctx); 14905 break; 14906 } 14907 } else { 14908 generate_exception_err(ctx, EXCP_CpU, 1); 14909 } 14910 break; 14911 14912 #if defined(TARGET_MIPS64) 14913 /* MIPS64 opcodes */ 14914 case OPC_LLD: 14915 if (ctx->insn_flags & INSN_R5900) { 14916 check_insn_opc_user_only(ctx, INSN_R5900); 14917 } 14918 /* fall through */ 14919 case OPC_LDL: 14920 case OPC_LDR: 14921 case OPC_LWU: 14922 case OPC_LD: 14923 check_insn(ctx, ISA_MIPS3); 14924 check_mips_64(ctx); 14925 gen_ld(ctx, op, rt, rs, imm); 14926 break; 14927 case OPC_SDL: 14928 case OPC_SDR: 14929 case OPC_SD: 14930 check_insn(ctx, ISA_MIPS3); 14931 check_mips_64(ctx); 14932 gen_st(ctx, op, rt, rs, imm); 14933 break; 14934 case OPC_SCD: 14935 check_insn(ctx, ISA_MIPS3); 14936 if (ctx->insn_flags & INSN_R5900) { 14937 check_insn_opc_user_only(ctx, INSN_R5900); 14938 } 14939 check_mips_64(ctx); 14940 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false); 14941 break; 14942 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ 14943 if (ctx->insn_flags & ISA_MIPS_R6) { 14944 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */ 14945 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14946 } else { 14947 /* OPC_DADDI */ 14948 check_insn(ctx, ISA_MIPS3); 14949 check_mips_64(ctx); 14950 gen_arith_imm(ctx, op, rt, rs, imm); 14951 } 14952 break; 14953 case OPC_DADDIU: 14954 check_insn(ctx, ISA_MIPS3); 14955 check_mips_64(ctx); 14956 gen_arith_imm(ctx, op, rt, rs, imm); 14957 break; 14958 #else 14959 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 14960 if (ctx->insn_flags & ISA_MIPS_R6) { 14961 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14962 } else { 14963 MIPS_INVAL("major opcode"); 14964 gen_reserved_instruction(ctx); 14965 } 14966 break; 14967 #endif 14968 case OPC_DAUI: /* OPC_JALX */ 14969 if (ctx->insn_flags & ISA_MIPS_R6) { 14970 #if defined(TARGET_MIPS64) 14971 /* OPC_DAUI */ 14972 check_mips_64(ctx); 14973 if (rs == 0) { 14974 generate_exception(ctx, EXCP_RI); 14975 } else if (rt != 0) { 14976 TCGv t0 = tcg_temp_new(); 14977 gen_load_gpr(t0, rs); 14978 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16); 14979 } 14980 #else 14981 gen_reserved_instruction(ctx); 14982 MIPS_INVAL("major opcode"); 14983 #endif 14984 } else { 14985 /* OPC_JALX */ 14986 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS); 14987 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 14988 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 14989 } 14990 break; 14991 case OPC_MDMX: 14992 /* MDMX: Not implemented. */ 14993 break; 14994 case OPC_PCREL: 14995 check_insn(ctx, ISA_MIPS_R6); 14996 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs); 14997 break; 14998 default: /* Invalid */ 14999 MIPS_INVAL("major opcode"); 15000 return false; 15001 } 15002 return true; 15003 } 15004 15005 static void decode_opc(CPUMIPSState *env, DisasContext *ctx) 15006 { 15007 /* make sure instructions are on a word boundary */ 15008 if (ctx->base.pc_next & 0x3) { 15009 env->CP0_BadVAddr = ctx->base.pc_next; 15010 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); 15011 return; 15012 } 15013 15014 /* Handle blikely not taken case */ 15015 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { 15016 TCGLabel *l1 = gen_new_label(); 15017 15018 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 15019 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 15020 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); 15021 gen_set_label(l1); 15022 } 15023 15024 /* Transition to the auto-generated decoder. */ 15025 15026 /* Vendor specific extensions */ 15027 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { 15028 return; 15029 } 15030 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) { 15031 return; 15032 } 15033 if (TARGET_LONG_BITS == 64 && decode_ext_loongson(ctx, ctx->opcode)) { 15034 return; 15035 } 15036 #if defined(TARGET_MIPS64) 15037 if (ase_lcsr_available(env) && decode_ase_lcsr(ctx, ctx->opcode)) { 15038 return; 15039 } 15040 if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) { 15041 return; 15042 } 15043 #endif 15044 15045 /* ISA extensions */ 15046 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) { 15047 return; 15048 } 15049 15050 /* ISA (from latest to oldest) */ 15051 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) { 15052 return; 15053 } 15054 15055 if (decode_opc_legacy(env, ctx)) { 15056 return; 15057 } 15058 15059 gen_reserved_instruction(ctx); 15060 } 15061 15062 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 15063 { 15064 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15065 CPUMIPSState *env = cpu_env(cs); 15066 15067 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; 15068 ctx->saved_pc = -1; 15069 ctx->insn_flags = env->insn_flags; 15070 ctx->CP0_Config0 = env->CP0_Config0; 15071 ctx->CP0_Config1 = env->CP0_Config1; 15072 ctx->CP0_Config2 = env->CP0_Config2; 15073 ctx->CP0_Config3 = env->CP0_Config3; 15074 ctx->CP0_Config5 = env->CP0_Config5; 15075 ctx->btarget = 0; 15076 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; 15077 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; 15078 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3; 15079 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1; 15080 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1; 15081 ctx->PAMask = env->PAMask; 15082 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; 15083 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; 15084 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1; 15085 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift; 15086 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; 15087 /* Restore delay slot state from the tb context. */ 15088 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ 15089 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; 15090 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || 15091 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); 15092 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1; 15093 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; 15094 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; 15095 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; 15096 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1; 15097 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3; 15098 restore_cpu_state(env, ctx); 15099 #ifdef CONFIG_USER_ONLY 15100 ctx->mem_idx = MIPS_HFLAG_UM; 15101 #else 15102 ctx->mem_idx = hflags_mmu_index(ctx->hflags); 15103 #endif 15104 ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) && 15105 (ctx->insn_flags & (ISA_MIPS_R6 | 15106 INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN; 15107 15108 /* 15109 * Execute a branch and its delay slot as a single instruction. 15110 * This is what GDB expects and is consistent with what the 15111 * hardware does (e.g. if a delay slot instruction faults, the 15112 * reported PC is the PC of the branch). 15113 */ 15114 if ((tb_cflags(ctx->base.tb) & CF_SINGLE_STEP) && 15115 (ctx->hflags & MIPS_HFLAG_BMASK)) { 15116 ctx->base.max_insns = 2; 15117 } 15118 15119 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, 15120 ctx->hflags); 15121 } 15122 15123 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) 15124 { 15125 } 15126 15127 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 15128 { 15129 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15130 15131 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, 15132 ctx->btarget); 15133 } 15134 15135 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 15136 { 15137 CPUMIPSState *env = cpu_env(cs); 15138 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15139 int insn_bytes; 15140 int is_slot; 15141 15142 is_slot = ctx->hflags & MIPS_HFLAG_BMASK; 15143 if (ctx->insn_flags & ISA_NANOMIPS32) { 15144 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15145 insn_bytes = decode_isa_nanomips(env, ctx); 15146 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) { 15147 ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next); 15148 insn_bytes = 4; 15149 decode_opc(env, ctx); 15150 } else if (ctx->insn_flags & ASE_MICROMIPS) { 15151 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15152 insn_bytes = decode_isa_micromips(env, ctx); 15153 } else if (ctx->insn_flags & ASE_MIPS16) { 15154 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15155 insn_bytes = decode_ase_mips16e(env, ctx); 15156 } else { 15157 gen_reserved_instruction(ctx); 15158 g_assert(ctx->base.is_jmp == DISAS_NORETURN); 15159 return; 15160 } 15161 15162 if (ctx->hflags & MIPS_HFLAG_BMASK) { 15163 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 | 15164 MIPS_HFLAG_FBNSLOT))) { 15165 /* 15166 * Force to generate branch as there is neither delay nor 15167 * forbidden slot. 15168 */ 15169 is_slot = 1; 15170 } 15171 if ((ctx->hflags & MIPS_HFLAG_M16) && 15172 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) { 15173 /* 15174 * Force to generate branch as microMIPS R6 doesn't restrict 15175 * branches in the forbidden slot. 15176 */ 15177 is_slot = 1; 15178 } 15179 } 15180 if (is_slot) { 15181 gen_branch(ctx, insn_bytes); 15182 } 15183 if (ctx->base.is_jmp == DISAS_SEMIHOST) { 15184 generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes); 15185 } 15186 ctx->base.pc_next += insn_bytes; 15187 15188 if (ctx->base.is_jmp != DISAS_NEXT) { 15189 return; 15190 } 15191 15192 /* 15193 * End the TB on (most) page crossings. 15194 * See mips_tr_init_disas_context about single-stepping a branch 15195 * together with its delay slot. 15196 */ 15197 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE 15198 && !(tb_cflags(ctx->base.tb) & CF_SINGLE_STEP)) { 15199 ctx->base.is_jmp = DISAS_TOO_MANY; 15200 } 15201 } 15202 15203 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 15204 { 15205 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15206 15207 switch (ctx->base.is_jmp) { 15208 case DISAS_STOP: 15209 gen_save_pc(ctx->base.pc_next); 15210 tcg_gen_lookup_and_goto_ptr(); 15211 break; 15212 case DISAS_NEXT: 15213 case DISAS_TOO_MANY: 15214 save_cpu_state(ctx, 0); 15215 gen_goto_tb(ctx, 0, ctx->base.pc_next); 15216 break; 15217 case DISAS_EXIT: 15218 tcg_gen_exit_tb(NULL, 0); 15219 break; 15220 case DISAS_NORETURN: 15221 break; 15222 default: 15223 g_assert_not_reached(); 15224 } 15225 } 15226 15227 static const TranslatorOps mips_tr_ops = { 15228 .init_disas_context = mips_tr_init_disas_context, 15229 .tb_start = mips_tr_tb_start, 15230 .insn_start = mips_tr_insn_start, 15231 .translate_insn = mips_tr_translate_insn, 15232 .tb_stop = mips_tr_tb_stop, 15233 }; 15234 15235 void mips_translate_code(CPUState *cs, TranslationBlock *tb, 15236 int *max_insns, vaddr pc, void *host_pc) 15237 { 15238 DisasContext ctx; 15239 15240 translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base); 15241 } 15242 15243 void mips_tcg_init(void) 15244 { 15245 cpu_gpr[0] = NULL; 15246 for (unsigned i = 1; i < 32; i++) 15247 cpu_gpr[i] = tcg_global_mem_new(tcg_env, 15248 offsetof(CPUMIPSState, 15249 active_tc.gpr[i]), 15250 regnames[i]); 15251 #if defined(TARGET_MIPS64) 15252 cpu_gpr_hi[0] = NULL; 15253 15254 for (unsigned i = 1; i < 32; i++) { 15255 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]); 15256 15257 cpu_gpr_hi[i] = tcg_global_mem_new_i64(tcg_env, 15258 offsetof(CPUMIPSState, 15259 active_tc.gpr_hi[i]), 15260 rname); 15261 } 15262 #endif /* !TARGET_MIPS64 */ 15263 for (unsigned i = 0; i < 32; i++) { 15264 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); 15265 15266 fpu_f64[i] = tcg_global_mem_new_i64(tcg_env, off, fregnames[i]); 15267 } 15268 msa_translate_init(); 15269 cpu_PC = tcg_global_mem_new(tcg_env, 15270 offsetof(CPUMIPSState, active_tc.PC), "PC"); 15271 for (unsigned i = 0; i < MIPS_DSP_ACC; i++) { 15272 cpu_HI[i] = tcg_global_mem_new(tcg_env, 15273 offsetof(CPUMIPSState, active_tc.HI[i]), 15274 regnames_HI[i]); 15275 cpu_LO[i] = tcg_global_mem_new(tcg_env, 15276 offsetof(CPUMIPSState, active_tc.LO[i]), 15277 regnames_LO[i]); 15278 } 15279 cpu_dspctrl = tcg_global_mem_new(tcg_env, 15280 offsetof(CPUMIPSState, 15281 active_tc.DSPControl), 15282 "DSPControl"); 15283 bcond = tcg_global_mem_new(tcg_env, 15284 offsetof(CPUMIPSState, bcond), "bcond"); 15285 btarget = tcg_global_mem_new(tcg_env, 15286 offsetof(CPUMIPSState, btarget), "btarget"); 15287 hflags = tcg_global_mem_new_i32(tcg_env, 15288 offsetof(CPUMIPSState, hflags), "hflags"); 15289 15290 fpu_fcr0 = tcg_global_mem_new_i32(tcg_env, 15291 offsetof(CPUMIPSState, active_fpu.fcr0), 15292 "fcr0"); 15293 fpu_fcr31 = tcg_global_mem_new_i32(tcg_env, 15294 offsetof(CPUMIPSState, active_fpu.fcr31), 15295 "fcr31"); 15296 cpu_lladdr = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, lladdr), 15297 "lladdr"); 15298 cpu_llval = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, llval), 15299 "llval"); 15300 15301 if (TARGET_LONG_BITS == 32) { 15302 mxu_translate_init(); 15303 } 15304 } 15305 15306 void mips_restore_state_to_opc(CPUState *cs, 15307 const TranslationBlock *tb, 15308 const uint64_t *data) 15309 { 15310 CPUMIPSState *env = cpu_env(cs); 15311 15312 env->active_tc.PC = data[0]; 15313 env->hflags &= ~MIPS_HFLAG_BMASK; 15314 env->hflags |= data[1]; 15315 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) { 15316 case MIPS_HFLAG_BR: 15317 break; 15318 case MIPS_HFLAG_BC: 15319 case MIPS_HFLAG_BL: 15320 case MIPS_HFLAG_B: 15321 env->btarget = data[2]; 15322 break; 15323 } 15324 } 15325