1 /* 2 * MIPS emulation for QEMU - main translation routines 3 * 4 * Copyright (c) 2004-2005 Jocelyn Mayer 5 * Copyright (c) 2006 Marius Groeger (FPU operations) 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) 9 * Copyright (c) 2020 Philippe Mathieu-Daudé 10 * 11 * This library is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU Lesser General Public 13 * License as published by the Free Software Foundation; either 14 * version 2.1 of the License, or (at your option) any later version. 15 * 16 * This library is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "translate.h" 27 #include "internal.h" 28 #include "exec/helper-proto.h" 29 #include "exec/translation-block.h" 30 #include "exec/target_page.h" 31 #include "semihosting/semihost.h" 32 #include "trace.h" 33 #include "fpu_helper.h" 34 35 #define HELPER_H "helper.h" 36 #include "exec/helper-info.c.inc" 37 #undef HELPER_H 38 39 40 /* 41 * Many system-only helpers are not reachable for user-only. 42 * Define stub generators here, so that we need not either sprinkle 43 * ifdefs through the translator, nor provide the helper function. 44 */ 45 #define STUB_HELPER(NAME, ...) \ 46 static inline void gen_helper_##NAME(__VA_ARGS__) \ 47 { g_assert_not_reached(); } 48 49 #ifdef CONFIG_USER_ONLY 50 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg) 51 #endif 52 53 enum { 54 /* indirect opcode tables */ 55 OPC_SPECIAL = (0x00 << 26), 56 OPC_REGIMM = (0x01 << 26), 57 OPC_CP0 = (0x10 << 26), 58 OPC_CP2 = (0x12 << 26), 59 OPC_CP3 = (0x13 << 26), 60 OPC_SPECIAL2 = (0x1C << 26), 61 OPC_SPECIAL3 = (0x1F << 26), 62 /* arithmetic with immediate */ 63 OPC_ADDI = (0x08 << 26), 64 OPC_ADDIU = (0x09 << 26), 65 OPC_SLTI = (0x0A << 26), 66 OPC_SLTIU = (0x0B << 26), 67 /* logic with immediate */ 68 OPC_ANDI = (0x0C << 26), 69 OPC_ORI = (0x0D << 26), 70 OPC_XORI = (0x0E << 26), 71 OPC_LUI = (0x0F << 26), 72 /* arithmetic with immediate */ 73 OPC_DADDI = (0x18 << 26), 74 OPC_DADDIU = (0x19 << 26), 75 /* Jump and branches */ 76 OPC_J = (0x02 << 26), 77 OPC_JAL = (0x03 << 26), 78 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */ 79 OPC_BEQL = (0x14 << 26), 80 OPC_BNE = (0x05 << 26), 81 OPC_BNEL = (0x15 << 26), 82 OPC_BLEZ = (0x06 << 26), 83 OPC_BLEZL = (0x16 << 26), 84 OPC_BGTZ = (0x07 << 26), 85 OPC_BGTZL = (0x17 << 26), 86 OPC_JALX = (0x1D << 26), 87 OPC_DAUI = (0x1D << 26), 88 /* Load and stores */ 89 OPC_LDL = (0x1A << 26), 90 OPC_LDR = (0x1B << 26), 91 OPC_LB = (0x20 << 26), 92 OPC_LH = (0x21 << 26), 93 OPC_LWL = (0x22 << 26), 94 OPC_LW = (0x23 << 26), 95 OPC_LWPC = OPC_LW | 0x5, 96 OPC_LBU = (0x24 << 26), 97 OPC_LHU = (0x25 << 26), 98 OPC_LWR = (0x26 << 26), 99 OPC_LWU = (0x27 << 26), 100 OPC_SB = (0x28 << 26), 101 OPC_SH = (0x29 << 26), 102 OPC_SWL = (0x2A << 26), 103 OPC_SW = (0x2B << 26), 104 OPC_SDL = (0x2C << 26), 105 OPC_SDR = (0x2D << 26), 106 OPC_SWR = (0x2E << 26), 107 OPC_LL = (0x30 << 26), 108 OPC_LLD = (0x34 << 26), 109 OPC_LD = (0x37 << 26), 110 OPC_LDPC = OPC_LD | 0x5, 111 OPC_SC = (0x38 << 26), 112 OPC_SCD = (0x3C << 26), 113 OPC_SD = (0x3F << 26), 114 /* Floating point load/store */ 115 OPC_LWC1 = (0x31 << 26), 116 OPC_LWC2 = (0x32 << 26), 117 OPC_LDC1 = (0x35 << 26), 118 OPC_LDC2 = (0x36 << 26), 119 OPC_SWC1 = (0x39 << 26), 120 OPC_SWC2 = (0x3A << 26), 121 OPC_SDC1 = (0x3D << 26), 122 OPC_SDC2 = (0x3E << 26), 123 /* Compact Branches */ 124 OPC_BLEZALC = (0x06 << 26), 125 OPC_BGEZALC = (0x06 << 26), 126 OPC_BGEUC = (0x06 << 26), 127 OPC_BGTZALC = (0x07 << 26), 128 OPC_BLTZALC = (0x07 << 26), 129 OPC_BLTUC = (0x07 << 26), 130 OPC_BOVC = (0x08 << 26), 131 OPC_BEQZALC = (0x08 << 26), 132 OPC_BEQC = (0x08 << 26), 133 OPC_BLEZC = (0x16 << 26), 134 OPC_BGEZC = (0x16 << 26), 135 OPC_BGEC = (0x16 << 26), 136 OPC_BGTZC = (0x17 << 26), 137 OPC_BLTZC = (0x17 << 26), 138 OPC_BLTC = (0x17 << 26), 139 OPC_BNVC = (0x18 << 26), 140 OPC_BNEZALC = (0x18 << 26), 141 OPC_BNEC = (0x18 << 26), 142 OPC_BC = (0x32 << 26), 143 OPC_BEQZC = (0x36 << 26), 144 OPC_JIC = (0x36 << 26), 145 OPC_BALC = (0x3A << 26), 146 OPC_BNEZC = (0x3E << 26), 147 OPC_JIALC = (0x3E << 26), 148 /* MDMX ASE specific */ 149 OPC_MDMX = (0x1E << 26), 150 /* Cache and prefetch */ 151 OPC_CACHE = (0x2F << 26), 152 OPC_PREF = (0x33 << 26), 153 /* PC-relative address computation / loads */ 154 OPC_PCREL = (0x3B << 26), 155 }; 156 157 /* PC-relative address computation / loads */ 158 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19))) 159 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16))) 160 enum { 161 /* Instructions determined by bits 19 and 20 */ 162 OPC_ADDIUPC = OPC_PCREL | (0 << 19), 163 R6_OPC_LWPC = OPC_PCREL | (1 << 19), 164 OPC_LWUPC = OPC_PCREL | (2 << 19), 165 166 /* Instructions determined by bits 16 ... 20 */ 167 OPC_AUIPC = OPC_PCREL | (0x1e << 16), 168 OPC_ALUIPC = OPC_PCREL | (0x1f << 16), 169 170 /* Other */ 171 R6_OPC_LDPC = OPC_PCREL | (6 << 18), 172 }; 173 174 /* MIPS special opcodes */ 175 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 176 177 enum { 178 /* Shifts */ 179 OPC_SLL = 0x00 | OPC_SPECIAL, 180 /* NOP is SLL r0, r0, 0 */ 181 /* SSNOP is SLL r0, r0, 1 */ 182 /* EHB is SLL r0, r0, 3 */ 183 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */ 184 OPC_ROTR = OPC_SRL | (1 << 21), 185 OPC_SRA = 0x03 | OPC_SPECIAL, 186 OPC_SLLV = 0x04 | OPC_SPECIAL, 187 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */ 188 OPC_ROTRV = OPC_SRLV | (1 << 6), 189 OPC_SRAV = 0x07 | OPC_SPECIAL, 190 OPC_DSLLV = 0x14 | OPC_SPECIAL, 191 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */ 192 OPC_DROTRV = OPC_DSRLV | (1 << 6), 193 OPC_DSRAV = 0x17 | OPC_SPECIAL, 194 OPC_DSLL = 0x38 | OPC_SPECIAL, 195 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */ 196 OPC_DROTR = OPC_DSRL | (1 << 21), 197 OPC_DSRA = 0x3B | OPC_SPECIAL, 198 OPC_DSLL32 = 0x3C | OPC_SPECIAL, 199 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */ 200 OPC_DROTR32 = OPC_DSRL32 | (1 << 21), 201 OPC_DSRA32 = 0x3F | OPC_SPECIAL, 202 /* Multiplication / division */ 203 OPC_MULT = 0x18 | OPC_SPECIAL, 204 OPC_MULTU = 0x19 | OPC_SPECIAL, 205 OPC_DIV = 0x1A | OPC_SPECIAL, 206 OPC_DIVU = 0x1B | OPC_SPECIAL, 207 OPC_DMULT = 0x1C | OPC_SPECIAL, 208 OPC_DMULTU = 0x1D | OPC_SPECIAL, 209 OPC_DDIV = 0x1E | OPC_SPECIAL, 210 OPC_DDIVU = 0x1F | OPC_SPECIAL, 211 212 /* 2 registers arithmetic / logic */ 213 OPC_ADD = 0x20 | OPC_SPECIAL, 214 OPC_ADDU = 0x21 | OPC_SPECIAL, 215 OPC_SUB = 0x22 | OPC_SPECIAL, 216 OPC_SUBU = 0x23 | OPC_SPECIAL, 217 OPC_AND = 0x24 | OPC_SPECIAL, 218 OPC_OR = 0x25 | OPC_SPECIAL, 219 OPC_XOR = 0x26 | OPC_SPECIAL, 220 OPC_NOR = 0x27 | OPC_SPECIAL, 221 OPC_SLT = 0x2A | OPC_SPECIAL, 222 OPC_SLTU = 0x2B | OPC_SPECIAL, 223 OPC_DADD = 0x2C | OPC_SPECIAL, 224 OPC_DADDU = 0x2D | OPC_SPECIAL, 225 OPC_DSUB = 0x2E | OPC_SPECIAL, 226 OPC_DSUBU = 0x2F | OPC_SPECIAL, 227 /* Jumps */ 228 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ 229 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ 230 /* Traps */ 231 OPC_TGE = 0x30 | OPC_SPECIAL, 232 OPC_TGEU = 0x31 | OPC_SPECIAL, 233 OPC_TLT = 0x32 | OPC_SPECIAL, 234 OPC_TLTU = 0x33 | OPC_SPECIAL, 235 OPC_TEQ = 0x34 | OPC_SPECIAL, 236 OPC_TNE = 0x36 | OPC_SPECIAL, 237 /* HI / LO registers load & stores */ 238 OPC_MFHI = 0x10 | OPC_SPECIAL, 239 OPC_MTHI = 0x11 | OPC_SPECIAL, 240 OPC_MFLO = 0x12 | OPC_SPECIAL, 241 OPC_MTLO = 0x13 | OPC_SPECIAL, 242 /* Conditional moves */ 243 OPC_MOVZ = 0x0A | OPC_SPECIAL, 244 OPC_MOVN = 0x0B | OPC_SPECIAL, 245 246 OPC_SELEQZ = 0x35 | OPC_SPECIAL, 247 OPC_SELNEZ = 0x37 | OPC_SPECIAL, 248 249 OPC_MOVCI = 0x01 | OPC_SPECIAL, 250 251 /* Special */ 252 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */ 253 OPC_SYSCALL = 0x0C | OPC_SPECIAL, 254 OPC_BREAK = 0x0D | OPC_SPECIAL, 255 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */ 256 OPC_SYNC = 0x0F | OPC_SPECIAL, 257 258 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, 259 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, 260 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, 261 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, 262 }; 263 264 /* 265 * R6 Multiply and Divide instructions have the same opcode 266 * and function field as legacy OPC_MULT[U]/OPC_DIV[U] 267 */ 268 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff))) 269 270 enum { 271 R6_OPC_MUL = OPC_MULT | (2 << 6), 272 R6_OPC_MUH = OPC_MULT | (3 << 6), 273 R6_OPC_MULU = OPC_MULTU | (2 << 6), 274 R6_OPC_MUHU = OPC_MULTU | (3 << 6), 275 R6_OPC_DIV = OPC_DIV | (2 << 6), 276 R6_OPC_MOD = OPC_DIV | (3 << 6), 277 R6_OPC_DIVU = OPC_DIVU | (2 << 6), 278 R6_OPC_MODU = OPC_DIVU | (3 << 6), 279 280 R6_OPC_DMUL = OPC_DMULT | (2 << 6), 281 R6_OPC_DMUH = OPC_DMULT | (3 << 6), 282 R6_OPC_DMULU = OPC_DMULTU | (2 << 6), 283 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6), 284 R6_OPC_DDIV = OPC_DDIV | (2 << 6), 285 R6_OPC_DMOD = OPC_DDIV | (3 << 6), 286 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6), 287 R6_OPC_DMODU = OPC_DDIVU | (3 << 6), 288 289 R6_OPC_CLZ = 0x10 | OPC_SPECIAL, 290 R6_OPC_CLO = 0x11 | OPC_SPECIAL, 291 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL, 292 R6_OPC_DCLO = 0x13 | OPC_SPECIAL, 293 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL, 294 }; 295 296 /* REGIMM (rt field) opcodes */ 297 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16))) 298 299 enum { 300 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM, 301 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM, 302 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM, 303 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM, 304 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM, 305 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM, 306 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM, 307 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM, 308 OPC_TGEI = (0x08 << 16) | OPC_REGIMM, 309 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM, 310 OPC_TLTI = (0x0A << 16) | OPC_REGIMM, 311 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM, 312 OPC_TEQI = (0x0C << 16) | OPC_REGIMM, 313 OPC_TNEI = (0x0E << 16) | OPC_REGIMM, 314 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM, 315 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM, 316 317 OPC_DAHI = (0x06 << 16) | OPC_REGIMM, 318 OPC_DATI = (0x1e << 16) | OPC_REGIMM, 319 }; 320 321 /* Special2 opcodes */ 322 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 323 324 enum { 325 /* Multiply & xxx operations */ 326 OPC_MADD = 0x00 | OPC_SPECIAL2, 327 OPC_MADDU = 0x01 | OPC_SPECIAL2, 328 OPC_MUL = 0x02 | OPC_SPECIAL2, 329 OPC_MSUB = 0x04 | OPC_SPECIAL2, 330 OPC_MSUBU = 0x05 | OPC_SPECIAL2, 331 /* Misc */ 332 OPC_CLZ = 0x20 | OPC_SPECIAL2, 333 OPC_CLO = 0x21 | OPC_SPECIAL2, 334 OPC_DCLZ = 0x24 | OPC_SPECIAL2, 335 OPC_DCLO = 0x25 | OPC_SPECIAL2, 336 /* Special */ 337 OPC_SDBBP = 0x3F | OPC_SPECIAL2, 338 }; 339 340 /* Special3 opcodes */ 341 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 342 343 enum { 344 OPC_EXT = 0x00 | OPC_SPECIAL3, 345 OPC_DEXTM = 0x01 | OPC_SPECIAL3, 346 OPC_DEXTU = 0x02 | OPC_SPECIAL3, 347 OPC_DEXT = 0x03 | OPC_SPECIAL3, 348 OPC_INS = 0x04 | OPC_SPECIAL3, 349 OPC_DINSM = 0x05 | OPC_SPECIAL3, 350 OPC_DINSU = 0x06 | OPC_SPECIAL3, 351 OPC_DINS = 0x07 | OPC_SPECIAL3, 352 OPC_FORK = 0x08 | OPC_SPECIAL3, 353 OPC_YIELD = 0x09 | OPC_SPECIAL3, 354 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 355 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 356 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 357 OPC_GINV = 0x3D | OPC_SPECIAL3, 358 359 /* MIPS DSP Load */ 360 OPC_LX_DSP = 0x0A | OPC_SPECIAL3, 361 /* MIPS DSP Arithmetic */ 362 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3, 363 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3, 364 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3, 365 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3, 366 OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, 367 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3, 368 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3, 369 /* MIPS DSP GPR-Based Shift Sub-class */ 370 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3, 371 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3, 372 /* MIPS DSP Multiply Sub-class insns */ 373 OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, 374 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3, 375 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3, 376 /* DSP Bit/Manipulation Sub-class */ 377 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, 378 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3, 379 /* MIPS DSP Append Sub-class */ 380 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3, 381 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3, 382 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 383 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, 384 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, 385 386 /* EVA */ 387 OPC_LWLE = 0x19 | OPC_SPECIAL3, 388 OPC_LWRE = 0x1A | OPC_SPECIAL3, 389 OPC_CACHEE = 0x1B | OPC_SPECIAL3, 390 OPC_SBE = 0x1C | OPC_SPECIAL3, 391 OPC_SHE = 0x1D | OPC_SPECIAL3, 392 OPC_SCE = 0x1E | OPC_SPECIAL3, 393 OPC_SWE = 0x1F | OPC_SPECIAL3, 394 OPC_SWLE = 0x21 | OPC_SPECIAL3, 395 OPC_SWRE = 0x22 | OPC_SPECIAL3, 396 OPC_PREFE = 0x23 | OPC_SPECIAL3, 397 OPC_LBUE = 0x28 | OPC_SPECIAL3, 398 OPC_LHUE = 0x29 | OPC_SPECIAL3, 399 OPC_LBE = 0x2C | OPC_SPECIAL3, 400 OPC_LHE = 0x2D | OPC_SPECIAL3, 401 OPC_LLE = 0x2E | OPC_SPECIAL3, 402 OPC_LWE = 0x2F | OPC_SPECIAL3, 403 404 /* R6 */ 405 R6_OPC_PREF = 0x35 | OPC_SPECIAL3, 406 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, 407 R6_OPC_LL = 0x36 | OPC_SPECIAL3, 408 R6_OPC_SC = 0x26 | OPC_SPECIAL3, 409 R6_OPC_LLD = 0x37 | OPC_SPECIAL3, 410 R6_OPC_SCD = 0x27 | OPC_SPECIAL3, 411 }; 412 413 /* Loongson EXT load/store quad word opcodes */ 414 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020)) 415 enum { 416 OPC_GSLQ = 0x0020 | OPC_LWC2, 417 OPC_GSLQC1 = 0x8020 | OPC_LWC2, 418 OPC_GSSHFL = OPC_LWC2, 419 OPC_GSSQ = 0x0020 | OPC_SWC2, 420 OPC_GSSQC1 = 0x8020 | OPC_SWC2, 421 OPC_GSSHFS = OPC_SWC2, 422 }; 423 424 /* Loongson EXT shifted load/store opcodes */ 425 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f)) 426 enum { 427 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL, 428 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL, 429 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL, 430 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL, 431 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS, 432 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS, 433 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS, 434 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS, 435 }; 436 437 /* Loongson EXT LDC2/SDC2 opcodes */ 438 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7)) 439 440 enum { 441 OPC_GSLBX = 0x0 | OPC_LDC2, 442 OPC_GSLHX = 0x1 | OPC_LDC2, 443 OPC_GSLWX = 0x2 | OPC_LDC2, 444 OPC_GSLDX = 0x3 | OPC_LDC2, 445 OPC_GSLWXC1 = 0x6 | OPC_LDC2, 446 OPC_GSLDXC1 = 0x7 | OPC_LDC2, 447 OPC_GSSBX = 0x0 | OPC_SDC2, 448 OPC_GSSHX = 0x1 | OPC_SDC2, 449 OPC_GSSWX = 0x2 | OPC_SDC2, 450 OPC_GSSDX = 0x3 | OPC_SDC2, 451 OPC_GSSWXC1 = 0x6 | OPC_SDC2, 452 OPC_GSSDXC1 = 0x7 | OPC_SDC2, 453 }; 454 455 /* BSHFL opcodes */ 456 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 457 458 enum { 459 OPC_WSBH = (0x02 << 6) | OPC_BSHFL, 460 OPC_SEB = (0x10 << 6) | OPC_BSHFL, 461 OPC_SEH = (0x18 << 6) | OPC_BSHFL, 462 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */ 463 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL, 464 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL, 465 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL, 466 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */ 467 }; 468 469 /* DBSHFL opcodes */ 470 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 471 472 enum { 473 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, 474 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, 475 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */ 476 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL, 477 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL, 478 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL, 479 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL, 480 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL, 481 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL, 482 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL, 483 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */ 484 }; 485 486 /* MIPS DSP REGIMM opcodes */ 487 enum { 488 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM, 489 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM, 490 }; 491 492 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 493 /* MIPS DSP Load */ 494 enum { 495 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP, 496 OPC_LHX = (0x04 << 6) | OPC_LX_DSP, 497 OPC_LWX = (0x00 << 6) | OPC_LX_DSP, 498 OPC_LDX = (0x08 << 6) | OPC_LX_DSP, 499 }; 500 501 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 502 enum { 503 /* MIPS DSP Arithmetic Sub-class */ 504 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP, 505 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP, 506 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP, 507 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP, 508 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP, 509 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP, 510 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP, 511 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP, 512 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP, 513 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP, 514 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP, 515 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP, 516 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP, 517 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP, 518 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP, 519 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP, 520 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP, 521 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP, 522 /* MIPS DSP Multiply Sub-class insns */ 523 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP, 524 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP, 525 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP, 526 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP, 527 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP, 528 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP, 529 }; 530 531 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 532 enum { 533 /* MIPS DSP Arithmetic Sub-class */ 534 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP, 535 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP, 536 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP, 537 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP, 538 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP, 539 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP, 540 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP, 541 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP, 542 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP, 543 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP, 544 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP, 545 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP, 546 /* MIPS DSP Multiply Sub-class insns */ 547 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP, 548 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP, 549 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP, 550 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP, 551 }; 552 553 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 554 enum { 555 /* MIPS DSP Arithmetic Sub-class */ 556 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP, 557 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP, 558 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP, 559 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP, 560 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP, 561 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP, 562 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP, 563 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP, 564 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP, 565 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP, 566 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP, 567 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP, 568 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP, 569 /* DSP Bit/Manipulation Sub-class */ 570 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP, 571 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP, 572 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP, 573 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP, 574 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP, 575 }; 576 577 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 578 enum { 579 /* MIPS DSP Arithmetic Sub-class */ 580 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP, 581 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP, 582 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP, 583 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP, 584 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP, 585 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP, 586 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP, 587 /* DSP Compare-Pick Sub-class */ 588 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP, 589 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP, 590 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP, 591 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP, 592 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP, 593 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP, 594 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP, 595 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP, 596 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP, 597 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP, 598 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP, 599 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP, 600 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, 601 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, 602 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, 603 }; 604 605 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 606 enum { 607 /* MIPS DSP GPR-Based Shift Sub-class */ 608 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP, 609 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP, 610 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP, 611 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP, 612 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP, 613 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP, 614 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP, 615 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP, 616 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP, 617 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP, 618 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP, 619 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP, 620 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP, 621 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP, 622 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP, 623 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP, 624 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP, 625 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP, 626 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP, 627 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP, 628 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP, 629 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP, 630 }; 631 632 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 633 enum { 634 /* MIPS DSP Multiply Sub-class insns */ 635 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP, 636 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP, 637 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP, 638 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP, 639 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP, 640 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP, 641 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP, 642 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP, 643 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP, 644 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP, 645 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP, 646 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP, 647 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP, 648 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP, 649 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP, 650 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP, 651 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP, 652 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP, 653 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP, 654 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP, 655 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP, 656 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP, 657 }; 658 659 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 660 enum { 661 /* DSP Bit/Manipulation Sub-class */ 662 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP, 663 }; 664 665 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 666 enum { 667 /* MIPS DSP Append Sub-class */ 668 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP, 669 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP, 670 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP, 671 }; 672 673 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 674 enum { 675 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 676 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP, 677 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP, 678 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP, 679 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP, 680 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP, 681 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP, 682 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP, 683 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP, 684 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP, 685 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP, 686 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP, 687 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP, 688 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP, 689 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP, 690 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP, 691 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP, 692 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP, 693 }; 694 695 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 696 enum { 697 /* MIPS DSP Arithmetic Sub-class */ 698 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP, 699 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP, 700 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP, 701 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP, 702 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP, 703 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP, 704 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP, 705 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP, 706 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP, 707 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP, 708 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP, 709 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP, 710 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP, 711 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP, 712 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP, 713 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP, 714 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP, 715 /* DSP Bit/Manipulation Sub-class */ 716 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP, 717 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP, 718 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP, 719 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP, 720 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP, 721 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP, 722 }; 723 724 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 725 enum { 726 /* MIPS DSP Multiply Sub-class insns */ 727 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP, 728 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP, 729 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP, 730 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP, 731 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP, 732 /* MIPS DSP Arithmetic Sub-class */ 733 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP, 734 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP, 735 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP, 736 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP, 737 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP, 738 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP, 739 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP, 740 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP, 741 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP, 742 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP, 743 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP, 744 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP, 745 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP, 746 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP, 747 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP, 748 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP, 749 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP, 750 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP, 751 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP, 752 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP, 753 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP, 754 }; 755 756 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 757 enum { 758 /* DSP Compare-Pick Sub-class */ 759 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP, 760 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP, 761 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP, 762 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP, 763 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP, 764 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP, 765 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP, 766 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP, 767 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP, 768 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP, 769 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP, 770 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP, 771 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP, 772 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP, 773 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP, 774 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP, 775 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP, 776 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP, 777 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP, 778 /* MIPS DSP Arithmetic Sub-class */ 779 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP, 780 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP, 781 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP, 782 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP, 783 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP, 784 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP, 785 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP, 786 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP, 787 }; 788 789 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 790 enum { 791 /* DSP Append Sub-class */ 792 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP, 793 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP, 794 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP, 795 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP, 796 }; 797 798 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 799 enum { 800 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 801 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP, 802 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP, 803 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP, 804 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP, 805 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP, 806 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP, 807 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP, 808 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP, 809 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP, 810 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP, 811 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP, 812 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP, 813 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP, 814 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP, 815 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP, 816 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP, 817 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP, 818 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP, 819 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP, 820 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP, 821 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP, 822 }; 823 824 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 825 enum { 826 /* DSP Bit/Manipulation Sub-class */ 827 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP, 828 }; 829 830 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 831 enum { 832 /* MIPS DSP Multiply Sub-class insns */ 833 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP, 834 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP, 835 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP, 836 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP, 837 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP, 838 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP, 839 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP, 840 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP, 841 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP, 842 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP, 843 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP, 844 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP, 845 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP, 846 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP, 847 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP, 848 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP, 849 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP, 850 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP, 851 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP, 852 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP, 853 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP, 854 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP, 855 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP, 856 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP, 857 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP, 858 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP, 859 }; 860 861 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 862 enum { 863 /* MIPS DSP GPR-Based Shift Sub-class */ 864 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP, 865 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP, 866 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP, 867 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP, 868 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP, 869 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP, 870 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP, 871 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP, 872 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP, 873 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP, 874 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP, 875 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP, 876 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP, 877 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP, 878 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP, 879 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP, 880 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP, 881 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP, 882 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP, 883 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP, 884 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP, 885 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP, 886 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP, 887 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP, 888 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP, 889 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP, 890 }; 891 892 /* Coprocessor 0 (rs field) */ 893 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 894 895 enum { 896 OPC_MFC0 = (0x00 << 21) | OPC_CP0, 897 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 898 OPC_MFHC0 = (0x02 << 21) | OPC_CP0, 899 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 900 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 901 OPC_MTHC0 = (0x06 << 21) | OPC_CP0, 902 OPC_MFTR = (0x08 << 21) | OPC_CP0, 903 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 904 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 905 OPC_MTTR = (0x0C << 21) | OPC_CP0, 906 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 907 OPC_C0 = (0x10 << 21) | OPC_CP0, 908 OPC_C0_1 = (0x11 << 21) | OPC_CP0, 909 OPC_C0_2 = (0x12 << 21) | OPC_CP0, 910 OPC_C0_3 = (0x13 << 21) | OPC_CP0, 911 OPC_C0_4 = (0x14 << 21) | OPC_CP0, 912 OPC_C0_5 = (0x15 << 21) | OPC_CP0, 913 OPC_C0_6 = (0x16 << 21) | OPC_CP0, 914 OPC_C0_7 = (0x17 << 21) | OPC_CP0, 915 OPC_C0_8 = (0x18 << 21) | OPC_CP0, 916 OPC_C0_9 = (0x19 << 21) | OPC_CP0, 917 OPC_C0_A = (0x1A << 21) | OPC_CP0, 918 OPC_C0_B = (0x1B << 21) | OPC_CP0, 919 OPC_C0_C = (0x1C << 21) | OPC_CP0, 920 OPC_C0_D = (0x1D << 21) | OPC_CP0, 921 OPC_C0_E = (0x1E << 21) | OPC_CP0, 922 OPC_C0_F = (0x1F << 21) | OPC_CP0, 923 }; 924 925 /* MFMC0 opcodes */ 926 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF)) 927 928 enum { 929 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 930 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 931 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0, 932 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0, 933 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 934 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 935 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0, 936 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0, 937 }; 938 939 /* Coprocessor 0 (with rs == C0) */ 940 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F)) 941 942 enum { 943 OPC_TLBR = 0x01 | OPC_C0, 944 OPC_TLBWI = 0x02 | OPC_C0, 945 OPC_TLBINV = 0x03 | OPC_C0, 946 OPC_TLBINVF = 0x04 | OPC_C0, 947 OPC_TLBWR = 0x06 | OPC_C0, 948 OPC_TLBP = 0x08 | OPC_C0, 949 OPC_RFE = 0x10 | OPC_C0, 950 OPC_ERET = 0x18 | OPC_C0, 951 OPC_DERET = 0x1F | OPC_C0, 952 OPC_WAIT = 0x20 | OPC_C0, 953 }; 954 955 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 956 957 enum { 958 OPC_MFC2 = (0x00 << 21) | OPC_CP2, 959 OPC_DMFC2 = (0x01 << 21) | OPC_CP2, 960 OPC_CFC2 = (0x02 << 21) | OPC_CP2, 961 OPC_MFHC2 = (0x03 << 21) | OPC_CP2, 962 OPC_MTC2 = (0x04 << 21) | OPC_CP2, 963 OPC_DMTC2 = (0x05 << 21) | OPC_CP2, 964 OPC_CTC2 = (0x06 << 21) | OPC_CP2, 965 OPC_MTHC2 = (0x07 << 21) | OPC_CP2, 966 OPC_BC2 = (0x08 << 21) | OPC_CP2, 967 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2, 968 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2, 969 }; 970 971 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F)) 972 973 enum { 974 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2, 975 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2, 976 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2, 977 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2, 978 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2, 979 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2, 980 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2, 981 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2, 982 983 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2, 984 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2, 985 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2, 986 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2, 987 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2, 988 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2, 989 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2, 990 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2, 991 992 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2, 993 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2, 994 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2, 995 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2, 996 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2, 997 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2, 998 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2, 999 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2, 1000 1001 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2, 1002 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2, 1003 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2, 1004 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2, 1005 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2, 1006 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2, 1007 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2, 1008 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2, 1009 1010 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2, 1011 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2, 1012 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2, 1013 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2, 1014 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2, 1015 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2, 1016 1017 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2, 1018 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2, 1019 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2, 1020 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2, 1021 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2, 1022 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2, 1023 1024 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2, 1025 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2, 1026 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2, 1027 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2, 1028 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2, 1029 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2, 1030 1031 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2, 1032 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2, 1033 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2, 1034 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2, 1035 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2, 1036 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2, 1037 1038 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2, 1039 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2, 1040 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2, 1041 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2, 1042 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2, 1043 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2, 1044 1045 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2, 1046 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2, 1047 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2, 1048 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2, 1049 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2, 1050 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2, 1051 1052 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2, 1053 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2, 1054 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2, 1055 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2, 1056 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2, 1057 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2, 1058 1059 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2, 1060 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2, 1061 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2, 1062 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2, 1063 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2, 1064 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2, 1065 }; 1066 1067 1068 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 1069 1070 enum { 1071 OPC_LWXC1 = 0x00 | OPC_CP3, 1072 OPC_LDXC1 = 0x01 | OPC_CP3, 1073 OPC_LUXC1 = 0x05 | OPC_CP3, 1074 OPC_SWXC1 = 0x08 | OPC_CP3, 1075 OPC_SDXC1 = 0x09 | OPC_CP3, 1076 OPC_SUXC1 = 0x0D | OPC_CP3, 1077 OPC_PREFX = 0x0F | OPC_CP3, 1078 OPC_ALNV_PS = 0x1E | OPC_CP3, 1079 OPC_MADD_S = 0x20 | OPC_CP3, 1080 OPC_MADD_D = 0x21 | OPC_CP3, 1081 OPC_MADD_PS = 0x26 | OPC_CP3, 1082 OPC_MSUB_S = 0x28 | OPC_CP3, 1083 OPC_MSUB_D = 0x29 | OPC_CP3, 1084 OPC_MSUB_PS = 0x2E | OPC_CP3, 1085 OPC_NMADD_S = 0x30 | OPC_CP3, 1086 OPC_NMADD_D = 0x31 | OPC_CP3, 1087 OPC_NMADD_PS = 0x36 | OPC_CP3, 1088 OPC_NMSUB_S = 0x38 | OPC_CP3, 1089 OPC_NMSUB_D = 0x39 | OPC_CP3, 1090 OPC_NMSUB_PS = 0x3E | OPC_CP3, 1091 }; 1092 1093 /* 1094 * MMI (MultiMedia Instruction) encodings 1095 * ====================================== 1096 * 1097 * MMI instructions encoding table keys: 1098 * 1099 * * This code is reserved for future use. An attempt to execute it 1100 * causes a Reserved Instruction exception. 1101 * % This code indicates an instruction class. The instruction word 1102 * must be further decoded by examining additional tables that show 1103 * the values for other instruction fields. 1104 * # This code is reserved for the unsupported instructions DMULT, 1105 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt 1106 * to execute it causes a Reserved Instruction exception. 1107 * 1108 * MMI instructions encoded by opcode field (MMI, LQ, SQ): 1109 * 1110 * 31 26 0 1111 * +--------+----------------------------------------+ 1112 * | opcode | | 1113 * +--------+----------------------------------------+ 1114 * 1115 * opcode bits 28..26 1116 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1117 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1118 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1119 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ 1120 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI 1121 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL 1122 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ 1123 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU 1124 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE 1125 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD 1126 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD 1127 */ 1128 1129 enum { 1130 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */ 1131 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */ 1132 }; 1133 1134 /* 1135 * MMI instructions with opcode field = MMI: 1136 * 1137 * 31 26 5 0 1138 * +--------+-------------------------------+--------+ 1139 * | MMI | |function| 1140 * +--------+-------------------------------+--------+ 1141 * 1142 * function bits 2..0 1143 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1144 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1145 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1146 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * 1147 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * 1148 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * 1149 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * 1150 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * 1151 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * 1152 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH 1153 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW 1154 */ 1155 1156 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) 1157 enum { 1158 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */ 1159 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */ 1160 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */ 1161 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */ 1162 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */ 1163 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */ 1164 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI, 1165 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI, 1166 }; 1167 1168 /* global register indices */ 1169 TCGv cpu_gpr[32], cpu_PC; 1170 /* 1171 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[]) 1172 * and the upper halves in cpu_gpr_hi[]. 1173 */ 1174 TCGv_i64 cpu_gpr_hi[32]; 1175 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; 1176 static TCGv cpu_dspctrl, btarget; 1177 TCGv bcond; 1178 static TCGv cpu_lladdr, cpu_llval; 1179 static TCGv_i32 hflags; 1180 TCGv_i32 fpu_fcr0, fpu_fcr31; 1181 TCGv_i64 fpu_f64[32]; 1182 1183 static const char regnames_HI[][4] = { 1184 "HI0", "HI1", "HI2", "HI3", 1185 }; 1186 1187 static const char regnames_LO[][4] = { 1188 "LO0", "LO1", "LO2", "LO3", 1189 }; 1190 1191 /* General purpose registers moves. */ 1192 void gen_load_gpr(TCGv t, int reg) 1193 { 1194 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr)); 1195 if (reg == 0) { 1196 tcg_gen_movi_tl(t, 0); 1197 } else { 1198 tcg_gen_mov_tl(t, cpu_gpr[reg]); 1199 } 1200 } 1201 1202 void gen_store_gpr(TCGv t, int reg) 1203 { 1204 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr)); 1205 if (reg != 0) { 1206 tcg_gen_mov_tl(cpu_gpr[reg], t); 1207 } 1208 } 1209 1210 #if defined(TARGET_MIPS64) 1211 void gen_load_gpr_hi(TCGv_i64 t, int reg) 1212 { 1213 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi)); 1214 if (reg == 0) { 1215 tcg_gen_movi_i64(t, 0); 1216 } else { 1217 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]); 1218 } 1219 } 1220 1221 void gen_store_gpr_hi(TCGv_i64 t, int reg) 1222 { 1223 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi)); 1224 if (reg != 0) { 1225 tcg_gen_mov_i64(cpu_gpr_hi[reg], t); 1226 } 1227 } 1228 #endif /* TARGET_MIPS64 */ 1229 1230 /* Moves to/from shadow registers. */ 1231 static inline void gen_load_srsgpr(int from, int to) 1232 { 1233 TCGv t0 = tcg_temp_new(); 1234 1235 if (from == 0) { 1236 tcg_gen_movi_tl(t0, 0); 1237 } else { 1238 TCGv_i32 t2 = tcg_temp_new_i32(); 1239 TCGv_ptr addr = tcg_temp_new_ptr(); 1240 1241 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1242 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1243 tcg_gen_andi_i32(t2, t2, 0xf); 1244 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1245 tcg_gen_ext_i32_ptr(addr, t2); 1246 tcg_gen_add_ptr(addr, tcg_env, addr); 1247 1248 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 1249 } 1250 gen_store_gpr(t0, to); 1251 } 1252 1253 static inline void gen_store_srsgpr(int from, int to) 1254 { 1255 if (to != 0) { 1256 TCGv t0 = tcg_temp_new(); 1257 TCGv_i32 t2 = tcg_temp_new_i32(); 1258 TCGv_ptr addr = tcg_temp_new_ptr(); 1259 1260 gen_load_gpr(t0, from); 1261 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1262 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1263 tcg_gen_andi_i32(t2, t2, 0xf); 1264 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1265 tcg_gen_ext_i32_ptr(addr, t2); 1266 tcg_gen_add_ptr(addr, tcg_env, addr); 1267 1268 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 1269 } 1270 } 1271 1272 /* Tests */ 1273 static inline void gen_save_pc(target_ulong pc) 1274 { 1275 tcg_gen_movi_tl(cpu_PC, pc); 1276 } 1277 1278 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) 1279 { 1280 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 1281 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { 1282 gen_save_pc(ctx->base.pc_next); 1283 ctx->saved_pc = ctx->base.pc_next; 1284 } 1285 if (ctx->hflags != ctx->saved_hflags) { 1286 tcg_gen_movi_i32(hflags, ctx->hflags); 1287 ctx->saved_hflags = ctx->hflags; 1288 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1289 case MIPS_HFLAG_BR: 1290 break; 1291 case MIPS_HFLAG_BC: 1292 case MIPS_HFLAG_BL: 1293 case MIPS_HFLAG_B: 1294 tcg_gen_movi_tl(btarget, ctx->btarget); 1295 break; 1296 } 1297 } 1298 } 1299 1300 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) 1301 { 1302 ctx->saved_hflags = ctx->hflags; 1303 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1304 case MIPS_HFLAG_BR: 1305 break; 1306 case MIPS_HFLAG_BC: 1307 case MIPS_HFLAG_BL: 1308 case MIPS_HFLAG_B: 1309 ctx->btarget = env->btarget; 1310 break; 1311 } 1312 } 1313 1314 void generate_exception_err(DisasContext *ctx, int excp, int err) 1315 { 1316 save_cpu_state(ctx, 1); 1317 gen_helper_raise_exception_err(tcg_env, tcg_constant_i32(excp), 1318 tcg_constant_i32(err)); 1319 ctx->base.is_jmp = DISAS_NORETURN; 1320 } 1321 1322 void generate_exception(DisasContext *ctx, int excp) 1323 { 1324 gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp)); 1325 } 1326 1327 void generate_exception_end(DisasContext *ctx, int excp) 1328 { 1329 generate_exception_err(ctx, excp, 0); 1330 } 1331 1332 void generate_exception_break(DisasContext *ctx, int code) 1333 { 1334 #ifdef CONFIG_USER_ONLY 1335 /* Pass the break code along to cpu_loop. */ 1336 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 1337 offsetof(CPUMIPSState, error_code)); 1338 #endif 1339 generate_exception_end(ctx, EXCP_BREAK); 1340 } 1341 1342 void gen_reserved_instruction(DisasContext *ctx) 1343 { 1344 generate_exception_end(ctx, EXCP_RI); 1345 } 1346 1347 /* Floating point register moves. */ 1348 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1349 { 1350 if (ctx->hflags & MIPS_HFLAG_FRE) { 1351 generate_exception(ctx, EXCP_RI); 1352 } 1353 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); 1354 } 1355 1356 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1357 { 1358 TCGv_i64 t64; 1359 if (ctx->hflags & MIPS_HFLAG_FRE) { 1360 generate_exception(ctx, EXCP_RI); 1361 } 1362 t64 = tcg_temp_new_i64(); 1363 tcg_gen_extu_i32_i64(t64, t); 1364 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); 1365 } 1366 1367 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1368 { 1369 if (ctx->hflags & MIPS_HFLAG_F64) { 1370 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); 1371 } else { 1372 gen_load_fpr32(ctx, t, reg | 1); 1373 } 1374 } 1375 1376 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1377 { 1378 if (ctx->hflags & MIPS_HFLAG_F64) { 1379 TCGv_i64 t64 = tcg_temp_new_i64(); 1380 tcg_gen_extu_i32_i64(t64, t); 1381 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); 1382 } else { 1383 gen_store_fpr32(ctx, t, reg | 1); 1384 } 1385 } 1386 1387 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1388 { 1389 if (ctx->hflags & MIPS_HFLAG_F64) { 1390 tcg_gen_mov_i64(t, fpu_f64[reg]); 1391 } else { 1392 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]); 1393 } 1394 } 1395 1396 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1397 { 1398 if (ctx->hflags & MIPS_HFLAG_F64) { 1399 tcg_gen_mov_i64(fpu_f64[reg], t); 1400 } else { 1401 TCGv_i64 t0; 1402 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32); 1403 t0 = tcg_temp_new_i64(); 1404 tcg_gen_shri_i64(t0, t, 32); 1405 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32); 1406 } 1407 } 1408 1409 int get_fp_bit(int cc) 1410 { 1411 if (cc) { 1412 return 24 + cc; 1413 } else { 1414 return 23; 1415 } 1416 } 1417 1418 /* Addresses computation */ 1419 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 1420 { 1421 tcg_gen_add_tl(ret, arg0, arg1); 1422 1423 #if defined(TARGET_MIPS64) 1424 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1425 tcg_gen_ext32s_i64(ret, ret); 1426 } 1427 #endif 1428 } 1429 1430 void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, target_long ofs) 1431 { 1432 tcg_gen_addi_tl(ret, base, ofs); 1433 1434 #if defined(TARGET_MIPS64) 1435 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1436 tcg_gen_ext32s_i64(ret, ret); 1437 } 1438 #endif 1439 } 1440 1441 /* Addresses computation (translation time) */ 1442 static target_long addr_add(DisasContext *ctx, target_long base, 1443 target_long offset) 1444 { 1445 target_long sum = base + offset; 1446 1447 #if defined(TARGET_MIPS64) 1448 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1449 sum = (int32_t)sum; 1450 } 1451 #endif 1452 return sum; 1453 } 1454 1455 /* Sign-extract the low 32-bits to a target_long. */ 1456 void gen_move_low32(TCGv ret, TCGv_i64 arg) 1457 { 1458 #if defined(TARGET_MIPS64) 1459 tcg_gen_ext32s_i64(ret, arg); 1460 #else 1461 tcg_gen_extrl_i64_i32(ret, arg); 1462 #endif 1463 } 1464 1465 /* Sign-extract the high 32-bits to a target_long. */ 1466 void gen_move_high32(TCGv ret, TCGv_i64 arg) 1467 { 1468 #if defined(TARGET_MIPS64) 1469 tcg_gen_sari_i64(ret, arg, 32); 1470 #else 1471 tcg_gen_extrh_i64_i32(ret, arg); 1472 #endif 1473 } 1474 1475 bool check_cp0_enabled(DisasContext *ctx) 1476 { 1477 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1478 generate_exception_end(ctx, EXCP_CpU); 1479 return false; 1480 } 1481 return true; 1482 } 1483 1484 void check_cp1_enabled(DisasContext *ctx) 1485 { 1486 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) { 1487 generate_exception_err(ctx, EXCP_CpU, 1); 1488 } 1489 } 1490 1491 /* 1492 * Verify that the processor is running with COP1X instructions enabled. 1493 * This is associated with the nabla symbol in the MIPS32 and MIPS64 1494 * opcode tables. 1495 */ 1496 void check_cop1x(DisasContext *ctx) 1497 { 1498 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { 1499 gen_reserved_instruction(ctx); 1500 } 1501 } 1502 1503 /* 1504 * Verify that the processor is running with 64-bit floating-point 1505 * operations enabled. 1506 */ 1507 void check_cp1_64bitmode(DisasContext *ctx) 1508 { 1509 if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) { 1510 gen_reserved_instruction(ctx); 1511 } 1512 } 1513 1514 /* 1515 * Verify if floating point register is valid; an operation is not defined 1516 * if bit 0 of any register specification is set and the FR bit in the 1517 * Status register equals zero, since the register numbers specify an 1518 * even-odd pair of adjacent coprocessor general registers. When the FR bit 1519 * in the Status register equals one, both even and odd register numbers 1520 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 1521 * 1522 * Multiple 64 bit wide registers can be checked by calling 1523 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 1524 */ 1525 void check_cp1_registers(DisasContext *ctx, int regs) 1526 { 1527 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { 1528 gen_reserved_instruction(ctx); 1529 } 1530 } 1531 1532 /* 1533 * Verify that the processor is running with DSP instructions enabled. 1534 * This is enabled by CP0 Status register MX(24) bit. 1535 */ 1536 static inline void check_dsp(DisasContext *ctx) 1537 { 1538 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { 1539 if (ctx->insn_flags & ASE_DSP) { 1540 generate_exception_end(ctx, EXCP_DSPDIS); 1541 } else { 1542 gen_reserved_instruction(ctx); 1543 } 1544 } 1545 } 1546 1547 static inline void check_dsp_r2(DisasContext *ctx) 1548 { 1549 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { 1550 if (ctx->insn_flags & ASE_DSP) { 1551 generate_exception_end(ctx, EXCP_DSPDIS); 1552 } else { 1553 gen_reserved_instruction(ctx); 1554 } 1555 } 1556 } 1557 1558 static inline void check_dsp_r3(DisasContext *ctx) 1559 { 1560 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { 1561 if (ctx->insn_flags & ASE_DSP) { 1562 generate_exception_end(ctx, EXCP_DSPDIS); 1563 } else { 1564 gen_reserved_instruction(ctx); 1565 } 1566 } 1567 } 1568 1569 /* 1570 * This code generates a "reserved instruction" exception if the 1571 * CPU does not support the instruction set corresponding to flags. 1572 */ 1573 void check_insn(DisasContext *ctx, uint64_t flags) 1574 { 1575 if (unlikely(!(ctx->insn_flags & flags))) { 1576 gen_reserved_instruction(ctx); 1577 } 1578 } 1579 1580 /* 1581 * This code generates a "reserved instruction" exception if the 1582 * CPU has corresponding flag set which indicates that the instruction 1583 * has been removed. 1584 */ 1585 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) 1586 { 1587 if (unlikely(ctx->insn_flags & flags)) { 1588 gen_reserved_instruction(ctx); 1589 } 1590 } 1591 1592 /* 1593 * The Linux kernel traps certain reserved instruction exceptions to 1594 * emulate the corresponding instructions. QEMU is the kernel in user 1595 * mode, so those traps are emulated by accepting the instructions. 1596 * 1597 * A reserved instruction exception is generated for flagged CPUs if 1598 * QEMU runs in system mode. 1599 */ 1600 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) 1601 { 1602 #ifndef CONFIG_USER_ONLY 1603 check_insn_opc_removed(ctx, flags); 1604 #endif 1605 } 1606 1607 /* 1608 * This code generates a "reserved instruction" exception if the 1609 * CPU does not support 64-bit paired-single (PS) floating point data type. 1610 */ 1611 static inline void check_ps(DisasContext *ctx) 1612 { 1613 if (unlikely(!ctx->ps)) { 1614 generate_exception(ctx, EXCP_RI); 1615 } 1616 check_cp1_64bitmode(ctx); 1617 } 1618 1619 bool decode_64bit_enabled(DisasContext *ctx) 1620 { 1621 return ctx->hflags & MIPS_HFLAG_64; 1622 } 1623 1624 /* 1625 * This code generates a "reserved instruction" exception if cpu is not 1626 * 64-bit or 64-bit instructions are not enabled. 1627 */ 1628 void check_mips_64(DisasContext *ctx) 1629 { 1630 if (unlikely((TARGET_LONG_BITS != 64) || !decode_64bit_enabled(ctx))) { 1631 gen_reserved_instruction(ctx); 1632 } 1633 } 1634 1635 #ifndef CONFIG_USER_ONLY 1636 static inline void check_mvh(DisasContext *ctx) 1637 { 1638 if (unlikely(!ctx->mvh)) { 1639 generate_exception(ctx, EXCP_RI); 1640 } 1641 } 1642 #endif 1643 1644 /* 1645 * This code generates a "reserved instruction" exception if the 1646 * Config5 XNP bit is set. 1647 */ 1648 static inline void check_xnp(DisasContext *ctx) 1649 { 1650 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) { 1651 gen_reserved_instruction(ctx); 1652 } 1653 } 1654 1655 #ifndef CONFIG_USER_ONLY 1656 /* 1657 * This code generates a "reserved instruction" exception if the 1658 * Config3 PW bit is NOT set. 1659 */ 1660 static inline void check_pw(DisasContext *ctx) 1661 { 1662 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) { 1663 gen_reserved_instruction(ctx); 1664 } 1665 } 1666 #endif 1667 1668 /* 1669 * This code generates a "reserved instruction" exception if the 1670 * Config3 MT bit is NOT set. 1671 */ 1672 static inline void check_mt(DisasContext *ctx) 1673 { 1674 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1675 gen_reserved_instruction(ctx); 1676 } 1677 } 1678 1679 #ifndef CONFIG_USER_ONLY 1680 /* 1681 * This code generates a "coprocessor unusable" exception if CP0 is not 1682 * available, and, if that is not the case, generates a "reserved instruction" 1683 * exception if the Config5 MT bit is NOT set. This is needed for availability 1684 * control of some of MT ASE instructions. 1685 */ 1686 static inline void check_cp0_mt(DisasContext *ctx) 1687 { 1688 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1689 generate_exception_end(ctx, EXCP_CpU); 1690 } else { 1691 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1692 gen_reserved_instruction(ctx); 1693 } 1694 } 1695 } 1696 #endif 1697 1698 /* 1699 * This code generates a "reserved instruction" exception if the 1700 * Config5 NMS bit is set. 1701 */ 1702 static inline void check_nms(DisasContext *ctx) 1703 { 1704 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) { 1705 gen_reserved_instruction(ctx); 1706 } 1707 } 1708 1709 /* 1710 * This code generates a "reserved instruction" exception if the 1711 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, 1712 * Config2 TL, and Config5 L2C are unset. 1713 */ 1714 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) 1715 { 1716 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) && 1717 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) && 1718 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) && 1719 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && 1720 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && 1721 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) { 1722 gen_reserved_instruction(ctx); 1723 } 1724 } 1725 1726 /* 1727 * This code generates a "reserved instruction" exception if the 1728 * Config5 EVA bit is NOT set. 1729 */ 1730 static inline void check_eva(DisasContext *ctx) 1731 { 1732 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) { 1733 gen_reserved_instruction(ctx); 1734 } 1735 } 1736 1737 1738 /* 1739 * Define small wrappers for gen_load_fpr* so that we have a uniform 1740 * calling interface for 32 and 64-bit FPRs. No sense in changing 1741 * all callers for gen_load_fpr32 when we need the CTX parameter for 1742 * this one use. 1743 */ 1744 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) 1745 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) 1746 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \ 1747 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ 1748 int ft, int fs, int cc) \ 1749 { \ 1750 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ 1751 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ 1752 switch (ifmt) { \ 1753 case FMT_PS: \ 1754 check_ps(ctx); \ 1755 break; \ 1756 case FMT_D: \ 1757 if (abs) { \ 1758 check_cop1x(ctx); \ 1759 } \ 1760 check_cp1_registers(ctx, fs | ft); \ 1761 break; \ 1762 case FMT_S: \ 1763 if (abs) { \ 1764 check_cop1x(ctx); \ 1765 } \ 1766 break; \ 1767 } \ 1768 gen_ldcmp_fpr##bits(ctx, fp0, fs); \ 1769 gen_ldcmp_fpr##bits(ctx, fp1, ft); \ 1770 switch (n) { \ 1771 case 0: \ 1772 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \ 1773 break; \ 1774 case 1: \ 1775 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \ 1776 break; \ 1777 case 2: \ 1778 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \ 1779 break; \ 1780 case 3: \ 1781 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \ 1782 break; \ 1783 case 4: \ 1784 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \ 1785 break; \ 1786 case 5: \ 1787 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \ 1788 break; \ 1789 case 6: \ 1790 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \ 1791 break; \ 1792 case 7: \ 1793 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \ 1794 break; \ 1795 case 8: \ 1796 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \ 1797 break; \ 1798 case 9: \ 1799 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \ 1800 break; \ 1801 case 10: \ 1802 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \ 1803 break; \ 1804 case 11: \ 1805 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \ 1806 break; \ 1807 case 12: \ 1808 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \ 1809 break; \ 1810 case 13: \ 1811 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \ 1812 break; \ 1813 case 14: \ 1814 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \ 1815 break; \ 1816 case 15: \ 1817 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \ 1818 break; \ 1819 default: \ 1820 abort(); \ 1821 } \ 1822 } 1823 1824 FOP_CONDS(, 0, d, FMT_D, 64) 1825 FOP_CONDS(abs, 1, d, FMT_D, 64) 1826 FOP_CONDS(, 0, s, FMT_S, 32) 1827 FOP_CONDS(abs, 1, s, FMT_S, 32) 1828 FOP_CONDS(, 0, ps, FMT_PS, 64) 1829 FOP_CONDS(abs, 1, ps, FMT_PS, 64) 1830 #undef FOP_CONDS 1831 1832 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \ 1833 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \ 1834 int ft, int fs, int fd) \ 1835 { \ 1836 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ 1837 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ 1838 if (ifmt == FMT_D) { \ 1839 check_cp1_registers(ctx, fs | ft | fd); \ 1840 } \ 1841 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ 1842 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ 1843 switch (n) { \ 1844 case 0: \ 1845 gen_helper_r6_cmp_ ## fmt ## _af(fp0, tcg_env, fp0, fp1); \ 1846 break; \ 1847 case 1: \ 1848 gen_helper_r6_cmp_ ## fmt ## _un(fp0, tcg_env, fp0, fp1); \ 1849 break; \ 1850 case 2: \ 1851 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, tcg_env, fp0, fp1); \ 1852 break; \ 1853 case 3: \ 1854 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, tcg_env, fp0, fp1); \ 1855 break; \ 1856 case 4: \ 1857 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, tcg_env, fp0, fp1); \ 1858 break; \ 1859 case 5: \ 1860 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, tcg_env, fp0, fp1); \ 1861 break; \ 1862 case 6: \ 1863 gen_helper_r6_cmp_ ## fmt ## _le(fp0, tcg_env, fp0, fp1); \ 1864 break; \ 1865 case 7: \ 1866 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, tcg_env, fp0, fp1); \ 1867 break; \ 1868 case 8: \ 1869 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, tcg_env, fp0, fp1); \ 1870 break; \ 1871 case 9: \ 1872 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, tcg_env, fp0, fp1); \ 1873 break; \ 1874 case 10: \ 1875 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, tcg_env, fp0, fp1); \ 1876 break; \ 1877 case 11: \ 1878 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, tcg_env, fp0, fp1); \ 1879 break; \ 1880 case 12: \ 1881 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, tcg_env, fp0, fp1); \ 1882 break; \ 1883 case 13: \ 1884 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, tcg_env, fp0, fp1); \ 1885 break; \ 1886 case 14: \ 1887 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, tcg_env, fp0, fp1); \ 1888 break; \ 1889 case 15: \ 1890 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, tcg_env, fp0, fp1); \ 1891 break; \ 1892 case 17: \ 1893 gen_helper_r6_cmp_ ## fmt ## _or(fp0, tcg_env, fp0, fp1); \ 1894 break; \ 1895 case 18: \ 1896 gen_helper_r6_cmp_ ## fmt ## _une(fp0, tcg_env, fp0, fp1); \ 1897 break; \ 1898 case 19: \ 1899 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, tcg_env, fp0, fp1); \ 1900 break; \ 1901 case 25: \ 1902 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, tcg_env, fp0, fp1); \ 1903 break; \ 1904 case 26: \ 1905 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, tcg_env, fp0, fp1); \ 1906 break; \ 1907 case 27: \ 1908 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, tcg_env, fp0, fp1); \ 1909 break; \ 1910 default: \ 1911 abort(); \ 1912 } \ 1913 STORE; \ 1914 } 1915 1916 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) 1917 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd)) 1918 #undef FOP_CONDNS 1919 #undef gen_ldcmp_fpr32 1920 #undef gen_ldcmp_fpr64 1921 1922 /* load/store instructions. */ 1923 #ifdef CONFIG_USER_ONLY 1924 #define OP_LD_ATOMIC(insn, memop) \ 1925 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1926 DisasContext *ctx) \ 1927 { \ 1928 TCGv t0 = tcg_temp_new(); \ 1929 tcg_gen_mov_tl(t0, arg1); \ 1930 tcg_gen_qemu_ld_tl(ret, arg1, ctx->mem_idx, memop); \ 1931 tcg_gen_st_tl(t0, tcg_env, offsetof(CPUMIPSState, lladdr)); \ 1932 tcg_gen_st_tl(ret, tcg_env, offsetof(CPUMIPSState, llval)); \ 1933 } 1934 #else 1935 #define OP_LD_ATOMIC(insn, ignored_memop) \ 1936 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1937 DisasContext *ctx) \ 1938 { \ 1939 gen_helper_##insn(ret, tcg_env, arg1, tcg_constant_i32(mem_idx)); \ 1940 } 1941 #endif 1942 OP_LD_ATOMIC(ll, mo_endian(ctx) | MO_SL); 1943 #if defined(TARGET_MIPS64) 1944 OP_LD_ATOMIC(lld, mo_endian(ctx) | MO_UQ); 1945 #endif 1946 #undef OP_LD_ATOMIC 1947 1948 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset) 1949 { 1950 if (base == 0) { 1951 tcg_gen_movi_tl(addr, offset); 1952 } else if (offset == 0) { 1953 gen_load_gpr(addr, base); 1954 } else { 1955 tcg_gen_movi_tl(addr, offset); 1956 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); 1957 } 1958 } 1959 1960 void gen_base_index_addr(DisasContext *ctx, TCGv addr, int base, int index) 1961 { 1962 if (base == 0) { 1963 gen_load_gpr(addr, index); 1964 } else if (index == 0) { 1965 gen_load_gpr(addr, base); 1966 } else { 1967 gen_op_addr_add(ctx, addr, cpu_gpr[base], cpu_gpr[index]); 1968 } 1969 } 1970 1971 static target_ulong pc_relative_pc(DisasContext *ctx) 1972 { 1973 target_ulong pc = ctx->base.pc_next; 1974 1975 if (ctx->hflags & MIPS_HFLAG_BMASK) { 1976 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4; 1977 1978 pc -= branch_bytes; 1979 } 1980 1981 pc &= ~(target_ulong)3; 1982 return pc; 1983 } 1984 1985 /* LWL or LDL, depending on MemOp. */ 1986 static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr, 1987 int mem_idx, MemOp mop) 1988 { 1989 int sizem1 = memop_size(mop) - 1; 1990 TCGv t0 = tcg_temp_new(); 1991 TCGv t1 = tcg_temp_new(); 1992 1993 /* 1994 * Do a byte access to possibly trigger a page 1995 * fault with the unaligned address. 1996 */ 1997 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); 1998 tcg_gen_andi_tl(t1, addr, sizem1); 1999 if (!disas_is_bigendian(ctx)) { 2000 tcg_gen_xori_tl(t1, t1, sizem1); 2001 } 2002 tcg_gen_shli_tl(t1, t1, 3); 2003 tcg_gen_andi_tl(t0, addr, ~sizem1); 2004 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); 2005 tcg_gen_shl_tl(t0, t0, t1); 2006 tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1); 2007 tcg_gen_andc_tl(t1, reg, t1); 2008 tcg_gen_or_tl(reg, t0, t1); 2009 } 2010 2011 /* LWR or LDR, depending on MemOp. */ 2012 static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr, 2013 int mem_idx, MemOp mop) 2014 { 2015 int size = memop_size(mop); 2016 int sizem1 = size - 1; 2017 TCGv t0 = tcg_temp_new(); 2018 TCGv t1 = tcg_temp_new(); 2019 2020 /* 2021 * Do a byte access to possibly trigger a page 2022 * fault with the unaligned address. 2023 */ 2024 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); 2025 tcg_gen_andi_tl(t1, addr, sizem1); 2026 if (disas_is_bigendian(ctx)) { 2027 tcg_gen_xori_tl(t1, t1, sizem1); 2028 } 2029 tcg_gen_shli_tl(t1, t1, 3); 2030 tcg_gen_andi_tl(t0, addr, ~sizem1); 2031 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); 2032 tcg_gen_shr_tl(t0, t0, t1); 2033 tcg_gen_xori_tl(t1, t1, size * 8 - 1); 2034 tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1); 2035 tcg_gen_and_tl(t1, reg, t1); 2036 tcg_gen_or_tl(reg, t0, t1); 2037 } 2038 2039 void gen_lx(DisasContext *ctx, int rd, int base, int index, MemOp mop) 2040 { 2041 TCGv t0 = tcg_temp_new(); 2042 2043 gen_base_index_addr(ctx, t0, base, index); 2044 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | mop); 2045 gen_store_gpr(t0, rd); 2046 } 2047 2048 /* Load */ 2049 static void gen_ld(DisasContext *ctx, uint32_t opc, 2050 int rt, int base, int offset) 2051 { 2052 TCGv t0, t1; 2053 int mem_idx = ctx->mem_idx; 2054 2055 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F | 2056 INSN_LOONGSON3A)) { 2057 /* 2058 * Loongson CPU uses a load to zero register for prefetch. 2059 * We emulate it as a NOP. On other CPU we must perform the 2060 * actual memory access. 2061 */ 2062 return; 2063 } 2064 2065 t0 = tcg_temp_new(); 2066 gen_base_offset_addr(ctx, t0, base, offset); 2067 2068 switch (opc) { 2069 #if defined(TARGET_MIPS64) 2070 case OPC_LWU: 2071 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UL | 2072 ctx->default_tcg_memop_mask); 2073 gen_store_gpr(t0, rt); 2074 break; 2075 case OPC_LD: 2076 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ | 2077 ctx->default_tcg_memop_mask); 2078 gen_store_gpr(t0, rt); 2079 break; 2080 case OPC_LLD: 2081 case R6_OPC_LLD: 2082 op_ld_lld(t0, t0, mem_idx, ctx); 2083 gen_store_gpr(t0, rt); 2084 break; 2085 case OPC_LDL: 2086 t1 = tcg_temp_new(); 2087 gen_load_gpr(t1, rt); 2088 gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2089 gen_store_gpr(t1, rt); 2090 break; 2091 case OPC_LDR: 2092 t1 = tcg_temp_new(); 2093 gen_load_gpr(t1, rt); 2094 gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2095 gen_store_gpr(t1, rt); 2096 break; 2097 case OPC_LDPC: 2098 t1 = tcg_constant_tl(pc_relative_pc(ctx)); 2099 gen_op_addr_add(ctx, t0, t0, t1); 2100 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2101 gen_store_gpr(t0, rt); 2102 break; 2103 #endif 2104 case OPC_LWPC: 2105 t1 = tcg_constant_tl(pc_relative_pc(ctx)); 2106 gen_op_addr_add(ctx, t0, t0, t1); 2107 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL); 2108 gen_store_gpr(t0, rt); 2109 break; 2110 case OPC_LWE: 2111 mem_idx = MIPS_HFLAG_UM; 2112 /* fall through */ 2113 case OPC_LW: 2114 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL | 2115 ctx->default_tcg_memop_mask); 2116 gen_store_gpr(t0, rt); 2117 break; 2118 case OPC_LHE: 2119 mem_idx = MIPS_HFLAG_UM; 2120 /* fall through */ 2121 case OPC_LH: 2122 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SW | 2123 ctx->default_tcg_memop_mask); 2124 gen_store_gpr(t0, rt); 2125 break; 2126 case OPC_LHUE: 2127 mem_idx = MIPS_HFLAG_UM; 2128 /* fall through */ 2129 case OPC_LHU: 2130 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UW | 2131 ctx->default_tcg_memop_mask); 2132 gen_store_gpr(t0, rt); 2133 break; 2134 case OPC_LBE: 2135 mem_idx = MIPS_HFLAG_UM; 2136 /* fall through */ 2137 case OPC_LB: 2138 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); 2139 gen_store_gpr(t0, rt); 2140 break; 2141 case OPC_LBUE: 2142 mem_idx = MIPS_HFLAG_UM; 2143 /* fall through */ 2144 case OPC_LBU: 2145 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); 2146 gen_store_gpr(t0, rt); 2147 break; 2148 case OPC_LWLE: 2149 mem_idx = MIPS_HFLAG_UM; 2150 /* fall through */ 2151 case OPC_LWL: 2152 t1 = tcg_temp_new(); 2153 gen_load_gpr(t1, rt); 2154 gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL); 2155 tcg_gen_ext32s_tl(t1, t1); 2156 gen_store_gpr(t1, rt); 2157 break; 2158 case OPC_LWRE: 2159 mem_idx = MIPS_HFLAG_UM; 2160 /* fall through */ 2161 case OPC_LWR: 2162 t1 = tcg_temp_new(); 2163 gen_load_gpr(t1, rt); 2164 gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL); 2165 tcg_gen_ext32s_tl(t1, t1); 2166 gen_store_gpr(t1, rt); 2167 break; 2168 case OPC_LLE: 2169 mem_idx = MIPS_HFLAG_UM; 2170 /* fall through */ 2171 case OPC_LL: 2172 case R6_OPC_LL: 2173 op_ld_ll(t0, t0, mem_idx, ctx); 2174 gen_store_gpr(t0, rt); 2175 break; 2176 } 2177 } 2178 2179 /* Store */ 2180 static void gen_st(DisasContext *ctx, uint32_t opc, int rt, 2181 int base, int offset) 2182 { 2183 TCGv t0 = tcg_temp_new(); 2184 TCGv t1 = tcg_temp_new(); 2185 int mem_idx = ctx->mem_idx; 2186 2187 gen_base_offset_addr(ctx, t0, base, offset); 2188 gen_load_gpr(t1, rt); 2189 switch (opc) { 2190 #if defined(TARGET_MIPS64) 2191 case OPC_SD: 2192 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UQ | 2193 ctx->default_tcg_memop_mask); 2194 break; 2195 case OPC_SDL: 2196 gen_helper_0e2i(sdl, t1, t0, mem_idx); 2197 break; 2198 case OPC_SDR: 2199 gen_helper_0e2i(sdr, t1, t0, mem_idx); 2200 break; 2201 #endif 2202 case OPC_SWE: 2203 mem_idx = MIPS_HFLAG_UM; 2204 /* fall through */ 2205 case OPC_SW: 2206 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UL | 2207 ctx->default_tcg_memop_mask); 2208 break; 2209 case OPC_SHE: 2210 mem_idx = MIPS_HFLAG_UM; 2211 /* fall through */ 2212 case OPC_SH: 2213 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UW | 2214 ctx->default_tcg_memop_mask); 2215 break; 2216 case OPC_SBE: 2217 mem_idx = MIPS_HFLAG_UM; 2218 /* fall through */ 2219 case OPC_SB: 2220 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); 2221 break; 2222 case OPC_SWLE: 2223 mem_idx = MIPS_HFLAG_UM; 2224 /* fall through */ 2225 case OPC_SWL: 2226 gen_helper_0e2i(swl, t1, t0, mem_idx); 2227 break; 2228 case OPC_SWRE: 2229 mem_idx = MIPS_HFLAG_UM; 2230 /* fall through */ 2231 case OPC_SWR: 2232 gen_helper_0e2i(swr, t1, t0, mem_idx); 2233 break; 2234 } 2235 } 2236 2237 2238 /* Store conditional */ 2239 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, 2240 MemOp tcg_mo, bool eva) 2241 { 2242 TCGv addr, t0, val; 2243 TCGLabel *l1 = gen_new_label(); 2244 TCGLabel *done = gen_new_label(); 2245 2246 t0 = tcg_temp_new(); 2247 addr = tcg_temp_new(); 2248 /* compare the address against that of the preceding LL */ 2249 gen_base_offset_addr(ctx, addr, base, offset); 2250 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); 2251 gen_store_gpr(tcg_constant_tl(0), rt); 2252 tcg_gen_br(done); 2253 2254 gen_set_label(l1); 2255 /* generate cmpxchg */ 2256 val = tcg_temp_new(); 2257 gen_load_gpr(val, rt); 2258 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, 2259 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo); 2260 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); 2261 gen_store_gpr(t0, rt); 2262 2263 gen_set_label(done); 2264 } 2265 2266 /* Load and store */ 2267 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, 2268 TCGv t0) 2269 { 2270 /* 2271 * Don't do NOP if destination is zero: we must perform the actual 2272 * memory access. 2273 */ 2274 switch (opc) { 2275 case OPC_LWC1: 2276 { 2277 TCGv_i32 fp0 = tcg_temp_new_i32(); 2278 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 2279 ctx->default_tcg_memop_mask); 2280 gen_store_fpr32(ctx, fp0, ft); 2281 } 2282 break; 2283 case OPC_SWC1: 2284 { 2285 TCGv_i32 fp0 = tcg_temp_new_i32(); 2286 gen_load_fpr32(ctx, fp0, ft); 2287 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 2288 ctx->default_tcg_memop_mask); 2289 } 2290 break; 2291 case OPC_LDC1: 2292 { 2293 TCGv_i64 fp0 = tcg_temp_new_i64(); 2294 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 2295 ctx->default_tcg_memop_mask); 2296 gen_store_fpr64(ctx, fp0, ft); 2297 } 2298 break; 2299 case OPC_SDC1: 2300 { 2301 TCGv_i64 fp0 = tcg_temp_new_i64(); 2302 gen_load_fpr64(ctx, fp0, ft); 2303 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 2304 ctx->default_tcg_memop_mask); 2305 } 2306 break; 2307 default: 2308 MIPS_INVAL("flt_ldst"); 2309 gen_reserved_instruction(ctx); 2310 break; 2311 } 2312 } 2313 2314 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, 2315 int rs, int16_t imm) 2316 { 2317 TCGv t0 = tcg_temp_new(); 2318 2319 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2320 check_cp1_enabled(ctx); 2321 switch (op) { 2322 case OPC_LDC1: 2323 case OPC_SDC1: 2324 check_insn(ctx, ISA_MIPS2); 2325 /* Fallthrough */ 2326 default: 2327 gen_base_offset_addr(ctx, t0, rs, imm); 2328 gen_flt_ldst(ctx, op, rt, t0); 2329 } 2330 } else { 2331 generate_exception_err(ctx, EXCP_CpU, 1); 2332 } 2333 } 2334 2335 /* Arithmetic with immediate operand */ 2336 static void gen_arith_imm(DisasContext *ctx, uint32_t opc, 2337 int rt, int rs, int imm) 2338 { 2339 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2340 2341 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 2342 /* 2343 * If no destination, treat it as a NOP. 2344 * For addi, we must generate the overflow exception when needed. 2345 */ 2346 return; 2347 } 2348 switch (opc) { 2349 case OPC_ADDI: 2350 { 2351 TCGv t0 = tcg_temp_new(); 2352 TCGv t1 = tcg_temp_new(); 2353 TCGv t2 = tcg_temp_new(); 2354 TCGLabel *l1 = gen_new_label(); 2355 2356 gen_load_gpr(t1, rs); 2357 tcg_gen_addi_tl(t0, t1, uimm); 2358 tcg_gen_ext32s_tl(t0, t0); 2359 2360 tcg_gen_xori_tl(t1, t1, ~uimm); 2361 tcg_gen_xori_tl(t2, t0, uimm); 2362 tcg_gen_and_tl(t1, t1, t2); 2363 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2364 /* operands of same sign, result different sign */ 2365 generate_exception(ctx, EXCP_OVERFLOW); 2366 gen_set_label(l1); 2367 tcg_gen_ext32s_tl(t0, t0); 2368 gen_store_gpr(t0, rt); 2369 } 2370 break; 2371 case OPC_ADDIU: 2372 if (rs != 0) { 2373 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2374 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2375 } else { 2376 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2377 } 2378 break; 2379 #if defined(TARGET_MIPS64) 2380 case OPC_DADDI: 2381 { 2382 TCGv t0 = tcg_temp_new(); 2383 TCGv t1 = tcg_temp_new(); 2384 TCGv t2 = tcg_temp_new(); 2385 TCGLabel *l1 = gen_new_label(); 2386 2387 gen_load_gpr(t1, rs); 2388 tcg_gen_addi_tl(t0, t1, uimm); 2389 2390 tcg_gen_xori_tl(t1, t1, ~uimm); 2391 tcg_gen_xori_tl(t2, t0, uimm); 2392 tcg_gen_and_tl(t1, t1, t2); 2393 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2394 /* operands of same sign, result different sign */ 2395 generate_exception(ctx, EXCP_OVERFLOW); 2396 gen_set_label(l1); 2397 gen_store_gpr(t0, rt); 2398 } 2399 break; 2400 case OPC_DADDIU: 2401 if (rs != 0) { 2402 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2403 } else { 2404 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2405 } 2406 break; 2407 #endif 2408 } 2409 } 2410 2411 /* Logic with immediate operand */ 2412 static void gen_logic_imm(DisasContext *ctx, uint32_t opc, 2413 int rt, int rs, int16_t imm) 2414 { 2415 target_ulong uimm; 2416 2417 if (rt == 0) { 2418 /* If no destination, treat it as a NOP. */ 2419 return; 2420 } 2421 uimm = (uint16_t)imm; 2422 switch (opc) { 2423 case OPC_ANDI: 2424 if (likely(rs != 0)) { 2425 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2426 } else { 2427 tcg_gen_movi_tl(cpu_gpr[rt], 0); 2428 } 2429 break; 2430 case OPC_ORI: 2431 if (rs != 0) { 2432 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2433 } else { 2434 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2435 } 2436 break; 2437 case OPC_XORI: 2438 if (likely(rs != 0)) { 2439 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2440 } else { 2441 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2442 } 2443 break; 2444 case OPC_LUI: 2445 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) { 2446 /* OPC_AUI */ 2447 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16); 2448 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2449 } else { 2450 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 2451 } 2452 break; 2453 2454 default: 2455 break; 2456 } 2457 } 2458 2459 /* Set on less than with immediate operand */ 2460 static void gen_slt_imm(DisasContext *ctx, uint32_t opc, 2461 int rt, int rs, int16_t imm) 2462 { 2463 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2464 TCGv t0; 2465 2466 if (rt == 0) { 2467 /* If no destination, treat it as a NOP. */ 2468 return; 2469 } 2470 t0 = tcg_temp_new(); 2471 gen_load_gpr(t0, rs); 2472 switch (opc) { 2473 case OPC_SLTI: 2474 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); 2475 break; 2476 case OPC_SLTIU: 2477 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); 2478 break; 2479 } 2480 } 2481 2482 /* Shifts with immediate operand */ 2483 static void gen_shift_imm(DisasContext *ctx, uint32_t opc, 2484 int rt, int rs, int16_t imm) 2485 { 2486 target_ulong uimm = ((uint16_t)imm) & 0x1f; 2487 TCGv t0; 2488 2489 if (rt == 0) { 2490 /* If no destination, treat it as a NOP. */ 2491 return; 2492 } 2493 2494 t0 = tcg_temp_new(); 2495 gen_load_gpr(t0, rs); 2496 switch (opc) { 2497 case OPC_SLL: 2498 tcg_gen_shli_tl(t0, t0, uimm); 2499 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2500 break; 2501 case OPC_SRA: 2502 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2503 break; 2504 case OPC_SRL: 2505 if (uimm != 0) { 2506 tcg_gen_ext32u_tl(t0, t0); 2507 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2508 } else { 2509 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2510 } 2511 break; 2512 case OPC_ROTR: 2513 if (uimm != 0) { 2514 TCGv_i32 t1 = tcg_temp_new_i32(); 2515 2516 tcg_gen_trunc_tl_i32(t1, t0); 2517 tcg_gen_rotri_i32(t1, t1, uimm); 2518 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 2519 } else { 2520 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2521 } 2522 break; 2523 #if defined(TARGET_MIPS64) 2524 case OPC_DSLL: 2525 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 2526 break; 2527 case OPC_DSRA: 2528 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2529 break; 2530 case OPC_DSRL: 2531 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2532 break; 2533 case OPC_DROTR: 2534 if (uimm != 0) { 2535 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 2536 } else { 2537 tcg_gen_mov_tl(cpu_gpr[rt], t0); 2538 } 2539 break; 2540 case OPC_DSLL32: 2541 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 2542 break; 2543 case OPC_DSRA32: 2544 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 2545 break; 2546 case OPC_DSRL32: 2547 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 2548 break; 2549 case OPC_DROTR32: 2550 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 2551 break; 2552 #endif 2553 } 2554 } 2555 2556 /* Arithmetic */ 2557 static void gen_arith(DisasContext *ctx, uint32_t opc, 2558 int rd, int rs, int rt) 2559 { 2560 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 2561 && opc != OPC_DADD && opc != OPC_DSUB) { 2562 /* 2563 * If no destination, treat it as a NOP. 2564 * For add & sub, we must generate the overflow exception when needed. 2565 */ 2566 return; 2567 } 2568 2569 switch (opc) { 2570 case OPC_ADD: 2571 { 2572 TCGv t0 = tcg_temp_new(); 2573 TCGv t1 = tcg_temp_new(); 2574 TCGv t2 = tcg_temp_new(); 2575 TCGLabel *l1 = gen_new_label(); 2576 2577 gen_load_gpr(t1, rs); 2578 gen_load_gpr(t2, rt); 2579 tcg_gen_add_tl(t0, t1, t2); 2580 tcg_gen_ext32s_tl(t0, t0); 2581 tcg_gen_xor_tl(t1, t1, t2); 2582 tcg_gen_xor_tl(t2, t0, t2); 2583 tcg_gen_andc_tl(t1, t2, t1); 2584 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2585 /* operands of same sign, result different sign */ 2586 generate_exception(ctx, EXCP_OVERFLOW); 2587 gen_set_label(l1); 2588 gen_store_gpr(t0, rd); 2589 } 2590 break; 2591 case OPC_ADDU: 2592 if (rs != 0 && rt != 0) { 2593 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2594 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2595 } else if (rs == 0 && rt != 0) { 2596 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2597 } else if (rs != 0 && rt == 0) { 2598 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2599 } else { 2600 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2601 } 2602 break; 2603 case OPC_SUB: 2604 { 2605 TCGv t0 = tcg_temp_new(); 2606 TCGv t1 = tcg_temp_new(); 2607 TCGv t2 = tcg_temp_new(); 2608 TCGLabel *l1 = gen_new_label(); 2609 2610 gen_load_gpr(t1, rs); 2611 gen_load_gpr(t2, rt); 2612 tcg_gen_sub_tl(t0, t1, t2); 2613 tcg_gen_ext32s_tl(t0, t0); 2614 tcg_gen_xor_tl(t2, t1, t2); 2615 tcg_gen_xor_tl(t1, t0, t1); 2616 tcg_gen_and_tl(t1, t1, t2); 2617 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2618 /* 2619 * operands of different sign, first operand and the result 2620 * of different sign 2621 */ 2622 generate_exception(ctx, EXCP_OVERFLOW); 2623 gen_set_label(l1); 2624 gen_store_gpr(t0, rd); 2625 } 2626 break; 2627 case OPC_SUBU: 2628 if (rs != 0 && rt != 0) { 2629 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2630 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2631 } else if (rs == 0 && rt != 0) { 2632 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2633 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2634 } else if (rs != 0 && rt == 0) { 2635 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2636 } else { 2637 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2638 } 2639 break; 2640 #if defined(TARGET_MIPS64) 2641 case OPC_DADD: 2642 { 2643 TCGv t0 = tcg_temp_new(); 2644 TCGv t1 = tcg_temp_new(); 2645 TCGv t2 = tcg_temp_new(); 2646 TCGLabel *l1 = gen_new_label(); 2647 2648 gen_load_gpr(t1, rs); 2649 gen_load_gpr(t2, rt); 2650 tcg_gen_add_tl(t0, t1, t2); 2651 tcg_gen_xor_tl(t1, t1, t2); 2652 tcg_gen_xor_tl(t2, t0, t2); 2653 tcg_gen_andc_tl(t1, t2, t1); 2654 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2655 /* operands of same sign, result different sign */ 2656 generate_exception(ctx, EXCP_OVERFLOW); 2657 gen_set_label(l1); 2658 gen_store_gpr(t0, rd); 2659 } 2660 break; 2661 case OPC_DADDU: 2662 if (rs != 0 && rt != 0) { 2663 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2664 } else if (rs == 0 && rt != 0) { 2665 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2666 } else if (rs != 0 && rt == 0) { 2667 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2668 } else { 2669 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2670 } 2671 break; 2672 case OPC_DSUB: 2673 { 2674 TCGv t0 = tcg_temp_new(); 2675 TCGv t1 = tcg_temp_new(); 2676 TCGv t2 = tcg_temp_new(); 2677 TCGLabel *l1 = gen_new_label(); 2678 2679 gen_load_gpr(t1, rs); 2680 gen_load_gpr(t2, rt); 2681 tcg_gen_sub_tl(t0, t1, t2); 2682 tcg_gen_xor_tl(t2, t1, t2); 2683 tcg_gen_xor_tl(t1, t0, t1); 2684 tcg_gen_and_tl(t1, t1, t2); 2685 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2686 /* 2687 * Operands of different sign, first operand and result different 2688 * sign. 2689 */ 2690 generate_exception(ctx, EXCP_OVERFLOW); 2691 gen_set_label(l1); 2692 gen_store_gpr(t0, rd); 2693 } 2694 break; 2695 case OPC_DSUBU: 2696 if (rs != 0 && rt != 0) { 2697 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2698 } else if (rs == 0 && rt != 0) { 2699 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2700 } else if (rs != 0 && rt == 0) { 2701 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2702 } else { 2703 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2704 } 2705 break; 2706 #endif 2707 case OPC_MUL: 2708 if (likely(rs != 0 && rt != 0)) { 2709 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2710 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2711 } else { 2712 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2713 } 2714 break; 2715 } 2716 } 2717 2718 /* Conditional move */ 2719 static void gen_cond_move(DisasContext *ctx, uint32_t opc, 2720 int rd, int rs, int rt) 2721 { 2722 TCGv t0, t1, t2; 2723 2724 if (rd == 0) { 2725 /* If no destination, treat it as a NOP. */ 2726 return; 2727 } 2728 2729 t0 = tcg_temp_new(); 2730 gen_load_gpr(t0, rt); 2731 t1 = tcg_constant_tl(0); 2732 t2 = tcg_temp_new(); 2733 gen_load_gpr(t2, rs); 2734 switch (opc) { 2735 case OPC_MOVN: 2736 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2737 break; 2738 case OPC_MOVZ: 2739 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2740 break; 2741 case OPC_SELNEZ: 2742 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); 2743 break; 2744 case OPC_SELEQZ: 2745 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); 2746 break; 2747 } 2748 } 2749 2750 /* Logic */ 2751 static void gen_logic(DisasContext *ctx, uint32_t opc, 2752 int rd, int rs, int rt) 2753 { 2754 if (rd == 0) { 2755 /* If no destination, treat it as a NOP. */ 2756 return; 2757 } 2758 2759 switch (opc) { 2760 case OPC_AND: 2761 if (likely(rs != 0 && rt != 0)) { 2762 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2763 } else { 2764 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2765 } 2766 break; 2767 case OPC_NOR: 2768 if (rs != 0 && rt != 0) { 2769 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2770 } else if (rs == 0 && rt != 0) { 2771 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 2772 } else if (rs != 0 && rt == 0) { 2773 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 2774 } else { 2775 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 2776 } 2777 break; 2778 case OPC_OR: 2779 if (likely(rs != 0 && rt != 0)) { 2780 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2781 } else if (rs == 0 && rt != 0) { 2782 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2783 } else if (rs != 0 && rt == 0) { 2784 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2785 } else { 2786 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2787 } 2788 break; 2789 case OPC_XOR: 2790 if (likely(rs != 0 && rt != 0)) { 2791 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2792 } else if (rs == 0 && rt != 0) { 2793 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2794 } else if (rs != 0 && rt == 0) { 2795 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2796 } else { 2797 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2798 } 2799 break; 2800 } 2801 } 2802 2803 /* Set on lower than */ 2804 static void gen_slt(DisasContext *ctx, uint32_t opc, 2805 int rd, int rs, int rt) 2806 { 2807 TCGv t0, t1; 2808 2809 if (rd == 0) { 2810 /* If no destination, treat it as a NOP. */ 2811 return; 2812 } 2813 2814 t0 = tcg_temp_new(); 2815 t1 = tcg_temp_new(); 2816 gen_load_gpr(t0, rs); 2817 gen_load_gpr(t1, rt); 2818 switch (opc) { 2819 case OPC_SLT: 2820 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); 2821 break; 2822 case OPC_SLTU: 2823 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); 2824 break; 2825 } 2826 } 2827 2828 /* Shifts */ 2829 static void gen_shift(DisasContext *ctx, uint32_t opc, 2830 int rd, int rs, int rt) 2831 { 2832 TCGv t0, t1; 2833 2834 if (rd == 0) { 2835 /* 2836 * If no destination, treat it as a NOP. 2837 * For add & sub, we must generate the overflow exception when needed. 2838 */ 2839 return; 2840 } 2841 2842 t0 = tcg_temp_new(); 2843 t1 = tcg_temp_new(); 2844 gen_load_gpr(t0, rs); 2845 gen_load_gpr(t1, rt); 2846 switch (opc) { 2847 case OPC_SLLV: 2848 tcg_gen_andi_tl(t0, t0, 0x1f); 2849 tcg_gen_shl_tl(t0, t1, t0); 2850 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2851 break; 2852 case OPC_SRAV: 2853 tcg_gen_andi_tl(t0, t0, 0x1f); 2854 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2855 break; 2856 case OPC_SRLV: 2857 tcg_gen_ext32u_tl(t1, t1); 2858 tcg_gen_andi_tl(t0, t0, 0x1f); 2859 tcg_gen_shr_tl(t0, t1, t0); 2860 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2861 break; 2862 case OPC_ROTRV: 2863 { 2864 TCGv_i32 t2 = tcg_temp_new_i32(); 2865 TCGv_i32 t3 = tcg_temp_new_i32(); 2866 2867 tcg_gen_trunc_tl_i32(t2, t0); 2868 tcg_gen_trunc_tl_i32(t3, t1); 2869 tcg_gen_andi_i32(t2, t2, 0x1f); 2870 tcg_gen_rotr_i32(t2, t3, t2); 2871 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 2872 } 2873 break; 2874 #if defined(TARGET_MIPS64) 2875 case OPC_DSLLV: 2876 tcg_gen_andi_tl(t0, t0, 0x3f); 2877 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 2878 break; 2879 case OPC_DSRAV: 2880 tcg_gen_andi_tl(t0, t0, 0x3f); 2881 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2882 break; 2883 case OPC_DSRLV: 2884 tcg_gen_andi_tl(t0, t0, 0x3f); 2885 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 2886 break; 2887 case OPC_DROTRV: 2888 tcg_gen_andi_tl(t0, t0, 0x3f); 2889 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 2890 break; 2891 #endif 2892 } 2893 } 2894 2895 /* Arithmetic on HI/LO registers */ 2896 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) 2897 { 2898 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 2899 /* Treat as NOP. */ 2900 return; 2901 } 2902 2903 if (acc != 0) { 2904 check_dsp(ctx); 2905 } 2906 2907 switch (opc) { 2908 case OPC_MFHI: 2909 #if defined(TARGET_MIPS64) 2910 if (acc != 0) { 2911 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); 2912 } else 2913 #endif 2914 { 2915 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); 2916 } 2917 break; 2918 case OPC_MFLO: 2919 #if defined(TARGET_MIPS64) 2920 if (acc != 0) { 2921 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); 2922 } else 2923 #endif 2924 { 2925 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); 2926 } 2927 break; 2928 case OPC_MTHI: 2929 if (reg != 0) { 2930 #if defined(TARGET_MIPS64) 2931 if (acc != 0) { 2932 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); 2933 } else 2934 #endif 2935 { 2936 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); 2937 } 2938 } else { 2939 tcg_gen_movi_tl(cpu_HI[acc], 0); 2940 } 2941 break; 2942 case OPC_MTLO: 2943 if (reg != 0) { 2944 #if defined(TARGET_MIPS64) 2945 if (acc != 0) { 2946 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); 2947 } else 2948 #endif 2949 { 2950 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); 2951 } 2952 } else { 2953 tcg_gen_movi_tl(cpu_LO[acc], 0); 2954 } 2955 break; 2956 } 2957 } 2958 2959 static inline void gen_r6_ld(target_long addr, int reg, int memidx, 2960 MemOp memop) 2961 { 2962 TCGv t0 = tcg_temp_new(); 2963 tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop); 2964 gen_store_gpr(t0, reg); 2965 } 2966 2967 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, 2968 int rs) 2969 { 2970 target_long offset; 2971 target_long addr; 2972 2973 switch (MASK_OPC_PCREL_TOP2BITS(opc)) { 2974 case OPC_ADDIUPC: 2975 if (rs != 0) { 2976 offset = sextract32(ctx->opcode << 2, 0, 21); 2977 addr = addr_add(ctx, pc, offset); 2978 tcg_gen_movi_tl(cpu_gpr[rs], addr); 2979 } 2980 break; 2981 case R6_OPC_LWPC: 2982 offset = sextract32(ctx->opcode << 2, 0, 21); 2983 addr = addr_add(ctx, pc, offset); 2984 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_SL); 2985 break; 2986 #if defined(TARGET_MIPS64) 2987 case OPC_LWUPC: 2988 check_mips_64(ctx); 2989 offset = sextract32(ctx->opcode << 2, 0, 21); 2990 addr = addr_add(ctx, pc, offset); 2991 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UL); 2992 break; 2993 #endif 2994 default: 2995 switch (MASK_OPC_PCREL_TOP5BITS(opc)) { 2996 case OPC_AUIPC: 2997 if (rs != 0) { 2998 offset = sextract32(ctx->opcode, 0, 16) << 16; 2999 addr = addr_add(ctx, pc, offset); 3000 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3001 } 3002 break; 3003 case OPC_ALUIPC: 3004 if (rs != 0) { 3005 offset = sextract32(ctx->opcode, 0, 16) << 16; 3006 addr = ~0xFFFF & addr_add(ctx, pc, offset); 3007 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3008 } 3009 break; 3010 #if defined(TARGET_MIPS64) 3011 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */ 3012 case R6_OPC_LDPC + (1 << 16): 3013 case R6_OPC_LDPC + (2 << 16): 3014 case R6_OPC_LDPC + (3 << 16): 3015 check_mips_64(ctx); 3016 offset = sextract32(ctx->opcode << 3, 0, 21); 3017 addr = addr_add(ctx, (pc & ~0x7), offset); 3018 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 3019 break; 3020 #endif 3021 default: 3022 MIPS_INVAL("OPC_PCREL"); 3023 gen_reserved_instruction(ctx); 3024 break; 3025 } 3026 break; 3027 } 3028 } 3029 3030 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) 3031 { 3032 TCGv t0, t1; 3033 3034 if (rd == 0) { 3035 /* Treat as NOP. */ 3036 return; 3037 } 3038 3039 t0 = tcg_temp_new(); 3040 t1 = tcg_temp_new(); 3041 3042 gen_load_gpr(t0, rs); 3043 gen_load_gpr(t1, rt); 3044 3045 switch (opc) { 3046 case R6_OPC_DIV: 3047 { 3048 TCGv t2 = tcg_temp_new(); 3049 TCGv t3 = tcg_temp_new(); 3050 tcg_gen_ext32s_tl(t0, t0); 3051 tcg_gen_ext32s_tl(t1, t1); 3052 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3053 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3054 tcg_gen_and_tl(t2, t2, t3); 3055 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3056 tcg_gen_or_tl(t2, t2, t3); 3057 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3058 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3059 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3060 } 3061 break; 3062 case R6_OPC_MOD: 3063 { 3064 TCGv t2 = tcg_temp_new(); 3065 TCGv t3 = tcg_temp_new(); 3066 tcg_gen_ext32s_tl(t0, t0); 3067 tcg_gen_ext32s_tl(t1, t1); 3068 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3069 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3070 tcg_gen_and_tl(t2, t2, t3); 3071 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3072 tcg_gen_or_tl(t2, t2, t3); 3073 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3074 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3075 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3076 } 3077 break; 3078 case R6_OPC_DIVU: 3079 { 3080 tcg_gen_ext32u_tl(t0, t0); 3081 tcg_gen_ext32u_tl(t1, t1); 3082 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3083 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3084 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3085 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3086 } 3087 break; 3088 case R6_OPC_MODU: 3089 { 3090 tcg_gen_ext32u_tl(t0, t0); 3091 tcg_gen_ext32u_tl(t1, t1); 3092 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3093 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3094 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3095 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3096 } 3097 break; 3098 case R6_OPC_MUL: 3099 { 3100 TCGv_i32 t2 = tcg_temp_new_i32(); 3101 TCGv_i32 t3 = tcg_temp_new_i32(); 3102 tcg_gen_trunc_tl_i32(t2, t0); 3103 tcg_gen_trunc_tl_i32(t3, t1); 3104 tcg_gen_mul_i32(t2, t2, t3); 3105 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3106 } 3107 break; 3108 case R6_OPC_MUH: 3109 { 3110 TCGv_i32 t2 = tcg_temp_new_i32(); 3111 TCGv_i32 t3 = tcg_temp_new_i32(); 3112 tcg_gen_trunc_tl_i32(t2, t0); 3113 tcg_gen_trunc_tl_i32(t3, t1); 3114 tcg_gen_muls2_i32(t2, t3, t2, t3); 3115 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3116 } 3117 break; 3118 case R6_OPC_MULU: 3119 { 3120 TCGv_i32 t2 = tcg_temp_new_i32(); 3121 TCGv_i32 t3 = tcg_temp_new_i32(); 3122 tcg_gen_trunc_tl_i32(t2, t0); 3123 tcg_gen_trunc_tl_i32(t3, t1); 3124 tcg_gen_mul_i32(t2, t2, t3); 3125 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3126 } 3127 break; 3128 case R6_OPC_MUHU: 3129 { 3130 TCGv_i32 t2 = tcg_temp_new_i32(); 3131 TCGv_i32 t3 = tcg_temp_new_i32(); 3132 tcg_gen_trunc_tl_i32(t2, t0); 3133 tcg_gen_trunc_tl_i32(t3, t1); 3134 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3135 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3136 } 3137 break; 3138 #if defined(TARGET_MIPS64) 3139 case R6_OPC_DDIV: 3140 { 3141 TCGv t2 = tcg_temp_new(); 3142 TCGv t3 = tcg_temp_new(); 3143 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3144 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3145 tcg_gen_and_tl(t2, t2, t3); 3146 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3147 tcg_gen_or_tl(t2, t2, t3); 3148 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3149 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3150 } 3151 break; 3152 case R6_OPC_DMOD: 3153 { 3154 TCGv t2 = tcg_temp_new(); 3155 TCGv t3 = tcg_temp_new(); 3156 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3157 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3158 tcg_gen_and_tl(t2, t2, t3); 3159 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3160 tcg_gen_or_tl(t2, t2, t3); 3161 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3162 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3163 } 3164 break; 3165 case R6_OPC_DDIVU: 3166 { 3167 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3168 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3169 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); 3170 } 3171 break; 3172 case R6_OPC_DMODU: 3173 { 3174 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3175 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3176 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); 3177 } 3178 break; 3179 case R6_OPC_DMUL: 3180 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3181 break; 3182 case R6_OPC_DMUH: 3183 { 3184 TCGv t2 = tcg_temp_new(); 3185 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); 3186 } 3187 break; 3188 case R6_OPC_DMULU: 3189 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3190 break; 3191 case R6_OPC_DMUHU: 3192 { 3193 TCGv t2 = tcg_temp_new(); 3194 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); 3195 } 3196 break; 3197 #endif 3198 default: 3199 MIPS_INVAL("r6 mul/div"); 3200 gen_reserved_instruction(ctx); 3201 break; 3202 } 3203 } 3204 3205 #if defined(TARGET_MIPS64) 3206 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) 3207 { 3208 TCGv t0, t1; 3209 3210 t0 = tcg_temp_new(); 3211 t1 = tcg_temp_new(); 3212 3213 gen_load_gpr(t0, rs); 3214 gen_load_gpr(t1, rt); 3215 3216 switch (opc) { 3217 case MMI_OPC_DIV1: 3218 { 3219 TCGv t2 = tcg_temp_new(); 3220 TCGv t3 = tcg_temp_new(); 3221 tcg_gen_ext32s_tl(t0, t0); 3222 tcg_gen_ext32s_tl(t1, t1); 3223 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3224 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3225 tcg_gen_and_tl(t2, t2, t3); 3226 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3227 tcg_gen_or_tl(t2, t2, t3); 3228 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3229 tcg_gen_div_tl(cpu_LO[1], t0, t1); 3230 tcg_gen_rem_tl(cpu_HI[1], t0, t1); 3231 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3232 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3233 } 3234 break; 3235 case MMI_OPC_DIVU1: 3236 { 3237 TCGv t2 = tcg_constant_tl(0); 3238 TCGv t3 = tcg_constant_tl(1); 3239 tcg_gen_ext32u_tl(t0, t0); 3240 tcg_gen_ext32u_tl(t1, t1); 3241 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3242 tcg_gen_divu_tl(cpu_LO[1], t0, t1); 3243 tcg_gen_remu_tl(cpu_HI[1], t0, t1); 3244 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3245 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3246 } 3247 break; 3248 default: 3249 MIPS_INVAL("div1 TX79"); 3250 gen_reserved_instruction(ctx); 3251 break; 3252 } 3253 } 3254 #endif 3255 3256 static void gen_muldiv(DisasContext *ctx, uint32_t opc, 3257 int acc, int rs, int rt) 3258 { 3259 TCGv t0, t1; 3260 3261 t0 = tcg_temp_new(); 3262 t1 = tcg_temp_new(); 3263 3264 gen_load_gpr(t0, rs); 3265 gen_load_gpr(t1, rt); 3266 3267 if (acc != 0) { 3268 check_dsp(ctx); 3269 } 3270 3271 switch (opc) { 3272 case OPC_DIV: 3273 { 3274 TCGv t2 = tcg_temp_new(); 3275 TCGv t3 = tcg_temp_new(); 3276 tcg_gen_ext32s_tl(t0, t0); 3277 tcg_gen_ext32s_tl(t1, t1); 3278 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3279 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3280 tcg_gen_and_tl(t2, t2, t3); 3281 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3282 tcg_gen_or_tl(t2, t2, t3); 3283 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3284 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3285 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3286 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3287 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3288 } 3289 break; 3290 case OPC_DIVU: 3291 { 3292 TCGv t2 = tcg_constant_tl(0); 3293 TCGv t3 = tcg_constant_tl(1); 3294 tcg_gen_ext32u_tl(t0, t0); 3295 tcg_gen_ext32u_tl(t1, t1); 3296 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3297 tcg_gen_divu_tl(cpu_LO[acc], t0, t1); 3298 tcg_gen_remu_tl(cpu_HI[acc], t0, t1); 3299 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3300 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3301 } 3302 break; 3303 case OPC_MULT: 3304 { 3305 TCGv_i32 t2 = tcg_temp_new_i32(); 3306 TCGv_i32 t3 = tcg_temp_new_i32(); 3307 tcg_gen_trunc_tl_i32(t2, t0); 3308 tcg_gen_trunc_tl_i32(t3, t1); 3309 tcg_gen_muls2_i32(t2, t3, t2, t3); 3310 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3311 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3312 } 3313 break; 3314 case OPC_MULTU: 3315 { 3316 TCGv_i32 t2 = tcg_temp_new_i32(); 3317 TCGv_i32 t3 = tcg_temp_new_i32(); 3318 tcg_gen_trunc_tl_i32(t2, t0); 3319 tcg_gen_trunc_tl_i32(t3, t1); 3320 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3321 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3322 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3323 } 3324 break; 3325 #if defined(TARGET_MIPS64) 3326 case OPC_DDIV: 3327 { 3328 TCGv t2 = tcg_temp_new(); 3329 TCGv t3 = tcg_temp_new(); 3330 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3331 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3332 tcg_gen_and_tl(t2, t2, t3); 3333 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3334 tcg_gen_or_tl(t2, t2, t3); 3335 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3336 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3337 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3338 } 3339 break; 3340 case OPC_DDIVU: 3341 { 3342 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3343 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3344 tcg_gen_divu_i64(cpu_LO[acc], t0, t1); 3345 tcg_gen_remu_i64(cpu_HI[acc], t0, t1); 3346 } 3347 break; 3348 case OPC_DMULT: 3349 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3350 break; 3351 case OPC_DMULTU: 3352 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3353 break; 3354 #endif 3355 case OPC_MADD: 3356 { 3357 TCGv_i64 t2 = tcg_temp_new_i64(); 3358 TCGv_i64 t3 = tcg_temp_new_i64(); 3359 3360 tcg_gen_ext_tl_i64(t2, t0); 3361 tcg_gen_ext_tl_i64(t3, t1); 3362 tcg_gen_mul_i64(t2, t2, t3); 3363 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3364 tcg_gen_add_i64(t2, t2, t3); 3365 gen_move_low32(cpu_LO[acc], t2); 3366 gen_move_high32(cpu_HI[acc], t2); 3367 } 3368 break; 3369 case OPC_MADDU: 3370 { 3371 TCGv_i64 t2 = tcg_temp_new_i64(); 3372 TCGv_i64 t3 = tcg_temp_new_i64(); 3373 3374 tcg_gen_ext32u_tl(t0, t0); 3375 tcg_gen_ext32u_tl(t1, t1); 3376 tcg_gen_extu_tl_i64(t2, t0); 3377 tcg_gen_extu_tl_i64(t3, t1); 3378 tcg_gen_mul_i64(t2, t2, t3); 3379 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3380 tcg_gen_add_i64(t2, t2, t3); 3381 gen_move_low32(cpu_LO[acc], t2); 3382 gen_move_high32(cpu_HI[acc], t2); 3383 } 3384 break; 3385 case OPC_MSUB: 3386 { 3387 TCGv_i64 t2 = tcg_temp_new_i64(); 3388 TCGv_i64 t3 = tcg_temp_new_i64(); 3389 3390 tcg_gen_ext_tl_i64(t2, t0); 3391 tcg_gen_ext_tl_i64(t3, t1); 3392 tcg_gen_mul_i64(t2, t2, t3); 3393 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3394 tcg_gen_sub_i64(t2, t3, t2); 3395 gen_move_low32(cpu_LO[acc], t2); 3396 gen_move_high32(cpu_HI[acc], t2); 3397 } 3398 break; 3399 case OPC_MSUBU: 3400 { 3401 TCGv_i64 t2 = tcg_temp_new_i64(); 3402 TCGv_i64 t3 = tcg_temp_new_i64(); 3403 3404 tcg_gen_ext32u_tl(t0, t0); 3405 tcg_gen_ext32u_tl(t1, t1); 3406 tcg_gen_extu_tl_i64(t2, t0); 3407 tcg_gen_extu_tl_i64(t3, t1); 3408 tcg_gen_mul_i64(t2, t2, t3); 3409 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3410 tcg_gen_sub_i64(t2, t3, t2); 3411 gen_move_low32(cpu_LO[acc], t2); 3412 gen_move_high32(cpu_HI[acc], t2); 3413 } 3414 break; 3415 default: 3416 MIPS_INVAL("mul/div"); 3417 gen_reserved_instruction(ctx); 3418 break; 3419 } 3420 } 3421 3422 /* 3423 * These MULT[U] and MADD[U] instructions implemented in for example 3424 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core 3425 * architectures are special three-operand variants with the syntax 3426 * 3427 * MULT[U][1] rd, rs, rt 3428 * 3429 * such that 3430 * 3431 * (rd, LO, HI) <- rs * rt 3432 * 3433 * and 3434 * 3435 * MADD[U][1] rd, rs, rt 3436 * 3437 * such that 3438 * 3439 * (rd, LO, HI) <- (LO, HI) + rs * rt 3440 * 3441 * where the low-order 32-bits of the result is placed into both the 3442 * GPR rd and the special register LO. The high-order 32-bits of the 3443 * result is placed into the special register HI. 3444 * 3445 * If the GPR rd is omitted in assembly language, it is taken to be 0, 3446 * which is the zero register that always reads as 0. 3447 */ 3448 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, 3449 int rd, int rs, int rt) 3450 { 3451 TCGv t0 = tcg_temp_new(); 3452 TCGv t1 = tcg_temp_new(); 3453 int acc = 0; 3454 3455 gen_load_gpr(t0, rs); 3456 gen_load_gpr(t1, rt); 3457 3458 switch (opc) { 3459 case MMI_OPC_MULT1: 3460 acc = 1; 3461 /* Fall through */ 3462 case OPC_MULT: 3463 { 3464 TCGv_i32 t2 = tcg_temp_new_i32(); 3465 TCGv_i32 t3 = tcg_temp_new_i32(); 3466 tcg_gen_trunc_tl_i32(t2, t0); 3467 tcg_gen_trunc_tl_i32(t3, t1); 3468 tcg_gen_muls2_i32(t2, t3, t2, t3); 3469 if (rd) { 3470 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3471 } 3472 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3473 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3474 } 3475 break; 3476 case MMI_OPC_MULTU1: 3477 acc = 1; 3478 /* Fall through */ 3479 case OPC_MULTU: 3480 { 3481 TCGv_i32 t2 = tcg_temp_new_i32(); 3482 TCGv_i32 t3 = tcg_temp_new_i32(); 3483 tcg_gen_trunc_tl_i32(t2, t0); 3484 tcg_gen_trunc_tl_i32(t3, t1); 3485 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3486 if (rd) { 3487 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3488 } 3489 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3490 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3491 } 3492 break; 3493 case MMI_OPC_MADD1: 3494 acc = 1; 3495 /* Fall through */ 3496 case MMI_OPC_MADD: 3497 { 3498 TCGv_i64 t2 = tcg_temp_new_i64(); 3499 TCGv_i64 t3 = tcg_temp_new_i64(); 3500 3501 tcg_gen_ext_tl_i64(t2, t0); 3502 tcg_gen_ext_tl_i64(t3, t1); 3503 tcg_gen_mul_i64(t2, t2, t3); 3504 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3505 tcg_gen_add_i64(t2, t2, t3); 3506 gen_move_low32(cpu_LO[acc], t2); 3507 gen_move_high32(cpu_HI[acc], t2); 3508 if (rd) { 3509 gen_move_low32(cpu_gpr[rd], t2); 3510 } 3511 } 3512 break; 3513 case MMI_OPC_MADDU1: 3514 acc = 1; 3515 /* Fall through */ 3516 case MMI_OPC_MADDU: 3517 { 3518 TCGv_i64 t2 = tcg_temp_new_i64(); 3519 TCGv_i64 t3 = tcg_temp_new_i64(); 3520 3521 tcg_gen_ext32u_tl(t0, t0); 3522 tcg_gen_ext32u_tl(t1, t1); 3523 tcg_gen_extu_tl_i64(t2, t0); 3524 tcg_gen_extu_tl_i64(t3, t1); 3525 tcg_gen_mul_i64(t2, t2, t3); 3526 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3527 tcg_gen_add_i64(t2, t2, t3); 3528 gen_move_low32(cpu_LO[acc], t2); 3529 gen_move_high32(cpu_HI[acc], t2); 3530 if (rd) { 3531 gen_move_low32(cpu_gpr[rd], t2); 3532 } 3533 } 3534 break; 3535 default: 3536 MIPS_INVAL("mul/madd TXx9"); 3537 gen_reserved_instruction(ctx); 3538 break; 3539 } 3540 } 3541 3542 static void gen_cl(DisasContext *ctx, uint32_t opc, 3543 int rd, int rs) 3544 { 3545 TCGv t0; 3546 3547 if (rd == 0) { 3548 /* Treat as NOP. */ 3549 return; 3550 } 3551 t0 = cpu_gpr[rd]; 3552 gen_load_gpr(t0, rs); 3553 3554 switch (opc) { 3555 case OPC_CLO: 3556 case R6_OPC_CLO: 3557 #if defined(TARGET_MIPS64) 3558 case OPC_DCLO: 3559 case R6_OPC_DCLO: 3560 #endif 3561 tcg_gen_not_tl(t0, t0); 3562 break; 3563 } 3564 3565 switch (opc) { 3566 case OPC_CLO: 3567 case R6_OPC_CLO: 3568 case OPC_CLZ: 3569 case R6_OPC_CLZ: 3570 tcg_gen_ext32u_tl(t0, t0); 3571 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); 3572 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); 3573 break; 3574 #if defined(TARGET_MIPS64) 3575 case OPC_DCLO: 3576 case R6_OPC_DCLO: 3577 case OPC_DCLZ: 3578 case R6_OPC_DCLZ: 3579 tcg_gen_clzi_i64(t0, t0, 64); 3580 break; 3581 #endif 3582 } 3583 } 3584 3585 /* Loongson multimedia instructions */ 3586 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) 3587 { 3588 uint32_t opc, shift_max; 3589 TCGv_i64 t0, t1; 3590 TCGCond cond; 3591 3592 opc = MASK_LMMI(ctx->opcode); 3593 check_cp1_enabled(ctx); 3594 3595 t0 = tcg_temp_new_i64(); 3596 t1 = tcg_temp_new_i64(); 3597 gen_load_fpr64(ctx, t0, rs); 3598 gen_load_fpr64(ctx, t1, rt); 3599 3600 switch (opc) { 3601 case OPC_PADDSH: 3602 gen_helper_paddsh(t0, t0, t1); 3603 break; 3604 case OPC_PADDUSH: 3605 gen_helper_paddush(t0, t0, t1); 3606 break; 3607 case OPC_PADDH: 3608 gen_helper_paddh(t0, t0, t1); 3609 break; 3610 case OPC_PADDW: 3611 gen_helper_paddw(t0, t0, t1); 3612 break; 3613 case OPC_PADDSB: 3614 gen_helper_paddsb(t0, t0, t1); 3615 break; 3616 case OPC_PADDUSB: 3617 gen_helper_paddusb(t0, t0, t1); 3618 break; 3619 case OPC_PADDB: 3620 gen_helper_paddb(t0, t0, t1); 3621 break; 3622 3623 case OPC_PSUBSH: 3624 gen_helper_psubsh(t0, t0, t1); 3625 break; 3626 case OPC_PSUBUSH: 3627 gen_helper_psubush(t0, t0, t1); 3628 break; 3629 case OPC_PSUBH: 3630 gen_helper_psubh(t0, t0, t1); 3631 break; 3632 case OPC_PSUBW: 3633 gen_helper_psubw(t0, t0, t1); 3634 break; 3635 case OPC_PSUBSB: 3636 gen_helper_psubsb(t0, t0, t1); 3637 break; 3638 case OPC_PSUBUSB: 3639 gen_helper_psubusb(t0, t0, t1); 3640 break; 3641 case OPC_PSUBB: 3642 gen_helper_psubb(t0, t0, t1); 3643 break; 3644 3645 case OPC_PSHUFH: 3646 gen_helper_pshufh(t0, t0, t1); 3647 break; 3648 case OPC_PACKSSWH: 3649 gen_helper_packsswh(t0, t0, t1); 3650 break; 3651 case OPC_PACKSSHB: 3652 gen_helper_packsshb(t0, t0, t1); 3653 break; 3654 case OPC_PACKUSHB: 3655 gen_helper_packushb(t0, t0, t1); 3656 break; 3657 3658 case OPC_PUNPCKLHW: 3659 gen_helper_punpcklhw(t0, t0, t1); 3660 break; 3661 case OPC_PUNPCKHHW: 3662 gen_helper_punpckhhw(t0, t0, t1); 3663 break; 3664 case OPC_PUNPCKLBH: 3665 gen_helper_punpcklbh(t0, t0, t1); 3666 break; 3667 case OPC_PUNPCKHBH: 3668 gen_helper_punpckhbh(t0, t0, t1); 3669 break; 3670 case OPC_PUNPCKLWD: 3671 gen_helper_punpcklwd(t0, t0, t1); 3672 break; 3673 case OPC_PUNPCKHWD: 3674 gen_helper_punpckhwd(t0, t0, t1); 3675 break; 3676 3677 case OPC_PAVGH: 3678 gen_helper_pavgh(t0, t0, t1); 3679 break; 3680 case OPC_PAVGB: 3681 gen_helper_pavgb(t0, t0, t1); 3682 break; 3683 case OPC_PMAXSH: 3684 gen_helper_pmaxsh(t0, t0, t1); 3685 break; 3686 case OPC_PMINSH: 3687 gen_helper_pminsh(t0, t0, t1); 3688 break; 3689 case OPC_PMAXUB: 3690 gen_helper_pmaxub(t0, t0, t1); 3691 break; 3692 case OPC_PMINUB: 3693 gen_helper_pminub(t0, t0, t1); 3694 break; 3695 3696 case OPC_PCMPEQW: 3697 gen_helper_pcmpeqw(t0, t0, t1); 3698 break; 3699 case OPC_PCMPGTW: 3700 gen_helper_pcmpgtw(t0, t0, t1); 3701 break; 3702 case OPC_PCMPEQH: 3703 gen_helper_pcmpeqh(t0, t0, t1); 3704 break; 3705 case OPC_PCMPGTH: 3706 gen_helper_pcmpgth(t0, t0, t1); 3707 break; 3708 case OPC_PCMPEQB: 3709 gen_helper_pcmpeqb(t0, t0, t1); 3710 break; 3711 case OPC_PCMPGTB: 3712 gen_helper_pcmpgtb(t0, t0, t1); 3713 break; 3714 3715 case OPC_PSLLW: 3716 gen_helper_psllw(t0, t0, t1); 3717 break; 3718 case OPC_PSLLH: 3719 gen_helper_psllh(t0, t0, t1); 3720 break; 3721 case OPC_PSRLW: 3722 gen_helper_psrlw(t0, t0, t1); 3723 break; 3724 case OPC_PSRLH: 3725 gen_helper_psrlh(t0, t0, t1); 3726 break; 3727 case OPC_PSRAW: 3728 gen_helper_psraw(t0, t0, t1); 3729 break; 3730 case OPC_PSRAH: 3731 gen_helper_psrah(t0, t0, t1); 3732 break; 3733 3734 case OPC_PMULLH: 3735 gen_helper_pmullh(t0, t0, t1); 3736 break; 3737 case OPC_PMULHH: 3738 gen_helper_pmulhh(t0, t0, t1); 3739 break; 3740 case OPC_PMULHUH: 3741 gen_helper_pmulhuh(t0, t0, t1); 3742 break; 3743 case OPC_PMADDHW: 3744 gen_helper_pmaddhw(t0, t0, t1); 3745 break; 3746 3747 case OPC_PASUBUB: 3748 gen_helper_pasubub(t0, t0, t1); 3749 break; 3750 case OPC_BIADD: 3751 gen_helper_biadd(t0, t0); 3752 break; 3753 case OPC_PMOVMSKB: 3754 gen_helper_pmovmskb(t0, t0); 3755 break; 3756 3757 case OPC_PADDD: 3758 tcg_gen_add_i64(t0, t0, t1); 3759 break; 3760 case OPC_PSUBD: 3761 tcg_gen_sub_i64(t0, t0, t1); 3762 break; 3763 case OPC_XOR_CP2: 3764 tcg_gen_xor_i64(t0, t0, t1); 3765 break; 3766 case OPC_NOR_CP2: 3767 tcg_gen_nor_i64(t0, t0, t1); 3768 break; 3769 case OPC_AND_CP2: 3770 tcg_gen_and_i64(t0, t0, t1); 3771 break; 3772 case OPC_OR_CP2: 3773 tcg_gen_or_i64(t0, t0, t1); 3774 break; 3775 3776 case OPC_PANDN: 3777 tcg_gen_andc_i64(t0, t1, t0); 3778 break; 3779 3780 case OPC_PINSRH_0: 3781 tcg_gen_deposit_i64(t0, t0, t1, 0, 16); 3782 break; 3783 case OPC_PINSRH_1: 3784 tcg_gen_deposit_i64(t0, t0, t1, 16, 16); 3785 break; 3786 case OPC_PINSRH_2: 3787 tcg_gen_deposit_i64(t0, t0, t1, 32, 16); 3788 break; 3789 case OPC_PINSRH_3: 3790 tcg_gen_deposit_i64(t0, t0, t1, 48, 16); 3791 break; 3792 3793 case OPC_PEXTRH: 3794 tcg_gen_andi_i64(t1, t1, 3); 3795 tcg_gen_shli_i64(t1, t1, 4); 3796 tcg_gen_shr_i64(t0, t0, t1); 3797 tcg_gen_ext16u_i64(t0, t0); 3798 break; 3799 3800 case OPC_ADDU_CP2: 3801 tcg_gen_add_i64(t0, t0, t1); 3802 tcg_gen_ext32s_i64(t0, t0); 3803 break; 3804 case OPC_SUBU_CP2: 3805 tcg_gen_sub_i64(t0, t0, t1); 3806 tcg_gen_ext32s_i64(t0, t0); 3807 break; 3808 3809 case OPC_SLL_CP2: 3810 shift_max = 32; 3811 goto do_shift; 3812 case OPC_SRL_CP2: 3813 shift_max = 32; 3814 goto do_shift; 3815 case OPC_SRA_CP2: 3816 shift_max = 32; 3817 goto do_shift; 3818 case OPC_DSLL_CP2: 3819 shift_max = 64; 3820 goto do_shift; 3821 case OPC_DSRL_CP2: 3822 shift_max = 64; 3823 goto do_shift; 3824 case OPC_DSRA_CP2: 3825 shift_max = 64; 3826 goto do_shift; 3827 do_shift: 3828 /* Make sure shift count isn't TCG undefined behaviour. */ 3829 tcg_gen_andi_i64(t1, t1, shift_max - 1); 3830 3831 switch (opc) { 3832 case OPC_SLL_CP2: 3833 case OPC_DSLL_CP2: 3834 tcg_gen_shl_i64(t0, t0, t1); 3835 break; 3836 case OPC_SRA_CP2: 3837 case OPC_DSRA_CP2: 3838 /* 3839 * Since SRA is UndefinedResult without sign-extended inputs, 3840 * we can treat SRA and DSRA the same. 3841 */ 3842 tcg_gen_sar_i64(t0, t0, t1); 3843 break; 3844 case OPC_SRL_CP2: 3845 /* We want to shift in zeros for SRL; zero-extend first. */ 3846 tcg_gen_ext32u_i64(t0, t0); 3847 /* FALLTHRU */ 3848 case OPC_DSRL_CP2: 3849 tcg_gen_shr_i64(t0, t0, t1); 3850 break; 3851 } 3852 3853 if (shift_max == 32) { 3854 tcg_gen_ext32s_i64(t0, t0); 3855 } 3856 3857 /* Shifts larger than MAX produce zero. */ 3858 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); 3859 tcg_gen_neg_i64(t1, t1); 3860 tcg_gen_and_i64(t0, t0, t1); 3861 break; 3862 3863 case OPC_ADD_CP2: 3864 case OPC_DADD_CP2: 3865 { 3866 TCGv_i64 t2 = tcg_temp_new_i64(); 3867 TCGLabel *lab = gen_new_label(); 3868 3869 tcg_gen_mov_i64(t2, t0); 3870 tcg_gen_add_i64(t0, t1, t2); 3871 if (opc == OPC_ADD_CP2) { 3872 tcg_gen_ext32s_i64(t0, t0); 3873 } 3874 tcg_gen_xor_i64(t1, t1, t2); 3875 tcg_gen_xor_i64(t2, t2, t0); 3876 tcg_gen_andc_i64(t1, t2, t1); 3877 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 3878 generate_exception(ctx, EXCP_OVERFLOW); 3879 gen_set_label(lab); 3880 break; 3881 } 3882 3883 case OPC_SUB_CP2: 3884 case OPC_DSUB_CP2: 3885 { 3886 TCGv_i64 t2 = tcg_temp_new_i64(); 3887 TCGLabel *lab = gen_new_label(); 3888 3889 tcg_gen_mov_i64(t2, t0); 3890 tcg_gen_sub_i64(t0, t1, t2); 3891 if (opc == OPC_SUB_CP2) { 3892 tcg_gen_ext32s_i64(t0, t0); 3893 } 3894 tcg_gen_xor_i64(t1, t1, t2); 3895 tcg_gen_xor_i64(t2, t2, t0); 3896 tcg_gen_and_i64(t1, t1, t2); 3897 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 3898 generate_exception(ctx, EXCP_OVERFLOW); 3899 gen_set_label(lab); 3900 break; 3901 } 3902 3903 case OPC_PMULUW: 3904 tcg_gen_ext32u_i64(t0, t0); 3905 tcg_gen_ext32u_i64(t1, t1); 3906 tcg_gen_mul_i64(t0, t0, t1); 3907 break; 3908 3909 case OPC_SEQU_CP2: 3910 case OPC_SEQ_CP2: 3911 cond = TCG_COND_EQ; 3912 goto do_cc_cond; 3913 break; 3914 case OPC_SLTU_CP2: 3915 cond = TCG_COND_LTU; 3916 goto do_cc_cond; 3917 break; 3918 case OPC_SLT_CP2: 3919 cond = TCG_COND_LT; 3920 goto do_cc_cond; 3921 break; 3922 case OPC_SLEU_CP2: 3923 cond = TCG_COND_LEU; 3924 goto do_cc_cond; 3925 break; 3926 case OPC_SLE_CP2: 3927 cond = TCG_COND_LE; 3928 do_cc_cond: 3929 { 3930 int cc = (ctx->opcode >> 8) & 0x7; 3931 TCGv_i64 t64 = tcg_temp_new_i64(); 3932 TCGv_i32 t32 = tcg_temp_new_i32(); 3933 3934 tcg_gen_setcond_i64(cond, t64, t0, t1); 3935 tcg_gen_extrl_i64_i32(t32, t64); 3936 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, 3937 get_fp_bit(cc), 1); 3938 } 3939 return; 3940 default: 3941 MIPS_INVAL("loongson_cp2"); 3942 gen_reserved_instruction(ctx); 3943 return; 3944 } 3945 3946 gen_store_fpr64(ctx, t0, rd); 3947 } 3948 3949 static void gen_loongson_lswc2(DisasContext *ctx, int rt, 3950 int rs, int rd) 3951 { 3952 TCGv t0, t1; 3953 TCGv_i32 fp0; 3954 #if defined(TARGET_MIPS64) 3955 int lsq_rt1 = ctx->opcode & 0x1f; 3956 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4; 3957 #endif 3958 int shf_offset = sextract32(ctx->opcode, 6, 8); 3959 3960 t0 = tcg_temp_new(); 3961 3962 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { 3963 #if defined(TARGET_MIPS64) 3964 case OPC_GSLQ: 3965 t1 = tcg_temp_new(); 3966 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3967 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3968 ctx->default_tcg_memop_mask); 3969 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 3970 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3971 ctx->default_tcg_memop_mask); 3972 gen_store_gpr(t1, rt); 3973 gen_store_gpr(t0, lsq_rt1); 3974 break; 3975 case OPC_GSLQC1: 3976 check_cp1_enabled(ctx); 3977 t1 = tcg_temp_new(); 3978 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3979 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3980 ctx->default_tcg_memop_mask); 3981 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 3982 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3983 ctx->default_tcg_memop_mask); 3984 gen_store_fpr64(ctx, t1, rt); 3985 gen_store_fpr64(ctx, t0, lsq_rt1); 3986 break; 3987 case OPC_GSSQ: 3988 t1 = tcg_temp_new(); 3989 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3990 gen_load_gpr(t1, rt); 3991 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3992 ctx->default_tcg_memop_mask); 3993 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 3994 gen_load_gpr(t1, lsq_rt1); 3995 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3996 ctx->default_tcg_memop_mask); 3997 break; 3998 case OPC_GSSQC1: 3999 check_cp1_enabled(ctx); 4000 t1 = tcg_temp_new(); 4001 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4002 gen_load_fpr64(ctx, t1, rt); 4003 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4004 ctx->default_tcg_memop_mask); 4005 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4006 gen_load_fpr64(ctx, t1, lsq_rt1); 4007 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4008 ctx->default_tcg_memop_mask); 4009 break; 4010 #endif 4011 case OPC_GSSHFL: 4012 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4013 case OPC_GSLWLC1: 4014 check_cp1_enabled(ctx); 4015 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4016 fp0 = tcg_temp_new_i32(); 4017 gen_load_fpr32(ctx, fp0, rt); 4018 t1 = tcg_temp_new(); 4019 tcg_gen_ext_i32_tl(t1, fp0); 4020 gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 4021 tcg_gen_trunc_tl_i32(fp0, t1); 4022 gen_store_fpr32(ctx, fp0, rt); 4023 break; 4024 case OPC_GSLWRC1: 4025 check_cp1_enabled(ctx); 4026 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4027 fp0 = tcg_temp_new_i32(); 4028 gen_load_fpr32(ctx, fp0, rt); 4029 t1 = tcg_temp_new(); 4030 tcg_gen_ext_i32_tl(t1, fp0); 4031 gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 4032 tcg_gen_trunc_tl_i32(fp0, t1); 4033 gen_store_fpr32(ctx, fp0, rt); 4034 break; 4035 #if defined(TARGET_MIPS64) 4036 case OPC_GSLDLC1: 4037 check_cp1_enabled(ctx); 4038 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4039 t1 = tcg_temp_new(); 4040 gen_load_fpr64(ctx, t1, rt); 4041 gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 4042 gen_store_fpr64(ctx, t1, rt); 4043 break; 4044 case OPC_GSLDRC1: 4045 check_cp1_enabled(ctx); 4046 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4047 t1 = tcg_temp_new(); 4048 gen_load_fpr64(ctx, t1, rt); 4049 gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 4050 gen_store_fpr64(ctx, t1, rt); 4051 break; 4052 #endif 4053 default: 4054 MIPS_INVAL("loongson_gsshfl"); 4055 gen_reserved_instruction(ctx); 4056 break; 4057 } 4058 break; 4059 case OPC_GSSHFS: 4060 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4061 case OPC_GSSWLC1: 4062 check_cp1_enabled(ctx); 4063 t1 = tcg_temp_new(); 4064 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4065 fp0 = tcg_temp_new_i32(); 4066 gen_load_fpr32(ctx, fp0, rt); 4067 tcg_gen_ext_i32_tl(t1, fp0); 4068 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); 4069 break; 4070 case OPC_GSSWRC1: 4071 check_cp1_enabled(ctx); 4072 t1 = tcg_temp_new(); 4073 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4074 fp0 = tcg_temp_new_i32(); 4075 gen_load_fpr32(ctx, fp0, rt); 4076 tcg_gen_ext_i32_tl(t1, fp0); 4077 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); 4078 break; 4079 #if defined(TARGET_MIPS64) 4080 case OPC_GSSDLC1: 4081 check_cp1_enabled(ctx); 4082 t1 = tcg_temp_new(); 4083 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4084 gen_load_fpr64(ctx, t1, rt); 4085 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); 4086 break; 4087 case OPC_GSSDRC1: 4088 check_cp1_enabled(ctx); 4089 t1 = tcg_temp_new(); 4090 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4091 gen_load_fpr64(ctx, t1, rt); 4092 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); 4093 break; 4094 #endif 4095 default: 4096 MIPS_INVAL("loongson_gsshfs"); 4097 gen_reserved_instruction(ctx); 4098 break; 4099 } 4100 break; 4101 default: 4102 MIPS_INVAL("loongson_gslsq"); 4103 gen_reserved_instruction(ctx); 4104 break; 4105 } 4106 } 4107 4108 /* Loongson EXT LDC2/SDC2 */ 4109 static void gen_loongson_lsdc2(DisasContext *ctx, int rt, 4110 int rs, int rd) 4111 { 4112 int offset = sextract32(ctx->opcode, 3, 8); 4113 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode); 4114 TCGv t0, t1; 4115 TCGv_i32 fp0; 4116 4117 /* Pre-conditions */ 4118 switch (opc) { 4119 case OPC_GSLBX: 4120 case OPC_GSLHX: 4121 case OPC_GSLWX: 4122 case OPC_GSLDX: 4123 /* prefetch, implement as NOP */ 4124 if (rt == 0) { 4125 return; 4126 } 4127 break; 4128 case OPC_GSSBX: 4129 case OPC_GSSHX: 4130 case OPC_GSSWX: 4131 case OPC_GSSDX: 4132 break; 4133 case OPC_GSLWXC1: 4134 #if defined(TARGET_MIPS64) 4135 case OPC_GSLDXC1: 4136 #endif 4137 check_cp1_enabled(ctx); 4138 /* prefetch, implement as NOP */ 4139 if (rt == 0) { 4140 return; 4141 } 4142 break; 4143 case OPC_GSSWXC1: 4144 #if defined(TARGET_MIPS64) 4145 case OPC_GSSDXC1: 4146 #endif 4147 check_cp1_enabled(ctx); 4148 break; 4149 default: 4150 MIPS_INVAL("loongson_lsdc2"); 4151 gen_reserved_instruction(ctx); 4152 return; 4153 break; 4154 } 4155 4156 t0 = tcg_temp_new(); 4157 4158 gen_base_offset_addr(ctx, t0, rs, offset); 4159 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4160 4161 switch (opc) { 4162 case OPC_GSLBX: 4163 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); 4164 gen_store_gpr(t0, rt); 4165 break; 4166 case OPC_GSLHX: 4167 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW | 4168 ctx->default_tcg_memop_mask); 4169 gen_store_gpr(t0, rt); 4170 break; 4171 case OPC_GSLWX: 4172 gen_base_offset_addr(ctx, t0, rs, offset); 4173 if (rd) { 4174 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4175 } 4176 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 4177 ctx->default_tcg_memop_mask); 4178 gen_store_gpr(t0, rt); 4179 break; 4180 #if defined(TARGET_MIPS64) 4181 case OPC_GSLDX: 4182 gen_base_offset_addr(ctx, t0, rs, offset); 4183 if (rd) { 4184 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4185 } 4186 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4187 ctx->default_tcg_memop_mask); 4188 gen_store_gpr(t0, rt); 4189 break; 4190 #endif 4191 case OPC_GSLWXC1: 4192 gen_base_offset_addr(ctx, t0, rs, offset); 4193 if (rd) { 4194 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4195 } 4196 fp0 = tcg_temp_new_i32(); 4197 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 4198 ctx->default_tcg_memop_mask); 4199 gen_store_fpr32(ctx, fp0, rt); 4200 break; 4201 #if defined(TARGET_MIPS64) 4202 case OPC_GSLDXC1: 4203 gen_base_offset_addr(ctx, t0, rs, offset); 4204 if (rd) { 4205 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4206 } 4207 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4208 ctx->default_tcg_memop_mask); 4209 gen_store_fpr64(ctx, t0, rt); 4210 break; 4211 #endif 4212 case OPC_GSSBX: 4213 t1 = tcg_temp_new(); 4214 gen_load_gpr(t1, rt); 4215 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); 4216 break; 4217 case OPC_GSSHX: 4218 t1 = tcg_temp_new(); 4219 gen_load_gpr(t1, rt); 4220 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UW | 4221 ctx->default_tcg_memop_mask); 4222 break; 4223 case OPC_GSSWX: 4224 t1 = tcg_temp_new(); 4225 gen_load_gpr(t1, rt); 4226 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 4227 ctx->default_tcg_memop_mask); 4228 break; 4229 #if defined(TARGET_MIPS64) 4230 case OPC_GSSDX: 4231 t1 = tcg_temp_new(); 4232 gen_load_gpr(t1, rt); 4233 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4234 ctx->default_tcg_memop_mask); 4235 break; 4236 #endif 4237 case OPC_GSSWXC1: 4238 fp0 = tcg_temp_new_i32(); 4239 gen_load_fpr32(ctx, fp0, rt); 4240 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 4241 ctx->default_tcg_memop_mask); 4242 break; 4243 #if defined(TARGET_MIPS64) 4244 case OPC_GSSDXC1: 4245 t1 = tcg_temp_new(); 4246 gen_load_fpr64(ctx, t1, rt); 4247 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4248 ctx->default_tcg_memop_mask); 4249 break; 4250 #endif 4251 default: 4252 break; 4253 } 4254 } 4255 4256 /* Traps */ 4257 static void gen_trap(DisasContext *ctx, uint32_t opc, 4258 int rs, int rt, int16_t imm, int code) 4259 { 4260 int cond; 4261 TCGv t0 = tcg_temp_new(); 4262 TCGv t1 = tcg_temp_new(); 4263 4264 cond = 0; 4265 /* Load needed operands */ 4266 switch (opc) { 4267 case OPC_TEQ: 4268 case OPC_TGE: 4269 case OPC_TGEU: 4270 case OPC_TLT: 4271 case OPC_TLTU: 4272 case OPC_TNE: 4273 /* Compare two registers */ 4274 if (rs != rt) { 4275 gen_load_gpr(t0, rs); 4276 gen_load_gpr(t1, rt); 4277 cond = 1; 4278 } 4279 break; 4280 case OPC_TEQI: 4281 case OPC_TGEI: 4282 case OPC_TGEIU: 4283 case OPC_TLTI: 4284 case OPC_TLTIU: 4285 case OPC_TNEI: 4286 /* Compare register to immediate */ 4287 if (rs != 0 || imm != 0) { 4288 gen_load_gpr(t0, rs); 4289 tcg_gen_movi_tl(t1, (int32_t)imm); 4290 cond = 1; 4291 } 4292 break; 4293 } 4294 if (cond == 0) { 4295 switch (opc) { 4296 case OPC_TEQ: /* rs == rs */ 4297 case OPC_TEQI: /* r0 == 0 */ 4298 case OPC_TGE: /* rs >= rs */ 4299 case OPC_TGEI: /* r0 >= 0 */ 4300 case OPC_TGEU: /* rs >= rs unsigned */ 4301 case OPC_TGEIU: /* r0 >= 0 unsigned */ 4302 /* Always trap */ 4303 #ifdef CONFIG_USER_ONLY 4304 /* Pass the break code along to cpu_loop. */ 4305 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 4306 offsetof(CPUMIPSState, error_code)); 4307 #endif 4308 generate_exception_end(ctx, EXCP_TRAP); 4309 break; 4310 case OPC_TLT: /* rs < rs */ 4311 case OPC_TLTI: /* r0 < 0 */ 4312 case OPC_TLTU: /* rs < rs unsigned */ 4313 case OPC_TLTIU: /* r0 < 0 unsigned */ 4314 case OPC_TNE: /* rs != rs */ 4315 case OPC_TNEI: /* r0 != 0 */ 4316 /* Never trap: treat as NOP. */ 4317 break; 4318 } 4319 } else { 4320 TCGLabel *l1 = gen_new_label(); 4321 4322 switch (opc) { 4323 case OPC_TEQ: 4324 case OPC_TEQI: 4325 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 4326 break; 4327 case OPC_TGE: 4328 case OPC_TGEI: 4329 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 4330 break; 4331 case OPC_TGEU: 4332 case OPC_TGEIU: 4333 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 4334 break; 4335 case OPC_TLT: 4336 case OPC_TLTI: 4337 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 4338 break; 4339 case OPC_TLTU: 4340 case OPC_TLTIU: 4341 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 4342 break; 4343 case OPC_TNE: 4344 case OPC_TNEI: 4345 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 4346 break; 4347 } 4348 #ifdef CONFIG_USER_ONLY 4349 /* Pass the break code along to cpu_loop. */ 4350 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 4351 offsetof(CPUMIPSState, error_code)); 4352 #endif 4353 /* Like save_cpu_state, only don't update saved values. */ 4354 if (ctx->base.pc_next != ctx->saved_pc) { 4355 gen_save_pc(ctx->base.pc_next); 4356 } 4357 if (ctx->hflags != ctx->saved_hflags) { 4358 tcg_gen_movi_i32(hflags, ctx->hflags); 4359 } 4360 generate_exception(ctx, EXCP_TRAP); 4361 gen_set_label(l1); 4362 } 4363 } 4364 4365 static void gen_goto_tb(DisasContext *ctx, unsigned tb_slot_idx, 4366 target_ulong dest) 4367 { 4368 if (translator_use_goto_tb(&ctx->base, dest)) { 4369 tcg_gen_goto_tb(tb_slot_idx); 4370 gen_save_pc(dest); 4371 tcg_gen_exit_tb(ctx->base.tb, tb_slot_idx); 4372 } else { 4373 gen_save_pc(dest); 4374 tcg_gen_lookup_and_goto_ptr(); 4375 } 4376 } 4377 4378 /* Branches (before delay slot) */ 4379 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, 4380 int insn_bytes, 4381 int rs, int rt, int32_t offset, 4382 int delayslot_size) 4383 { 4384 target_ulong btgt = -1; 4385 int blink = 0; 4386 int bcond_compute = 0; 4387 TCGv t0 = tcg_temp_new(); 4388 TCGv t1 = tcg_temp_new(); 4389 4390 if (ctx->hflags & MIPS_HFLAG_BMASK) { 4391 #ifdef MIPS_DEBUG_DISAS 4392 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 4393 VADDR_PRIx "\n", ctx->base.pc_next); 4394 #endif 4395 gen_reserved_instruction(ctx); 4396 goto out; 4397 } 4398 4399 /* Load needed operands */ 4400 switch (opc) { 4401 case OPC_BEQ: 4402 case OPC_BEQL: 4403 case OPC_BNE: 4404 case OPC_BNEL: 4405 /* Compare two registers */ 4406 if (rs != rt) { 4407 gen_load_gpr(t0, rs); 4408 gen_load_gpr(t1, rt); 4409 bcond_compute = 1; 4410 } 4411 btgt = ctx->base.pc_next + insn_bytes + offset; 4412 break; 4413 case OPC_BGEZ: 4414 case OPC_BGEZAL: 4415 case OPC_BGEZALL: 4416 case OPC_BGEZL: 4417 case OPC_BGTZ: 4418 case OPC_BGTZL: 4419 case OPC_BLEZ: 4420 case OPC_BLEZL: 4421 case OPC_BLTZ: 4422 case OPC_BLTZAL: 4423 case OPC_BLTZALL: 4424 case OPC_BLTZL: 4425 /* Compare to zero */ 4426 if (rs != 0) { 4427 gen_load_gpr(t0, rs); 4428 bcond_compute = 1; 4429 } 4430 btgt = ctx->base.pc_next + insn_bytes + offset; 4431 break; 4432 case OPC_BPOSGE32: 4433 #if defined(TARGET_MIPS64) 4434 case OPC_BPOSGE64: 4435 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F); 4436 #else 4437 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 4438 #endif 4439 bcond_compute = 1; 4440 btgt = ctx->base.pc_next + insn_bytes + offset; 4441 break; 4442 case OPC_J: 4443 case OPC_JAL: 4444 { 4445 /* Jump to immediate */ 4446 int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000 4447 : 0xF0000000; 4448 btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask) 4449 | (uint32_t)offset; 4450 break; 4451 } 4452 case OPC_JALX: 4453 /* Jump to immediate */ 4454 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) | 4455 (uint32_t)offset; 4456 break; 4457 case OPC_JR: 4458 case OPC_JALR: 4459 /* Jump to register */ 4460 if (offset != 0 && offset != 16) { 4461 /* 4462 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 4463 * others are reserved. 4464 */ 4465 MIPS_INVAL("jump hint"); 4466 gen_reserved_instruction(ctx); 4467 goto out; 4468 } 4469 gen_load_gpr(btarget, rs); 4470 break; 4471 default: 4472 MIPS_INVAL("branch/jump"); 4473 gen_reserved_instruction(ctx); 4474 goto out; 4475 } 4476 if (bcond_compute == 0) { 4477 /* No condition to be computed */ 4478 switch (opc) { 4479 case OPC_BEQ: /* rx == rx */ 4480 case OPC_BEQL: /* rx == rx likely */ 4481 case OPC_BGEZ: /* 0 >= 0 */ 4482 case OPC_BGEZL: /* 0 >= 0 likely */ 4483 case OPC_BLEZ: /* 0 <= 0 */ 4484 case OPC_BLEZL: /* 0 <= 0 likely */ 4485 /* Always take */ 4486 ctx->hflags |= MIPS_HFLAG_B; 4487 break; 4488 case OPC_BGEZAL: /* 0 >= 0 */ 4489 case OPC_BGEZALL: /* 0 >= 0 likely */ 4490 /* Always take and link */ 4491 blink = 31; 4492 ctx->hflags |= MIPS_HFLAG_B; 4493 break; 4494 case OPC_BNE: /* rx != rx */ 4495 case OPC_BGTZ: /* 0 > 0 */ 4496 case OPC_BLTZ: /* 0 < 0 */ 4497 /* Treat as NOP. */ 4498 goto out; 4499 case OPC_BLTZAL: /* 0 < 0 */ 4500 /* 4501 * Handle as an unconditional branch to get correct delay 4502 * slot checking. 4503 */ 4504 blink = 31; 4505 btgt = ctx->base.pc_next + insn_bytes + delayslot_size; 4506 ctx->hflags |= MIPS_HFLAG_B; 4507 break; 4508 case OPC_BLTZALL: /* 0 < 0 likely */ 4509 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 4510 /* Skip the instruction in the delay slot */ 4511 ctx->base.pc_next += 4; 4512 goto out; 4513 case OPC_BNEL: /* rx != rx likely */ 4514 case OPC_BGTZL: /* 0 > 0 likely */ 4515 case OPC_BLTZL: /* 0 < 0 likely */ 4516 /* Skip the instruction in the delay slot */ 4517 ctx->base.pc_next += 4; 4518 goto out; 4519 case OPC_J: 4520 ctx->hflags |= MIPS_HFLAG_B; 4521 break; 4522 case OPC_JALX: 4523 ctx->hflags |= MIPS_HFLAG_BX; 4524 /* Fallthrough */ 4525 case OPC_JAL: 4526 blink = 31; 4527 ctx->hflags |= MIPS_HFLAG_B; 4528 break; 4529 case OPC_JR: 4530 ctx->hflags |= MIPS_HFLAG_BR; 4531 break; 4532 case OPC_JALR: 4533 blink = rt; 4534 ctx->hflags |= MIPS_HFLAG_BR; 4535 break; 4536 default: 4537 MIPS_INVAL("branch/jump"); 4538 gen_reserved_instruction(ctx); 4539 goto out; 4540 } 4541 } else { 4542 switch (opc) { 4543 case OPC_BEQ: 4544 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 4545 goto not_likely; 4546 case OPC_BEQL: 4547 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 4548 goto likely; 4549 case OPC_BNE: 4550 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 4551 goto not_likely; 4552 case OPC_BNEL: 4553 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 4554 goto likely; 4555 case OPC_BGEZ: 4556 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4557 goto not_likely; 4558 case OPC_BGEZL: 4559 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4560 goto likely; 4561 case OPC_BGEZAL: 4562 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4563 blink = 31; 4564 goto not_likely; 4565 case OPC_BGEZALL: 4566 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4567 blink = 31; 4568 goto likely; 4569 case OPC_BGTZ: 4570 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 4571 goto not_likely; 4572 case OPC_BGTZL: 4573 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 4574 goto likely; 4575 case OPC_BLEZ: 4576 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 4577 goto not_likely; 4578 case OPC_BLEZL: 4579 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 4580 goto likely; 4581 case OPC_BLTZ: 4582 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4583 goto not_likely; 4584 case OPC_BLTZL: 4585 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4586 goto likely; 4587 case OPC_BPOSGE32: 4588 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 4589 goto not_likely; 4590 #if defined(TARGET_MIPS64) 4591 case OPC_BPOSGE64: 4592 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64); 4593 goto not_likely; 4594 #endif 4595 case OPC_BLTZAL: 4596 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4597 blink = 31; 4598 not_likely: 4599 ctx->hflags |= MIPS_HFLAG_BC; 4600 break; 4601 case OPC_BLTZALL: 4602 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4603 blink = 31; 4604 likely: 4605 ctx->hflags |= MIPS_HFLAG_BL; 4606 break; 4607 default: 4608 MIPS_INVAL("conditional branch/jump"); 4609 gen_reserved_instruction(ctx); 4610 goto out; 4611 } 4612 } 4613 4614 ctx->btarget = btgt; 4615 4616 switch (delayslot_size) { 4617 case 2: 4618 ctx->hflags |= MIPS_HFLAG_BDS16; 4619 break; 4620 case 4: 4621 ctx->hflags |= MIPS_HFLAG_BDS32; 4622 break; 4623 } 4624 4625 if (blink > 0) { 4626 int post_delay = insn_bytes + delayslot_size; 4627 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); 4628 4629 tcg_gen_movi_tl(cpu_gpr[blink], 4630 ctx->base.pc_next + post_delay + lowbit); 4631 } 4632 4633 out: 4634 if (insn_bytes == 2) { 4635 ctx->hflags |= MIPS_HFLAG_B16; 4636 } 4637 } 4638 4639 4640 /* special3 bitfield operations */ 4641 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, 4642 int rs, int lsb, int msb) 4643 { 4644 TCGv t0 = tcg_temp_new(); 4645 TCGv t1 = tcg_temp_new(); 4646 4647 gen_load_gpr(t1, rs); 4648 switch (opc) { 4649 case OPC_EXT: 4650 if (lsb + msb > 31) { 4651 goto fail; 4652 } 4653 if (msb != 31) { 4654 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 4655 } else { 4656 /* 4657 * The two checks together imply that lsb == 0, 4658 * so this is a simple sign-extension. 4659 */ 4660 tcg_gen_ext32s_tl(t0, t1); 4661 } 4662 break; 4663 #if defined(TARGET_MIPS64) 4664 case OPC_DEXTU: 4665 lsb += 32; 4666 goto do_dext; 4667 case OPC_DEXTM: 4668 msb += 32; 4669 goto do_dext; 4670 case OPC_DEXT: 4671 do_dext: 4672 if (lsb + msb > 63) { 4673 goto fail; 4674 } 4675 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 4676 break; 4677 #endif 4678 case OPC_INS: 4679 if (lsb > msb) { 4680 goto fail; 4681 } 4682 gen_load_gpr(t0, rt); 4683 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 4684 tcg_gen_ext32s_tl(t0, t0); 4685 break; 4686 #if defined(TARGET_MIPS64) 4687 case OPC_DINSU: 4688 lsb += 32; 4689 /* FALLTHRU */ 4690 case OPC_DINSM: 4691 msb += 32; 4692 /* FALLTHRU */ 4693 case OPC_DINS: 4694 if (lsb > msb) { 4695 goto fail; 4696 } 4697 gen_load_gpr(t0, rt); 4698 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 4699 break; 4700 #endif 4701 default: 4702 fail: 4703 MIPS_INVAL("bitops"); 4704 gen_reserved_instruction(ctx); 4705 return; 4706 } 4707 gen_store_gpr(t0, rt); 4708 } 4709 4710 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) 4711 { 4712 TCGv t0; 4713 4714 if (rd == 0) { 4715 /* If no destination, treat it as a NOP. */ 4716 return; 4717 } 4718 4719 t0 = tcg_temp_new(); 4720 gen_load_gpr(t0, rt); 4721 switch (op2) { 4722 case OPC_WSBH: 4723 { 4724 TCGv t1 = tcg_temp_new(); 4725 TCGv t2 = tcg_constant_tl(0x00FF00FF); 4726 4727 tcg_gen_shri_tl(t1, t0, 8); 4728 tcg_gen_and_tl(t1, t1, t2); 4729 tcg_gen_and_tl(t0, t0, t2); 4730 tcg_gen_shli_tl(t0, t0, 8); 4731 tcg_gen_or_tl(t0, t0, t1); 4732 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 4733 } 4734 break; 4735 case OPC_SEB: 4736 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 4737 break; 4738 case OPC_SEH: 4739 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 4740 break; 4741 #if defined(TARGET_MIPS64) 4742 case OPC_DSBH: 4743 { 4744 TCGv t1 = tcg_temp_new(); 4745 TCGv t2 = tcg_constant_tl(0x00FF00FF00FF00FFULL); 4746 4747 tcg_gen_shri_tl(t1, t0, 8); 4748 tcg_gen_and_tl(t1, t1, t2); 4749 tcg_gen_and_tl(t0, t0, t2); 4750 tcg_gen_shli_tl(t0, t0, 8); 4751 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 4752 } 4753 break; 4754 case OPC_DSHD: 4755 { 4756 TCGv t1 = tcg_temp_new(); 4757 TCGv t2 = tcg_constant_tl(0x0000FFFF0000FFFFULL); 4758 4759 tcg_gen_shri_tl(t1, t0, 16); 4760 tcg_gen_and_tl(t1, t1, t2); 4761 tcg_gen_and_tl(t0, t0, t2); 4762 tcg_gen_shli_tl(t0, t0, 16); 4763 tcg_gen_or_tl(t0, t0, t1); 4764 tcg_gen_shri_tl(t1, t0, 32); 4765 tcg_gen_shli_tl(t0, t0, 32); 4766 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 4767 } 4768 break; 4769 #endif 4770 default: 4771 MIPS_INVAL("bsfhl"); 4772 gen_reserved_instruction(ctx); 4773 return; 4774 } 4775 } 4776 4777 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, 4778 int rt, int bits) 4779 { 4780 TCGv t0; 4781 if (rd == 0) { 4782 /* Treat as NOP. */ 4783 return; 4784 } 4785 t0 = tcg_temp_new(); 4786 if (bits == 0 || bits == wordsz) { 4787 if (bits == 0) { 4788 gen_load_gpr(t0, rt); 4789 } else { 4790 gen_load_gpr(t0, rs); 4791 } 4792 switch (wordsz) { 4793 case 32: 4794 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 4795 break; 4796 #if defined(TARGET_MIPS64) 4797 case 64: 4798 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4799 break; 4800 #endif 4801 } 4802 } else { 4803 TCGv t1 = tcg_temp_new(); 4804 gen_load_gpr(t0, rt); 4805 gen_load_gpr(t1, rs); 4806 switch (wordsz) { 4807 case 32: 4808 { 4809 TCGv_i64 t2 = tcg_temp_new_i64(); 4810 tcg_gen_concat_tl_i64(t2, t1, t0); 4811 tcg_gen_shri_i64(t2, t2, 32 - bits); 4812 gen_move_low32(cpu_gpr[rd], t2); 4813 } 4814 break; 4815 #if defined(TARGET_MIPS64) 4816 case 64: 4817 tcg_gen_shli_tl(t0, t0, bits); 4818 tcg_gen_shri_tl(t1, t1, 64 - bits); 4819 tcg_gen_or_tl(cpu_gpr[rd], t1, t0); 4820 break; 4821 #endif 4822 } 4823 } 4824 } 4825 4826 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp) 4827 { 4828 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); 4829 } 4830 4831 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) 4832 { 4833 TCGv t0; 4834 if (rd == 0) { 4835 /* Treat as NOP. */ 4836 return; 4837 } 4838 t0 = tcg_temp_new(); 4839 gen_load_gpr(t0, rt); 4840 switch (opc) { 4841 case OPC_BITSWAP: 4842 gen_helper_bitswap(cpu_gpr[rd], t0); 4843 break; 4844 #if defined(TARGET_MIPS64) 4845 case OPC_DBITSWAP: 4846 gen_helper_dbitswap(cpu_gpr[rd], t0); 4847 break; 4848 #endif 4849 } 4850 } 4851 4852 #ifndef CONFIG_USER_ONLY 4853 /* CP0 (MMU and control) */ 4854 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off) 4855 { 4856 TCGv_i64 t0 = tcg_temp_new_i64(); 4857 TCGv_i64 t1 = tcg_temp_new_i64(); 4858 4859 tcg_gen_ext_tl_i64(t0, arg); 4860 tcg_gen_ld_i64(t1, tcg_env, off); 4861 #if defined(TARGET_MIPS64) 4862 tcg_gen_deposit_i64(t1, t1, t0, 30, 32); 4863 #else 4864 tcg_gen_concat32_i64(t1, t1, t0); 4865 #endif 4866 tcg_gen_st_i64(t1, tcg_env, off); 4867 } 4868 4869 static inline void gen_mthc0_store64(TCGv arg, target_ulong off) 4870 { 4871 TCGv_i64 t0 = tcg_temp_new_i64(); 4872 TCGv_i64 t1 = tcg_temp_new_i64(); 4873 4874 tcg_gen_ext_tl_i64(t0, arg); 4875 tcg_gen_ld_i64(t1, tcg_env, off); 4876 tcg_gen_concat32_i64(t1, t1, t0); 4877 tcg_gen_st_i64(t1, tcg_env, off); 4878 } 4879 4880 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off) 4881 { 4882 TCGv_i64 t0 = tcg_temp_new_i64(); 4883 4884 tcg_gen_ld_i64(t0, tcg_env, off); 4885 #if defined(TARGET_MIPS64) 4886 tcg_gen_shri_i64(t0, t0, 30); 4887 #else 4888 tcg_gen_shri_i64(t0, t0, 32); 4889 #endif 4890 gen_move_low32(arg, t0); 4891 } 4892 4893 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift) 4894 { 4895 TCGv_i64 t0 = tcg_temp_new_i64(); 4896 4897 tcg_gen_ld_i64(t0, tcg_env, off); 4898 tcg_gen_shri_i64(t0, t0, 32 + shift); 4899 gen_move_low32(arg, t0); 4900 } 4901 4902 static inline void gen_mfc0_load32(TCGv arg, target_ulong off) 4903 { 4904 TCGv_i32 t0 = tcg_temp_new_i32(); 4905 4906 tcg_gen_ld_i32(t0, tcg_env, off); 4907 tcg_gen_ext_i32_tl(arg, t0); 4908 } 4909 4910 static inline void gen_mfc0_load64(TCGv arg, target_ulong off) 4911 { 4912 tcg_gen_ld_tl(arg, tcg_env, off); 4913 tcg_gen_ext32s_tl(arg, arg); 4914 } 4915 4916 static inline void gen_mtc0_store32(TCGv arg, target_ulong off) 4917 { 4918 TCGv_i32 t0 = tcg_temp_new_i32(); 4919 4920 tcg_gen_trunc_tl_i32(t0, arg); 4921 tcg_gen_st_i32(t0, tcg_env, off); 4922 } 4923 4924 #define CP0_CHECK(c) \ 4925 do { \ 4926 if (!(c)) { \ 4927 goto cp0_unimplemented; \ 4928 } \ 4929 } while (0) 4930 4931 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) 4932 { 4933 const char *register_name = "invalid"; 4934 4935 switch (reg) { 4936 case CP0_REGISTER_02: 4937 switch (sel) { 4938 case 0: 4939 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 4940 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 4941 register_name = "EntryLo0"; 4942 break; 4943 default: 4944 goto cp0_unimplemented; 4945 } 4946 break; 4947 case CP0_REGISTER_03: 4948 switch (sel) { 4949 case CP0_REG03__ENTRYLO1: 4950 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 4951 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 4952 register_name = "EntryLo1"; 4953 break; 4954 default: 4955 goto cp0_unimplemented; 4956 } 4957 break; 4958 case CP0_REGISTER_17: 4959 switch (sel) { 4960 case CP0_REG17__LLADDR: 4961 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr), 4962 ctx->CP0_LLAddr_shift); 4963 register_name = "LLAddr"; 4964 break; 4965 case CP0_REG17__MAAR: 4966 CP0_CHECK(ctx->mrp); 4967 gen_helper_mfhc0_maar(arg, tcg_env); 4968 register_name = "MAAR"; 4969 break; 4970 default: 4971 goto cp0_unimplemented; 4972 } 4973 break; 4974 case CP0_REGISTER_19: 4975 switch (sel) { 4976 case CP0_REG19__WATCHHI0: 4977 case CP0_REG19__WATCHHI1: 4978 case CP0_REG19__WATCHHI2: 4979 case CP0_REG19__WATCHHI3: 4980 case CP0_REG19__WATCHHI4: 4981 case CP0_REG19__WATCHHI5: 4982 case CP0_REG19__WATCHHI6: 4983 case CP0_REG19__WATCHHI7: 4984 /* upper 32 bits are only available when Config5MI != 0 */ 4985 CP0_CHECK(ctx->mi); 4986 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0); 4987 register_name = "WatchHi"; 4988 break; 4989 default: 4990 goto cp0_unimplemented; 4991 } 4992 break; 4993 case CP0_REGISTER_28: 4994 switch (sel) { 4995 case 0: 4996 case 2: 4997 case 4: 4998 case 6: 4999 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0); 5000 register_name = "TagLo"; 5001 break; 5002 default: 5003 goto cp0_unimplemented; 5004 } 5005 break; 5006 default: 5007 goto cp0_unimplemented; 5008 } 5009 trace_mips_translate_c0("mfhc0", register_name, reg, sel); 5010 return; 5011 5012 cp0_unimplemented: 5013 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", 5014 register_name, reg, sel); 5015 tcg_gen_movi_tl(arg, 0); 5016 } 5017 5018 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5019 { 5020 const char *register_name = "invalid"; 5021 uint64_t mask = ctx->PAMask >> 36; 5022 5023 switch (reg) { 5024 case CP0_REGISTER_02: 5025 switch (sel) { 5026 case 0: 5027 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5028 tcg_gen_andi_tl(arg, arg, mask); 5029 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5030 register_name = "EntryLo0"; 5031 break; 5032 default: 5033 goto cp0_unimplemented; 5034 } 5035 break; 5036 case CP0_REGISTER_03: 5037 switch (sel) { 5038 case CP0_REG03__ENTRYLO1: 5039 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5040 tcg_gen_andi_tl(arg, arg, mask); 5041 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5042 register_name = "EntryLo1"; 5043 break; 5044 default: 5045 goto cp0_unimplemented; 5046 } 5047 break; 5048 case CP0_REGISTER_17: 5049 switch (sel) { 5050 case CP0_REG17__LLADDR: 5051 /* 5052 * LLAddr is read-only (the only exception is bit 0 if LLB is 5053 * supported); the CP0_LLAddr_rw_bitmask does not seem to be 5054 * relevant for modern MIPS cores supporting MTHC0, therefore 5055 * treating MTHC0 to LLAddr as NOP. 5056 */ 5057 register_name = "LLAddr"; 5058 break; 5059 case CP0_REG17__MAAR: 5060 CP0_CHECK(ctx->mrp); 5061 gen_helper_mthc0_maar(tcg_env, arg); 5062 register_name = "MAAR"; 5063 break; 5064 default: 5065 goto cp0_unimplemented; 5066 } 5067 break; 5068 case CP0_REGISTER_19: 5069 switch (sel) { 5070 case CP0_REG19__WATCHHI0: 5071 case CP0_REG19__WATCHHI1: 5072 case CP0_REG19__WATCHHI2: 5073 case CP0_REG19__WATCHHI3: 5074 case CP0_REG19__WATCHHI4: 5075 case CP0_REG19__WATCHHI5: 5076 case CP0_REG19__WATCHHI6: 5077 case CP0_REG19__WATCHHI7: 5078 /* upper 32 bits are only available when Config5MI != 0 */ 5079 CP0_CHECK(ctx->mi); 5080 gen_helper_0e1i(mthc0_watchhi, arg, sel); 5081 register_name = "WatchHi"; 5082 break; 5083 default: 5084 goto cp0_unimplemented; 5085 } 5086 break; 5087 case CP0_REGISTER_28: 5088 switch (sel) { 5089 case 0: 5090 case 2: 5091 case 4: 5092 case 6: 5093 tcg_gen_andi_tl(arg, arg, mask); 5094 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo)); 5095 register_name = "TagLo"; 5096 break; 5097 default: 5098 goto cp0_unimplemented; 5099 } 5100 break; 5101 default: 5102 goto cp0_unimplemented; 5103 } 5104 trace_mips_translate_c0("mthc0", register_name, reg, sel); 5105 return; 5106 5107 cp0_unimplemented: 5108 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", 5109 register_name, reg, sel); 5110 } 5111 5112 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg) 5113 { 5114 if (ctx->insn_flags & ISA_MIPS_R6) { 5115 tcg_gen_movi_tl(arg, 0); 5116 } else { 5117 tcg_gen_movi_tl(arg, ~0); 5118 } 5119 } 5120 5121 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5122 { 5123 const char *register_name = "invalid"; 5124 5125 if (sel != 0) { 5126 check_insn(ctx, ISA_MIPS_R1); 5127 } 5128 5129 switch (reg) { 5130 case CP0_REGISTER_00: 5131 switch (sel) { 5132 case CP0_REG00__INDEX: 5133 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 5134 register_name = "Index"; 5135 break; 5136 case CP0_REG00__MVPCONTROL: 5137 CP0_CHECK(disas_mt_available(ctx)); 5138 gen_helper_mfc0_mvpcontrol(arg, tcg_env); 5139 register_name = "MVPControl"; 5140 break; 5141 case CP0_REG00__MVPCONF0: 5142 CP0_CHECK(disas_mt_available(ctx)); 5143 gen_helper_mfc0_mvpconf0(arg, tcg_env); 5144 register_name = "MVPConf0"; 5145 break; 5146 case CP0_REG00__MVPCONF1: 5147 CP0_CHECK(disas_mt_available(ctx)); 5148 gen_helper_mfc0_mvpconf1(arg, tcg_env); 5149 register_name = "MVPConf1"; 5150 break; 5151 case CP0_REG00__VPCONTROL: 5152 CP0_CHECK(ctx->vp); 5153 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 5154 register_name = "VPControl"; 5155 break; 5156 default: 5157 goto cp0_unimplemented; 5158 } 5159 break; 5160 case CP0_REGISTER_01: 5161 switch (sel) { 5162 case CP0_REG01__RANDOM: 5163 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5164 gen_helper_mfc0_random(arg, tcg_env); 5165 register_name = "Random"; 5166 break; 5167 case CP0_REG01__VPECONTROL: 5168 CP0_CHECK(disas_mt_available(ctx)); 5169 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 5170 register_name = "VPEControl"; 5171 break; 5172 case CP0_REG01__VPECONF0: 5173 CP0_CHECK(disas_mt_available(ctx)); 5174 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 5175 register_name = "VPEConf0"; 5176 break; 5177 case CP0_REG01__VPECONF1: 5178 CP0_CHECK(disas_mt_available(ctx)); 5179 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 5180 register_name = "VPEConf1"; 5181 break; 5182 case CP0_REG01__YQMASK: 5183 CP0_CHECK(disas_mt_available(ctx)); 5184 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 5185 register_name = "YQMask"; 5186 break; 5187 case CP0_REG01__VPESCHEDULE: 5188 CP0_CHECK(disas_mt_available(ctx)); 5189 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 5190 register_name = "VPESchedule"; 5191 break; 5192 case CP0_REG01__VPESCHEFBACK: 5193 CP0_CHECK(disas_mt_available(ctx)); 5194 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5195 register_name = "VPEScheFBack"; 5196 break; 5197 case CP0_REG01__VPEOPT: 5198 CP0_CHECK(disas_mt_available(ctx)); 5199 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 5200 register_name = "VPEOpt"; 5201 break; 5202 default: 5203 goto cp0_unimplemented; 5204 } 5205 break; 5206 case CP0_REGISTER_02: 5207 switch (sel) { 5208 case CP0_REG02__ENTRYLO0: 5209 { 5210 TCGv_i64 tmp = tcg_temp_new_i64(); 5211 tcg_gen_ld_i64(tmp, tcg_env, 5212 offsetof(CPUMIPSState, CP0_EntryLo0)); 5213 #if defined(TARGET_MIPS64) 5214 if (ctx->rxi) { 5215 /* Move RI/XI fields to bits 31:30 */ 5216 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5217 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5218 } 5219 #endif 5220 gen_move_low32(arg, tmp); 5221 } 5222 register_name = "EntryLo0"; 5223 break; 5224 case CP0_REG02__TCSTATUS: 5225 CP0_CHECK(disas_mt_available(ctx)); 5226 gen_helper_mfc0_tcstatus(arg, tcg_env); 5227 register_name = "TCStatus"; 5228 break; 5229 case CP0_REG02__TCBIND: 5230 CP0_CHECK(disas_mt_available(ctx)); 5231 gen_helper_mfc0_tcbind(arg, tcg_env); 5232 register_name = "TCBind"; 5233 break; 5234 case CP0_REG02__TCRESTART: 5235 CP0_CHECK(disas_mt_available(ctx)); 5236 gen_helper_mfc0_tcrestart(arg, tcg_env); 5237 register_name = "TCRestart"; 5238 break; 5239 case CP0_REG02__TCHALT: 5240 CP0_CHECK(disas_mt_available(ctx)); 5241 gen_helper_mfc0_tchalt(arg, tcg_env); 5242 register_name = "TCHalt"; 5243 break; 5244 case CP0_REG02__TCCONTEXT: 5245 CP0_CHECK(disas_mt_available(ctx)); 5246 gen_helper_mfc0_tccontext(arg, tcg_env); 5247 register_name = "TCContext"; 5248 break; 5249 case CP0_REG02__TCSCHEDULE: 5250 CP0_CHECK(disas_mt_available(ctx)); 5251 gen_helper_mfc0_tcschedule(arg, tcg_env); 5252 register_name = "TCSchedule"; 5253 break; 5254 case CP0_REG02__TCSCHEFBACK: 5255 CP0_CHECK(disas_mt_available(ctx)); 5256 gen_helper_mfc0_tcschefback(arg, tcg_env); 5257 register_name = "TCScheFBack"; 5258 break; 5259 default: 5260 goto cp0_unimplemented; 5261 } 5262 break; 5263 case CP0_REGISTER_03: 5264 switch (sel) { 5265 case CP0_REG03__ENTRYLO1: 5266 { 5267 TCGv_i64 tmp = tcg_temp_new_i64(); 5268 tcg_gen_ld_i64(tmp, tcg_env, 5269 offsetof(CPUMIPSState, CP0_EntryLo1)); 5270 #if defined(TARGET_MIPS64) 5271 if (ctx->rxi) { 5272 /* Move RI/XI fields to bits 31:30 */ 5273 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5274 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5275 } 5276 #endif 5277 gen_move_low32(arg, tmp); 5278 } 5279 register_name = "EntryLo1"; 5280 break; 5281 case CP0_REG03__GLOBALNUM: 5282 CP0_CHECK(ctx->vp); 5283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 5284 register_name = "GlobalNumber"; 5285 break; 5286 default: 5287 goto cp0_unimplemented; 5288 } 5289 break; 5290 case CP0_REGISTER_04: 5291 switch (sel) { 5292 case CP0_REG04__CONTEXT: 5293 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context)); 5294 tcg_gen_ext32s_tl(arg, arg); 5295 register_name = "Context"; 5296 break; 5297 case CP0_REG04__CONTEXTCONFIG: 5298 /* SmartMIPS ASE */ 5299 /* gen_helper_mfc0_contextconfig(arg); */ 5300 register_name = "ContextConfig"; 5301 goto cp0_unimplemented; 5302 case CP0_REG04__USERLOCAL: 5303 CP0_CHECK(ctx->ulri); 5304 tcg_gen_ld_tl(arg, tcg_env, 5305 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 5306 tcg_gen_ext32s_tl(arg, arg); 5307 register_name = "UserLocal"; 5308 break; 5309 case CP0_REG04__MMID: 5310 CP0_CHECK(ctx->mi); 5311 gen_helper_mtc0_memorymapid(tcg_env, arg); 5312 register_name = "MMID"; 5313 break; 5314 default: 5315 goto cp0_unimplemented; 5316 } 5317 break; 5318 case CP0_REGISTER_05: 5319 switch (sel) { 5320 case CP0_REG05__PAGEMASK: 5321 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 5322 register_name = "PageMask"; 5323 break; 5324 case CP0_REG05__PAGEGRAIN: 5325 check_insn(ctx, ISA_MIPS_R2); 5326 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 5327 register_name = "PageGrain"; 5328 break; 5329 case CP0_REG05__SEGCTL0: 5330 CP0_CHECK(ctx->sc); 5331 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 5332 tcg_gen_ext32s_tl(arg, arg); 5333 register_name = "SegCtl0"; 5334 break; 5335 case CP0_REG05__SEGCTL1: 5336 CP0_CHECK(ctx->sc); 5337 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 5338 tcg_gen_ext32s_tl(arg, arg); 5339 register_name = "SegCtl1"; 5340 break; 5341 case CP0_REG05__SEGCTL2: 5342 CP0_CHECK(ctx->sc); 5343 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 5344 tcg_gen_ext32s_tl(arg, arg); 5345 register_name = "SegCtl2"; 5346 break; 5347 case CP0_REG05__PWBASE: 5348 check_pw(ctx); 5349 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 5350 register_name = "PWBase"; 5351 break; 5352 case CP0_REG05__PWFIELD: 5353 check_pw(ctx); 5354 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField)); 5355 register_name = "PWField"; 5356 break; 5357 case CP0_REG05__PWSIZE: 5358 check_pw(ctx); 5359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize)); 5360 register_name = "PWSize"; 5361 break; 5362 default: 5363 goto cp0_unimplemented; 5364 } 5365 break; 5366 case CP0_REGISTER_06: 5367 switch (sel) { 5368 case CP0_REG06__WIRED: 5369 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 5370 register_name = "Wired"; 5371 break; 5372 case CP0_REG06__SRSCONF0: 5373 check_insn(ctx, ISA_MIPS_R2); 5374 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 5375 register_name = "SRSConf0"; 5376 break; 5377 case CP0_REG06__SRSCONF1: 5378 check_insn(ctx, ISA_MIPS_R2); 5379 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 5380 register_name = "SRSConf1"; 5381 break; 5382 case CP0_REG06__SRSCONF2: 5383 check_insn(ctx, ISA_MIPS_R2); 5384 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 5385 register_name = "SRSConf2"; 5386 break; 5387 case CP0_REG06__SRSCONF3: 5388 check_insn(ctx, ISA_MIPS_R2); 5389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 5390 register_name = "SRSConf3"; 5391 break; 5392 case CP0_REG06__SRSCONF4: 5393 check_insn(ctx, ISA_MIPS_R2); 5394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 5395 register_name = "SRSConf4"; 5396 break; 5397 case CP0_REG06__PWCTL: 5398 check_pw(ctx); 5399 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 5400 register_name = "PWCtl"; 5401 break; 5402 default: 5403 goto cp0_unimplemented; 5404 } 5405 break; 5406 case CP0_REGISTER_07: 5407 switch (sel) { 5408 case CP0_REG07__HWRENA: 5409 check_insn(ctx, ISA_MIPS_R2); 5410 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 5411 register_name = "HWREna"; 5412 break; 5413 default: 5414 goto cp0_unimplemented; 5415 } 5416 break; 5417 case CP0_REGISTER_08: 5418 switch (sel) { 5419 case CP0_REG08__BADVADDR: 5420 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 5421 tcg_gen_ext32s_tl(arg, arg); 5422 register_name = "BadVAddr"; 5423 break; 5424 case CP0_REG08__BADINSTR: 5425 CP0_CHECK(ctx->bi); 5426 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 5427 register_name = "BadInstr"; 5428 break; 5429 case CP0_REG08__BADINSTRP: 5430 CP0_CHECK(ctx->bp); 5431 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 5432 register_name = "BadInstrP"; 5433 break; 5434 case CP0_REG08__BADINSTRX: 5435 CP0_CHECK(ctx->bi); 5436 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 5437 tcg_gen_andi_tl(arg, arg, ~0xffff); 5438 register_name = "BadInstrX"; 5439 break; 5440 default: 5441 goto cp0_unimplemented; 5442 } 5443 break; 5444 case CP0_REGISTER_09: 5445 switch (sel) { 5446 case CP0_REG09__COUNT: 5447 /* Mark as an IO operation because we read the time. */ 5448 translator_io_start(&ctx->base); 5449 5450 gen_helper_mfc0_count(arg, tcg_env); 5451 /* 5452 * Break the TB to be able to take timer interrupts immediately 5453 * after reading count. DISAS_STOP isn't sufficient, we need to 5454 * ensure we break completely out of translated code. 5455 */ 5456 gen_save_pc(ctx->base.pc_next + 4); 5457 ctx->base.is_jmp = DISAS_EXIT; 5458 register_name = "Count"; 5459 break; 5460 default: 5461 goto cp0_unimplemented; 5462 } 5463 break; 5464 case CP0_REGISTER_10: 5465 switch (sel) { 5466 case CP0_REG10__ENTRYHI: 5467 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi)); 5468 tcg_gen_ext32s_tl(arg, arg); 5469 register_name = "EntryHi"; 5470 break; 5471 default: 5472 goto cp0_unimplemented; 5473 } 5474 break; 5475 case CP0_REGISTER_11: 5476 switch (sel) { 5477 case CP0_REG11__COMPARE: 5478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 5479 register_name = "Compare"; 5480 break; 5481 /* 6,7 are implementation dependent */ 5482 default: 5483 goto cp0_unimplemented; 5484 } 5485 break; 5486 case CP0_REGISTER_12: 5487 switch (sel) { 5488 case CP0_REG12__STATUS: 5489 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 5490 register_name = "Status"; 5491 break; 5492 case CP0_REG12__INTCTL: 5493 check_insn(ctx, ISA_MIPS_R2); 5494 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 5495 register_name = "IntCtl"; 5496 break; 5497 case CP0_REG12__SRSCTL: 5498 check_insn(ctx, ISA_MIPS_R2); 5499 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 5500 register_name = "SRSCtl"; 5501 break; 5502 case CP0_REG12__SRSMAP: 5503 check_insn(ctx, ISA_MIPS_R2); 5504 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 5505 register_name = "SRSMap"; 5506 break; 5507 default: 5508 goto cp0_unimplemented; 5509 } 5510 break; 5511 case CP0_REGISTER_13: 5512 switch (sel) { 5513 case CP0_REG13__CAUSE: 5514 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 5515 register_name = "Cause"; 5516 break; 5517 default: 5518 goto cp0_unimplemented; 5519 } 5520 break; 5521 case CP0_REGISTER_14: 5522 switch (sel) { 5523 case CP0_REG14__EPC: 5524 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 5525 tcg_gen_ext32s_tl(arg, arg); 5526 register_name = "EPC"; 5527 break; 5528 default: 5529 goto cp0_unimplemented; 5530 } 5531 break; 5532 case CP0_REGISTER_15: 5533 switch (sel) { 5534 case CP0_REG15__PRID: 5535 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 5536 register_name = "PRid"; 5537 break; 5538 case CP0_REG15__EBASE: 5539 check_insn(ctx, ISA_MIPS_R2); 5540 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase)); 5541 tcg_gen_ext32s_tl(arg, arg); 5542 register_name = "EBase"; 5543 break; 5544 case CP0_REG15__CMGCRBASE: 5545 check_insn(ctx, ISA_MIPS_R2); 5546 CP0_CHECK(ctx->cmgcr); 5547 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 5548 tcg_gen_ext32s_tl(arg, arg); 5549 register_name = "CMGCRBase"; 5550 break; 5551 default: 5552 goto cp0_unimplemented; 5553 } 5554 break; 5555 case CP0_REGISTER_16: 5556 switch (sel) { 5557 case CP0_REG16__CONFIG: 5558 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 5559 register_name = "Config"; 5560 break; 5561 case CP0_REG16__CONFIG1: 5562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 5563 register_name = "Config1"; 5564 break; 5565 case CP0_REG16__CONFIG2: 5566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 5567 register_name = "Config2"; 5568 break; 5569 case CP0_REG16__CONFIG3: 5570 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 5571 register_name = "Config3"; 5572 break; 5573 case CP0_REG16__CONFIG4: 5574 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 5575 register_name = "Config4"; 5576 break; 5577 case CP0_REG16__CONFIG5: 5578 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 5579 register_name = "Config5"; 5580 break; 5581 /* 6,7 are implementation dependent */ 5582 case CP0_REG16__CONFIG6: 5583 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 5584 register_name = "Config6"; 5585 break; 5586 case CP0_REG16__CONFIG7: 5587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 5588 register_name = "Config7"; 5589 break; 5590 default: 5591 goto cp0_unimplemented; 5592 } 5593 break; 5594 case CP0_REGISTER_17: 5595 switch (sel) { 5596 case CP0_REG17__LLADDR: 5597 gen_helper_mfc0_lladdr(arg, tcg_env); 5598 register_name = "LLAddr"; 5599 break; 5600 case CP0_REG17__MAAR: 5601 CP0_CHECK(ctx->mrp); 5602 gen_helper_mfc0_maar(arg, tcg_env); 5603 register_name = "MAAR"; 5604 break; 5605 case CP0_REG17__MAARI: 5606 CP0_CHECK(ctx->mrp); 5607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 5608 register_name = "MAARI"; 5609 break; 5610 default: 5611 goto cp0_unimplemented; 5612 } 5613 break; 5614 case CP0_REGISTER_18: 5615 switch (sel) { 5616 case CP0_REG18__WATCHLO0: 5617 case CP0_REG18__WATCHLO1: 5618 case CP0_REG18__WATCHLO2: 5619 case CP0_REG18__WATCHLO3: 5620 case CP0_REG18__WATCHLO4: 5621 case CP0_REG18__WATCHLO5: 5622 case CP0_REG18__WATCHLO6: 5623 case CP0_REG18__WATCHLO7: 5624 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 5625 gen_helper_1e0i(mfc0_watchlo, arg, sel); 5626 register_name = "WatchLo"; 5627 break; 5628 default: 5629 goto cp0_unimplemented; 5630 } 5631 break; 5632 case CP0_REGISTER_19: 5633 switch (sel) { 5634 case CP0_REG19__WATCHHI0: 5635 case CP0_REG19__WATCHHI1: 5636 case CP0_REG19__WATCHHI2: 5637 case CP0_REG19__WATCHHI3: 5638 case CP0_REG19__WATCHHI4: 5639 case CP0_REG19__WATCHHI5: 5640 case CP0_REG19__WATCHHI6: 5641 case CP0_REG19__WATCHHI7: 5642 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 5643 gen_helper_1e0i(mfc0_watchhi, arg, sel); 5644 register_name = "WatchHi"; 5645 break; 5646 default: 5647 goto cp0_unimplemented; 5648 } 5649 break; 5650 case CP0_REGISTER_20: 5651 switch (sel) { 5652 case CP0_REG20__XCONTEXT: 5653 #if defined(TARGET_MIPS64) 5654 check_insn(ctx, ISA_MIPS3); 5655 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext)); 5656 tcg_gen_ext32s_tl(arg, arg); 5657 register_name = "XContext"; 5658 break; 5659 #endif 5660 default: 5661 goto cp0_unimplemented; 5662 } 5663 break; 5664 case CP0_REGISTER_21: 5665 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 5666 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5667 switch (sel) { 5668 case 0: 5669 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 5670 register_name = "Framemask"; 5671 break; 5672 default: 5673 goto cp0_unimplemented; 5674 } 5675 break; 5676 case CP0_REGISTER_22: 5677 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 5678 register_name = "'Diagnostic"; /* implementation dependent */ 5679 break; 5680 case CP0_REGISTER_23: 5681 switch (sel) { 5682 case CP0_REG23__DEBUG: 5683 gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */ 5684 register_name = "Debug"; 5685 break; 5686 case CP0_REG23__TRACECONTROL: 5687 /* PDtrace support */ 5688 /* gen_helper_mfc0_tracecontrol(arg); */ 5689 register_name = "TraceControl"; 5690 goto cp0_unimplemented; 5691 case CP0_REG23__TRACECONTROL2: 5692 /* PDtrace support */ 5693 /* gen_helper_mfc0_tracecontrol2(arg); */ 5694 register_name = "TraceControl2"; 5695 goto cp0_unimplemented; 5696 case CP0_REG23__USERTRACEDATA1: 5697 /* PDtrace support */ 5698 /* gen_helper_mfc0_usertracedata1(arg);*/ 5699 register_name = "UserTraceData1"; 5700 goto cp0_unimplemented; 5701 case CP0_REG23__TRACEIBPC: 5702 /* PDtrace support */ 5703 /* gen_helper_mfc0_traceibpc(arg); */ 5704 register_name = "TraceIBPC"; 5705 goto cp0_unimplemented; 5706 case CP0_REG23__TRACEDBPC: 5707 /* PDtrace support */ 5708 /* gen_helper_mfc0_tracedbpc(arg); */ 5709 register_name = "TraceDBPC"; 5710 goto cp0_unimplemented; 5711 default: 5712 goto cp0_unimplemented; 5713 } 5714 break; 5715 case CP0_REGISTER_24: 5716 switch (sel) { 5717 case CP0_REG24__DEPC: 5718 /* EJTAG support */ 5719 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 5720 tcg_gen_ext32s_tl(arg, arg); 5721 register_name = "DEPC"; 5722 break; 5723 default: 5724 goto cp0_unimplemented; 5725 } 5726 break; 5727 case CP0_REGISTER_25: 5728 switch (sel) { 5729 case CP0_REG25__PERFCTL0: 5730 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 5731 register_name = "Performance0"; 5732 break; 5733 case CP0_REG25__PERFCNT0: 5734 /* gen_helper_mfc0_performance1(arg); */ 5735 register_name = "Performance1"; 5736 goto cp0_unimplemented; 5737 case CP0_REG25__PERFCTL1: 5738 /* gen_helper_mfc0_performance2(arg); */ 5739 register_name = "Performance2"; 5740 goto cp0_unimplemented; 5741 case CP0_REG25__PERFCNT1: 5742 /* gen_helper_mfc0_performance3(arg); */ 5743 register_name = "Performance3"; 5744 goto cp0_unimplemented; 5745 case CP0_REG25__PERFCTL2: 5746 /* gen_helper_mfc0_performance4(arg); */ 5747 register_name = "Performance4"; 5748 goto cp0_unimplemented; 5749 case CP0_REG25__PERFCNT2: 5750 /* gen_helper_mfc0_performance5(arg); */ 5751 register_name = "Performance5"; 5752 goto cp0_unimplemented; 5753 case CP0_REG25__PERFCTL3: 5754 /* gen_helper_mfc0_performance6(arg); */ 5755 register_name = "Performance6"; 5756 goto cp0_unimplemented; 5757 case CP0_REG25__PERFCNT3: 5758 /* gen_helper_mfc0_performance7(arg); */ 5759 register_name = "Performance7"; 5760 goto cp0_unimplemented; 5761 default: 5762 goto cp0_unimplemented; 5763 } 5764 break; 5765 case CP0_REGISTER_26: 5766 switch (sel) { 5767 case CP0_REG26__ERRCTL: 5768 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 5769 register_name = "ErrCtl"; 5770 break; 5771 default: 5772 goto cp0_unimplemented; 5773 } 5774 break; 5775 case CP0_REGISTER_27: 5776 switch (sel) { 5777 case CP0_REG27__CACHERR: 5778 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 5779 register_name = "CacheErr"; 5780 break; 5781 default: 5782 goto cp0_unimplemented; 5783 } 5784 break; 5785 case CP0_REGISTER_28: 5786 switch (sel) { 5787 case CP0_REG28__TAGLO: 5788 case CP0_REG28__TAGLO1: 5789 case CP0_REG28__TAGLO2: 5790 case CP0_REG28__TAGLO3: 5791 { 5792 TCGv_i64 tmp = tcg_temp_new_i64(); 5793 tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPUMIPSState, CP0_TagLo)); 5794 gen_move_low32(arg, tmp); 5795 } 5796 register_name = "TagLo"; 5797 break; 5798 case CP0_REG28__DATALO: 5799 case CP0_REG28__DATALO1: 5800 case CP0_REG28__DATALO2: 5801 case CP0_REG28__DATALO3: 5802 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 5803 register_name = "DataLo"; 5804 break; 5805 default: 5806 goto cp0_unimplemented; 5807 } 5808 break; 5809 case CP0_REGISTER_29: 5810 switch (sel) { 5811 case CP0_REG29__TAGHI: 5812 case CP0_REG29__TAGHI1: 5813 case CP0_REG29__TAGHI2: 5814 case CP0_REG29__TAGHI3: 5815 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 5816 register_name = "TagHi"; 5817 break; 5818 case CP0_REG29__DATAHI: 5819 case CP0_REG29__DATAHI1: 5820 case CP0_REG29__DATAHI2: 5821 case CP0_REG29__DATAHI3: 5822 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 5823 register_name = "DataHi"; 5824 break; 5825 default: 5826 goto cp0_unimplemented; 5827 } 5828 break; 5829 case CP0_REGISTER_30: 5830 switch (sel) { 5831 case CP0_REG30__ERROREPC: 5832 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 5833 tcg_gen_ext32s_tl(arg, arg); 5834 register_name = "ErrorEPC"; 5835 break; 5836 default: 5837 goto cp0_unimplemented; 5838 } 5839 break; 5840 case CP0_REGISTER_31: 5841 switch (sel) { 5842 case CP0_REG31__DESAVE: 5843 /* EJTAG support */ 5844 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 5845 register_name = "DESAVE"; 5846 break; 5847 case CP0_REG31__KSCRATCH1: 5848 case CP0_REG31__KSCRATCH2: 5849 case CP0_REG31__KSCRATCH3: 5850 case CP0_REG31__KSCRATCH4: 5851 case CP0_REG31__KSCRATCH5: 5852 case CP0_REG31__KSCRATCH6: 5853 CP0_CHECK(ctx->kscrexist & (1 << sel)); 5854 tcg_gen_ld_tl(arg, tcg_env, 5855 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 5856 tcg_gen_ext32s_tl(arg, arg); 5857 register_name = "KScratch"; 5858 break; 5859 default: 5860 goto cp0_unimplemented; 5861 } 5862 break; 5863 default: 5864 goto cp0_unimplemented; 5865 } 5866 trace_mips_translate_c0("mfc0", register_name, reg, sel); 5867 return; 5868 5869 cp0_unimplemented: 5870 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", 5871 register_name, reg, sel); 5872 gen_mfc0_unimplemented(ctx, arg); 5873 } 5874 5875 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5876 { 5877 const char *register_name = "invalid"; 5878 bool icount; 5879 5880 if (sel != 0) { 5881 check_insn(ctx, ISA_MIPS_R1); 5882 } 5883 5884 icount = translator_io_start(&ctx->base); 5885 5886 switch (reg) { 5887 case CP0_REGISTER_00: 5888 switch (sel) { 5889 case CP0_REG00__INDEX: 5890 gen_helper_mtc0_index(tcg_env, arg); 5891 register_name = "Index"; 5892 break; 5893 case CP0_REG00__MVPCONTROL: 5894 CP0_CHECK(disas_mt_available(ctx)); 5895 gen_helper_mtc0_mvpcontrol(tcg_env, arg); 5896 register_name = "MVPControl"; 5897 break; 5898 case CP0_REG00__MVPCONF0: 5899 CP0_CHECK(disas_mt_available(ctx)); 5900 /* ignored */ 5901 register_name = "MVPConf0"; 5902 break; 5903 case CP0_REG00__MVPCONF1: 5904 CP0_CHECK(disas_mt_available(ctx)); 5905 /* ignored */ 5906 register_name = "MVPConf1"; 5907 break; 5908 case CP0_REG00__VPCONTROL: 5909 CP0_CHECK(ctx->vp); 5910 /* ignored */ 5911 register_name = "VPControl"; 5912 break; 5913 default: 5914 goto cp0_unimplemented; 5915 } 5916 break; 5917 case CP0_REGISTER_01: 5918 switch (sel) { 5919 case CP0_REG01__RANDOM: 5920 /* ignored */ 5921 register_name = "Random"; 5922 break; 5923 case CP0_REG01__VPECONTROL: 5924 CP0_CHECK(disas_mt_available(ctx)); 5925 gen_helper_mtc0_vpecontrol(tcg_env, arg); 5926 register_name = "VPEControl"; 5927 break; 5928 case CP0_REG01__VPECONF0: 5929 CP0_CHECK(disas_mt_available(ctx)); 5930 gen_helper_mtc0_vpeconf0(tcg_env, arg); 5931 register_name = "VPEConf0"; 5932 break; 5933 case CP0_REG01__VPECONF1: 5934 CP0_CHECK(disas_mt_available(ctx)); 5935 gen_helper_mtc0_vpeconf1(tcg_env, arg); 5936 register_name = "VPEConf1"; 5937 break; 5938 case CP0_REG01__YQMASK: 5939 CP0_CHECK(disas_mt_available(ctx)); 5940 gen_helper_mtc0_yqmask(tcg_env, arg); 5941 register_name = "YQMask"; 5942 break; 5943 case CP0_REG01__VPESCHEDULE: 5944 CP0_CHECK(disas_mt_available(ctx)); 5945 tcg_gen_st_tl(arg, tcg_env, 5946 offsetof(CPUMIPSState, CP0_VPESchedule)); 5947 register_name = "VPESchedule"; 5948 break; 5949 case CP0_REG01__VPESCHEFBACK: 5950 CP0_CHECK(disas_mt_available(ctx)); 5951 tcg_gen_st_tl(arg, tcg_env, 5952 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5953 register_name = "VPEScheFBack"; 5954 break; 5955 case CP0_REG01__VPEOPT: 5956 CP0_CHECK(disas_mt_available(ctx)); 5957 gen_helper_mtc0_vpeopt(tcg_env, arg); 5958 register_name = "VPEOpt"; 5959 break; 5960 default: 5961 goto cp0_unimplemented; 5962 } 5963 break; 5964 case CP0_REGISTER_02: 5965 switch (sel) { 5966 case CP0_REG02__ENTRYLO0: 5967 gen_helper_mtc0_entrylo0(tcg_env, arg); 5968 register_name = "EntryLo0"; 5969 break; 5970 case CP0_REG02__TCSTATUS: 5971 CP0_CHECK(disas_mt_available(ctx)); 5972 gen_helper_mtc0_tcstatus(tcg_env, arg); 5973 register_name = "TCStatus"; 5974 break; 5975 case CP0_REG02__TCBIND: 5976 CP0_CHECK(disas_mt_available(ctx)); 5977 gen_helper_mtc0_tcbind(tcg_env, arg); 5978 register_name = "TCBind"; 5979 break; 5980 case CP0_REG02__TCRESTART: 5981 CP0_CHECK(disas_mt_available(ctx)); 5982 gen_helper_mtc0_tcrestart(tcg_env, arg); 5983 register_name = "TCRestart"; 5984 break; 5985 case CP0_REG02__TCHALT: 5986 CP0_CHECK(disas_mt_available(ctx)); 5987 gen_helper_mtc0_tchalt(tcg_env, arg); 5988 register_name = "TCHalt"; 5989 break; 5990 case CP0_REG02__TCCONTEXT: 5991 CP0_CHECK(disas_mt_available(ctx)); 5992 gen_helper_mtc0_tccontext(tcg_env, arg); 5993 register_name = "TCContext"; 5994 break; 5995 case CP0_REG02__TCSCHEDULE: 5996 CP0_CHECK(disas_mt_available(ctx)); 5997 gen_helper_mtc0_tcschedule(tcg_env, arg); 5998 register_name = "TCSchedule"; 5999 break; 6000 case CP0_REG02__TCSCHEFBACK: 6001 CP0_CHECK(disas_mt_available(ctx)); 6002 gen_helper_mtc0_tcschefback(tcg_env, arg); 6003 register_name = "TCScheFBack"; 6004 break; 6005 default: 6006 goto cp0_unimplemented; 6007 } 6008 break; 6009 case CP0_REGISTER_03: 6010 switch (sel) { 6011 case CP0_REG03__ENTRYLO1: 6012 gen_helper_mtc0_entrylo1(tcg_env, arg); 6013 register_name = "EntryLo1"; 6014 break; 6015 case CP0_REG03__GLOBALNUM: 6016 CP0_CHECK(ctx->vp); 6017 /* ignored */ 6018 register_name = "GlobalNumber"; 6019 break; 6020 default: 6021 goto cp0_unimplemented; 6022 } 6023 break; 6024 case CP0_REGISTER_04: 6025 switch (sel) { 6026 case CP0_REG04__CONTEXT: 6027 gen_helper_mtc0_context(tcg_env, arg); 6028 register_name = "Context"; 6029 break; 6030 case CP0_REG04__CONTEXTCONFIG: 6031 /* SmartMIPS ASE */ 6032 /* gen_helper_mtc0_contextconfig(arg); */ 6033 register_name = "ContextConfig"; 6034 goto cp0_unimplemented; 6035 case CP0_REG04__USERLOCAL: 6036 CP0_CHECK(ctx->ulri); 6037 tcg_gen_st_tl(arg, tcg_env, 6038 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6039 register_name = "UserLocal"; 6040 break; 6041 case CP0_REG04__MMID: 6042 CP0_CHECK(ctx->mi); 6043 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 6044 register_name = "MMID"; 6045 break; 6046 default: 6047 goto cp0_unimplemented; 6048 } 6049 break; 6050 case CP0_REGISTER_05: 6051 switch (sel) { 6052 case CP0_REG05__PAGEMASK: 6053 gen_helper_mtc0_pagemask(tcg_env, arg); 6054 register_name = "PageMask"; 6055 break; 6056 case CP0_REG05__PAGEGRAIN: 6057 check_insn(ctx, ISA_MIPS_R2); 6058 gen_helper_mtc0_pagegrain(tcg_env, arg); 6059 register_name = "PageGrain"; 6060 ctx->base.is_jmp = DISAS_STOP; 6061 break; 6062 case CP0_REG05__SEGCTL0: 6063 CP0_CHECK(ctx->sc); 6064 gen_helper_mtc0_segctl0(tcg_env, arg); 6065 register_name = "SegCtl0"; 6066 break; 6067 case CP0_REG05__SEGCTL1: 6068 CP0_CHECK(ctx->sc); 6069 gen_helper_mtc0_segctl1(tcg_env, arg); 6070 register_name = "SegCtl1"; 6071 break; 6072 case CP0_REG05__SEGCTL2: 6073 CP0_CHECK(ctx->sc); 6074 gen_helper_mtc0_segctl2(tcg_env, arg); 6075 register_name = "SegCtl2"; 6076 break; 6077 case CP0_REG05__PWBASE: 6078 check_pw(ctx); 6079 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 6080 register_name = "PWBase"; 6081 break; 6082 case CP0_REG05__PWFIELD: 6083 check_pw(ctx); 6084 gen_helper_mtc0_pwfield(tcg_env, arg); 6085 register_name = "PWField"; 6086 break; 6087 case CP0_REG05__PWSIZE: 6088 check_pw(ctx); 6089 gen_helper_mtc0_pwsize(tcg_env, arg); 6090 register_name = "PWSize"; 6091 break; 6092 default: 6093 goto cp0_unimplemented; 6094 } 6095 break; 6096 case CP0_REGISTER_06: 6097 switch (sel) { 6098 case CP0_REG06__WIRED: 6099 gen_helper_mtc0_wired(tcg_env, arg); 6100 register_name = "Wired"; 6101 break; 6102 case CP0_REG06__SRSCONF0: 6103 check_insn(ctx, ISA_MIPS_R2); 6104 gen_helper_mtc0_srsconf0(tcg_env, arg); 6105 register_name = "SRSConf0"; 6106 break; 6107 case CP0_REG06__SRSCONF1: 6108 check_insn(ctx, ISA_MIPS_R2); 6109 gen_helper_mtc0_srsconf1(tcg_env, arg); 6110 register_name = "SRSConf1"; 6111 break; 6112 case CP0_REG06__SRSCONF2: 6113 check_insn(ctx, ISA_MIPS_R2); 6114 gen_helper_mtc0_srsconf2(tcg_env, arg); 6115 register_name = "SRSConf2"; 6116 break; 6117 case CP0_REG06__SRSCONF3: 6118 check_insn(ctx, ISA_MIPS_R2); 6119 gen_helper_mtc0_srsconf3(tcg_env, arg); 6120 register_name = "SRSConf3"; 6121 break; 6122 case CP0_REG06__SRSCONF4: 6123 check_insn(ctx, ISA_MIPS_R2); 6124 gen_helper_mtc0_srsconf4(tcg_env, arg); 6125 register_name = "SRSConf4"; 6126 break; 6127 case CP0_REG06__PWCTL: 6128 check_pw(ctx); 6129 gen_helper_mtc0_pwctl(tcg_env, arg); 6130 register_name = "PWCtl"; 6131 break; 6132 default: 6133 goto cp0_unimplemented; 6134 } 6135 break; 6136 case CP0_REGISTER_07: 6137 switch (sel) { 6138 case CP0_REG07__HWRENA: 6139 check_insn(ctx, ISA_MIPS_R2); 6140 gen_helper_mtc0_hwrena(tcg_env, arg); 6141 ctx->base.is_jmp = DISAS_STOP; 6142 register_name = "HWREna"; 6143 break; 6144 default: 6145 goto cp0_unimplemented; 6146 } 6147 break; 6148 case CP0_REGISTER_08: 6149 switch (sel) { 6150 case CP0_REG08__BADVADDR: 6151 /* ignored */ 6152 register_name = "BadVAddr"; 6153 break; 6154 case CP0_REG08__BADINSTR: 6155 /* ignored */ 6156 register_name = "BadInstr"; 6157 break; 6158 case CP0_REG08__BADINSTRP: 6159 /* ignored */ 6160 register_name = "BadInstrP"; 6161 break; 6162 case CP0_REG08__BADINSTRX: 6163 /* ignored */ 6164 register_name = "BadInstrX"; 6165 break; 6166 default: 6167 goto cp0_unimplemented; 6168 } 6169 break; 6170 case CP0_REGISTER_09: 6171 switch (sel) { 6172 case CP0_REG09__COUNT: 6173 gen_helper_mtc0_count(tcg_env, arg); 6174 register_name = "Count"; 6175 break; 6176 default: 6177 goto cp0_unimplemented; 6178 } 6179 break; 6180 case CP0_REGISTER_10: 6181 switch (sel) { 6182 case CP0_REG10__ENTRYHI: 6183 gen_helper_mtc0_entryhi(tcg_env, arg); 6184 register_name = "EntryHi"; 6185 break; 6186 default: 6187 goto cp0_unimplemented; 6188 } 6189 break; 6190 case CP0_REGISTER_11: 6191 switch (sel) { 6192 case CP0_REG11__COMPARE: 6193 gen_helper_mtc0_compare(tcg_env, arg); 6194 register_name = "Compare"; 6195 break; 6196 /* 6,7 are implementation dependent */ 6197 default: 6198 goto cp0_unimplemented; 6199 } 6200 break; 6201 case CP0_REGISTER_12: 6202 switch (sel) { 6203 case CP0_REG12__STATUS: 6204 save_cpu_state(ctx, 1); 6205 gen_helper_mtc0_status(tcg_env, arg); 6206 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6207 gen_save_pc(ctx->base.pc_next + 4); 6208 ctx->base.is_jmp = DISAS_EXIT; 6209 register_name = "Status"; 6210 break; 6211 case CP0_REG12__INTCTL: 6212 check_insn(ctx, ISA_MIPS_R2); 6213 gen_helper_mtc0_intctl(tcg_env, arg); 6214 /* Stop translation as we may have switched the execution mode */ 6215 ctx->base.is_jmp = DISAS_STOP; 6216 register_name = "IntCtl"; 6217 break; 6218 case CP0_REG12__SRSCTL: 6219 check_insn(ctx, ISA_MIPS_R2); 6220 gen_helper_mtc0_srsctl(tcg_env, arg); 6221 /* Stop translation as we may have switched the execution mode */ 6222 ctx->base.is_jmp = DISAS_STOP; 6223 register_name = "SRSCtl"; 6224 break; 6225 case CP0_REG12__SRSMAP: 6226 check_insn(ctx, ISA_MIPS_R2); 6227 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6228 /* Stop translation as we may have switched the execution mode */ 6229 ctx->base.is_jmp = DISAS_STOP; 6230 register_name = "SRSMap"; 6231 break; 6232 default: 6233 goto cp0_unimplemented; 6234 } 6235 break; 6236 case CP0_REGISTER_13: 6237 switch (sel) { 6238 case CP0_REG13__CAUSE: 6239 save_cpu_state(ctx, 1); 6240 gen_helper_mtc0_cause(tcg_env, arg); 6241 /* 6242 * Stop translation as we may have triggered an interrupt. 6243 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6244 * translated code to check for pending interrupts. 6245 */ 6246 gen_save_pc(ctx->base.pc_next + 4); 6247 ctx->base.is_jmp = DISAS_EXIT; 6248 register_name = "Cause"; 6249 break; 6250 default: 6251 goto cp0_unimplemented; 6252 } 6253 break; 6254 case CP0_REGISTER_14: 6255 switch (sel) { 6256 case CP0_REG14__EPC: 6257 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 6258 register_name = "EPC"; 6259 break; 6260 default: 6261 goto cp0_unimplemented; 6262 } 6263 break; 6264 case CP0_REGISTER_15: 6265 switch (sel) { 6266 case CP0_REG15__PRID: 6267 /* ignored */ 6268 register_name = "PRid"; 6269 break; 6270 case CP0_REG15__EBASE: 6271 check_insn(ctx, ISA_MIPS_R2); 6272 gen_helper_mtc0_ebase(tcg_env, arg); 6273 register_name = "EBase"; 6274 break; 6275 default: 6276 goto cp0_unimplemented; 6277 } 6278 break; 6279 case CP0_REGISTER_16: 6280 switch (sel) { 6281 case CP0_REG16__CONFIG: 6282 gen_helper_mtc0_config0(tcg_env, arg); 6283 register_name = "Config"; 6284 /* Stop translation as we may have switched the execution mode */ 6285 ctx->base.is_jmp = DISAS_STOP; 6286 break; 6287 case CP0_REG16__CONFIG1: 6288 /* ignored, read only */ 6289 register_name = "Config1"; 6290 break; 6291 case CP0_REG16__CONFIG2: 6292 gen_helper_mtc0_config2(tcg_env, arg); 6293 register_name = "Config2"; 6294 /* Stop translation as we may have switched the execution mode */ 6295 ctx->base.is_jmp = DISAS_STOP; 6296 break; 6297 case CP0_REG16__CONFIG3: 6298 gen_helper_mtc0_config3(tcg_env, arg); 6299 register_name = "Config3"; 6300 /* Stop translation as we may have switched the execution mode */ 6301 ctx->base.is_jmp = DISAS_STOP; 6302 break; 6303 case CP0_REG16__CONFIG4: 6304 gen_helper_mtc0_config4(tcg_env, arg); 6305 register_name = "Config4"; 6306 ctx->base.is_jmp = DISAS_STOP; 6307 break; 6308 case CP0_REG16__CONFIG5: 6309 gen_helper_mtc0_config5(tcg_env, arg); 6310 register_name = "Config5"; 6311 /* Stop translation as we may have switched the execution mode */ 6312 ctx->base.is_jmp = DISAS_STOP; 6313 break; 6314 /* 6,7 are implementation dependent */ 6315 case CP0_REG16__CONFIG6: 6316 /* ignored */ 6317 register_name = "Config6"; 6318 break; 6319 case CP0_REG16__CONFIG7: 6320 /* ignored */ 6321 register_name = "Config7"; 6322 break; 6323 default: 6324 register_name = "Invalid config selector"; 6325 goto cp0_unimplemented; 6326 } 6327 break; 6328 case CP0_REGISTER_17: 6329 switch (sel) { 6330 case CP0_REG17__LLADDR: 6331 gen_helper_mtc0_lladdr(tcg_env, arg); 6332 register_name = "LLAddr"; 6333 break; 6334 case CP0_REG17__MAAR: 6335 CP0_CHECK(ctx->mrp); 6336 gen_helper_mtc0_maar(tcg_env, arg); 6337 register_name = "MAAR"; 6338 break; 6339 case CP0_REG17__MAARI: 6340 CP0_CHECK(ctx->mrp); 6341 gen_helper_mtc0_maari(tcg_env, arg); 6342 register_name = "MAARI"; 6343 break; 6344 default: 6345 goto cp0_unimplemented; 6346 } 6347 break; 6348 case CP0_REGISTER_18: 6349 switch (sel) { 6350 case CP0_REG18__WATCHLO0: 6351 case CP0_REG18__WATCHLO1: 6352 case CP0_REG18__WATCHLO2: 6353 case CP0_REG18__WATCHLO3: 6354 case CP0_REG18__WATCHLO4: 6355 case CP0_REG18__WATCHLO5: 6356 case CP0_REG18__WATCHLO6: 6357 case CP0_REG18__WATCHLO7: 6358 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6359 gen_helper_0e1i(mtc0_watchlo, arg, sel); 6360 register_name = "WatchLo"; 6361 break; 6362 default: 6363 goto cp0_unimplemented; 6364 } 6365 break; 6366 case CP0_REGISTER_19: 6367 switch (sel) { 6368 case CP0_REG19__WATCHHI0: 6369 case CP0_REG19__WATCHHI1: 6370 case CP0_REG19__WATCHHI2: 6371 case CP0_REG19__WATCHHI3: 6372 case CP0_REG19__WATCHHI4: 6373 case CP0_REG19__WATCHHI5: 6374 case CP0_REG19__WATCHHI6: 6375 case CP0_REG19__WATCHHI7: 6376 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6377 gen_helper_0e1i(mtc0_watchhi, arg, sel); 6378 register_name = "WatchHi"; 6379 break; 6380 default: 6381 goto cp0_unimplemented; 6382 } 6383 break; 6384 case CP0_REGISTER_20: 6385 switch (sel) { 6386 case CP0_REG20__XCONTEXT: 6387 #if defined(TARGET_MIPS64) 6388 check_insn(ctx, ISA_MIPS3); 6389 gen_helper_mtc0_xcontext(tcg_env, arg); 6390 register_name = "XContext"; 6391 break; 6392 #endif 6393 default: 6394 goto cp0_unimplemented; 6395 } 6396 break; 6397 case CP0_REGISTER_21: 6398 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6399 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6400 switch (sel) { 6401 case 0: 6402 gen_helper_mtc0_framemask(tcg_env, arg); 6403 register_name = "Framemask"; 6404 break; 6405 default: 6406 goto cp0_unimplemented; 6407 } 6408 break; 6409 case CP0_REGISTER_22: 6410 /* ignored */ 6411 register_name = "Diagnostic"; /* implementation dependent */ 6412 break; 6413 case CP0_REGISTER_23: 6414 switch (sel) { 6415 case CP0_REG23__DEBUG: 6416 gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */ 6417 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6418 gen_save_pc(ctx->base.pc_next + 4); 6419 ctx->base.is_jmp = DISAS_EXIT; 6420 register_name = "Debug"; 6421 break; 6422 case CP0_REG23__TRACECONTROL: 6423 /* PDtrace support */ 6424 /* gen_helper_mtc0_tracecontrol(tcg_env, arg); */ 6425 register_name = "TraceControl"; 6426 /* Stop translation as we may have switched the execution mode */ 6427 ctx->base.is_jmp = DISAS_STOP; 6428 goto cp0_unimplemented; 6429 case CP0_REG23__TRACECONTROL2: 6430 /* PDtrace support */ 6431 /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */ 6432 register_name = "TraceControl2"; 6433 /* Stop translation as we may have switched the execution mode */ 6434 ctx->base.is_jmp = DISAS_STOP; 6435 goto cp0_unimplemented; 6436 case CP0_REG23__USERTRACEDATA1: 6437 /* Stop translation as we may have switched the execution mode */ 6438 ctx->base.is_jmp = DISAS_STOP; 6439 /* PDtrace support */ 6440 /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/ 6441 register_name = "UserTraceData"; 6442 /* Stop translation as we may have switched the execution mode */ 6443 ctx->base.is_jmp = DISAS_STOP; 6444 goto cp0_unimplemented; 6445 case CP0_REG23__TRACEIBPC: 6446 /* PDtrace support */ 6447 /* gen_helper_mtc0_traceibpc(tcg_env, arg); */ 6448 /* Stop translation as we may have switched the execution mode */ 6449 ctx->base.is_jmp = DISAS_STOP; 6450 register_name = "TraceIBPC"; 6451 goto cp0_unimplemented; 6452 case CP0_REG23__TRACEDBPC: 6453 /* PDtrace support */ 6454 /* gen_helper_mtc0_tracedbpc(tcg_env, arg); */ 6455 /* Stop translation as we may have switched the execution mode */ 6456 ctx->base.is_jmp = DISAS_STOP; 6457 register_name = "TraceDBPC"; 6458 goto cp0_unimplemented; 6459 default: 6460 goto cp0_unimplemented; 6461 } 6462 break; 6463 case CP0_REGISTER_24: 6464 switch (sel) { 6465 case CP0_REG24__DEPC: 6466 /* EJTAG support */ 6467 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 6468 register_name = "DEPC"; 6469 break; 6470 default: 6471 goto cp0_unimplemented; 6472 } 6473 break; 6474 case CP0_REGISTER_25: 6475 switch (sel) { 6476 case CP0_REG25__PERFCTL0: 6477 gen_helper_mtc0_performance0(tcg_env, arg); 6478 register_name = "Performance0"; 6479 break; 6480 case CP0_REG25__PERFCNT0: 6481 /* gen_helper_mtc0_performance1(arg); */ 6482 register_name = "Performance1"; 6483 goto cp0_unimplemented; 6484 case CP0_REG25__PERFCTL1: 6485 /* gen_helper_mtc0_performance2(arg); */ 6486 register_name = "Performance2"; 6487 goto cp0_unimplemented; 6488 case CP0_REG25__PERFCNT1: 6489 /* gen_helper_mtc0_performance3(arg); */ 6490 register_name = "Performance3"; 6491 goto cp0_unimplemented; 6492 case CP0_REG25__PERFCTL2: 6493 /* gen_helper_mtc0_performance4(arg); */ 6494 register_name = "Performance4"; 6495 goto cp0_unimplemented; 6496 case CP0_REG25__PERFCNT2: 6497 /* gen_helper_mtc0_performance5(arg); */ 6498 register_name = "Performance5"; 6499 goto cp0_unimplemented; 6500 case CP0_REG25__PERFCTL3: 6501 /* gen_helper_mtc0_performance6(arg); */ 6502 register_name = "Performance6"; 6503 goto cp0_unimplemented; 6504 case CP0_REG25__PERFCNT3: 6505 /* gen_helper_mtc0_performance7(arg); */ 6506 register_name = "Performance7"; 6507 goto cp0_unimplemented; 6508 default: 6509 goto cp0_unimplemented; 6510 } 6511 break; 6512 case CP0_REGISTER_26: 6513 switch (sel) { 6514 case CP0_REG26__ERRCTL: 6515 gen_helper_mtc0_errctl(tcg_env, arg); 6516 ctx->base.is_jmp = DISAS_STOP; 6517 register_name = "ErrCtl"; 6518 break; 6519 default: 6520 goto cp0_unimplemented; 6521 } 6522 break; 6523 case CP0_REGISTER_27: 6524 switch (sel) { 6525 case CP0_REG27__CACHERR: 6526 /* ignored */ 6527 register_name = "CacheErr"; 6528 break; 6529 default: 6530 goto cp0_unimplemented; 6531 } 6532 break; 6533 case CP0_REGISTER_28: 6534 switch (sel) { 6535 case CP0_REG28__TAGLO: 6536 case CP0_REG28__TAGLO1: 6537 case CP0_REG28__TAGLO2: 6538 case CP0_REG28__TAGLO3: 6539 gen_helper_mtc0_taglo(tcg_env, arg); 6540 register_name = "TagLo"; 6541 break; 6542 case CP0_REG28__DATALO: 6543 case CP0_REG28__DATALO1: 6544 case CP0_REG28__DATALO2: 6545 case CP0_REG28__DATALO3: 6546 gen_helper_mtc0_datalo(tcg_env, arg); 6547 register_name = "DataLo"; 6548 break; 6549 default: 6550 goto cp0_unimplemented; 6551 } 6552 break; 6553 case CP0_REGISTER_29: 6554 switch (sel) { 6555 case CP0_REG29__TAGHI: 6556 case CP0_REG29__TAGHI1: 6557 case CP0_REG29__TAGHI2: 6558 case CP0_REG29__TAGHI3: 6559 gen_helper_mtc0_taghi(tcg_env, arg); 6560 register_name = "TagHi"; 6561 break; 6562 case CP0_REG29__DATAHI: 6563 case CP0_REG29__DATAHI1: 6564 case CP0_REG29__DATAHI2: 6565 case CP0_REG29__DATAHI3: 6566 gen_helper_mtc0_datahi(tcg_env, arg); 6567 register_name = "DataHi"; 6568 break; 6569 default: 6570 register_name = "invalid sel"; 6571 goto cp0_unimplemented; 6572 } 6573 break; 6574 case CP0_REGISTER_30: 6575 switch (sel) { 6576 case CP0_REG30__ERROREPC: 6577 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 6578 register_name = "ErrorEPC"; 6579 break; 6580 default: 6581 goto cp0_unimplemented; 6582 } 6583 break; 6584 case CP0_REGISTER_31: 6585 switch (sel) { 6586 case CP0_REG31__DESAVE: 6587 /* EJTAG support */ 6588 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 6589 register_name = "DESAVE"; 6590 break; 6591 case CP0_REG31__KSCRATCH1: 6592 case CP0_REG31__KSCRATCH2: 6593 case CP0_REG31__KSCRATCH3: 6594 case CP0_REG31__KSCRATCH4: 6595 case CP0_REG31__KSCRATCH5: 6596 case CP0_REG31__KSCRATCH6: 6597 CP0_CHECK(ctx->kscrexist & (1 << sel)); 6598 tcg_gen_st_tl(arg, tcg_env, 6599 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 6600 register_name = "KScratch"; 6601 break; 6602 default: 6603 goto cp0_unimplemented; 6604 } 6605 break; 6606 default: 6607 goto cp0_unimplemented; 6608 } 6609 trace_mips_translate_c0("mtc0", register_name, reg, sel); 6610 6611 /* For simplicity assume that all writes can cause interrupts. */ 6612 if (icount) { 6613 /* 6614 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6615 * translated code to check for pending interrupts. 6616 */ 6617 gen_save_pc(ctx->base.pc_next + 4); 6618 ctx->base.is_jmp = DISAS_EXIT; 6619 } 6620 return; 6621 6622 cp0_unimplemented: 6623 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", 6624 register_name, reg, sel); 6625 } 6626 6627 #if defined(TARGET_MIPS64) 6628 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 6629 { 6630 const char *register_name = "invalid"; 6631 6632 if (sel != 0) { 6633 check_insn(ctx, ISA_MIPS_R1); 6634 } 6635 6636 switch (reg) { 6637 case CP0_REGISTER_00: 6638 switch (sel) { 6639 case CP0_REG00__INDEX: 6640 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 6641 register_name = "Index"; 6642 break; 6643 case CP0_REG00__MVPCONTROL: 6644 CP0_CHECK(disas_mt_available(ctx)); 6645 gen_helper_mfc0_mvpcontrol(arg, tcg_env); 6646 register_name = "MVPControl"; 6647 break; 6648 case CP0_REG00__MVPCONF0: 6649 CP0_CHECK(disas_mt_available(ctx)); 6650 gen_helper_mfc0_mvpconf0(arg, tcg_env); 6651 register_name = "MVPConf0"; 6652 break; 6653 case CP0_REG00__MVPCONF1: 6654 CP0_CHECK(disas_mt_available(ctx)); 6655 gen_helper_mfc0_mvpconf1(arg, tcg_env); 6656 register_name = "MVPConf1"; 6657 break; 6658 case CP0_REG00__VPCONTROL: 6659 CP0_CHECK(ctx->vp); 6660 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 6661 register_name = "VPControl"; 6662 break; 6663 default: 6664 goto cp0_unimplemented; 6665 } 6666 break; 6667 case CP0_REGISTER_01: 6668 switch (sel) { 6669 case CP0_REG01__RANDOM: 6670 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6671 gen_helper_mfc0_random(arg, tcg_env); 6672 register_name = "Random"; 6673 break; 6674 case CP0_REG01__VPECONTROL: 6675 CP0_CHECK(disas_mt_available(ctx)); 6676 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 6677 register_name = "VPEControl"; 6678 break; 6679 case CP0_REG01__VPECONF0: 6680 CP0_CHECK(disas_mt_available(ctx)); 6681 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 6682 register_name = "VPEConf0"; 6683 break; 6684 case CP0_REG01__VPECONF1: 6685 CP0_CHECK(disas_mt_available(ctx)); 6686 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 6687 register_name = "VPEConf1"; 6688 break; 6689 case CP0_REG01__YQMASK: 6690 CP0_CHECK(disas_mt_available(ctx)); 6691 tcg_gen_ld_tl(arg, tcg_env, 6692 offsetof(CPUMIPSState, CP0_YQMask)); 6693 register_name = "YQMask"; 6694 break; 6695 case CP0_REG01__VPESCHEDULE: 6696 CP0_CHECK(disas_mt_available(ctx)); 6697 tcg_gen_ld_tl(arg, tcg_env, 6698 offsetof(CPUMIPSState, CP0_VPESchedule)); 6699 register_name = "VPESchedule"; 6700 break; 6701 case CP0_REG01__VPESCHEFBACK: 6702 CP0_CHECK(disas_mt_available(ctx)); 6703 tcg_gen_ld_tl(arg, tcg_env, 6704 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6705 register_name = "VPEScheFBack"; 6706 break; 6707 case CP0_REG01__VPEOPT: 6708 CP0_CHECK(disas_mt_available(ctx)); 6709 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 6710 register_name = "VPEOpt"; 6711 break; 6712 default: 6713 goto cp0_unimplemented; 6714 } 6715 break; 6716 case CP0_REGISTER_02: 6717 switch (sel) { 6718 case CP0_REG02__ENTRYLO0: 6719 tcg_gen_ld_tl(arg, tcg_env, 6720 offsetof(CPUMIPSState, CP0_EntryLo0)); 6721 register_name = "EntryLo0"; 6722 break; 6723 case CP0_REG02__TCSTATUS: 6724 CP0_CHECK(disas_mt_available(ctx)); 6725 gen_helper_mfc0_tcstatus(arg, tcg_env); 6726 register_name = "TCStatus"; 6727 break; 6728 case CP0_REG02__TCBIND: 6729 CP0_CHECK(disas_mt_available(ctx)); 6730 gen_helper_mfc0_tcbind(arg, tcg_env); 6731 register_name = "TCBind"; 6732 break; 6733 case CP0_REG02__TCRESTART: 6734 CP0_CHECK(disas_mt_available(ctx)); 6735 gen_helper_dmfc0_tcrestart(arg, tcg_env); 6736 register_name = "TCRestart"; 6737 break; 6738 case CP0_REG02__TCHALT: 6739 CP0_CHECK(disas_mt_available(ctx)); 6740 gen_helper_dmfc0_tchalt(arg, tcg_env); 6741 register_name = "TCHalt"; 6742 break; 6743 case CP0_REG02__TCCONTEXT: 6744 CP0_CHECK(disas_mt_available(ctx)); 6745 gen_helper_dmfc0_tccontext(arg, tcg_env); 6746 register_name = "TCContext"; 6747 break; 6748 case CP0_REG02__TCSCHEDULE: 6749 CP0_CHECK(disas_mt_available(ctx)); 6750 gen_helper_dmfc0_tcschedule(arg, tcg_env); 6751 register_name = "TCSchedule"; 6752 break; 6753 case CP0_REG02__TCSCHEFBACK: 6754 CP0_CHECK(disas_mt_available(ctx)); 6755 gen_helper_dmfc0_tcschefback(arg, tcg_env); 6756 register_name = "TCScheFBack"; 6757 break; 6758 default: 6759 goto cp0_unimplemented; 6760 } 6761 break; 6762 case CP0_REGISTER_03: 6763 switch (sel) { 6764 case CP0_REG03__ENTRYLO1: 6765 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 6766 register_name = "EntryLo1"; 6767 break; 6768 case CP0_REG03__GLOBALNUM: 6769 CP0_CHECK(ctx->vp); 6770 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 6771 register_name = "GlobalNumber"; 6772 break; 6773 default: 6774 goto cp0_unimplemented; 6775 } 6776 break; 6777 case CP0_REGISTER_04: 6778 switch (sel) { 6779 case CP0_REG04__CONTEXT: 6780 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context)); 6781 register_name = "Context"; 6782 break; 6783 case CP0_REG04__CONTEXTCONFIG: 6784 /* SmartMIPS ASE */ 6785 /* gen_helper_dmfc0_contextconfig(arg); */ 6786 register_name = "ContextConfig"; 6787 goto cp0_unimplemented; 6788 case CP0_REG04__USERLOCAL: 6789 CP0_CHECK(ctx->ulri); 6790 tcg_gen_ld_tl(arg, tcg_env, 6791 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6792 register_name = "UserLocal"; 6793 break; 6794 case CP0_REG04__MMID: 6795 CP0_CHECK(ctx->mi); 6796 gen_helper_mtc0_memorymapid(tcg_env, arg); 6797 register_name = "MMID"; 6798 break; 6799 default: 6800 goto cp0_unimplemented; 6801 } 6802 break; 6803 case CP0_REGISTER_05: 6804 switch (sel) { 6805 case CP0_REG05__PAGEMASK: 6806 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 6807 register_name = "PageMask"; 6808 break; 6809 case CP0_REG05__PAGEGRAIN: 6810 check_insn(ctx, ISA_MIPS_R2); 6811 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 6812 register_name = "PageGrain"; 6813 break; 6814 case CP0_REG05__SEGCTL0: 6815 CP0_CHECK(ctx->sc); 6816 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 6817 register_name = "SegCtl0"; 6818 break; 6819 case CP0_REG05__SEGCTL1: 6820 CP0_CHECK(ctx->sc); 6821 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 6822 register_name = "SegCtl1"; 6823 break; 6824 case CP0_REG05__SEGCTL2: 6825 CP0_CHECK(ctx->sc); 6826 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 6827 register_name = "SegCtl2"; 6828 break; 6829 case CP0_REG05__PWBASE: 6830 check_pw(ctx); 6831 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase)); 6832 register_name = "PWBase"; 6833 break; 6834 case CP0_REG05__PWFIELD: 6835 check_pw(ctx); 6836 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWField)); 6837 register_name = "PWField"; 6838 break; 6839 case CP0_REG05__PWSIZE: 6840 check_pw(ctx); 6841 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWSize)); 6842 register_name = "PWSize"; 6843 break; 6844 default: 6845 goto cp0_unimplemented; 6846 } 6847 break; 6848 case CP0_REGISTER_06: 6849 switch (sel) { 6850 case CP0_REG06__WIRED: 6851 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 6852 register_name = "Wired"; 6853 break; 6854 case CP0_REG06__SRSCONF0: 6855 check_insn(ctx, ISA_MIPS_R2); 6856 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 6857 register_name = "SRSConf0"; 6858 break; 6859 case CP0_REG06__SRSCONF1: 6860 check_insn(ctx, ISA_MIPS_R2); 6861 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 6862 register_name = "SRSConf1"; 6863 break; 6864 case CP0_REG06__SRSCONF2: 6865 check_insn(ctx, ISA_MIPS_R2); 6866 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 6867 register_name = "SRSConf2"; 6868 break; 6869 case CP0_REG06__SRSCONF3: 6870 check_insn(ctx, ISA_MIPS_R2); 6871 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 6872 register_name = "SRSConf3"; 6873 break; 6874 case CP0_REG06__SRSCONF4: 6875 check_insn(ctx, ISA_MIPS_R2); 6876 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 6877 register_name = "SRSConf4"; 6878 break; 6879 case CP0_REG06__PWCTL: 6880 check_pw(ctx); 6881 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 6882 register_name = "PWCtl"; 6883 break; 6884 default: 6885 goto cp0_unimplemented; 6886 } 6887 break; 6888 case CP0_REGISTER_07: 6889 switch (sel) { 6890 case CP0_REG07__HWRENA: 6891 check_insn(ctx, ISA_MIPS_R2); 6892 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 6893 register_name = "HWREna"; 6894 break; 6895 default: 6896 goto cp0_unimplemented; 6897 } 6898 break; 6899 case CP0_REGISTER_08: 6900 switch (sel) { 6901 case CP0_REG08__BADVADDR: 6902 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 6903 register_name = "BadVAddr"; 6904 break; 6905 case CP0_REG08__BADINSTR: 6906 CP0_CHECK(ctx->bi); 6907 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 6908 register_name = "BadInstr"; 6909 break; 6910 case CP0_REG08__BADINSTRP: 6911 CP0_CHECK(ctx->bp); 6912 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 6913 register_name = "BadInstrP"; 6914 break; 6915 case CP0_REG08__BADINSTRX: 6916 CP0_CHECK(ctx->bi); 6917 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 6918 tcg_gen_andi_tl(arg, arg, ~0xffff); 6919 register_name = "BadInstrX"; 6920 break; 6921 default: 6922 goto cp0_unimplemented; 6923 } 6924 break; 6925 case CP0_REGISTER_09: 6926 switch (sel) { 6927 case CP0_REG09__COUNT: 6928 /* Mark as an IO operation because we read the time. */ 6929 translator_io_start(&ctx->base); 6930 gen_helper_mfc0_count(arg, tcg_env); 6931 /* 6932 * Break the TB to be able to take timer interrupts immediately 6933 * after reading count. DISAS_STOP isn't sufficient, we need to 6934 * ensure we break completely out of translated code. 6935 */ 6936 gen_save_pc(ctx->base.pc_next + 4); 6937 ctx->base.is_jmp = DISAS_EXIT; 6938 register_name = "Count"; 6939 break; 6940 default: 6941 goto cp0_unimplemented; 6942 } 6943 break; 6944 case CP0_REGISTER_10: 6945 switch (sel) { 6946 case CP0_REG10__ENTRYHI: 6947 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi)); 6948 register_name = "EntryHi"; 6949 break; 6950 default: 6951 goto cp0_unimplemented; 6952 } 6953 break; 6954 case CP0_REGISTER_11: 6955 switch (sel) { 6956 case CP0_REG11__COMPARE: 6957 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 6958 register_name = "Compare"; 6959 break; 6960 /* 6,7 are implementation dependent */ 6961 default: 6962 goto cp0_unimplemented; 6963 } 6964 break; 6965 case CP0_REGISTER_12: 6966 switch (sel) { 6967 case CP0_REG12__STATUS: 6968 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 6969 register_name = "Status"; 6970 break; 6971 case CP0_REG12__INTCTL: 6972 check_insn(ctx, ISA_MIPS_R2); 6973 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 6974 register_name = "IntCtl"; 6975 break; 6976 case CP0_REG12__SRSCTL: 6977 check_insn(ctx, ISA_MIPS_R2); 6978 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 6979 register_name = "SRSCtl"; 6980 break; 6981 case CP0_REG12__SRSMAP: 6982 check_insn(ctx, ISA_MIPS_R2); 6983 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6984 register_name = "SRSMap"; 6985 break; 6986 default: 6987 goto cp0_unimplemented; 6988 } 6989 break; 6990 case CP0_REGISTER_13: 6991 switch (sel) { 6992 case CP0_REG13__CAUSE: 6993 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 6994 register_name = "Cause"; 6995 break; 6996 default: 6997 goto cp0_unimplemented; 6998 } 6999 break; 7000 case CP0_REGISTER_14: 7001 switch (sel) { 7002 case CP0_REG14__EPC: 7003 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 7004 register_name = "EPC"; 7005 break; 7006 default: 7007 goto cp0_unimplemented; 7008 } 7009 break; 7010 case CP0_REGISTER_15: 7011 switch (sel) { 7012 case CP0_REG15__PRID: 7013 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 7014 register_name = "PRid"; 7015 break; 7016 case CP0_REG15__EBASE: 7017 check_insn(ctx, ISA_MIPS_R2); 7018 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase)); 7019 register_name = "EBase"; 7020 break; 7021 case CP0_REG15__CMGCRBASE: 7022 check_insn(ctx, ISA_MIPS_R2); 7023 CP0_CHECK(ctx->cmgcr); 7024 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 7025 register_name = "CMGCRBase"; 7026 break; 7027 default: 7028 goto cp0_unimplemented; 7029 } 7030 break; 7031 case CP0_REGISTER_16: 7032 switch (sel) { 7033 case CP0_REG16__CONFIG: 7034 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 7035 register_name = "Config"; 7036 break; 7037 case CP0_REG16__CONFIG1: 7038 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 7039 register_name = "Config1"; 7040 break; 7041 case CP0_REG16__CONFIG2: 7042 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 7043 register_name = "Config2"; 7044 break; 7045 case CP0_REG16__CONFIG3: 7046 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 7047 register_name = "Config3"; 7048 break; 7049 case CP0_REG16__CONFIG4: 7050 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 7051 register_name = "Config4"; 7052 break; 7053 case CP0_REG16__CONFIG5: 7054 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 7055 register_name = "Config5"; 7056 break; 7057 /* 6,7 are implementation dependent */ 7058 case CP0_REG16__CONFIG6: 7059 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 7060 register_name = "Config6"; 7061 break; 7062 case CP0_REG16__CONFIG7: 7063 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 7064 register_name = "Config7"; 7065 break; 7066 default: 7067 goto cp0_unimplemented; 7068 } 7069 break; 7070 case CP0_REGISTER_17: 7071 switch (sel) { 7072 case CP0_REG17__LLADDR: 7073 gen_helper_dmfc0_lladdr(arg, tcg_env); 7074 register_name = "LLAddr"; 7075 break; 7076 case CP0_REG17__MAAR: 7077 CP0_CHECK(ctx->mrp); 7078 gen_helper_dmfc0_maar(arg, tcg_env); 7079 register_name = "MAAR"; 7080 break; 7081 case CP0_REG17__MAARI: 7082 CP0_CHECK(ctx->mrp); 7083 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 7084 register_name = "MAARI"; 7085 break; 7086 default: 7087 goto cp0_unimplemented; 7088 } 7089 break; 7090 case CP0_REGISTER_18: 7091 switch (sel) { 7092 case CP0_REG18__WATCHLO0: 7093 case CP0_REG18__WATCHLO1: 7094 case CP0_REG18__WATCHLO2: 7095 case CP0_REG18__WATCHLO3: 7096 case CP0_REG18__WATCHLO4: 7097 case CP0_REG18__WATCHLO5: 7098 case CP0_REG18__WATCHLO6: 7099 case CP0_REG18__WATCHLO7: 7100 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7101 gen_helper_1e0i(dmfc0_watchlo, arg, sel); 7102 register_name = "WatchLo"; 7103 break; 7104 default: 7105 goto cp0_unimplemented; 7106 } 7107 break; 7108 case CP0_REGISTER_19: 7109 switch (sel) { 7110 case CP0_REG19__WATCHHI0: 7111 case CP0_REG19__WATCHHI1: 7112 case CP0_REG19__WATCHHI2: 7113 case CP0_REG19__WATCHHI3: 7114 case CP0_REG19__WATCHHI4: 7115 case CP0_REG19__WATCHHI5: 7116 case CP0_REG19__WATCHHI6: 7117 case CP0_REG19__WATCHHI7: 7118 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7119 gen_helper_1e0i(dmfc0_watchhi, arg, sel); 7120 register_name = "WatchHi"; 7121 break; 7122 default: 7123 goto cp0_unimplemented; 7124 } 7125 break; 7126 case CP0_REGISTER_20: 7127 switch (sel) { 7128 case CP0_REG20__XCONTEXT: 7129 check_insn(ctx, ISA_MIPS3); 7130 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext)); 7131 register_name = "XContext"; 7132 break; 7133 default: 7134 goto cp0_unimplemented; 7135 } 7136 break; 7137 case CP0_REGISTER_21: 7138 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7139 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7140 switch (sel) { 7141 case 0: 7142 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 7143 register_name = "Framemask"; 7144 break; 7145 default: 7146 goto cp0_unimplemented; 7147 } 7148 break; 7149 case CP0_REGISTER_22: 7150 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7151 register_name = "'Diagnostic"; /* implementation dependent */ 7152 break; 7153 case CP0_REGISTER_23: 7154 switch (sel) { 7155 case CP0_REG23__DEBUG: 7156 gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */ 7157 register_name = "Debug"; 7158 break; 7159 case CP0_REG23__TRACECONTROL: 7160 /* PDtrace support */ 7161 /* gen_helper_dmfc0_tracecontrol(arg, tcg_env); */ 7162 register_name = "TraceControl"; 7163 goto cp0_unimplemented; 7164 case CP0_REG23__TRACECONTROL2: 7165 /* PDtrace support */ 7166 /* gen_helper_dmfc0_tracecontrol2(arg, tcg_env); */ 7167 register_name = "TraceControl2"; 7168 goto cp0_unimplemented; 7169 case CP0_REG23__USERTRACEDATA1: 7170 /* PDtrace support */ 7171 /* gen_helper_dmfc0_usertracedata1(arg, tcg_env);*/ 7172 register_name = "UserTraceData1"; 7173 goto cp0_unimplemented; 7174 case CP0_REG23__TRACEIBPC: 7175 /* PDtrace support */ 7176 /* gen_helper_dmfc0_traceibpc(arg, tcg_env); */ 7177 register_name = "TraceIBPC"; 7178 goto cp0_unimplemented; 7179 case CP0_REG23__TRACEDBPC: 7180 /* PDtrace support */ 7181 /* gen_helper_dmfc0_tracedbpc(arg, tcg_env); */ 7182 register_name = "TraceDBPC"; 7183 goto cp0_unimplemented; 7184 default: 7185 goto cp0_unimplemented; 7186 } 7187 break; 7188 case CP0_REGISTER_24: 7189 switch (sel) { 7190 case CP0_REG24__DEPC: 7191 /* EJTAG support */ 7192 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 7193 register_name = "DEPC"; 7194 break; 7195 default: 7196 goto cp0_unimplemented; 7197 } 7198 break; 7199 case CP0_REGISTER_25: 7200 switch (sel) { 7201 case CP0_REG25__PERFCTL0: 7202 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 7203 register_name = "Performance0"; 7204 break; 7205 case CP0_REG25__PERFCNT0: 7206 /* gen_helper_dmfc0_performance1(arg); */ 7207 register_name = "Performance1"; 7208 goto cp0_unimplemented; 7209 case CP0_REG25__PERFCTL1: 7210 /* gen_helper_dmfc0_performance2(arg); */ 7211 register_name = "Performance2"; 7212 goto cp0_unimplemented; 7213 case CP0_REG25__PERFCNT1: 7214 /* gen_helper_dmfc0_performance3(arg); */ 7215 register_name = "Performance3"; 7216 goto cp0_unimplemented; 7217 case CP0_REG25__PERFCTL2: 7218 /* gen_helper_dmfc0_performance4(arg); */ 7219 register_name = "Performance4"; 7220 goto cp0_unimplemented; 7221 case CP0_REG25__PERFCNT2: 7222 /* gen_helper_dmfc0_performance5(arg); */ 7223 register_name = "Performance5"; 7224 goto cp0_unimplemented; 7225 case CP0_REG25__PERFCTL3: 7226 /* gen_helper_dmfc0_performance6(arg); */ 7227 register_name = "Performance6"; 7228 goto cp0_unimplemented; 7229 case CP0_REG25__PERFCNT3: 7230 /* gen_helper_dmfc0_performance7(arg); */ 7231 register_name = "Performance7"; 7232 goto cp0_unimplemented; 7233 default: 7234 goto cp0_unimplemented; 7235 } 7236 break; 7237 case CP0_REGISTER_26: 7238 switch (sel) { 7239 case CP0_REG26__ERRCTL: 7240 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 7241 register_name = "ErrCtl"; 7242 break; 7243 default: 7244 goto cp0_unimplemented; 7245 } 7246 break; 7247 case CP0_REGISTER_27: 7248 switch (sel) { 7249 /* ignored */ 7250 case CP0_REG27__CACHERR: 7251 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7252 register_name = "CacheErr"; 7253 break; 7254 default: 7255 goto cp0_unimplemented; 7256 } 7257 break; 7258 case CP0_REGISTER_28: 7259 switch (sel) { 7260 case CP0_REG28__TAGLO: 7261 case CP0_REG28__TAGLO1: 7262 case CP0_REG28__TAGLO2: 7263 case CP0_REG28__TAGLO3: 7264 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 7265 register_name = "TagLo"; 7266 break; 7267 case CP0_REG28__DATALO: 7268 case CP0_REG28__DATALO1: 7269 case CP0_REG28__DATALO2: 7270 case CP0_REG28__DATALO3: 7271 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 7272 register_name = "DataLo"; 7273 break; 7274 default: 7275 goto cp0_unimplemented; 7276 } 7277 break; 7278 case CP0_REGISTER_29: 7279 switch (sel) { 7280 case CP0_REG29__TAGHI: 7281 case CP0_REG29__TAGHI1: 7282 case CP0_REG29__TAGHI2: 7283 case CP0_REG29__TAGHI3: 7284 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 7285 register_name = "TagHi"; 7286 break; 7287 case CP0_REG29__DATAHI: 7288 case CP0_REG29__DATAHI1: 7289 case CP0_REG29__DATAHI2: 7290 case CP0_REG29__DATAHI3: 7291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 7292 register_name = "DataHi"; 7293 break; 7294 default: 7295 goto cp0_unimplemented; 7296 } 7297 break; 7298 case CP0_REGISTER_30: 7299 switch (sel) { 7300 case CP0_REG30__ERROREPC: 7301 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7302 register_name = "ErrorEPC"; 7303 break; 7304 default: 7305 goto cp0_unimplemented; 7306 } 7307 break; 7308 case CP0_REGISTER_31: 7309 switch (sel) { 7310 case CP0_REG31__DESAVE: 7311 /* EJTAG support */ 7312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7313 register_name = "DESAVE"; 7314 break; 7315 case CP0_REG31__KSCRATCH1: 7316 case CP0_REG31__KSCRATCH2: 7317 case CP0_REG31__KSCRATCH3: 7318 case CP0_REG31__KSCRATCH4: 7319 case CP0_REG31__KSCRATCH5: 7320 case CP0_REG31__KSCRATCH6: 7321 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7322 tcg_gen_ld_tl(arg, tcg_env, 7323 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7324 register_name = "KScratch"; 7325 break; 7326 default: 7327 goto cp0_unimplemented; 7328 } 7329 break; 7330 default: 7331 goto cp0_unimplemented; 7332 } 7333 trace_mips_translate_c0("dmfc0", register_name, reg, sel); 7334 return; 7335 7336 cp0_unimplemented: 7337 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", 7338 register_name, reg, sel); 7339 gen_mfc0_unimplemented(ctx, arg); 7340 } 7341 7342 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7343 { 7344 const char *register_name = "invalid"; 7345 bool icount; 7346 7347 if (sel != 0) { 7348 check_insn(ctx, ISA_MIPS_R1); 7349 } 7350 7351 icount = translator_io_start(&ctx->base); 7352 7353 switch (reg) { 7354 case CP0_REGISTER_00: 7355 switch (sel) { 7356 case CP0_REG00__INDEX: 7357 gen_helper_mtc0_index(tcg_env, arg); 7358 register_name = "Index"; 7359 break; 7360 case CP0_REG00__MVPCONTROL: 7361 CP0_CHECK(disas_mt_available(ctx)); 7362 gen_helper_mtc0_mvpcontrol(tcg_env, arg); 7363 register_name = "MVPControl"; 7364 break; 7365 case CP0_REG00__MVPCONF0: 7366 CP0_CHECK(disas_mt_available(ctx)); 7367 /* ignored */ 7368 register_name = "MVPConf0"; 7369 break; 7370 case CP0_REG00__MVPCONF1: 7371 CP0_CHECK(disas_mt_available(ctx)); 7372 /* ignored */ 7373 register_name = "MVPConf1"; 7374 break; 7375 case CP0_REG00__VPCONTROL: 7376 CP0_CHECK(ctx->vp); 7377 /* ignored */ 7378 register_name = "VPControl"; 7379 break; 7380 default: 7381 goto cp0_unimplemented; 7382 } 7383 break; 7384 case CP0_REGISTER_01: 7385 switch (sel) { 7386 case CP0_REG01__RANDOM: 7387 /* ignored */ 7388 register_name = "Random"; 7389 break; 7390 case CP0_REG01__VPECONTROL: 7391 CP0_CHECK(disas_mt_available(ctx)); 7392 gen_helper_mtc0_vpecontrol(tcg_env, arg); 7393 register_name = "VPEControl"; 7394 break; 7395 case CP0_REG01__VPECONF0: 7396 CP0_CHECK(disas_mt_available(ctx)); 7397 gen_helper_mtc0_vpeconf0(tcg_env, arg); 7398 register_name = "VPEConf0"; 7399 break; 7400 case CP0_REG01__VPECONF1: 7401 CP0_CHECK(disas_mt_available(ctx)); 7402 gen_helper_mtc0_vpeconf1(tcg_env, arg); 7403 register_name = "VPEConf1"; 7404 break; 7405 case CP0_REG01__YQMASK: 7406 CP0_CHECK(disas_mt_available(ctx)); 7407 gen_helper_mtc0_yqmask(tcg_env, arg); 7408 register_name = "YQMask"; 7409 break; 7410 case CP0_REG01__VPESCHEDULE: 7411 CP0_CHECK(disas_mt_available(ctx)); 7412 tcg_gen_st_tl(arg, tcg_env, 7413 offsetof(CPUMIPSState, CP0_VPESchedule)); 7414 register_name = "VPESchedule"; 7415 break; 7416 case CP0_REG01__VPESCHEFBACK: 7417 CP0_CHECK(disas_mt_available(ctx)); 7418 tcg_gen_st_tl(arg, tcg_env, 7419 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7420 register_name = "VPEScheFBack"; 7421 break; 7422 case CP0_REG01__VPEOPT: 7423 CP0_CHECK(disas_mt_available(ctx)); 7424 gen_helper_mtc0_vpeopt(tcg_env, arg); 7425 register_name = "VPEOpt"; 7426 break; 7427 default: 7428 goto cp0_unimplemented; 7429 } 7430 break; 7431 case CP0_REGISTER_02: 7432 switch (sel) { 7433 case CP0_REG02__ENTRYLO0: 7434 gen_helper_dmtc0_entrylo0(tcg_env, arg); 7435 register_name = "EntryLo0"; 7436 break; 7437 case CP0_REG02__TCSTATUS: 7438 CP0_CHECK(disas_mt_available(ctx)); 7439 gen_helper_mtc0_tcstatus(tcg_env, arg); 7440 register_name = "TCStatus"; 7441 break; 7442 case CP0_REG02__TCBIND: 7443 CP0_CHECK(disas_mt_available(ctx)); 7444 gen_helper_mtc0_tcbind(tcg_env, arg); 7445 register_name = "TCBind"; 7446 break; 7447 case CP0_REG02__TCRESTART: 7448 CP0_CHECK(disas_mt_available(ctx)); 7449 gen_helper_mtc0_tcrestart(tcg_env, arg); 7450 register_name = "TCRestart"; 7451 break; 7452 case CP0_REG02__TCHALT: 7453 CP0_CHECK(disas_mt_available(ctx)); 7454 gen_helper_mtc0_tchalt(tcg_env, arg); 7455 register_name = "TCHalt"; 7456 break; 7457 case CP0_REG02__TCCONTEXT: 7458 CP0_CHECK(disas_mt_available(ctx)); 7459 gen_helper_mtc0_tccontext(tcg_env, arg); 7460 register_name = "TCContext"; 7461 break; 7462 case CP0_REG02__TCSCHEDULE: 7463 CP0_CHECK(disas_mt_available(ctx)); 7464 gen_helper_mtc0_tcschedule(tcg_env, arg); 7465 register_name = "TCSchedule"; 7466 break; 7467 case CP0_REG02__TCSCHEFBACK: 7468 CP0_CHECK(disas_mt_available(ctx)); 7469 gen_helper_mtc0_tcschefback(tcg_env, arg); 7470 register_name = "TCScheFBack"; 7471 break; 7472 default: 7473 goto cp0_unimplemented; 7474 } 7475 break; 7476 case CP0_REGISTER_03: 7477 switch (sel) { 7478 case CP0_REG03__ENTRYLO1: 7479 gen_helper_dmtc0_entrylo1(tcg_env, arg); 7480 register_name = "EntryLo1"; 7481 break; 7482 case CP0_REG03__GLOBALNUM: 7483 CP0_CHECK(ctx->vp); 7484 /* ignored */ 7485 register_name = "GlobalNumber"; 7486 break; 7487 default: 7488 goto cp0_unimplemented; 7489 } 7490 break; 7491 case CP0_REGISTER_04: 7492 switch (sel) { 7493 case CP0_REG04__CONTEXT: 7494 gen_helper_mtc0_context(tcg_env, arg); 7495 register_name = "Context"; 7496 break; 7497 case CP0_REG04__CONTEXTCONFIG: 7498 /* SmartMIPS ASE */ 7499 /* gen_helper_dmtc0_contextconfig(arg); */ 7500 register_name = "ContextConfig"; 7501 goto cp0_unimplemented; 7502 case CP0_REG04__USERLOCAL: 7503 CP0_CHECK(ctx->ulri); 7504 tcg_gen_st_tl(arg, tcg_env, 7505 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 7506 register_name = "UserLocal"; 7507 break; 7508 case CP0_REG04__MMID: 7509 CP0_CHECK(ctx->mi); 7510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 7511 register_name = "MMID"; 7512 break; 7513 default: 7514 goto cp0_unimplemented; 7515 } 7516 break; 7517 case CP0_REGISTER_05: 7518 switch (sel) { 7519 case CP0_REG05__PAGEMASK: 7520 gen_helper_mtc0_pagemask(tcg_env, arg); 7521 register_name = "PageMask"; 7522 break; 7523 case CP0_REG05__PAGEGRAIN: 7524 check_insn(ctx, ISA_MIPS_R2); 7525 gen_helper_mtc0_pagegrain(tcg_env, arg); 7526 register_name = "PageGrain"; 7527 break; 7528 case CP0_REG05__SEGCTL0: 7529 CP0_CHECK(ctx->sc); 7530 gen_helper_mtc0_segctl0(tcg_env, arg); 7531 register_name = "SegCtl0"; 7532 break; 7533 case CP0_REG05__SEGCTL1: 7534 CP0_CHECK(ctx->sc); 7535 gen_helper_mtc0_segctl1(tcg_env, arg); 7536 register_name = "SegCtl1"; 7537 break; 7538 case CP0_REG05__SEGCTL2: 7539 CP0_CHECK(ctx->sc); 7540 gen_helper_mtc0_segctl2(tcg_env, arg); 7541 register_name = "SegCtl2"; 7542 break; 7543 case CP0_REG05__PWBASE: 7544 check_pw(ctx); 7545 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase)); 7546 register_name = "PWBase"; 7547 break; 7548 case CP0_REG05__PWFIELD: 7549 check_pw(ctx); 7550 gen_helper_mtc0_pwfield(tcg_env, arg); 7551 register_name = "PWField"; 7552 break; 7553 case CP0_REG05__PWSIZE: 7554 check_pw(ctx); 7555 gen_helper_mtc0_pwsize(tcg_env, arg); 7556 register_name = "PWSize"; 7557 break; 7558 default: 7559 goto cp0_unimplemented; 7560 } 7561 break; 7562 case CP0_REGISTER_06: 7563 switch (sel) { 7564 case CP0_REG06__WIRED: 7565 gen_helper_mtc0_wired(tcg_env, arg); 7566 register_name = "Wired"; 7567 break; 7568 case CP0_REG06__SRSCONF0: 7569 check_insn(ctx, ISA_MIPS_R2); 7570 gen_helper_mtc0_srsconf0(tcg_env, arg); 7571 register_name = "SRSConf0"; 7572 break; 7573 case CP0_REG06__SRSCONF1: 7574 check_insn(ctx, ISA_MIPS_R2); 7575 gen_helper_mtc0_srsconf1(tcg_env, arg); 7576 register_name = "SRSConf1"; 7577 break; 7578 case CP0_REG06__SRSCONF2: 7579 check_insn(ctx, ISA_MIPS_R2); 7580 gen_helper_mtc0_srsconf2(tcg_env, arg); 7581 register_name = "SRSConf2"; 7582 break; 7583 case CP0_REG06__SRSCONF3: 7584 check_insn(ctx, ISA_MIPS_R2); 7585 gen_helper_mtc0_srsconf3(tcg_env, arg); 7586 register_name = "SRSConf3"; 7587 break; 7588 case CP0_REG06__SRSCONF4: 7589 check_insn(ctx, ISA_MIPS_R2); 7590 gen_helper_mtc0_srsconf4(tcg_env, arg); 7591 register_name = "SRSConf4"; 7592 break; 7593 case CP0_REG06__PWCTL: 7594 check_pw(ctx); 7595 gen_helper_mtc0_pwctl(tcg_env, arg); 7596 register_name = "PWCtl"; 7597 break; 7598 default: 7599 goto cp0_unimplemented; 7600 } 7601 break; 7602 case CP0_REGISTER_07: 7603 switch (sel) { 7604 case CP0_REG07__HWRENA: 7605 check_insn(ctx, ISA_MIPS_R2); 7606 gen_helper_mtc0_hwrena(tcg_env, arg); 7607 ctx->base.is_jmp = DISAS_STOP; 7608 register_name = "HWREna"; 7609 break; 7610 default: 7611 goto cp0_unimplemented; 7612 } 7613 break; 7614 case CP0_REGISTER_08: 7615 switch (sel) { 7616 case CP0_REG08__BADVADDR: 7617 /* ignored */ 7618 register_name = "BadVAddr"; 7619 break; 7620 case CP0_REG08__BADINSTR: 7621 /* ignored */ 7622 register_name = "BadInstr"; 7623 break; 7624 case CP0_REG08__BADINSTRP: 7625 /* ignored */ 7626 register_name = "BadInstrP"; 7627 break; 7628 case CP0_REG08__BADINSTRX: 7629 /* ignored */ 7630 register_name = "BadInstrX"; 7631 break; 7632 default: 7633 goto cp0_unimplemented; 7634 } 7635 break; 7636 case CP0_REGISTER_09: 7637 switch (sel) { 7638 case CP0_REG09__COUNT: 7639 gen_helper_mtc0_count(tcg_env, arg); 7640 register_name = "Count"; 7641 break; 7642 default: 7643 goto cp0_unimplemented; 7644 } 7645 /* Stop translation as we may have switched the execution mode */ 7646 ctx->base.is_jmp = DISAS_STOP; 7647 break; 7648 case CP0_REGISTER_10: 7649 switch (sel) { 7650 case CP0_REG10__ENTRYHI: 7651 gen_helper_mtc0_entryhi(tcg_env, arg); 7652 register_name = "EntryHi"; 7653 break; 7654 default: 7655 goto cp0_unimplemented; 7656 } 7657 break; 7658 case CP0_REGISTER_11: 7659 switch (sel) { 7660 case CP0_REG11__COMPARE: 7661 gen_helper_mtc0_compare(tcg_env, arg); 7662 register_name = "Compare"; 7663 break; 7664 /* 6,7 are implementation dependent */ 7665 default: 7666 goto cp0_unimplemented; 7667 } 7668 /* Stop translation as we may have switched the execution mode */ 7669 ctx->base.is_jmp = DISAS_STOP; 7670 break; 7671 case CP0_REGISTER_12: 7672 switch (sel) { 7673 case CP0_REG12__STATUS: 7674 save_cpu_state(ctx, 1); 7675 gen_helper_mtc0_status(tcg_env, arg); 7676 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7677 gen_save_pc(ctx->base.pc_next + 4); 7678 ctx->base.is_jmp = DISAS_EXIT; 7679 register_name = "Status"; 7680 break; 7681 case CP0_REG12__INTCTL: 7682 check_insn(ctx, ISA_MIPS_R2); 7683 gen_helper_mtc0_intctl(tcg_env, arg); 7684 /* Stop translation as we may have switched the execution mode */ 7685 ctx->base.is_jmp = DISAS_STOP; 7686 register_name = "IntCtl"; 7687 break; 7688 case CP0_REG12__SRSCTL: 7689 check_insn(ctx, ISA_MIPS_R2); 7690 gen_helper_mtc0_srsctl(tcg_env, arg); 7691 /* Stop translation as we may have switched the execution mode */ 7692 ctx->base.is_jmp = DISAS_STOP; 7693 register_name = "SRSCtl"; 7694 break; 7695 case CP0_REG12__SRSMAP: 7696 check_insn(ctx, ISA_MIPS_R2); 7697 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7698 /* Stop translation as we may have switched the execution mode */ 7699 ctx->base.is_jmp = DISAS_STOP; 7700 register_name = "SRSMap"; 7701 break; 7702 default: 7703 goto cp0_unimplemented; 7704 } 7705 break; 7706 case CP0_REGISTER_13: 7707 switch (sel) { 7708 case CP0_REG13__CAUSE: 7709 save_cpu_state(ctx, 1); 7710 gen_helper_mtc0_cause(tcg_env, arg); 7711 /* 7712 * Stop translation as we may have triggered an interrupt. 7713 * DISAS_STOP isn't sufficient, we need to ensure we break out of 7714 * translated code to check for pending interrupts. 7715 */ 7716 gen_save_pc(ctx->base.pc_next + 4); 7717 ctx->base.is_jmp = DISAS_EXIT; 7718 register_name = "Cause"; 7719 break; 7720 default: 7721 goto cp0_unimplemented; 7722 } 7723 break; 7724 case CP0_REGISTER_14: 7725 switch (sel) { 7726 case CP0_REG14__EPC: 7727 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 7728 register_name = "EPC"; 7729 break; 7730 default: 7731 goto cp0_unimplemented; 7732 } 7733 break; 7734 case CP0_REGISTER_15: 7735 switch (sel) { 7736 case CP0_REG15__PRID: 7737 /* ignored */ 7738 register_name = "PRid"; 7739 break; 7740 case CP0_REG15__EBASE: 7741 check_insn(ctx, ISA_MIPS_R2); 7742 gen_helper_mtc0_ebase(tcg_env, arg); 7743 register_name = "EBase"; 7744 break; 7745 default: 7746 goto cp0_unimplemented; 7747 } 7748 break; 7749 case CP0_REGISTER_16: 7750 switch (sel) { 7751 case CP0_REG16__CONFIG: 7752 gen_helper_mtc0_config0(tcg_env, arg); 7753 register_name = "Config"; 7754 /* Stop translation as we may have switched the execution mode */ 7755 ctx->base.is_jmp = DISAS_STOP; 7756 break; 7757 case CP0_REG16__CONFIG1: 7758 /* ignored, read only */ 7759 register_name = "Config1"; 7760 break; 7761 case CP0_REG16__CONFIG2: 7762 gen_helper_mtc0_config2(tcg_env, arg); 7763 register_name = "Config2"; 7764 /* Stop translation as we may have switched the execution mode */ 7765 ctx->base.is_jmp = DISAS_STOP; 7766 break; 7767 case CP0_REG16__CONFIG3: 7768 gen_helper_mtc0_config3(tcg_env, arg); 7769 register_name = "Config3"; 7770 /* Stop translation as we may have switched the execution mode */ 7771 ctx->base.is_jmp = DISAS_STOP; 7772 break; 7773 case CP0_REG16__CONFIG4: 7774 /* currently ignored */ 7775 register_name = "Config4"; 7776 break; 7777 case CP0_REG16__CONFIG5: 7778 gen_helper_mtc0_config5(tcg_env, arg); 7779 register_name = "Config5"; 7780 /* Stop translation as we may have switched the execution mode */ 7781 ctx->base.is_jmp = DISAS_STOP; 7782 break; 7783 /* 6,7 are implementation dependent */ 7784 default: 7785 register_name = "Invalid config selector"; 7786 goto cp0_unimplemented; 7787 } 7788 break; 7789 case CP0_REGISTER_17: 7790 switch (sel) { 7791 case CP0_REG17__LLADDR: 7792 gen_helper_mtc0_lladdr(tcg_env, arg); 7793 register_name = "LLAddr"; 7794 break; 7795 case CP0_REG17__MAAR: 7796 CP0_CHECK(ctx->mrp); 7797 gen_helper_mtc0_maar(tcg_env, arg); 7798 register_name = "MAAR"; 7799 break; 7800 case CP0_REG17__MAARI: 7801 CP0_CHECK(ctx->mrp); 7802 gen_helper_mtc0_maari(tcg_env, arg); 7803 register_name = "MAARI"; 7804 break; 7805 default: 7806 goto cp0_unimplemented; 7807 } 7808 break; 7809 case CP0_REGISTER_18: 7810 switch (sel) { 7811 case CP0_REG18__WATCHLO0: 7812 case CP0_REG18__WATCHLO1: 7813 case CP0_REG18__WATCHLO2: 7814 case CP0_REG18__WATCHLO3: 7815 case CP0_REG18__WATCHLO4: 7816 case CP0_REG18__WATCHLO5: 7817 case CP0_REG18__WATCHLO6: 7818 case CP0_REG18__WATCHLO7: 7819 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7820 gen_helper_0e1i(mtc0_watchlo, arg, sel); 7821 register_name = "WatchLo"; 7822 break; 7823 default: 7824 goto cp0_unimplemented; 7825 } 7826 break; 7827 case CP0_REGISTER_19: 7828 switch (sel) { 7829 case CP0_REG19__WATCHHI0: 7830 case CP0_REG19__WATCHHI1: 7831 case CP0_REG19__WATCHHI2: 7832 case CP0_REG19__WATCHHI3: 7833 case CP0_REG19__WATCHHI4: 7834 case CP0_REG19__WATCHHI5: 7835 case CP0_REG19__WATCHHI6: 7836 case CP0_REG19__WATCHHI7: 7837 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7838 gen_helper_0e1i(mtc0_watchhi, arg, sel); 7839 register_name = "WatchHi"; 7840 break; 7841 default: 7842 goto cp0_unimplemented; 7843 } 7844 break; 7845 case CP0_REGISTER_20: 7846 switch (sel) { 7847 case CP0_REG20__XCONTEXT: 7848 check_insn(ctx, ISA_MIPS3); 7849 gen_helper_mtc0_xcontext(tcg_env, arg); 7850 register_name = "XContext"; 7851 break; 7852 default: 7853 goto cp0_unimplemented; 7854 } 7855 break; 7856 case CP0_REGISTER_21: 7857 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7858 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7859 switch (sel) { 7860 case 0: 7861 gen_helper_mtc0_framemask(tcg_env, arg); 7862 register_name = "Framemask"; 7863 break; 7864 default: 7865 goto cp0_unimplemented; 7866 } 7867 break; 7868 case CP0_REGISTER_22: 7869 /* ignored */ 7870 register_name = "Diagnostic"; /* implementation dependent */ 7871 break; 7872 case CP0_REGISTER_23: 7873 switch (sel) { 7874 case CP0_REG23__DEBUG: 7875 gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */ 7876 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7877 gen_save_pc(ctx->base.pc_next + 4); 7878 ctx->base.is_jmp = DISAS_EXIT; 7879 register_name = "Debug"; 7880 break; 7881 case CP0_REG23__TRACECONTROL: 7882 /* PDtrace support */ 7883 /* gen_helper_mtc0_tracecontrol(tcg_env, arg); */ 7884 /* Stop translation as we may have switched the execution mode */ 7885 ctx->base.is_jmp = DISAS_STOP; 7886 register_name = "TraceControl"; 7887 goto cp0_unimplemented; 7888 case CP0_REG23__TRACECONTROL2: 7889 /* PDtrace support */ 7890 /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */ 7891 /* Stop translation as we may have switched the execution mode */ 7892 ctx->base.is_jmp = DISAS_STOP; 7893 register_name = "TraceControl2"; 7894 goto cp0_unimplemented; 7895 case CP0_REG23__USERTRACEDATA1: 7896 /* PDtrace support */ 7897 /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/ 7898 /* Stop translation as we may have switched the execution mode */ 7899 ctx->base.is_jmp = DISAS_STOP; 7900 register_name = "UserTraceData1"; 7901 goto cp0_unimplemented; 7902 case CP0_REG23__TRACEIBPC: 7903 /* PDtrace support */ 7904 /* gen_helper_mtc0_traceibpc(tcg_env, arg); */ 7905 /* Stop translation as we may have switched the execution mode */ 7906 ctx->base.is_jmp = DISAS_STOP; 7907 register_name = "TraceIBPC"; 7908 goto cp0_unimplemented; 7909 case CP0_REG23__TRACEDBPC: 7910 /* PDtrace support */ 7911 /* gen_helper_mtc0_tracedbpc(tcg_env, arg); */ 7912 /* Stop translation as we may have switched the execution mode */ 7913 ctx->base.is_jmp = DISAS_STOP; 7914 register_name = "TraceDBPC"; 7915 goto cp0_unimplemented; 7916 default: 7917 goto cp0_unimplemented; 7918 } 7919 break; 7920 case CP0_REGISTER_24: 7921 switch (sel) { 7922 case CP0_REG24__DEPC: 7923 /* EJTAG support */ 7924 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 7925 register_name = "DEPC"; 7926 break; 7927 default: 7928 goto cp0_unimplemented; 7929 } 7930 break; 7931 case CP0_REGISTER_25: 7932 switch (sel) { 7933 case CP0_REG25__PERFCTL0: 7934 gen_helper_mtc0_performance0(tcg_env, arg); 7935 register_name = "Performance0"; 7936 break; 7937 case CP0_REG25__PERFCNT0: 7938 /* gen_helper_mtc0_performance1(tcg_env, arg); */ 7939 register_name = "Performance1"; 7940 goto cp0_unimplemented; 7941 case CP0_REG25__PERFCTL1: 7942 /* gen_helper_mtc0_performance2(tcg_env, arg); */ 7943 register_name = "Performance2"; 7944 goto cp0_unimplemented; 7945 case CP0_REG25__PERFCNT1: 7946 /* gen_helper_mtc0_performance3(tcg_env, arg); */ 7947 register_name = "Performance3"; 7948 goto cp0_unimplemented; 7949 case CP0_REG25__PERFCTL2: 7950 /* gen_helper_mtc0_performance4(tcg_env, arg); */ 7951 register_name = "Performance4"; 7952 goto cp0_unimplemented; 7953 case CP0_REG25__PERFCNT2: 7954 /* gen_helper_mtc0_performance5(tcg_env, arg); */ 7955 register_name = "Performance5"; 7956 goto cp0_unimplemented; 7957 case CP0_REG25__PERFCTL3: 7958 /* gen_helper_mtc0_performance6(tcg_env, arg); */ 7959 register_name = "Performance6"; 7960 goto cp0_unimplemented; 7961 case CP0_REG25__PERFCNT3: 7962 /* gen_helper_mtc0_performance7(tcg_env, arg); */ 7963 register_name = "Performance7"; 7964 goto cp0_unimplemented; 7965 default: 7966 goto cp0_unimplemented; 7967 } 7968 break; 7969 case CP0_REGISTER_26: 7970 switch (sel) { 7971 case CP0_REG26__ERRCTL: 7972 gen_helper_mtc0_errctl(tcg_env, arg); 7973 ctx->base.is_jmp = DISAS_STOP; 7974 register_name = "ErrCtl"; 7975 break; 7976 default: 7977 goto cp0_unimplemented; 7978 } 7979 break; 7980 case CP0_REGISTER_27: 7981 switch (sel) { 7982 case CP0_REG27__CACHERR: 7983 /* ignored */ 7984 register_name = "CacheErr"; 7985 break; 7986 default: 7987 goto cp0_unimplemented; 7988 } 7989 break; 7990 case CP0_REGISTER_28: 7991 switch (sel) { 7992 case CP0_REG28__TAGLO: 7993 case CP0_REG28__TAGLO1: 7994 case CP0_REG28__TAGLO2: 7995 case CP0_REG28__TAGLO3: 7996 gen_helper_mtc0_taglo(tcg_env, arg); 7997 register_name = "TagLo"; 7998 break; 7999 case CP0_REG28__DATALO: 8000 case CP0_REG28__DATALO1: 8001 case CP0_REG28__DATALO2: 8002 case CP0_REG28__DATALO3: 8003 gen_helper_mtc0_datalo(tcg_env, arg); 8004 register_name = "DataLo"; 8005 break; 8006 default: 8007 goto cp0_unimplemented; 8008 } 8009 break; 8010 case CP0_REGISTER_29: 8011 switch (sel) { 8012 case CP0_REG29__TAGHI: 8013 case CP0_REG29__TAGHI1: 8014 case CP0_REG29__TAGHI2: 8015 case CP0_REG29__TAGHI3: 8016 gen_helper_mtc0_taghi(tcg_env, arg); 8017 register_name = "TagHi"; 8018 break; 8019 case CP0_REG29__DATAHI: 8020 case CP0_REG29__DATAHI1: 8021 case CP0_REG29__DATAHI2: 8022 case CP0_REG29__DATAHI3: 8023 gen_helper_mtc0_datahi(tcg_env, arg); 8024 register_name = "DataHi"; 8025 break; 8026 default: 8027 register_name = "invalid sel"; 8028 goto cp0_unimplemented; 8029 } 8030 break; 8031 case CP0_REGISTER_30: 8032 switch (sel) { 8033 case CP0_REG30__ERROREPC: 8034 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 8035 register_name = "ErrorEPC"; 8036 break; 8037 default: 8038 goto cp0_unimplemented; 8039 } 8040 break; 8041 case CP0_REGISTER_31: 8042 switch (sel) { 8043 case CP0_REG31__DESAVE: 8044 /* EJTAG support */ 8045 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 8046 register_name = "DESAVE"; 8047 break; 8048 case CP0_REG31__KSCRATCH1: 8049 case CP0_REG31__KSCRATCH2: 8050 case CP0_REG31__KSCRATCH3: 8051 case CP0_REG31__KSCRATCH4: 8052 case CP0_REG31__KSCRATCH5: 8053 case CP0_REG31__KSCRATCH6: 8054 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8055 tcg_gen_st_tl(arg, tcg_env, 8056 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8057 register_name = "KScratch"; 8058 break; 8059 default: 8060 goto cp0_unimplemented; 8061 } 8062 break; 8063 default: 8064 goto cp0_unimplemented; 8065 } 8066 trace_mips_translate_c0("dmtc0", register_name, reg, sel); 8067 8068 /* For simplicity assume that all writes can cause interrupts. */ 8069 if (icount) { 8070 /* 8071 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8072 * translated code to check for pending interrupts. 8073 */ 8074 gen_save_pc(ctx->base.pc_next + 4); 8075 ctx->base.is_jmp = DISAS_EXIT; 8076 } 8077 return; 8078 8079 cp0_unimplemented: 8080 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", 8081 register_name, reg, sel); 8082 } 8083 #endif /* TARGET_MIPS64 */ 8084 8085 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 8086 int u, int sel, int h) 8087 { 8088 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8089 TCGv t0 = tcg_temp_new(); 8090 8091 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8092 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8093 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8094 tcg_gen_movi_tl(t0, -1); 8095 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8096 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8097 tcg_gen_movi_tl(t0, -1); 8098 } else if (u == 0) { 8099 switch (rt) { 8100 case 1: 8101 switch (sel) { 8102 case 1: 8103 gen_helper_mftc0_vpecontrol(t0, tcg_env); 8104 break; 8105 case 2: 8106 gen_helper_mftc0_vpeconf0(t0, tcg_env); 8107 break; 8108 default: 8109 goto die; 8110 break; 8111 } 8112 break; 8113 case 2: 8114 switch (sel) { 8115 case 1: 8116 gen_helper_mftc0_tcstatus(t0, tcg_env); 8117 break; 8118 case 2: 8119 gen_helper_mftc0_tcbind(t0, tcg_env); 8120 break; 8121 case 3: 8122 gen_helper_mftc0_tcrestart(t0, tcg_env); 8123 break; 8124 case 4: 8125 gen_helper_mftc0_tchalt(t0, tcg_env); 8126 break; 8127 case 5: 8128 gen_helper_mftc0_tccontext(t0, tcg_env); 8129 break; 8130 case 6: 8131 gen_helper_mftc0_tcschedule(t0, tcg_env); 8132 break; 8133 case 7: 8134 gen_helper_mftc0_tcschefback(t0, tcg_env); 8135 break; 8136 default: 8137 gen_mfc0(ctx, t0, rt, sel); 8138 break; 8139 } 8140 break; 8141 case 10: 8142 switch (sel) { 8143 case 0: 8144 gen_helper_mftc0_entryhi(t0, tcg_env); 8145 break; 8146 default: 8147 gen_mfc0(ctx, t0, rt, sel); 8148 break; 8149 } 8150 break; 8151 case 12: 8152 switch (sel) { 8153 case 0: 8154 gen_helper_mftc0_status(t0, tcg_env); 8155 break; 8156 default: 8157 gen_mfc0(ctx, t0, rt, sel); 8158 break; 8159 } 8160 break; 8161 case 13: 8162 switch (sel) { 8163 case 0: 8164 gen_helper_mftc0_cause(t0, tcg_env); 8165 break; 8166 default: 8167 goto die; 8168 break; 8169 } 8170 break; 8171 case 14: 8172 switch (sel) { 8173 case 0: 8174 gen_helper_mftc0_epc(t0, tcg_env); 8175 break; 8176 default: 8177 goto die; 8178 break; 8179 } 8180 break; 8181 case 15: 8182 switch (sel) { 8183 case 1: 8184 gen_helper_mftc0_ebase(t0, tcg_env); 8185 break; 8186 default: 8187 goto die; 8188 break; 8189 } 8190 break; 8191 case 16: 8192 switch (sel) { 8193 case 0: 8194 case 1: 8195 case 2: 8196 case 3: 8197 case 4: 8198 case 5: 8199 case 6: 8200 case 7: 8201 gen_helper_mftc0_configx(t0, tcg_env, tcg_constant_tl(sel)); 8202 break; 8203 default: 8204 goto die; 8205 break; 8206 } 8207 break; 8208 case 23: 8209 switch (sel) { 8210 case 0: 8211 gen_helper_mftc0_debug(t0, tcg_env); 8212 break; 8213 default: 8214 gen_mfc0(ctx, t0, rt, sel); 8215 break; 8216 } 8217 break; 8218 default: 8219 gen_mfc0(ctx, t0, rt, sel); 8220 } 8221 } else { 8222 switch (sel) { 8223 /* GPR registers. */ 8224 case 0: 8225 gen_helper_1e0i(mftgpr, t0, rt); 8226 break; 8227 /* Auxiliary CPU registers */ 8228 case 1: 8229 switch (rt) { 8230 case 0: 8231 gen_helper_1e0i(mftlo, t0, 0); 8232 break; 8233 case 1: 8234 gen_helper_1e0i(mfthi, t0, 0); 8235 break; 8236 case 2: 8237 gen_helper_1e0i(mftacx, t0, 0); 8238 break; 8239 case 4: 8240 gen_helper_1e0i(mftlo, t0, 1); 8241 break; 8242 case 5: 8243 gen_helper_1e0i(mfthi, t0, 1); 8244 break; 8245 case 6: 8246 gen_helper_1e0i(mftacx, t0, 1); 8247 break; 8248 case 8: 8249 gen_helper_1e0i(mftlo, t0, 2); 8250 break; 8251 case 9: 8252 gen_helper_1e0i(mfthi, t0, 2); 8253 break; 8254 case 10: 8255 gen_helper_1e0i(mftacx, t0, 2); 8256 break; 8257 case 12: 8258 gen_helper_1e0i(mftlo, t0, 3); 8259 break; 8260 case 13: 8261 gen_helper_1e0i(mfthi, t0, 3); 8262 break; 8263 case 14: 8264 gen_helper_1e0i(mftacx, t0, 3); 8265 break; 8266 case 16: 8267 gen_helper_mftdsp(t0, tcg_env); 8268 break; 8269 default: 8270 goto die; 8271 } 8272 break; 8273 /* Floating point (COP1). */ 8274 case 2: 8275 /* XXX: For now we support only a single FPU context. */ 8276 if (h == 0) { 8277 TCGv_i32 fp0 = tcg_temp_new_i32(); 8278 8279 gen_load_fpr32(ctx, fp0, rt); 8280 tcg_gen_ext_i32_tl(t0, fp0); 8281 } else { 8282 TCGv_i32 fp0 = tcg_temp_new_i32(); 8283 8284 gen_load_fpr32h(ctx, fp0, rt); 8285 tcg_gen_ext_i32_tl(t0, fp0); 8286 } 8287 break; 8288 case 3: 8289 /* XXX: For now we support only a single FPU context. */ 8290 gen_helper_1e0i(cfc1, t0, rt); 8291 break; 8292 /* COP2: Not implemented. */ 8293 case 4: 8294 case 5: 8295 /* fall through */ 8296 default: 8297 goto die; 8298 } 8299 } 8300 trace_mips_translate_tr("mftr", rt, u, sel, h); 8301 gen_store_gpr(t0, rd); 8302 return; 8303 8304 die: 8305 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 8306 gen_reserved_instruction(ctx); 8307 } 8308 8309 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 8310 int u, int sel, int h) 8311 { 8312 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8313 TCGv t0 = tcg_temp_new(); 8314 8315 gen_load_gpr(t0, rt); 8316 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8317 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8318 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8319 /* NOP */ 8320 ; 8321 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8322 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8323 /* NOP */ 8324 ; 8325 } else if (u == 0) { 8326 switch (rd) { 8327 case 1: 8328 switch (sel) { 8329 case 1: 8330 gen_helper_mttc0_vpecontrol(tcg_env, t0); 8331 break; 8332 case 2: 8333 gen_helper_mttc0_vpeconf0(tcg_env, t0); 8334 break; 8335 default: 8336 goto die; 8337 break; 8338 } 8339 break; 8340 case 2: 8341 switch (sel) { 8342 case 1: 8343 gen_helper_mttc0_tcstatus(tcg_env, t0); 8344 break; 8345 case 2: 8346 gen_helper_mttc0_tcbind(tcg_env, t0); 8347 break; 8348 case 3: 8349 gen_helper_mttc0_tcrestart(tcg_env, t0); 8350 break; 8351 case 4: 8352 gen_helper_mttc0_tchalt(tcg_env, t0); 8353 break; 8354 case 5: 8355 gen_helper_mttc0_tccontext(tcg_env, t0); 8356 break; 8357 case 6: 8358 gen_helper_mttc0_tcschedule(tcg_env, t0); 8359 break; 8360 case 7: 8361 gen_helper_mttc0_tcschefback(tcg_env, t0); 8362 break; 8363 default: 8364 gen_mtc0(ctx, t0, rd, sel); 8365 break; 8366 } 8367 break; 8368 case 10: 8369 switch (sel) { 8370 case 0: 8371 gen_helper_mttc0_entryhi(tcg_env, t0); 8372 break; 8373 default: 8374 gen_mtc0(ctx, t0, rd, sel); 8375 break; 8376 } 8377 break; 8378 case 12: 8379 switch (sel) { 8380 case 0: 8381 gen_helper_mttc0_status(tcg_env, t0); 8382 break; 8383 default: 8384 gen_mtc0(ctx, t0, rd, sel); 8385 break; 8386 } 8387 break; 8388 case 13: 8389 switch (sel) { 8390 case 0: 8391 gen_helper_mttc0_cause(tcg_env, t0); 8392 break; 8393 default: 8394 goto die; 8395 break; 8396 } 8397 break; 8398 case 15: 8399 switch (sel) { 8400 case 1: 8401 gen_helper_mttc0_ebase(tcg_env, t0); 8402 break; 8403 default: 8404 goto die; 8405 break; 8406 } 8407 break; 8408 case 23: 8409 switch (sel) { 8410 case 0: 8411 gen_helper_mttc0_debug(tcg_env, t0); 8412 break; 8413 default: 8414 gen_mtc0(ctx, t0, rd, sel); 8415 break; 8416 } 8417 break; 8418 default: 8419 gen_mtc0(ctx, t0, rd, sel); 8420 } 8421 } else { 8422 switch (sel) { 8423 /* GPR registers. */ 8424 case 0: 8425 gen_helper_0e1i(mttgpr, t0, rd); 8426 break; 8427 /* Auxiliary CPU registers */ 8428 case 1: 8429 switch (rd) { 8430 case 0: 8431 gen_helper_0e1i(mttlo, t0, 0); 8432 break; 8433 case 1: 8434 gen_helper_0e1i(mtthi, t0, 0); 8435 break; 8436 case 2: 8437 gen_helper_0e1i(mttacx, t0, 0); 8438 break; 8439 case 4: 8440 gen_helper_0e1i(mttlo, t0, 1); 8441 break; 8442 case 5: 8443 gen_helper_0e1i(mtthi, t0, 1); 8444 break; 8445 case 6: 8446 gen_helper_0e1i(mttacx, t0, 1); 8447 break; 8448 case 8: 8449 gen_helper_0e1i(mttlo, t0, 2); 8450 break; 8451 case 9: 8452 gen_helper_0e1i(mtthi, t0, 2); 8453 break; 8454 case 10: 8455 gen_helper_0e1i(mttacx, t0, 2); 8456 break; 8457 case 12: 8458 gen_helper_0e1i(mttlo, t0, 3); 8459 break; 8460 case 13: 8461 gen_helper_0e1i(mtthi, t0, 3); 8462 break; 8463 case 14: 8464 gen_helper_0e1i(mttacx, t0, 3); 8465 break; 8466 case 16: 8467 gen_helper_mttdsp(tcg_env, t0); 8468 break; 8469 default: 8470 goto die; 8471 } 8472 break; 8473 /* Floating point (COP1). */ 8474 case 2: 8475 /* XXX: For now we support only a single FPU context. */ 8476 if (h == 0) { 8477 TCGv_i32 fp0 = tcg_temp_new_i32(); 8478 8479 tcg_gen_trunc_tl_i32(fp0, t0); 8480 gen_store_fpr32(ctx, fp0, rd); 8481 } else { 8482 TCGv_i32 fp0 = tcg_temp_new_i32(); 8483 8484 tcg_gen_trunc_tl_i32(fp0, t0); 8485 gen_store_fpr32h(ctx, fp0, rd); 8486 } 8487 break; 8488 case 3: 8489 /* XXX: For now we support only a single FPU context. */ 8490 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt); 8491 /* Stop translation as we may have changed hflags */ 8492 ctx->base.is_jmp = DISAS_STOP; 8493 break; 8494 /* COP2: Not implemented. */ 8495 case 4: 8496 case 5: 8497 /* fall through */ 8498 default: 8499 goto die; 8500 } 8501 } 8502 trace_mips_translate_tr("mttr", rd, u, sel, h); 8503 return; 8504 8505 die: 8506 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 8507 gen_reserved_instruction(ctx); 8508 } 8509 8510 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 8511 int rt, int rd) 8512 { 8513 const char *opn = "ldst"; 8514 8515 check_cp0_enabled(ctx); 8516 switch (opc) { 8517 case OPC_MFC0: 8518 if (rt == 0) { 8519 /* Treat as NOP. */ 8520 return; 8521 } 8522 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8523 opn = "mfc0"; 8524 break; 8525 case OPC_MTC0: 8526 { 8527 TCGv t0 = tcg_temp_new(); 8528 8529 gen_load_gpr(t0, rt); 8530 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7); 8531 } 8532 opn = "mtc0"; 8533 break; 8534 #if defined(TARGET_MIPS64) 8535 case OPC_DMFC0: 8536 check_insn(ctx, ISA_MIPS3); 8537 if (rt == 0) { 8538 /* Treat as NOP. */ 8539 return; 8540 } 8541 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8542 opn = "dmfc0"; 8543 break; 8544 case OPC_DMTC0: 8545 check_insn(ctx, ISA_MIPS3); 8546 { 8547 TCGv t0 = tcg_temp_new(); 8548 8549 gen_load_gpr(t0, rt); 8550 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7); 8551 } 8552 opn = "dmtc0"; 8553 break; 8554 #endif 8555 case OPC_MFHC0: 8556 check_mvh(ctx); 8557 if (rt == 0) { 8558 /* Treat as NOP. */ 8559 return; 8560 } 8561 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8562 opn = "mfhc0"; 8563 break; 8564 case OPC_MTHC0: 8565 check_mvh(ctx); 8566 { 8567 TCGv t0 = tcg_temp_new(); 8568 gen_load_gpr(t0, rt); 8569 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7); 8570 } 8571 opn = "mthc0"; 8572 break; 8573 case OPC_MFTR: 8574 check_cp0_enabled(ctx); 8575 if (rd == 0) { 8576 /* Treat as NOP. */ 8577 return; 8578 } 8579 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 8580 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 8581 opn = "mftr"; 8582 break; 8583 case OPC_MTTR: 8584 check_cp0_enabled(ctx); 8585 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 8586 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 8587 opn = "mttr"; 8588 break; 8589 case OPC_TLBWI: 8590 opn = "tlbwi"; 8591 if (!env->tlb->helper_tlbwi) { 8592 goto die; 8593 } 8594 gen_helper_tlbwi(tcg_env); 8595 break; 8596 case OPC_TLBINV: 8597 opn = "tlbinv"; 8598 if (ctx->ie >= 2) { 8599 if (!env->tlb->helper_tlbinv) { 8600 goto die; 8601 } 8602 gen_helper_tlbinv(tcg_env); 8603 } /* treat as nop if TLBINV not supported */ 8604 break; 8605 case OPC_TLBINVF: 8606 opn = "tlbinvf"; 8607 if (ctx->ie >= 2) { 8608 if (!env->tlb->helper_tlbinvf) { 8609 goto die; 8610 } 8611 gen_helper_tlbinvf(tcg_env); 8612 } /* treat as nop if TLBINV not supported */ 8613 break; 8614 case OPC_TLBWR: 8615 opn = "tlbwr"; 8616 if (!env->tlb->helper_tlbwr) { 8617 goto die; 8618 } 8619 gen_helper_tlbwr(tcg_env); 8620 break; 8621 case OPC_TLBP: 8622 opn = "tlbp"; 8623 if (!env->tlb->helper_tlbp) { 8624 goto die; 8625 } 8626 gen_helper_tlbp(tcg_env); 8627 break; 8628 case OPC_TLBR: 8629 opn = "tlbr"; 8630 if (!env->tlb->helper_tlbr) { 8631 goto die; 8632 } 8633 gen_helper_tlbr(tcg_env); 8634 break; 8635 case OPC_ERET: /* OPC_ERETNC */ 8636 if ((ctx->insn_flags & ISA_MIPS_R6) && 8637 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8638 goto die; 8639 } else { 8640 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6; 8641 if (ctx->opcode & (1 << bit_shift)) { 8642 /* OPC_ERETNC */ 8643 opn = "eretnc"; 8644 check_insn(ctx, ISA_MIPS_R5); 8645 gen_helper_eretnc(tcg_env); 8646 } else { 8647 /* OPC_ERET */ 8648 opn = "eret"; 8649 check_insn(ctx, ISA_MIPS2); 8650 gen_helper_eret(tcg_env); 8651 } 8652 ctx->base.is_jmp = DISAS_EXIT; 8653 } 8654 break; 8655 case OPC_DERET: 8656 opn = "deret"; 8657 check_insn(ctx, ISA_MIPS_R1); 8658 if ((ctx->insn_flags & ISA_MIPS_R6) && 8659 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8660 goto die; 8661 } 8662 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 8663 MIPS_INVAL(opn); 8664 gen_reserved_instruction(ctx); 8665 } else { 8666 gen_helper_deret(tcg_env); 8667 ctx->base.is_jmp = DISAS_EXIT; 8668 } 8669 break; 8670 case OPC_WAIT: 8671 opn = "wait"; 8672 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 8673 if ((ctx->insn_flags & ISA_MIPS_R6) && 8674 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8675 goto die; 8676 } 8677 /* If we get an exception, we want to restart at next instruction */ 8678 ctx->base.pc_next += 4; 8679 save_cpu_state(ctx, 1); 8680 ctx->base.pc_next -= 4; 8681 gen_helper_wait(tcg_env); 8682 ctx->base.is_jmp = DISAS_NORETURN; 8683 break; 8684 default: 8685 die: 8686 MIPS_INVAL(opn); 8687 gen_reserved_instruction(ctx); 8688 return; 8689 } 8690 (void)opn; /* avoid a compiler warning */ 8691 } 8692 #endif /* !CONFIG_USER_ONLY */ 8693 8694 /* CP1 Branches (before delay slot) */ 8695 static void gen_compute_branch1(DisasContext *ctx, uint32_t op, 8696 int32_t cc, int32_t offset) 8697 { 8698 target_ulong btarget; 8699 TCGv_i32 t0 = tcg_temp_new_i32(); 8700 8701 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { 8702 gen_reserved_instruction(ctx); 8703 return; 8704 } 8705 8706 if (cc != 0) { 8707 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 8708 } 8709 8710 btarget = ctx->base.pc_next + 4 + offset; 8711 8712 switch (op) { 8713 case OPC_BC1F: 8714 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8715 tcg_gen_not_i32(t0, t0); 8716 tcg_gen_andi_i32(t0, t0, 1); 8717 tcg_gen_extu_i32_tl(bcond, t0); 8718 goto not_likely; 8719 case OPC_BC1FL: 8720 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8721 tcg_gen_not_i32(t0, t0); 8722 tcg_gen_andi_i32(t0, t0, 1); 8723 tcg_gen_extu_i32_tl(bcond, t0); 8724 goto likely; 8725 case OPC_BC1T: 8726 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8727 tcg_gen_andi_i32(t0, t0, 1); 8728 tcg_gen_extu_i32_tl(bcond, t0); 8729 goto not_likely; 8730 case OPC_BC1TL: 8731 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8732 tcg_gen_andi_i32(t0, t0, 1); 8733 tcg_gen_extu_i32_tl(bcond, t0); 8734 likely: 8735 ctx->hflags |= MIPS_HFLAG_BL; 8736 break; 8737 case OPC_BC1FANY2: 8738 { 8739 TCGv_i32 t1 = tcg_temp_new_i32(); 8740 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8741 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8742 tcg_gen_nand_i32(t0, t0, t1); 8743 tcg_gen_andi_i32(t0, t0, 1); 8744 tcg_gen_extu_i32_tl(bcond, t0); 8745 } 8746 goto not_likely; 8747 case OPC_BC1TANY2: 8748 { 8749 TCGv_i32 t1 = tcg_temp_new_i32(); 8750 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8751 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8752 tcg_gen_or_i32(t0, t0, t1); 8753 tcg_gen_andi_i32(t0, t0, 1); 8754 tcg_gen_extu_i32_tl(bcond, t0); 8755 } 8756 goto not_likely; 8757 case OPC_BC1FANY4: 8758 { 8759 TCGv_i32 t1 = tcg_temp_new_i32(); 8760 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8761 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8762 tcg_gen_and_i32(t0, t0, t1); 8763 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 8764 tcg_gen_and_i32(t0, t0, t1); 8765 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 8766 tcg_gen_nand_i32(t0, t0, t1); 8767 tcg_gen_andi_i32(t0, t0, 1); 8768 tcg_gen_extu_i32_tl(bcond, t0); 8769 } 8770 goto not_likely; 8771 case OPC_BC1TANY4: 8772 { 8773 TCGv_i32 t1 = tcg_temp_new_i32(); 8774 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8775 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8776 tcg_gen_or_i32(t0, t0, t1); 8777 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 8778 tcg_gen_or_i32(t0, t0, t1); 8779 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 8780 tcg_gen_or_i32(t0, t0, t1); 8781 tcg_gen_andi_i32(t0, t0, 1); 8782 tcg_gen_extu_i32_tl(bcond, t0); 8783 } 8784 not_likely: 8785 ctx->hflags |= MIPS_HFLAG_BC; 8786 break; 8787 default: 8788 MIPS_INVAL("cp1 cond branch"); 8789 gen_reserved_instruction(ctx); 8790 return; 8791 } 8792 ctx->btarget = btarget; 8793 ctx->hflags |= MIPS_HFLAG_BDS32; 8794 } 8795 8796 /* R6 CP1 Branches */ 8797 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, 8798 int32_t ft, int32_t offset, 8799 int delayslot_size) 8800 { 8801 target_ulong btarget; 8802 TCGv_i64 t0 = tcg_temp_new_i64(); 8803 8804 if (ctx->hflags & MIPS_HFLAG_BMASK) { 8805 #ifdef MIPS_DEBUG_DISAS 8806 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 8807 VADDR_PRIx "\n", ctx->base.pc_next); 8808 #endif 8809 gen_reserved_instruction(ctx); 8810 return; 8811 } 8812 8813 gen_load_fpr64(ctx, t0, ft); 8814 tcg_gen_andi_i64(t0, t0, 1); 8815 8816 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 8817 8818 switch (op) { 8819 case OPC_BC1EQZ: 8820 tcg_gen_xori_i64(t0, t0, 1); 8821 ctx->hflags |= MIPS_HFLAG_BC; 8822 break; 8823 case OPC_BC1NEZ: 8824 /* t0 already set */ 8825 ctx->hflags |= MIPS_HFLAG_BC; 8826 break; 8827 default: 8828 MIPS_INVAL("cp1 cond branch"); 8829 gen_reserved_instruction(ctx); 8830 return; 8831 } 8832 8833 tcg_gen_trunc_i64_tl(bcond, t0); 8834 8835 ctx->btarget = btarget; 8836 8837 switch (delayslot_size) { 8838 case 2: 8839 ctx->hflags |= MIPS_HFLAG_BDS16; 8840 break; 8841 case 4: 8842 ctx->hflags |= MIPS_HFLAG_BDS32; 8843 break; 8844 } 8845 } 8846 8847 /* Coprocessor 1 (FPU) */ 8848 8849 #define FOP(func, fmt) (((fmt) << 21) | (func)) 8850 8851 enum fopcode { 8852 OPC_ADD_S = FOP(0, FMT_S), 8853 OPC_SUB_S = FOP(1, FMT_S), 8854 OPC_MUL_S = FOP(2, FMT_S), 8855 OPC_DIV_S = FOP(3, FMT_S), 8856 OPC_SQRT_S = FOP(4, FMT_S), 8857 OPC_ABS_S = FOP(5, FMT_S), 8858 OPC_MOV_S = FOP(6, FMT_S), 8859 OPC_NEG_S = FOP(7, FMT_S), 8860 OPC_ROUND_L_S = FOP(8, FMT_S), 8861 OPC_TRUNC_L_S = FOP(9, FMT_S), 8862 OPC_CEIL_L_S = FOP(10, FMT_S), 8863 OPC_FLOOR_L_S = FOP(11, FMT_S), 8864 OPC_ROUND_W_S = FOP(12, FMT_S), 8865 OPC_TRUNC_W_S = FOP(13, FMT_S), 8866 OPC_CEIL_W_S = FOP(14, FMT_S), 8867 OPC_FLOOR_W_S = FOP(15, FMT_S), 8868 OPC_SEL_S = FOP(16, FMT_S), 8869 OPC_MOVCF_S = FOP(17, FMT_S), 8870 OPC_MOVZ_S = FOP(18, FMT_S), 8871 OPC_MOVN_S = FOP(19, FMT_S), 8872 OPC_SELEQZ_S = FOP(20, FMT_S), 8873 OPC_RECIP_S = FOP(21, FMT_S), 8874 OPC_RSQRT_S = FOP(22, FMT_S), 8875 OPC_SELNEZ_S = FOP(23, FMT_S), 8876 OPC_MADDF_S = FOP(24, FMT_S), 8877 OPC_MSUBF_S = FOP(25, FMT_S), 8878 OPC_RINT_S = FOP(26, FMT_S), 8879 OPC_CLASS_S = FOP(27, FMT_S), 8880 OPC_MIN_S = FOP(28, FMT_S), 8881 OPC_RECIP2_S = FOP(28, FMT_S), 8882 OPC_MINA_S = FOP(29, FMT_S), 8883 OPC_RECIP1_S = FOP(29, FMT_S), 8884 OPC_MAX_S = FOP(30, FMT_S), 8885 OPC_RSQRT1_S = FOP(30, FMT_S), 8886 OPC_MAXA_S = FOP(31, FMT_S), 8887 OPC_RSQRT2_S = FOP(31, FMT_S), 8888 OPC_CVT_D_S = FOP(33, FMT_S), 8889 OPC_CVT_W_S = FOP(36, FMT_S), 8890 OPC_CVT_L_S = FOP(37, FMT_S), 8891 OPC_CVT_PS_S = FOP(38, FMT_S), 8892 OPC_CMP_F_S = FOP(48, FMT_S), 8893 OPC_CMP_UN_S = FOP(49, FMT_S), 8894 OPC_CMP_EQ_S = FOP(50, FMT_S), 8895 OPC_CMP_UEQ_S = FOP(51, FMT_S), 8896 OPC_CMP_OLT_S = FOP(52, FMT_S), 8897 OPC_CMP_ULT_S = FOP(53, FMT_S), 8898 OPC_CMP_OLE_S = FOP(54, FMT_S), 8899 OPC_CMP_ULE_S = FOP(55, FMT_S), 8900 OPC_CMP_SF_S = FOP(56, FMT_S), 8901 OPC_CMP_NGLE_S = FOP(57, FMT_S), 8902 OPC_CMP_SEQ_S = FOP(58, FMT_S), 8903 OPC_CMP_NGL_S = FOP(59, FMT_S), 8904 OPC_CMP_LT_S = FOP(60, FMT_S), 8905 OPC_CMP_NGE_S = FOP(61, FMT_S), 8906 OPC_CMP_LE_S = FOP(62, FMT_S), 8907 OPC_CMP_NGT_S = FOP(63, FMT_S), 8908 8909 OPC_ADD_D = FOP(0, FMT_D), 8910 OPC_SUB_D = FOP(1, FMT_D), 8911 OPC_MUL_D = FOP(2, FMT_D), 8912 OPC_DIV_D = FOP(3, FMT_D), 8913 OPC_SQRT_D = FOP(4, FMT_D), 8914 OPC_ABS_D = FOP(5, FMT_D), 8915 OPC_MOV_D = FOP(6, FMT_D), 8916 OPC_NEG_D = FOP(7, FMT_D), 8917 OPC_ROUND_L_D = FOP(8, FMT_D), 8918 OPC_TRUNC_L_D = FOP(9, FMT_D), 8919 OPC_CEIL_L_D = FOP(10, FMT_D), 8920 OPC_FLOOR_L_D = FOP(11, FMT_D), 8921 OPC_ROUND_W_D = FOP(12, FMT_D), 8922 OPC_TRUNC_W_D = FOP(13, FMT_D), 8923 OPC_CEIL_W_D = FOP(14, FMT_D), 8924 OPC_FLOOR_W_D = FOP(15, FMT_D), 8925 OPC_SEL_D = FOP(16, FMT_D), 8926 OPC_MOVCF_D = FOP(17, FMT_D), 8927 OPC_MOVZ_D = FOP(18, FMT_D), 8928 OPC_MOVN_D = FOP(19, FMT_D), 8929 OPC_SELEQZ_D = FOP(20, FMT_D), 8930 OPC_RECIP_D = FOP(21, FMT_D), 8931 OPC_RSQRT_D = FOP(22, FMT_D), 8932 OPC_SELNEZ_D = FOP(23, FMT_D), 8933 OPC_MADDF_D = FOP(24, FMT_D), 8934 OPC_MSUBF_D = FOP(25, FMT_D), 8935 OPC_RINT_D = FOP(26, FMT_D), 8936 OPC_CLASS_D = FOP(27, FMT_D), 8937 OPC_MIN_D = FOP(28, FMT_D), 8938 OPC_RECIP2_D = FOP(28, FMT_D), 8939 OPC_MINA_D = FOP(29, FMT_D), 8940 OPC_RECIP1_D = FOP(29, FMT_D), 8941 OPC_MAX_D = FOP(30, FMT_D), 8942 OPC_RSQRT1_D = FOP(30, FMT_D), 8943 OPC_MAXA_D = FOP(31, FMT_D), 8944 OPC_RSQRT2_D = FOP(31, FMT_D), 8945 OPC_CVT_S_D = FOP(32, FMT_D), 8946 OPC_CVT_W_D = FOP(36, FMT_D), 8947 OPC_CVT_L_D = FOP(37, FMT_D), 8948 OPC_CMP_F_D = FOP(48, FMT_D), 8949 OPC_CMP_UN_D = FOP(49, FMT_D), 8950 OPC_CMP_EQ_D = FOP(50, FMT_D), 8951 OPC_CMP_UEQ_D = FOP(51, FMT_D), 8952 OPC_CMP_OLT_D = FOP(52, FMT_D), 8953 OPC_CMP_ULT_D = FOP(53, FMT_D), 8954 OPC_CMP_OLE_D = FOP(54, FMT_D), 8955 OPC_CMP_ULE_D = FOP(55, FMT_D), 8956 OPC_CMP_SF_D = FOP(56, FMT_D), 8957 OPC_CMP_NGLE_D = FOP(57, FMT_D), 8958 OPC_CMP_SEQ_D = FOP(58, FMT_D), 8959 OPC_CMP_NGL_D = FOP(59, FMT_D), 8960 OPC_CMP_LT_D = FOP(60, FMT_D), 8961 OPC_CMP_NGE_D = FOP(61, FMT_D), 8962 OPC_CMP_LE_D = FOP(62, FMT_D), 8963 OPC_CMP_NGT_D = FOP(63, FMT_D), 8964 8965 OPC_CVT_S_W = FOP(32, FMT_W), 8966 OPC_CVT_D_W = FOP(33, FMT_W), 8967 OPC_CVT_S_L = FOP(32, FMT_L), 8968 OPC_CVT_D_L = FOP(33, FMT_L), 8969 OPC_CVT_PS_PW = FOP(38, FMT_W), 8970 8971 OPC_ADD_PS = FOP(0, FMT_PS), 8972 OPC_SUB_PS = FOP(1, FMT_PS), 8973 OPC_MUL_PS = FOP(2, FMT_PS), 8974 OPC_DIV_PS = FOP(3, FMT_PS), 8975 OPC_ABS_PS = FOP(5, FMT_PS), 8976 OPC_MOV_PS = FOP(6, FMT_PS), 8977 OPC_NEG_PS = FOP(7, FMT_PS), 8978 OPC_MOVCF_PS = FOP(17, FMT_PS), 8979 OPC_MOVZ_PS = FOP(18, FMT_PS), 8980 OPC_MOVN_PS = FOP(19, FMT_PS), 8981 OPC_ADDR_PS = FOP(24, FMT_PS), 8982 OPC_MULR_PS = FOP(26, FMT_PS), 8983 OPC_RECIP2_PS = FOP(28, FMT_PS), 8984 OPC_RECIP1_PS = FOP(29, FMT_PS), 8985 OPC_RSQRT1_PS = FOP(30, FMT_PS), 8986 OPC_RSQRT2_PS = FOP(31, FMT_PS), 8987 8988 OPC_CVT_S_PU = FOP(32, FMT_PS), 8989 OPC_CVT_PW_PS = FOP(36, FMT_PS), 8990 OPC_CVT_S_PL = FOP(40, FMT_PS), 8991 OPC_PLL_PS = FOP(44, FMT_PS), 8992 OPC_PLU_PS = FOP(45, FMT_PS), 8993 OPC_PUL_PS = FOP(46, FMT_PS), 8994 OPC_PUU_PS = FOP(47, FMT_PS), 8995 OPC_CMP_F_PS = FOP(48, FMT_PS), 8996 OPC_CMP_UN_PS = FOP(49, FMT_PS), 8997 OPC_CMP_EQ_PS = FOP(50, FMT_PS), 8998 OPC_CMP_UEQ_PS = FOP(51, FMT_PS), 8999 OPC_CMP_OLT_PS = FOP(52, FMT_PS), 9000 OPC_CMP_ULT_PS = FOP(53, FMT_PS), 9001 OPC_CMP_OLE_PS = FOP(54, FMT_PS), 9002 OPC_CMP_ULE_PS = FOP(55, FMT_PS), 9003 OPC_CMP_SF_PS = FOP(56, FMT_PS), 9004 OPC_CMP_NGLE_PS = FOP(57, FMT_PS), 9005 OPC_CMP_SEQ_PS = FOP(58, FMT_PS), 9006 OPC_CMP_NGL_PS = FOP(59, FMT_PS), 9007 OPC_CMP_LT_PS = FOP(60, FMT_PS), 9008 OPC_CMP_NGE_PS = FOP(61, FMT_PS), 9009 OPC_CMP_LE_PS = FOP(62, FMT_PS), 9010 OPC_CMP_NGT_PS = FOP(63, FMT_PS), 9011 }; 9012 9013 enum r6_f_cmp_op { 9014 R6_OPC_CMP_AF_S = FOP(0, FMT_W), 9015 R6_OPC_CMP_UN_S = FOP(1, FMT_W), 9016 R6_OPC_CMP_EQ_S = FOP(2, FMT_W), 9017 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W), 9018 R6_OPC_CMP_LT_S = FOP(4, FMT_W), 9019 R6_OPC_CMP_ULT_S = FOP(5, FMT_W), 9020 R6_OPC_CMP_LE_S = FOP(6, FMT_W), 9021 R6_OPC_CMP_ULE_S = FOP(7, FMT_W), 9022 R6_OPC_CMP_SAF_S = FOP(8, FMT_W), 9023 R6_OPC_CMP_SUN_S = FOP(9, FMT_W), 9024 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W), 9025 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W), 9026 R6_OPC_CMP_SLT_S = FOP(12, FMT_W), 9027 R6_OPC_CMP_SULT_S = FOP(13, FMT_W), 9028 R6_OPC_CMP_SLE_S = FOP(14, FMT_W), 9029 R6_OPC_CMP_SULE_S = FOP(15, FMT_W), 9030 R6_OPC_CMP_OR_S = FOP(17, FMT_W), 9031 R6_OPC_CMP_UNE_S = FOP(18, FMT_W), 9032 R6_OPC_CMP_NE_S = FOP(19, FMT_W), 9033 R6_OPC_CMP_SOR_S = FOP(25, FMT_W), 9034 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W), 9035 R6_OPC_CMP_SNE_S = FOP(27, FMT_W), 9036 9037 R6_OPC_CMP_AF_D = FOP(0, FMT_L), 9038 R6_OPC_CMP_UN_D = FOP(1, FMT_L), 9039 R6_OPC_CMP_EQ_D = FOP(2, FMT_L), 9040 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L), 9041 R6_OPC_CMP_LT_D = FOP(4, FMT_L), 9042 R6_OPC_CMP_ULT_D = FOP(5, FMT_L), 9043 R6_OPC_CMP_LE_D = FOP(6, FMT_L), 9044 R6_OPC_CMP_ULE_D = FOP(7, FMT_L), 9045 R6_OPC_CMP_SAF_D = FOP(8, FMT_L), 9046 R6_OPC_CMP_SUN_D = FOP(9, FMT_L), 9047 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L), 9048 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L), 9049 R6_OPC_CMP_SLT_D = FOP(12, FMT_L), 9050 R6_OPC_CMP_SULT_D = FOP(13, FMT_L), 9051 R6_OPC_CMP_SLE_D = FOP(14, FMT_L), 9052 R6_OPC_CMP_SULE_D = FOP(15, FMT_L), 9053 R6_OPC_CMP_OR_D = FOP(17, FMT_L), 9054 R6_OPC_CMP_UNE_D = FOP(18, FMT_L), 9055 R6_OPC_CMP_NE_D = FOP(19, FMT_L), 9056 R6_OPC_CMP_SOR_D = FOP(25, FMT_L), 9057 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L), 9058 R6_OPC_CMP_SNE_D = FOP(27, FMT_L), 9059 }; 9060 9061 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) 9062 { 9063 TCGv t0 = tcg_temp_new(); 9064 9065 switch (opc) { 9066 case OPC_MFC1: 9067 { 9068 TCGv_i32 fp0 = tcg_temp_new_i32(); 9069 9070 gen_load_fpr32(ctx, fp0, fs); 9071 tcg_gen_ext_i32_tl(t0, fp0); 9072 } 9073 gen_store_gpr(t0, rt); 9074 break; 9075 case OPC_MTC1: 9076 gen_load_gpr(t0, rt); 9077 { 9078 TCGv_i32 fp0 = tcg_temp_new_i32(); 9079 9080 tcg_gen_trunc_tl_i32(fp0, t0); 9081 gen_store_fpr32(ctx, fp0, fs); 9082 } 9083 break; 9084 case OPC_CFC1: 9085 gen_helper_1e0i(cfc1, t0, fs); 9086 gen_store_gpr(t0, rt); 9087 break; 9088 case OPC_CTC1: 9089 gen_load_gpr(t0, rt); 9090 save_cpu_state(ctx, 0); 9091 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt); 9092 /* Stop translation as we may have changed hflags */ 9093 ctx->base.is_jmp = DISAS_STOP; 9094 break; 9095 #if defined(TARGET_MIPS64) 9096 case OPC_DMFC1: 9097 gen_load_fpr64(ctx, t0, fs); 9098 gen_store_gpr(t0, rt); 9099 break; 9100 case OPC_DMTC1: 9101 gen_load_gpr(t0, rt); 9102 gen_store_fpr64(ctx, t0, fs); 9103 break; 9104 #endif 9105 case OPC_MFHC1: 9106 { 9107 TCGv_i32 fp0 = tcg_temp_new_i32(); 9108 9109 gen_load_fpr32h(ctx, fp0, fs); 9110 tcg_gen_ext_i32_tl(t0, fp0); 9111 } 9112 gen_store_gpr(t0, rt); 9113 break; 9114 case OPC_MTHC1: 9115 gen_load_gpr(t0, rt); 9116 { 9117 TCGv_i32 fp0 = tcg_temp_new_i32(); 9118 9119 tcg_gen_trunc_tl_i32(fp0, t0); 9120 gen_store_fpr32h(ctx, fp0, fs); 9121 } 9122 break; 9123 default: 9124 MIPS_INVAL("cp1 move"); 9125 gen_reserved_instruction(ctx); 9126 return; 9127 } 9128 } 9129 9130 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf) 9131 { 9132 TCGLabel *l1; 9133 TCGCond cond; 9134 TCGv_i32 t0; 9135 9136 if (rd == 0) { 9137 /* Treat as NOP. */ 9138 return; 9139 } 9140 9141 if (tf) { 9142 cond = TCG_COND_EQ; 9143 } else { 9144 cond = TCG_COND_NE; 9145 } 9146 9147 l1 = gen_new_label(); 9148 t0 = tcg_temp_new_i32(); 9149 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9150 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9151 gen_load_gpr(cpu_gpr[rd], rs); 9152 gen_set_label(l1); 9153 } 9154 9155 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, 9156 int tf) 9157 { 9158 int cond; 9159 TCGv_i32 t0 = tcg_temp_new_i32(); 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 gen_load_fpr32(ctx, t0, fs); 9171 gen_store_fpr32(ctx, t0, fd); 9172 gen_set_label(l1); 9173 } 9174 9175 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, 9176 int tf) 9177 { 9178 int cond; 9179 TCGv_i32 t0 = tcg_temp_new_i32(); 9180 TCGv_i64 fp0; 9181 TCGLabel *l1 = gen_new_label(); 9182 9183 if (tf) { 9184 cond = TCG_COND_EQ; 9185 } else { 9186 cond = TCG_COND_NE; 9187 } 9188 9189 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9190 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9191 fp0 = tcg_temp_new_i64(); 9192 gen_load_fpr64(ctx, fp0, fs); 9193 gen_store_fpr64(ctx, fp0, fd); 9194 gen_set_label(l1); 9195 } 9196 9197 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, 9198 int cc, int tf) 9199 { 9200 int cond; 9201 TCGv_i32 t0 = tcg_temp_new_i32(); 9202 TCGLabel *l1 = gen_new_label(); 9203 TCGLabel *l2 = gen_new_label(); 9204 9205 if (tf) { 9206 cond = TCG_COND_EQ; 9207 } else { 9208 cond = TCG_COND_NE; 9209 } 9210 9211 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9212 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9213 gen_load_fpr32(ctx, t0, fs); 9214 gen_store_fpr32(ctx, t0, fd); 9215 gen_set_label(l1); 9216 9217 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1)); 9218 tcg_gen_brcondi_i32(cond, t0, 0, l2); 9219 gen_load_fpr32h(ctx, t0, fs); 9220 gen_store_fpr32h(ctx, t0, fd); 9221 gen_set_label(l2); 9222 } 9223 9224 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9225 int fs) 9226 { 9227 TCGv_i32 t1 = tcg_constant_i32(0); 9228 TCGv_i32 fp0 = tcg_temp_new_i32(); 9229 TCGv_i32 fp1 = tcg_temp_new_i32(); 9230 TCGv_i32 fp2 = tcg_temp_new_i32(); 9231 gen_load_fpr32(ctx, fp0, fd); 9232 gen_load_fpr32(ctx, fp1, ft); 9233 gen_load_fpr32(ctx, fp2, fs); 9234 9235 switch (op1) { 9236 case OPC_SEL_S: 9237 tcg_gen_andi_i32(fp0, fp0, 1); 9238 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9239 break; 9240 case OPC_SELEQZ_S: 9241 tcg_gen_andi_i32(fp1, fp1, 1); 9242 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9243 break; 9244 case OPC_SELNEZ_S: 9245 tcg_gen_andi_i32(fp1, fp1, 1); 9246 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9247 break; 9248 default: 9249 MIPS_INVAL("gen_sel_s"); 9250 gen_reserved_instruction(ctx); 9251 break; 9252 } 9253 9254 gen_store_fpr32(ctx, fp0, fd); 9255 } 9256 9257 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9258 int fs) 9259 { 9260 TCGv_i64 t1 = tcg_constant_i64(0); 9261 TCGv_i64 fp0 = tcg_temp_new_i64(); 9262 TCGv_i64 fp1 = tcg_temp_new_i64(); 9263 TCGv_i64 fp2 = tcg_temp_new_i64(); 9264 gen_load_fpr64(ctx, fp0, fd); 9265 gen_load_fpr64(ctx, fp1, ft); 9266 gen_load_fpr64(ctx, fp2, fs); 9267 9268 switch (op1) { 9269 case OPC_SEL_D: 9270 tcg_gen_andi_i64(fp0, fp0, 1); 9271 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9272 break; 9273 case OPC_SELEQZ_D: 9274 tcg_gen_andi_i64(fp1, fp1, 1); 9275 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9276 break; 9277 case OPC_SELNEZ_D: 9278 tcg_gen_andi_i64(fp1, fp1, 1); 9279 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9280 break; 9281 default: 9282 MIPS_INVAL("gen_sel_d"); 9283 gen_reserved_instruction(ctx); 9284 break; 9285 } 9286 9287 gen_store_fpr64(ctx, fp0, fd); 9288 } 9289 9290 static void gen_farith(DisasContext *ctx, enum fopcode op1, 9291 int ft, int fs, int fd, int cc) 9292 { 9293 uint32_t func = ctx->opcode & 0x3f; 9294 switch (op1) { 9295 case OPC_ADD_S: 9296 { 9297 TCGv_i32 fp0 = tcg_temp_new_i32(); 9298 TCGv_i32 fp1 = tcg_temp_new_i32(); 9299 9300 gen_load_fpr32(ctx, fp0, fs); 9301 gen_load_fpr32(ctx, fp1, ft); 9302 gen_helper_float_add_s(fp0, tcg_env, fp0, fp1); 9303 gen_store_fpr32(ctx, fp0, fd); 9304 } 9305 break; 9306 case OPC_SUB_S: 9307 { 9308 TCGv_i32 fp0 = tcg_temp_new_i32(); 9309 TCGv_i32 fp1 = tcg_temp_new_i32(); 9310 9311 gen_load_fpr32(ctx, fp0, fs); 9312 gen_load_fpr32(ctx, fp1, ft); 9313 gen_helper_float_sub_s(fp0, tcg_env, fp0, fp1); 9314 gen_store_fpr32(ctx, fp0, fd); 9315 } 9316 break; 9317 case OPC_MUL_S: 9318 { 9319 TCGv_i32 fp0 = tcg_temp_new_i32(); 9320 TCGv_i32 fp1 = tcg_temp_new_i32(); 9321 9322 gen_load_fpr32(ctx, fp0, fs); 9323 gen_load_fpr32(ctx, fp1, ft); 9324 gen_helper_float_mul_s(fp0, tcg_env, fp0, fp1); 9325 gen_store_fpr32(ctx, fp0, fd); 9326 } 9327 break; 9328 case OPC_DIV_S: 9329 { 9330 TCGv_i32 fp0 = tcg_temp_new_i32(); 9331 TCGv_i32 fp1 = tcg_temp_new_i32(); 9332 9333 gen_load_fpr32(ctx, fp0, fs); 9334 gen_load_fpr32(ctx, fp1, ft); 9335 gen_helper_float_div_s(fp0, tcg_env, fp0, fp1); 9336 gen_store_fpr32(ctx, fp0, fd); 9337 } 9338 break; 9339 case OPC_SQRT_S: 9340 { 9341 TCGv_i32 fp0 = tcg_temp_new_i32(); 9342 9343 gen_load_fpr32(ctx, fp0, fs); 9344 gen_helper_float_sqrt_s(fp0, tcg_env, fp0); 9345 gen_store_fpr32(ctx, fp0, fd); 9346 } 9347 break; 9348 case OPC_ABS_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_andi_i32(fp0, fp0, 0x7fffffffUL); 9355 } else { 9356 gen_helper_float_abs_s(fp0, fp0); 9357 } 9358 gen_store_fpr32(ctx, fp0, fd); 9359 } 9360 break; 9361 case OPC_MOV_S: 9362 { 9363 TCGv_i32 fp0 = tcg_temp_new_i32(); 9364 9365 gen_load_fpr32(ctx, fp0, fs); 9366 gen_store_fpr32(ctx, fp0, fd); 9367 } 9368 break; 9369 case OPC_NEG_S: 9370 { 9371 TCGv_i32 fp0 = tcg_temp_new_i32(); 9372 9373 gen_load_fpr32(ctx, fp0, fs); 9374 if (ctx->abs2008) { 9375 tcg_gen_xori_i32(fp0, fp0, 1UL << 31); 9376 } else { 9377 gen_helper_float_chs_s(fp0, fp0); 9378 } 9379 gen_store_fpr32(ctx, fp0, fd); 9380 } 9381 break; 9382 case OPC_ROUND_L_S: 9383 check_cp1_64bitmode(ctx); 9384 { 9385 TCGv_i32 fp32 = tcg_temp_new_i32(); 9386 TCGv_i64 fp64 = tcg_temp_new_i64(); 9387 9388 gen_load_fpr32(ctx, fp32, fs); 9389 if (ctx->nan2008) { 9390 gen_helper_float_round_2008_l_s(fp64, tcg_env, fp32); 9391 } else { 9392 gen_helper_float_round_l_s(fp64, tcg_env, fp32); 9393 } 9394 gen_store_fpr64(ctx, fp64, fd); 9395 } 9396 break; 9397 case OPC_TRUNC_L_S: 9398 check_cp1_64bitmode(ctx); 9399 { 9400 TCGv_i32 fp32 = tcg_temp_new_i32(); 9401 TCGv_i64 fp64 = tcg_temp_new_i64(); 9402 9403 gen_load_fpr32(ctx, fp32, fs); 9404 if (ctx->nan2008) { 9405 gen_helper_float_trunc_2008_l_s(fp64, tcg_env, fp32); 9406 } else { 9407 gen_helper_float_trunc_l_s(fp64, tcg_env, fp32); 9408 } 9409 gen_store_fpr64(ctx, fp64, fd); 9410 } 9411 break; 9412 case OPC_CEIL_L_S: 9413 check_cp1_64bitmode(ctx); 9414 { 9415 TCGv_i32 fp32 = tcg_temp_new_i32(); 9416 TCGv_i64 fp64 = tcg_temp_new_i64(); 9417 9418 gen_load_fpr32(ctx, fp32, fs); 9419 if (ctx->nan2008) { 9420 gen_helper_float_ceil_2008_l_s(fp64, tcg_env, fp32); 9421 } else { 9422 gen_helper_float_ceil_l_s(fp64, tcg_env, fp32); 9423 } 9424 gen_store_fpr64(ctx, fp64, fd); 9425 } 9426 break; 9427 case OPC_FLOOR_L_S: 9428 check_cp1_64bitmode(ctx); 9429 { 9430 TCGv_i32 fp32 = tcg_temp_new_i32(); 9431 TCGv_i64 fp64 = tcg_temp_new_i64(); 9432 9433 gen_load_fpr32(ctx, fp32, fs); 9434 if (ctx->nan2008) { 9435 gen_helper_float_floor_2008_l_s(fp64, tcg_env, fp32); 9436 } else { 9437 gen_helper_float_floor_l_s(fp64, tcg_env, fp32); 9438 } 9439 gen_store_fpr64(ctx, fp64, fd); 9440 } 9441 break; 9442 case OPC_ROUND_W_S: 9443 { 9444 TCGv_i32 fp0 = tcg_temp_new_i32(); 9445 9446 gen_load_fpr32(ctx, fp0, fs); 9447 if (ctx->nan2008) { 9448 gen_helper_float_round_2008_w_s(fp0, tcg_env, fp0); 9449 } else { 9450 gen_helper_float_round_w_s(fp0, tcg_env, fp0); 9451 } 9452 gen_store_fpr32(ctx, fp0, fd); 9453 } 9454 break; 9455 case OPC_TRUNC_W_S: 9456 { 9457 TCGv_i32 fp0 = tcg_temp_new_i32(); 9458 9459 gen_load_fpr32(ctx, fp0, fs); 9460 if (ctx->nan2008) { 9461 gen_helper_float_trunc_2008_w_s(fp0, tcg_env, fp0); 9462 } else { 9463 gen_helper_float_trunc_w_s(fp0, tcg_env, fp0); 9464 } 9465 gen_store_fpr32(ctx, fp0, fd); 9466 } 9467 break; 9468 case OPC_CEIL_W_S: 9469 { 9470 TCGv_i32 fp0 = tcg_temp_new_i32(); 9471 9472 gen_load_fpr32(ctx, fp0, fs); 9473 if (ctx->nan2008) { 9474 gen_helper_float_ceil_2008_w_s(fp0, tcg_env, fp0); 9475 } else { 9476 gen_helper_float_ceil_w_s(fp0, tcg_env, fp0); 9477 } 9478 gen_store_fpr32(ctx, fp0, fd); 9479 } 9480 break; 9481 case OPC_FLOOR_W_S: 9482 { 9483 TCGv_i32 fp0 = tcg_temp_new_i32(); 9484 9485 gen_load_fpr32(ctx, fp0, fs); 9486 if (ctx->nan2008) { 9487 gen_helper_float_floor_2008_w_s(fp0, tcg_env, fp0); 9488 } else { 9489 gen_helper_float_floor_w_s(fp0, tcg_env, fp0); 9490 } 9491 gen_store_fpr32(ctx, fp0, fd); 9492 } 9493 break; 9494 case OPC_SEL_S: 9495 check_insn(ctx, ISA_MIPS_R6); 9496 gen_sel_s(ctx, op1, fd, ft, fs); 9497 break; 9498 case OPC_SELEQZ_S: 9499 check_insn(ctx, ISA_MIPS_R6); 9500 gen_sel_s(ctx, op1, fd, ft, fs); 9501 break; 9502 case OPC_SELNEZ_S: 9503 check_insn(ctx, ISA_MIPS_R6); 9504 gen_sel_s(ctx, op1, fd, ft, fs); 9505 break; 9506 case OPC_MOVCF_S: 9507 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9508 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 9509 break; 9510 case OPC_MOVZ_S: 9511 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9512 { 9513 TCGLabel *l1 = gen_new_label(); 9514 TCGv_i32 fp0; 9515 9516 if (ft != 0) { 9517 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 9518 } 9519 fp0 = tcg_temp_new_i32(); 9520 gen_load_fpr32(ctx, fp0, fs); 9521 gen_store_fpr32(ctx, fp0, fd); 9522 gen_set_label(l1); 9523 } 9524 break; 9525 case OPC_MOVN_S: 9526 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9527 { 9528 TCGLabel *l1 = gen_new_label(); 9529 TCGv_i32 fp0; 9530 9531 if (ft != 0) { 9532 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 9533 fp0 = tcg_temp_new_i32(); 9534 gen_load_fpr32(ctx, fp0, fs); 9535 gen_store_fpr32(ctx, fp0, fd); 9536 gen_set_label(l1); 9537 } 9538 } 9539 break; 9540 case OPC_RECIP_S: 9541 { 9542 TCGv_i32 fp0 = tcg_temp_new_i32(); 9543 9544 gen_load_fpr32(ctx, fp0, fs); 9545 gen_helper_float_recip_s(fp0, tcg_env, fp0); 9546 gen_store_fpr32(ctx, fp0, fd); 9547 } 9548 break; 9549 case OPC_RSQRT_S: 9550 { 9551 TCGv_i32 fp0 = tcg_temp_new_i32(); 9552 9553 gen_load_fpr32(ctx, fp0, fs); 9554 gen_helper_float_rsqrt_s(fp0, tcg_env, fp0); 9555 gen_store_fpr32(ctx, fp0, fd); 9556 } 9557 break; 9558 case OPC_MADDF_S: 9559 check_insn(ctx, ISA_MIPS_R6); 9560 { 9561 TCGv_i32 fp0 = tcg_temp_new_i32(); 9562 TCGv_i32 fp1 = tcg_temp_new_i32(); 9563 TCGv_i32 fp2 = tcg_temp_new_i32(); 9564 gen_load_fpr32(ctx, fp0, fs); 9565 gen_load_fpr32(ctx, fp1, ft); 9566 gen_load_fpr32(ctx, fp2, fd); 9567 gen_helper_float_maddf_s(fp2, tcg_env, fp0, fp1, fp2); 9568 gen_store_fpr32(ctx, fp2, fd); 9569 } 9570 break; 9571 case OPC_MSUBF_S: 9572 check_insn(ctx, ISA_MIPS_R6); 9573 { 9574 TCGv_i32 fp0 = tcg_temp_new_i32(); 9575 TCGv_i32 fp1 = tcg_temp_new_i32(); 9576 TCGv_i32 fp2 = tcg_temp_new_i32(); 9577 gen_load_fpr32(ctx, fp0, fs); 9578 gen_load_fpr32(ctx, fp1, ft); 9579 gen_load_fpr32(ctx, fp2, fd); 9580 gen_helper_float_msubf_s(fp2, tcg_env, fp0, fp1, fp2); 9581 gen_store_fpr32(ctx, fp2, fd); 9582 } 9583 break; 9584 case OPC_RINT_S: 9585 check_insn(ctx, ISA_MIPS_R6); 9586 { 9587 TCGv_i32 fp0 = tcg_temp_new_i32(); 9588 gen_load_fpr32(ctx, fp0, fs); 9589 gen_helper_float_rint_s(fp0, tcg_env, fp0); 9590 gen_store_fpr32(ctx, fp0, fd); 9591 } 9592 break; 9593 case OPC_CLASS_S: 9594 check_insn(ctx, ISA_MIPS_R6); 9595 { 9596 TCGv_i32 fp0 = tcg_temp_new_i32(); 9597 gen_load_fpr32(ctx, fp0, fs); 9598 gen_helper_float_class_s(fp0, tcg_env, fp0); 9599 gen_store_fpr32(ctx, fp0, fd); 9600 } 9601 break; 9602 case OPC_MIN_S: /* OPC_RECIP2_S */ 9603 if (ctx->insn_flags & ISA_MIPS_R6) { 9604 /* OPC_MIN_S */ 9605 TCGv_i32 fp0 = tcg_temp_new_i32(); 9606 TCGv_i32 fp1 = tcg_temp_new_i32(); 9607 TCGv_i32 fp2 = tcg_temp_new_i32(); 9608 gen_load_fpr32(ctx, fp0, fs); 9609 gen_load_fpr32(ctx, fp1, ft); 9610 gen_helper_float_min_s(fp2, tcg_env, fp0, fp1); 9611 gen_store_fpr32(ctx, fp2, fd); 9612 } else { 9613 /* OPC_RECIP2_S */ 9614 check_cp1_64bitmode(ctx); 9615 { 9616 TCGv_i32 fp0 = tcg_temp_new_i32(); 9617 TCGv_i32 fp1 = tcg_temp_new_i32(); 9618 9619 gen_load_fpr32(ctx, fp0, fs); 9620 gen_load_fpr32(ctx, fp1, ft); 9621 gen_helper_float_recip2_s(fp0, tcg_env, fp0, fp1); 9622 gen_store_fpr32(ctx, fp0, fd); 9623 } 9624 } 9625 break; 9626 case OPC_MINA_S: /* OPC_RECIP1_S */ 9627 if (ctx->insn_flags & ISA_MIPS_R6) { 9628 /* OPC_MINA_S */ 9629 TCGv_i32 fp0 = tcg_temp_new_i32(); 9630 TCGv_i32 fp1 = tcg_temp_new_i32(); 9631 TCGv_i32 fp2 = tcg_temp_new_i32(); 9632 gen_load_fpr32(ctx, fp0, fs); 9633 gen_load_fpr32(ctx, fp1, ft); 9634 gen_helper_float_mina_s(fp2, tcg_env, fp0, fp1); 9635 gen_store_fpr32(ctx, fp2, fd); 9636 } else { 9637 /* OPC_RECIP1_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_recip1_s(fp0, tcg_env, fp0); 9644 gen_store_fpr32(ctx, fp0, fd); 9645 } 9646 } 9647 break; 9648 case OPC_MAX_S: /* OPC_RSQRT1_S */ 9649 if (ctx->insn_flags & ISA_MIPS_R6) { 9650 /* OPC_MAX_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_max_s(fp1, tcg_env, fp0, fp1); 9656 gen_store_fpr32(ctx, fp1, fd); 9657 } else { 9658 /* OPC_RSQRT1_S */ 9659 check_cp1_64bitmode(ctx); 9660 { 9661 TCGv_i32 fp0 = tcg_temp_new_i32(); 9662 9663 gen_load_fpr32(ctx, fp0, fs); 9664 gen_helper_float_rsqrt1_s(fp0, tcg_env, fp0); 9665 gen_store_fpr32(ctx, fp0, fd); 9666 } 9667 } 9668 break; 9669 case OPC_MAXA_S: /* OPC_RSQRT2_S */ 9670 if (ctx->insn_flags & ISA_MIPS_R6) { 9671 /* OPC_MAXA_S */ 9672 TCGv_i32 fp0 = tcg_temp_new_i32(); 9673 TCGv_i32 fp1 = tcg_temp_new_i32(); 9674 gen_load_fpr32(ctx, fp0, fs); 9675 gen_load_fpr32(ctx, fp1, ft); 9676 gen_helper_float_maxa_s(fp1, tcg_env, fp0, fp1); 9677 gen_store_fpr32(ctx, fp1, fd); 9678 } else { 9679 /* OPC_RSQRT2_S */ 9680 check_cp1_64bitmode(ctx); 9681 { 9682 TCGv_i32 fp0 = tcg_temp_new_i32(); 9683 TCGv_i32 fp1 = tcg_temp_new_i32(); 9684 9685 gen_load_fpr32(ctx, fp0, fs); 9686 gen_load_fpr32(ctx, fp1, ft); 9687 gen_helper_float_rsqrt2_s(fp0, tcg_env, fp0, fp1); 9688 gen_store_fpr32(ctx, fp0, fd); 9689 } 9690 } 9691 break; 9692 case OPC_CVT_D_S: 9693 check_cp1_registers(ctx, fd); 9694 { 9695 TCGv_i32 fp32 = tcg_temp_new_i32(); 9696 TCGv_i64 fp64 = tcg_temp_new_i64(); 9697 9698 gen_load_fpr32(ctx, fp32, fs); 9699 gen_helper_float_cvtd_s(fp64, tcg_env, fp32); 9700 gen_store_fpr64(ctx, fp64, fd); 9701 } 9702 break; 9703 case OPC_CVT_W_S: 9704 { 9705 TCGv_i32 fp0 = tcg_temp_new_i32(); 9706 9707 gen_load_fpr32(ctx, fp0, fs); 9708 if (ctx->nan2008) { 9709 gen_helper_float_cvt_2008_w_s(fp0, tcg_env, fp0); 9710 } else { 9711 gen_helper_float_cvt_w_s(fp0, tcg_env, fp0); 9712 } 9713 gen_store_fpr32(ctx, fp0, fd); 9714 } 9715 break; 9716 case OPC_CVT_L_S: 9717 check_cp1_64bitmode(ctx); 9718 { 9719 TCGv_i32 fp32 = tcg_temp_new_i32(); 9720 TCGv_i64 fp64 = tcg_temp_new_i64(); 9721 9722 gen_load_fpr32(ctx, fp32, fs); 9723 if (ctx->nan2008) { 9724 gen_helper_float_cvt_2008_l_s(fp64, tcg_env, fp32); 9725 } else { 9726 gen_helper_float_cvt_l_s(fp64, tcg_env, fp32); 9727 } 9728 gen_store_fpr64(ctx, fp64, fd); 9729 } 9730 break; 9731 case OPC_CVT_PS_S: 9732 check_ps(ctx); 9733 { 9734 TCGv_i64 fp64 = tcg_temp_new_i64(); 9735 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 9736 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 9737 9738 gen_load_fpr32(ctx, fp32_0, fs); 9739 gen_load_fpr32(ctx, fp32_1, ft); 9740 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); 9741 gen_store_fpr64(ctx, fp64, fd); 9742 } 9743 break; 9744 case OPC_CMP_F_S: 9745 case OPC_CMP_UN_S: 9746 case OPC_CMP_EQ_S: 9747 case OPC_CMP_UEQ_S: 9748 case OPC_CMP_OLT_S: 9749 case OPC_CMP_ULT_S: 9750 case OPC_CMP_OLE_S: 9751 case OPC_CMP_ULE_S: 9752 case OPC_CMP_SF_S: 9753 case OPC_CMP_NGLE_S: 9754 case OPC_CMP_SEQ_S: 9755 case OPC_CMP_NGL_S: 9756 case OPC_CMP_LT_S: 9757 case OPC_CMP_NGE_S: 9758 case OPC_CMP_LE_S: 9759 case OPC_CMP_NGT_S: 9760 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9761 if (ctx->opcode & (1 << 6)) { 9762 gen_cmpabs_s(ctx, func - 48, ft, fs, cc); 9763 } else { 9764 gen_cmp_s(ctx, func - 48, ft, fs, cc); 9765 } 9766 break; 9767 case OPC_ADD_D: 9768 check_cp1_registers(ctx, fs | ft | fd); 9769 { 9770 TCGv_i64 fp0 = tcg_temp_new_i64(); 9771 TCGv_i64 fp1 = tcg_temp_new_i64(); 9772 9773 gen_load_fpr64(ctx, fp0, fs); 9774 gen_load_fpr64(ctx, fp1, ft); 9775 gen_helper_float_add_d(fp0, tcg_env, fp0, fp1); 9776 gen_store_fpr64(ctx, fp0, fd); 9777 } 9778 break; 9779 case OPC_SUB_D: 9780 check_cp1_registers(ctx, fs | ft | fd); 9781 { 9782 TCGv_i64 fp0 = tcg_temp_new_i64(); 9783 TCGv_i64 fp1 = tcg_temp_new_i64(); 9784 9785 gen_load_fpr64(ctx, fp0, fs); 9786 gen_load_fpr64(ctx, fp1, ft); 9787 gen_helper_float_sub_d(fp0, tcg_env, fp0, fp1); 9788 gen_store_fpr64(ctx, fp0, fd); 9789 } 9790 break; 9791 case OPC_MUL_D: 9792 check_cp1_registers(ctx, fs | ft | fd); 9793 { 9794 TCGv_i64 fp0 = tcg_temp_new_i64(); 9795 TCGv_i64 fp1 = tcg_temp_new_i64(); 9796 9797 gen_load_fpr64(ctx, fp0, fs); 9798 gen_load_fpr64(ctx, fp1, ft); 9799 gen_helper_float_mul_d(fp0, tcg_env, fp0, fp1); 9800 gen_store_fpr64(ctx, fp0, fd); 9801 } 9802 break; 9803 case OPC_DIV_D: 9804 check_cp1_registers(ctx, fs | ft | fd); 9805 { 9806 TCGv_i64 fp0 = tcg_temp_new_i64(); 9807 TCGv_i64 fp1 = tcg_temp_new_i64(); 9808 9809 gen_load_fpr64(ctx, fp0, fs); 9810 gen_load_fpr64(ctx, fp1, ft); 9811 gen_helper_float_div_d(fp0, tcg_env, fp0, fp1); 9812 gen_store_fpr64(ctx, fp0, fd); 9813 } 9814 break; 9815 case OPC_SQRT_D: 9816 check_cp1_registers(ctx, fs | fd); 9817 { 9818 TCGv_i64 fp0 = tcg_temp_new_i64(); 9819 9820 gen_load_fpr64(ctx, fp0, fs); 9821 gen_helper_float_sqrt_d(fp0, tcg_env, fp0); 9822 gen_store_fpr64(ctx, fp0, fd); 9823 } 9824 break; 9825 case OPC_ABS_D: 9826 check_cp1_registers(ctx, fs | fd); 9827 { 9828 TCGv_i64 fp0 = tcg_temp_new_i64(); 9829 9830 gen_load_fpr64(ctx, fp0, fs); 9831 if (ctx->abs2008) { 9832 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL); 9833 } else { 9834 gen_helper_float_abs_d(fp0, fp0); 9835 } 9836 gen_store_fpr64(ctx, fp0, fd); 9837 } 9838 break; 9839 case OPC_MOV_D: 9840 check_cp1_registers(ctx, fs | fd); 9841 { 9842 TCGv_i64 fp0 = tcg_temp_new_i64(); 9843 9844 gen_load_fpr64(ctx, fp0, fs); 9845 gen_store_fpr64(ctx, fp0, fd); 9846 } 9847 break; 9848 case OPC_NEG_D: 9849 check_cp1_registers(ctx, fs | fd); 9850 { 9851 TCGv_i64 fp0 = tcg_temp_new_i64(); 9852 9853 gen_load_fpr64(ctx, fp0, fs); 9854 if (ctx->abs2008) { 9855 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63); 9856 } else { 9857 gen_helper_float_chs_d(fp0, fp0); 9858 } 9859 gen_store_fpr64(ctx, fp0, fd); 9860 } 9861 break; 9862 case OPC_ROUND_L_D: 9863 check_cp1_64bitmode(ctx); 9864 { 9865 TCGv_i64 fp0 = tcg_temp_new_i64(); 9866 9867 gen_load_fpr64(ctx, fp0, fs); 9868 if (ctx->nan2008) { 9869 gen_helper_float_round_2008_l_d(fp0, tcg_env, fp0); 9870 } else { 9871 gen_helper_float_round_l_d(fp0, tcg_env, fp0); 9872 } 9873 gen_store_fpr64(ctx, fp0, fd); 9874 } 9875 break; 9876 case OPC_TRUNC_L_D: 9877 check_cp1_64bitmode(ctx); 9878 { 9879 TCGv_i64 fp0 = tcg_temp_new_i64(); 9880 9881 gen_load_fpr64(ctx, fp0, fs); 9882 if (ctx->nan2008) { 9883 gen_helper_float_trunc_2008_l_d(fp0, tcg_env, fp0); 9884 } else { 9885 gen_helper_float_trunc_l_d(fp0, tcg_env, fp0); 9886 } 9887 gen_store_fpr64(ctx, fp0, fd); 9888 } 9889 break; 9890 case OPC_CEIL_L_D: 9891 check_cp1_64bitmode(ctx); 9892 { 9893 TCGv_i64 fp0 = tcg_temp_new_i64(); 9894 9895 gen_load_fpr64(ctx, fp0, fs); 9896 if (ctx->nan2008) { 9897 gen_helper_float_ceil_2008_l_d(fp0, tcg_env, fp0); 9898 } else { 9899 gen_helper_float_ceil_l_d(fp0, tcg_env, fp0); 9900 } 9901 gen_store_fpr64(ctx, fp0, fd); 9902 } 9903 break; 9904 case OPC_FLOOR_L_D: 9905 check_cp1_64bitmode(ctx); 9906 { 9907 TCGv_i64 fp0 = tcg_temp_new_i64(); 9908 9909 gen_load_fpr64(ctx, fp0, fs); 9910 if (ctx->nan2008) { 9911 gen_helper_float_floor_2008_l_d(fp0, tcg_env, fp0); 9912 } else { 9913 gen_helper_float_floor_l_d(fp0, tcg_env, fp0); 9914 } 9915 gen_store_fpr64(ctx, fp0, fd); 9916 } 9917 break; 9918 case OPC_ROUND_W_D: 9919 check_cp1_registers(ctx, fs); 9920 { 9921 TCGv_i32 fp32 = tcg_temp_new_i32(); 9922 TCGv_i64 fp64 = tcg_temp_new_i64(); 9923 9924 gen_load_fpr64(ctx, fp64, fs); 9925 if (ctx->nan2008) { 9926 gen_helper_float_round_2008_w_d(fp32, tcg_env, fp64); 9927 } else { 9928 gen_helper_float_round_w_d(fp32, tcg_env, fp64); 9929 } 9930 gen_store_fpr32(ctx, fp32, fd); 9931 } 9932 break; 9933 case OPC_TRUNC_W_D: 9934 check_cp1_registers(ctx, fs); 9935 { 9936 TCGv_i32 fp32 = tcg_temp_new_i32(); 9937 TCGv_i64 fp64 = tcg_temp_new_i64(); 9938 9939 gen_load_fpr64(ctx, fp64, fs); 9940 if (ctx->nan2008) { 9941 gen_helper_float_trunc_2008_w_d(fp32, tcg_env, fp64); 9942 } else { 9943 gen_helper_float_trunc_w_d(fp32, tcg_env, fp64); 9944 } 9945 gen_store_fpr32(ctx, fp32, fd); 9946 } 9947 break; 9948 case OPC_CEIL_W_D: 9949 check_cp1_registers(ctx, fs); 9950 { 9951 TCGv_i32 fp32 = tcg_temp_new_i32(); 9952 TCGv_i64 fp64 = tcg_temp_new_i64(); 9953 9954 gen_load_fpr64(ctx, fp64, fs); 9955 if (ctx->nan2008) { 9956 gen_helper_float_ceil_2008_w_d(fp32, tcg_env, fp64); 9957 } else { 9958 gen_helper_float_ceil_w_d(fp32, tcg_env, fp64); 9959 } 9960 gen_store_fpr32(ctx, fp32, fd); 9961 } 9962 break; 9963 case OPC_FLOOR_W_D: 9964 check_cp1_registers(ctx, fs); 9965 { 9966 TCGv_i32 fp32 = tcg_temp_new_i32(); 9967 TCGv_i64 fp64 = tcg_temp_new_i64(); 9968 9969 gen_load_fpr64(ctx, fp64, fs); 9970 if (ctx->nan2008) { 9971 gen_helper_float_floor_2008_w_d(fp32, tcg_env, fp64); 9972 } else { 9973 gen_helper_float_floor_w_d(fp32, tcg_env, fp64); 9974 } 9975 gen_store_fpr32(ctx, fp32, fd); 9976 } 9977 break; 9978 case OPC_SEL_D: 9979 check_insn(ctx, ISA_MIPS_R6); 9980 gen_sel_d(ctx, op1, fd, ft, fs); 9981 break; 9982 case OPC_SELEQZ_D: 9983 check_insn(ctx, ISA_MIPS_R6); 9984 gen_sel_d(ctx, op1, fd, ft, fs); 9985 break; 9986 case OPC_SELNEZ_D: 9987 check_insn(ctx, ISA_MIPS_R6); 9988 gen_sel_d(ctx, op1, fd, ft, fs); 9989 break; 9990 case OPC_MOVCF_D: 9991 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9992 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 9993 break; 9994 case OPC_MOVZ_D: 9995 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9996 { 9997 TCGLabel *l1 = gen_new_label(); 9998 TCGv_i64 fp0; 9999 10000 if (ft != 0) { 10001 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10002 } 10003 fp0 = tcg_temp_new_i64(); 10004 gen_load_fpr64(ctx, fp0, fs); 10005 gen_store_fpr64(ctx, fp0, fd); 10006 gen_set_label(l1); 10007 } 10008 break; 10009 case OPC_MOVN_D: 10010 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10011 { 10012 TCGLabel *l1 = gen_new_label(); 10013 TCGv_i64 fp0; 10014 10015 if (ft != 0) { 10016 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10017 fp0 = tcg_temp_new_i64(); 10018 gen_load_fpr64(ctx, fp0, fs); 10019 gen_store_fpr64(ctx, fp0, fd); 10020 gen_set_label(l1); 10021 } 10022 } 10023 break; 10024 case OPC_RECIP_D: 10025 check_cp1_registers(ctx, fs | fd); 10026 { 10027 TCGv_i64 fp0 = tcg_temp_new_i64(); 10028 10029 gen_load_fpr64(ctx, fp0, fs); 10030 gen_helper_float_recip_d(fp0, tcg_env, fp0); 10031 gen_store_fpr64(ctx, fp0, fd); 10032 } 10033 break; 10034 case OPC_RSQRT_D: 10035 check_cp1_registers(ctx, fs | fd); 10036 { 10037 TCGv_i64 fp0 = tcg_temp_new_i64(); 10038 10039 gen_load_fpr64(ctx, fp0, fs); 10040 gen_helper_float_rsqrt_d(fp0, tcg_env, fp0); 10041 gen_store_fpr64(ctx, fp0, fd); 10042 } 10043 break; 10044 case OPC_MADDF_D: 10045 check_insn(ctx, ISA_MIPS_R6); 10046 { 10047 TCGv_i64 fp0 = tcg_temp_new_i64(); 10048 TCGv_i64 fp1 = tcg_temp_new_i64(); 10049 TCGv_i64 fp2 = tcg_temp_new_i64(); 10050 gen_load_fpr64(ctx, fp0, fs); 10051 gen_load_fpr64(ctx, fp1, ft); 10052 gen_load_fpr64(ctx, fp2, fd); 10053 gen_helper_float_maddf_d(fp2, tcg_env, fp0, fp1, fp2); 10054 gen_store_fpr64(ctx, fp2, fd); 10055 } 10056 break; 10057 case OPC_MSUBF_D: 10058 check_insn(ctx, ISA_MIPS_R6); 10059 { 10060 TCGv_i64 fp0 = tcg_temp_new_i64(); 10061 TCGv_i64 fp1 = tcg_temp_new_i64(); 10062 TCGv_i64 fp2 = tcg_temp_new_i64(); 10063 gen_load_fpr64(ctx, fp0, fs); 10064 gen_load_fpr64(ctx, fp1, ft); 10065 gen_load_fpr64(ctx, fp2, fd); 10066 gen_helper_float_msubf_d(fp2, tcg_env, fp0, fp1, fp2); 10067 gen_store_fpr64(ctx, fp2, fd); 10068 } 10069 break; 10070 case OPC_RINT_D: 10071 check_insn(ctx, ISA_MIPS_R6); 10072 { 10073 TCGv_i64 fp0 = tcg_temp_new_i64(); 10074 gen_load_fpr64(ctx, fp0, fs); 10075 gen_helper_float_rint_d(fp0, tcg_env, fp0); 10076 gen_store_fpr64(ctx, fp0, fd); 10077 } 10078 break; 10079 case OPC_CLASS_D: 10080 check_insn(ctx, ISA_MIPS_R6); 10081 { 10082 TCGv_i64 fp0 = tcg_temp_new_i64(); 10083 gen_load_fpr64(ctx, fp0, fs); 10084 gen_helper_float_class_d(fp0, tcg_env, fp0); 10085 gen_store_fpr64(ctx, fp0, fd); 10086 } 10087 break; 10088 case OPC_MIN_D: /* OPC_RECIP2_D */ 10089 if (ctx->insn_flags & ISA_MIPS_R6) { 10090 /* OPC_MIN_D */ 10091 TCGv_i64 fp0 = tcg_temp_new_i64(); 10092 TCGv_i64 fp1 = tcg_temp_new_i64(); 10093 gen_load_fpr64(ctx, fp0, fs); 10094 gen_load_fpr64(ctx, fp1, ft); 10095 gen_helper_float_min_d(fp1, tcg_env, fp0, fp1); 10096 gen_store_fpr64(ctx, fp1, fd); 10097 } else { 10098 /* OPC_RECIP2_D */ 10099 check_cp1_64bitmode(ctx); 10100 { 10101 TCGv_i64 fp0 = tcg_temp_new_i64(); 10102 TCGv_i64 fp1 = tcg_temp_new_i64(); 10103 10104 gen_load_fpr64(ctx, fp0, fs); 10105 gen_load_fpr64(ctx, fp1, ft); 10106 gen_helper_float_recip2_d(fp0, tcg_env, fp0, fp1); 10107 gen_store_fpr64(ctx, fp0, fd); 10108 } 10109 } 10110 break; 10111 case OPC_MINA_D: /* OPC_RECIP1_D */ 10112 if (ctx->insn_flags & ISA_MIPS_R6) { 10113 /* OPC_MINA_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_mina_d(fp1, tcg_env, fp0, fp1); 10119 gen_store_fpr64(ctx, fp1, fd); 10120 } else { 10121 /* OPC_RECIP1_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_recip1_d(fp0, tcg_env, fp0); 10128 gen_store_fpr64(ctx, fp0, fd); 10129 } 10130 } 10131 break; 10132 case OPC_MAX_D: /* OPC_RSQRT1_D */ 10133 if (ctx->insn_flags & ISA_MIPS_R6) { 10134 /* OPC_MAX_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_max_d(fp1, tcg_env, fp0, fp1); 10140 gen_store_fpr64(ctx, fp1, fd); 10141 } else { 10142 /* OPC_RSQRT1_D */ 10143 check_cp1_64bitmode(ctx); 10144 { 10145 TCGv_i64 fp0 = tcg_temp_new_i64(); 10146 10147 gen_load_fpr64(ctx, fp0, fs); 10148 gen_helper_float_rsqrt1_d(fp0, tcg_env, fp0); 10149 gen_store_fpr64(ctx, fp0, fd); 10150 } 10151 } 10152 break; 10153 case OPC_MAXA_D: /* OPC_RSQRT2_D */ 10154 if (ctx->insn_flags & ISA_MIPS_R6) { 10155 /* OPC_MAXA_D */ 10156 TCGv_i64 fp0 = tcg_temp_new_i64(); 10157 TCGv_i64 fp1 = tcg_temp_new_i64(); 10158 gen_load_fpr64(ctx, fp0, fs); 10159 gen_load_fpr64(ctx, fp1, ft); 10160 gen_helper_float_maxa_d(fp1, tcg_env, fp0, fp1); 10161 gen_store_fpr64(ctx, fp1, fd); 10162 } else { 10163 /* OPC_RSQRT2_D */ 10164 check_cp1_64bitmode(ctx); 10165 { 10166 TCGv_i64 fp0 = tcg_temp_new_i64(); 10167 TCGv_i64 fp1 = tcg_temp_new_i64(); 10168 10169 gen_load_fpr64(ctx, fp0, fs); 10170 gen_load_fpr64(ctx, fp1, ft); 10171 gen_helper_float_rsqrt2_d(fp0, tcg_env, fp0, fp1); 10172 gen_store_fpr64(ctx, fp0, fd); 10173 } 10174 } 10175 break; 10176 case OPC_CMP_F_D: 10177 case OPC_CMP_UN_D: 10178 case OPC_CMP_EQ_D: 10179 case OPC_CMP_UEQ_D: 10180 case OPC_CMP_OLT_D: 10181 case OPC_CMP_ULT_D: 10182 case OPC_CMP_OLE_D: 10183 case OPC_CMP_ULE_D: 10184 case OPC_CMP_SF_D: 10185 case OPC_CMP_NGLE_D: 10186 case OPC_CMP_SEQ_D: 10187 case OPC_CMP_NGL_D: 10188 case OPC_CMP_LT_D: 10189 case OPC_CMP_NGE_D: 10190 case OPC_CMP_LE_D: 10191 case OPC_CMP_NGT_D: 10192 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10193 if (ctx->opcode & (1 << 6)) { 10194 gen_cmpabs_d(ctx, func - 48, ft, fs, cc); 10195 } else { 10196 gen_cmp_d(ctx, func - 48, ft, fs, cc); 10197 } 10198 break; 10199 case OPC_CVT_S_D: 10200 check_cp1_registers(ctx, fs); 10201 { 10202 TCGv_i32 fp32 = tcg_temp_new_i32(); 10203 TCGv_i64 fp64 = tcg_temp_new_i64(); 10204 10205 gen_load_fpr64(ctx, fp64, fs); 10206 gen_helper_float_cvts_d(fp32, tcg_env, fp64); 10207 gen_store_fpr32(ctx, fp32, fd); 10208 } 10209 break; 10210 case OPC_CVT_W_D: 10211 check_cp1_registers(ctx, fs); 10212 { 10213 TCGv_i32 fp32 = tcg_temp_new_i32(); 10214 TCGv_i64 fp64 = tcg_temp_new_i64(); 10215 10216 gen_load_fpr64(ctx, fp64, fs); 10217 if (ctx->nan2008) { 10218 gen_helper_float_cvt_2008_w_d(fp32, tcg_env, fp64); 10219 } else { 10220 gen_helper_float_cvt_w_d(fp32, tcg_env, fp64); 10221 } 10222 gen_store_fpr32(ctx, fp32, fd); 10223 } 10224 break; 10225 case OPC_CVT_L_D: 10226 check_cp1_64bitmode(ctx); 10227 { 10228 TCGv_i64 fp0 = tcg_temp_new_i64(); 10229 10230 gen_load_fpr64(ctx, fp0, fs); 10231 if (ctx->nan2008) { 10232 gen_helper_float_cvt_2008_l_d(fp0, tcg_env, fp0); 10233 } else { 10234 gen_helper_float_cvt_l_d(fp0, tcg_env, fp0); 10235 } 10236 gen_store_fpr64(ctx, fp0, fd); 10237 } 10238 break; 10239 case OPC_CVT_S_W: 10240 { 10241 TCGv_i32 fp0 = tcg_temp_new_i32(); 10242 10243 gen_load_fpr32(ctx, fp0, fs); 10244 gen_helper_float_cvts_w(fp0, tcg_env, fp0); 10245 gen_store_fpr32(ctx, fp0, fd); 10246 } 10247 break; 10248 case OPC_CVT_D_W: 10249 check_cp1_registers(ctx, fd); 10250 { 10251 TCGv_i32 fp32 = tcg_temp_new_i32(); 10252 TCGv_i64 fp64 = tcg_temp_new_i64(); 10253 10254 gen_load_fpr32(ctx, fp32, fs); 10255 gen_helper_float_cvtd_w(fp64, tcg_env, fp32); 10256 gen_store_fpr64(ctx, fp64, fd); 10257 } 10258 break; 10259 case OPC_CVT_S_L: 10260 check_cp1_64bitmode(ctx); 10261 { 10262 TCGv_i32 fp32 = tcg_temp_new_i32(); 10263 TCGv_i64 fp64 = tcg_temp_new_i64(); 10264 10265 gen_load_fpr64(ctx, fp64, fs); 10266 gen_helper_float_cvts_l(fp32, tcg_env, fp64); 10267 gen_store_fpr32(ctx, fp32, fd); 10268 } 10269 break; 10270 case OPC_CVT_D_L: 10271 check_cp1_64bitmode(ctx); 10272 { 10273 TCGv_i64 fp0 = tcg_temp_new_i64(); 10274 10275 gen_load_fpr64(ctx, fp0, fs); 10276 gen_helper_float_cvtd_l(fp0, tcg_env, fp0); 10277 gen_store_fpr64(ctx, fp0, fd); 10278 } 10279 break; 10280 case OPC_CVT_PS_PW: 10281 check_ps(ctx); 10282 { 10283 TCGv_i64 fp0 = tcg_temp_new_i64(); 10284 10285 gen_load_fpr64(ctx, fp0, fs); 10286 gen_helper_float_cvtps_pw(fp0, tcg_env, fp0); 10287 gen_store_fpr64(ctx, fp0, fd); 10288 } 10289 break; 10290 case OPC_ADD_PS: 10291 check_ps(ctx); 10292 { 10293 TCGv_i64 fp0 = tcg_temp_new_i64(); 10294 TCGv_i64 fp1 = tcg_temp_new_i64(); 10295 10296 gen_load_fpr64(ctx, fp0, fs); 10297 gen_load_fpr64(ctx, fp1, ft); 10298 gen_helper_float_add_ps(fp0, tcg_env, fp0, fp1); 10299 gen_store_fpr64(ctx, fp0, fd); 10300 } 10301 break; 10302 case OPC_SUB_PS: 10303 check_ps(ctx); 10304 { 10305 TCGv_i64 fp0 = tcg_temp_new_i64(); 10306 TCGv_i64 fp1 = tcg_temp_new_i64(); 10307 10308 gen_load_fpr64(ctx, fp0, fs); 10309 gen_load_fpr64(ctx, fp1, ft); 10310 gen_helper_float_sub_ps(fp0, tcg_env, fp0, fp1); 10311 gen_store_fpr64(ctx, fp0, fd); 10312 } 10313 break; 10314 case OPC_MUL_PS: 10315 check_ps(ctx); 10316 { 10317 TCGv_i64 fp0 = tcg_temp_new_i64(); 10318 TCGv_i64 fp1 = tcg_temp_new_i64(); 10319 10320 gen_load_fpr64(ctx, fp0, fs); 10321 gen_load_fpr64(ctx, fp1, ft); 10322 gen_helper_float_mul_ps(fp0, tcg_env, fp0, fp1); 10323 gen_store_fpr64(ctx, fp0, fd); 10324 } 10325 break; 10326 case OPC_ABS_PS: 10327 check_ps(ctx); 10328 { 10329 TCGv_i64 fp0 = tcg_temp_new_i64(); 10330 10331 gen_load_fpr64(ctx, fp0, fs); 10332 gen_helper_float_abs_ps(fp0, fp0); 10333 gen_store_fpr64(ctx, fp0, fd); 10334 } 10335 break; 10336 case OPC_MOV_PS: 10337 check_ps(ctx); 10338 { 10339 TCGv_i64 fp0 = tcg_temp_new_i64(); 10340 10341 gen_load_fpr64(ctx, fp0, fs); 10342 gen_store_fpr64(ctx, fp0, fd); 10343 } 10344 break; 10345 case OPC_NEG_PS: 10346 check_ps(ctx); 10347 { 10348 TCGv_i64 fp0 = tcg_temp_new_i64(); 10349 10350 gen_load_fpr64(ctx, fp0, fs); 10351 gen_helper_float_chs_ps(fp0, fp0); 10352 gen_store_fpr64(ctx, fp0, fd); 10353 } 10354 break; 10355 case OPC_MOVCF_PS: 10356 check_ps(ctx); 10357 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10358 break; 10359 case OPC_MOVZ_PS: 10360 check_ps(ctx); 10361 { 10362 TCGLabel *l1 = gen_new_label(); 10363 TCGv_i64 fp0; 10364 10365 if (ft != 0) { 10366 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10367 } 10368 fp0 = tcg_temp_new_i64(); 10369 gen_load_fpr64(ctx, fp0, fs); 10370 gen_store_fpr64(ctx, fp0, fd); 10371 gen_set_label(l1); 10372 } 10373 break; 10374 case OPC_MOVN_PS: 10375 check_ps(ctx); 10376 { 10377 TCGLabel *l1 = gen_new_label(); 10378 TCGv_i64 fp0; 10379 10380 if (ft != 0) { 10381 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10382 fp0 = tcg_temp_new_i64(); 10383 gen_load_fpr64(ctx, fp0, fs); 10384 gen_store_fpr64(ctx, fp0, fd); 10385 gen_set_label(l1); 10386 } 10387 } 10388 break; 10389 case OPC_ADDR_PS: 10390 check_ps(ctx); 10391 { 10392 TCGv_i64 fp0 = tcg_temp_new_i64(); 10393 TCGv_i64 fp1 = tcg_temp_new_i64(); 10394 10395 gen_load_fpr64(ctx, fp0, ft); 10396 gen_load_fpr64(ctx, fp1, fs); 10397 gen_helper_float_addr_ps(fp0, tcg_env, fp0, fp1); 10398 gen_store_fpr64(ctx, fp0, fd); 10399 } 10400 break; 10401 case OPC_MULR_PS: 10402 check_ps(ctx); 10403 { 10404 TCGv_i64 fp0 = tcg_temp_new_i64(); 10405 TCGv_i64 fp1 = tcg_temp_new_i64(); 10406 10407 gen_load_fpr64(ctx, fp0, ft); 10408 gen_load_fpr64(ctx, fp1, fs); 10409 gen_helper_float_mulr_ps(fp0, tcg_env, fp0, fp1); 10410 gen_store_fpr64(ctx, fp0, fd); 10411 } 10412 break; 10413 case OPC_RECIP2_PS: 10414 check_ps(ctx); 10415 { 10416 TCGv_i64 fp0 = tcg_temp_new_i64(); 10417 TCGv_i64 fp1 = tcg_temp_new_i64(); 10418 10419 gen_load_fpr64(ctx, fp0, fs); 10420 gen_load_fpr64(ctx, fp1, ft); 10421 gen_helper_float_recip2_ps(fp0, tcg_env, fp0, fp1); 10422 gen_store_fpr64(ctx, fp0, fd); 10423 } 10424 break; 10425 case OPC_RECIP1_PS: 10426 check_ps(ctx); 10427 { 10428 TCGv_i64 fp0 = tcg_temp_new_i64(); 10429 10430 gen_load_fpr64(ctx, fp0, fs); 10431 gen_helper_float_recip1_ps(fp0, tcg_env, fp0); 10432 gen_store_fpr64(ctx, fp0, fd); 10433 } 10434 break; 10435 case OPC_RSQRT1_PS: 10436 check_ps(ctx); 10437 { 10438 TCGv_i64 fp0 = tcg_temp_new_i64(); 10439 10440 gen_load_fpr64(ctx, fp0, fs); 10441 gen_helper_float_rsqrt1_ps(fp0, tcg_env, fp0); 10442 gen_store_fpr64(ctx, fp0, fd); 10443 } 10444 break; 10445 case OPC_RSQRT2_PS: 10446 check_ps(ctx); 10447 { 10448 TCGv_i64 fp0 = tcg_temp_new_i64(); 10449 TCGv_i64 fp1 = tcg_temp_new_i64(); 10450 10451 gen_load_fpr64(ctx, fp0, fs); 10452 gen_load_fpr64(ctx, fp1, ft); 10453 gen_helper_float_rsqrt2_ps(fp0, tcg_env, fp0, fp1); 10454 gen_store_fpr64(ctx, fp0, fd); 10455 } 10456 break; 10457 case OPC_CVT_S_PU: 10458 check_cp1_64bitmode(ctx); 10459 { 10460 TCGv_i32 fp0 = tcg_temp_new_i32(); 10461 10462 gen_load_fpr32h(ctx, fp0, fs); 10463 gen_helper_float_cvts_pu(fp0, tcg_env, fp0); 10464 gen_store_fpr32(ctx, fp0, fd); 10465 } 10466 break; 10467 case OPC_CVT_PW_PS: 10468 check_ps(ctx); 10469 { 10470 TCGv_i64 fp0 = tcg_temp_new_i64(); 10471 10472 gen_load_fpr64(ctx, fp0, fs); 10473 gen_helper_float_cvtpw_ps(fp0, tcg_env, fp0); 10474 gen_store_fpr64(ctx, fp0, fd); 10475 } 10476 break; 10477 case OPC_CVT_S_PL: 10478 check_cp1_64bitmode(ctx); 10479 { 10480 TCGv_i32 fp0 = tcg_temp_new_i32(); 10481 10482 gen_load_fpr32(ctx, fp0, fs); 10483 gen_helper_float_cvts_pl(fp0, tcg_env, fp0); 10484 gen_store_fpr32(ctx, fp0, fd); 10485 } 10486 break; 10487 case OPC_PLL_PS: 10488 check_ps(ctx); 10489 { 10490 TCGv_i32 fp0 = tcg_temp_new_i32(); 10491 TCGv_i32 fp1 = tcg_temp_new_i32(); 10492 10493 gen_load_fpr32(ctx, fp0, fs); 10494 gen_load_fpr32(ctx, fp1, ft); 10495 gen_store_fpr32h(ctx, fp0, fd); 10496 gen_store_fpr32(ctx, fp1, fd); 10497 } 10498 break; 10499 case OPC_PLU_PS: 10500 check_ps(ctx); 10501 { 10502 TCGv_i32 fp0 = tcg_temp_new_i32(); 10503 TCGv_i32 fp1 = tcg_temp_new_i32(); 10504 10505 gen_load_fpr32(ctx, fp0, fs); 10506 gen_load_fpr32h(ctx, fp1, ft); 10507 gen_store_fpr32(ctx, fp1, fd); 10508 gen_store_fpr32h(ctx, fp0, fd); 10509 } 10510 break; 10511 case OPC_PUL_PS: 10512 check_ps(ctx); 10513 { 10514 TCGv_i32 fp0 = tcg_temp_new_i32(); 10515 TCGv_i32 fp1 = tcg_temp_new_i32(); 10516 10517 gen_load_fpr32h(ctx, fp0, fs); 10518 gen_load_fpr32(ctx, fp1, ft); 10519 gen_store_fpr32(ctx, fp1, fd); 10520 gen_store_fpr32h(ctx, fp0, fd); 10521 } 10522 break; 10523 case OPC_PUU_PS: 10524 check_ps(ctx); 10525 { 10526 TCGv_i32 fp0 = tcg_temp_new_i32(); 10527 TCGv_i32 fp1 = tcg_temp_new_i32(); 10528 10529 gen_load_fpr32h(ctx, fp0, fs); 10530 gen_load_fpr32h(ctx, fp1, ft); 10531 gen_store_fpr32(ctx, fp1, fd); 10532 gen_store_fpr32h(ctx, fp0, fd); 10533 } 10534 break; 10535 case OPC_CMP_F_PS: 10536 case OPC_CMP_UN_PS: 10537 case OPC_CMP_EQ_PS: 10538 case OPC_CMP_UEQ_PS: 10539 case OPC_CMP_OLT_PS: 10540 case OPC_CMP_ULT_PS: 10541 case OPC_CMP_OLE_PS: 10542 case OPC_CMP_ULE_PS: 10543 case OPC_CMP_SF_PS: 10544 case OPC_CMP_NGLE_PS: 10545 case OPC_CMP_SEQ_PS: 10546 case OPC_CMP_NGL_PS: 10547 case OPC_CMP_LT_PS: 10548 case OPC_CMP_NGE_PS: 10549 case OPC_CMP_LE_PS: 10550 case OPC_CMP_NGT_PS: 10551 if (ctx->opcode & (1 << 6)) { 10552 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc); 10553 } else { 10554 gen_cmp_ps(ctx, func - 48, ft, fs, cc); 10555 } 10556 break; 10557 default: 10558 MIPS_INVAL("farith"); 10559 gen_reserved_instruction(ctx); 10560 return; 10561 } 10562 } 10563 10564 /* Coprocessor 3 (FPU) */ 10565 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, 10566 int fd, int fs, int base, int index) 10567 { 10568 TCGv t0 = tcg_temp_new(); 10569 10570 gen_base_index_addr(ctx, t0, base, index); 10571 /* 10572 * Don't do NOP if destination is zero: we must perform the actual 10573 * memory access. 10574 */ 10575 switch (opc) { 10576 case OPC_LWXC1: 10577 check_cop1x(ctx); 10578 { 10579 TCGv_i32 fp0 = tcg_temp_new_i32(); 10580 10581 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 10582 tcg_gen_trunc_tl_i32(fp0, t0); 10583 gen_store_fpr32(ctx, fp0, fd); 10584 } 10585 break; 10586 case OPC_LDXC1: 10587 check_cop1x(ctx); 10588 check_cp1_registers(ctx, fd); 10589 { 10590 TCGv_i64 fp0 = tcg_temp_new_i64(); 10591 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10592 gen_store_fpr64(ctx, fp0, fd); 10593 } 10594 break; 10595 case OPC_LUXC1: 10596 check_cp1_64bitmode(ctx); 10597 tcg_gen_andi_tl(t0, t0, ~0x7); 10598 { 10599 TCGv_i64 fp0 = tcg_temp_new_i64(); 10600 10601 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10602 gen_store_fpr64(ctx, fp0, fd); 10603 } 10604 break; 10605 case OPC_SWXC1: 10606 check_cop1x(ctx); 10607 { 10608 TCGv_i32 fp0 = tcg_temp_new_i32(); 10609 gen_load_fpr32(ctx, fp0, fs); 10610 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 10611 } 10612 break; 10613 case OPC_SDXC1: 10614 check_cop1x(ctx); 10615 check_cp1_registers(ctx, fs); 10616 { 10617 TCGv_i64 fp0 = tcg_temp_new_i64(); 10618 gen_load_fpr64(ctx, fp0, fs); 10619 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10620 } 10621 break; 10622 case OPC_SUXC1: 10623 check_cp1_64bitmode(ctx); 10624 tcg_gen_andi_tl(t0, t0, ~0x7); 10625 { 10626 TCGv_i64 fp0 = tcg_temp_new_i64(); 10627 gen_load_fpr64(ctx, fp0, fs); 10628 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10629 } 10630 break; 10631 } 10632 } 10633 10634 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, 10635 int fd, int fr, int fs, int ft) 10636 { 10637 switch (opc) { 10638 case OPC_ALNV_PS: 10639 check_ps(ctx); 10640 { 10641 TCGv t0 = tcg_temp_new(); 10642 TCGv_i32 fp = tcg_temp_new_i32(); 10643 TCGv_i32 fph = tcg_temp_new_i32(); 10644 TCGLabel *l1 = gen_new_label(); 10645 TCGLabel *l2 = gen_new_label(); 10646 10647 gen_load_gpr(t0, fr); 10648 tcg_gen_andi_tl(t0, t0, 0x7); 10649 10650 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 10651 gen_load_fpr32(ctx, fp, fs); 10652 gen_load_fpr32h(ctx, fph, fs); 10653 gen_store_fpr32(ctx, fp, fd); 10654 gen_store_fpr32h(ctx, fph, fd); 10655 tcg_gen_br(l2); 10656 gen_set_label(l1); 10657 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 10658 if (disas_is_bigendian(ctx)) { 10659 gen_load_fpr32(ctx, fp, fs); 10660 gen_load_fpr32h(ctx, fph, ft); 10661 gen_store_fpr32h(ctx, fp, fd); 10662 gen_store_fpr32(ctx, fph, fd); 10663 } else { 10664 gen_load_fpr32h(ctx, fph, fs); 10665 gen_load_fpr32(ctx, fp, ft); 10666 gen_store_fpr32(ctx, fph, fd); 10667 gen_store_fpr32h(ctx, fp, fd); 10668 } 10669 gen_set_label(l2); 10670 } 10671 break; 10672 case OPC_MADD_S: 10673 check_cop1x(ctx); 10674 { 10675 TCGv_i32 fp0 = tcg_temp_new_i32(); 10676 TCGv_i32 fp1 = tcg_temp_new_i32(); 10677 TCGv_i32 fp2 = tcg_temp_new_i32(); 10678 10679 gen_load_fpr32(ctx, fp0, fs); 10680 gen_load_fpr32(ctx, fp1, ft); 10681 gen_load_fpr32(ctx, fp2, fr); 10682 gen_helper_float_madd_s(fp2, tcg_env, fp0, fp1, fp2); 10683 gen_store_fpr32(ctx, fp2, fd); 10684 } 10685 break; 10686 case OPC_MADD_D: 10687 check_cop1x(ctx); 10688 check_cp1_registers(ctx, fd | fs | ft | fr); 10689 { 10690 TCGv_i64 fp0 = tcg_temp_new_i64(); 10691 TCGv_i64 fp1 = tcg_temp_new_i64(); 10692 TCGv_i64 fp2 = tcg_temp_new_i64(); 10693 10694 gen_load_fpr64(ctx, fp0, fs); 10695 gen_load_fpr64(ctx, fp1, ft); 10696 gen_load_fpr64(ctx, fp2, fr); 10697 gen_helper_float_madd_d(fp2, tcg_env, fp0, fp1, fp2); 10698 gen_store_fpr64(ctx, fp2, fd); 10699 } 10700 break; 10701 case OPC_MADD_PS: 10702 check_ps(ctx); 10703 { 10704 TCGv_i64 fp0 = tcg_temp_new_i64(); 10705 TCGv_i64 fp1 = tcg_temp_new_i64(); 10706 TCGv_i64 fp2 = tcg_temp_new_i64(); 10707 10708 gen_load_fpr64(ctx, fp0, fs); 10709 gen_load_fpr64(ctx, fp1, ft); 10710 gen_load_fpr64(ctx, fp2, fr); 10711 gen_helper_float_madd_ps(fp2, tcg_env, fp0, fp1, fp2); 10712 gen_store_fpr64(ctx, fp2, fd); 10713 } 10714 break; 10715 case OPC_MSUB_S: 10716 check_cop1x(ctx); 10717 { 10718 TCGv_i32 fp0 = tcg_temp_new_i32(); 10719 TCGv_i32 fp1 = tcg_temp_new_i32(); 10720 TCGv_i32 fp2 = tcg_temp_new_i32(); 10721 10722 gen_load_fpr32(ctx, fp0, fs); 10723 gen_load_fpr32(ctx, fp1, ft); 10724 gen_load_fpr32(ctx, fp2, fr); 10725 gen_helper_float_msub_s(fp2, tcg_env, fp0, fp1, fp2); 10726 gen_store_fpr32(ctx, fp2, fd); 10727 } 10728 break; 10729 case OPC_MSUB_D: 10730 check_cop1x(ctx); 10731 check_cp1_registers(ctx, fd | fs | ft | fr); 10732 { 10733 TCGv_i64 fp0 = tcg_temp_new_i64(); 10734 TCGv_i64 fp1 = tcg_temp_new_i64(); 10735 TCGv_i64 fp2 = tcg_temp_new_i64(); 10736 10737 gen_load_fpr64(ctx, fp0, fs); 10738 gen_load_fpr64(ctx, fp1, ft); 10739 gen_load_fpr64(ctx, fp2, fr); 10740 gen_helper_float_msub_d(fp2, tcg_env, fp0, fp1, fp2); 10741 gen_store_fpr64(ctx, fp2, fd); 10742 } 10743 break; 10744 case OPC_MSUB_PS: 10745 check_ps(ctx); 10746 { 10747 TCGv_i64 fp0 = tcg_temp_new_i64(); 10748 TCGv_i64 fp1 = tcg_temp_new_i64(); 10749 TCGv_i64 fp2 = tcg_temp_new_i64(); 10750 10751 gen_load_fpr64(ctx, fp0, fs); 10752 gen_load_fpr64(ctx, fp1, ft); 10753 gen_load_fpr64(ctx, fp2, fr); 10754 gen_helper_float_msub_ps(fp2, tcg_env, fp0, fp1, fp2); 10755 gen_store_fpr64(ctx, fp2, fd); 10756 } 10757 break; 10758 case OPC_NMADD_S: 10759 check_cop1x(ctx); 10760 { 10761 TCGv_i32 fp0 = tcg_temp_new_i32(); 10762 TCGv_i32 fp1 = tcg_temp_new_i32(); 10763 TCGv_i32 fp2 = tcg_temp_new_i32(); 10764 10765 gen_load_fpr32(ctx, fp0, fs); 10766 gen_load_fpr32(ctx, fp1, ft); 10767 gen_load_fpr32(ctx, fp2, fr); 10768 gen_helper_float_nmadd_s(fp2, tcg_env, fp0, fp1, fp2); 10769 gen_store_fpr32(ctx, fp2, fd); 10770 } 10771 break; 10772 case OPC_NMADD_D: 10773 check_cop1x(ctx); 10774 check_cp1_registers(ctx, fd | fs | ft | fr); 10775 { 10776 TCGv_i64 fp0 = tcg_temp_new_i64(); 10777 TCGv_i64 fp1 = tcg_temp_new_i64(); 10778 TCGv_i64 fp2 = tcg_temp_new_i64(); 10779 10780 gen_load_fpr64(ctx, fp0, fs); 10781 gen_load_fpr64(ctx, fp1, ft); 10782 gen_load_fpr64(ctx, fp2, fr); 10783 gen_helper_float_nmadd_d(fp2, tcg_env, fp0, fp1, fp2); 10784 gen_store_fpr64(ctx, fp2, fd); 10785 } 10786 break; 10787 case OPC_NMADD_PS: 10788 check_ps(ctx); 10789 { 10790 TCGv_i64 fp0 = tcg_temp_new_i64(); 10791 TCGv_i64 fp1 = tcg_temp_new_i64(); 10792 TCGv_i64 fp2 = tcg_temp_new_i64(); 10793 10794 gen_load_fpr64(ctx, fp0, fs); 10795 gen_load_fpr64(ctx, fp1, ft); 10796 gen_load_fpr64(ctx, fp2, fr); 10797 gen_helper_float_nmadd_ps(fp2, tcg_env, fp0, fp1, fp2); 10798 gen_store_fpr64(ctx, fp2, fd); 10799 } 10800 break; 10801 case OPC_NMSUB_S: 10802 check_cop1x(ctx); 10803 { 10804 TCGv_i32 fp0 = tcg_temp_new_i32(); 10805 TCGv_i32 fp1 = tcg_temp_new_i32(); 10806 TCGv_i32 fp2 = tcg_temp_new_i32(); 10807 10808 gen_load_fpr32(ctx, fp0, fs); 10809 gen_load_fpr32(ctx, fp1, ft); 10810 gen_load_fpr32(ctx, fp2, fr); 10811 gen_helper_float_nmsub_s(fp2, tcg_env, fp0, fp1, fp2); 10812 gen_store_fpr32(ctx, fp2, fd); 10813 } 10814 break; 10815 case OPC_NMSUB_D: 10816 check_cop1x(ctx); 10817 check_cp1_registers(ctx, fd | fs | ft | fr); 10818 { 10819 TCGv_i64 fp0 = tcg_temp_new_i64(); 10820 TCGv_i64 fp1 = tcg_temp_new_i64(); 10821 TCGv_i64 fp2 = tcg_temp_new_i64(); 10822 10823 gen_load_fpr64(ctx, fp0, fs); 10824 gen_load_fpr64(ctx, fp1, ft); 10825 gen_load_fpr64(ctx, fp2, fr); 10826 gen_helper_float_nmsub_d(fp2, tcg_env, fp0, fp1, fp2); 10827 gen_store_fpr64(ctx, fp2, fd); 10828 } 10829 break; 10830 case OPC_NMSUB_PS: 10831 check_ps(ctx); 10832 { 10833 TCGv_i64 fp0 = tcg_temp_new_i64(); 10834 TCGv_i64 fp1 = tcg_temp_new_i64(); 10835 TCGv_i64 fp2 = tcg_temp_new_i64(); 10836 10837 gen_load_fpr64(ctx, fp0, fs); 10838 gen_load_fpr64(ctx, fp1, ft); 10839 gen_load_fpr64(ctx, fp2, fr); 10840 gen_helper_float_nmsub_ps(fp2, tcg_env, fp0, fp1, fp2); 10841 gen_store_fpr64(ctx, fp2, fd); 10842 } 10843 break; 10844 default: 10845 MIPS_INVAL("flt3_arith"); 10846 gen_reserved_instruction(ctx); 10847 return; 10848 } 10849 } 10850 10851 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) 10852 { 10853 TCGv t0; 10854 10855 #if !defined(CONFIG_USER_ONLY) 10856 /* 10857 * The Linux kernel will emulate rdhwr if it's not supported natively. 10858 * Therefore only check the ISA in system mode. 10859 */ 10860 check_insn(ctx, ISA_MIPS_R2); 10861 #endif 10862 t0 = tcg_temp_new(); 10863 10864 switch (rd) { 10865 case 0: 10866 gen_helper_rdhwr_cpunum(t0, tcg_env); 10867 gen_store_gpr(t0, rt); 10868 break; 10869 case 1: 10870 gen_helper_rdhwr_synci_step(t0, tcg_env); 10871 gen_store_gpr(t0, rt); 10872 break; 10873 case 2: 10874 translator_io_start(&ctx->base); 10875 gen_helper_rdhwr_cc(t0, tcg_env); 10876 gen_store_gpr(t0, rt); 10877 /* 10878 * Break the TB to be able to take timer interrupts immediately 10879 * after reading count. DISAS_STOP isn't sufficient, we need to ensure 10880 * we break completely out of translated code. 10881 */ 10882 gen_save_pc(ctx->base.pc_next + 4); 10883 ctx->base.is_jmp = DISAS_EXIT; 10884 break; 10885 case 3: 10886 gen_helper_rdhwr_ccres(t0, tcg_env); 10887 gen_store_gpr(t0, rt); 10888 break; 10889 case 4: 10890 check_insn(ctx, ISA_MIPS_R6); 10891 if (sel != 0) { 10892 /* 10893 * Performance counter registers are not implemented other than 10894 * control register 0. 10895 */ 10896 generate_exception(ctx, EXCP_RI); 10897 } 10898 gen_helper_rdhwr_performance(t0, tcg_env); 10899 gen_store_gpr(t0, rt); 10900 break; 10901 case 5: 10902 check_insn(ctx, ISA_MIPS_R6); 10903 gen_helper_rdhwr_xnp(t0, tcg_env); 10904 gen_store_gpr(t0, rt); 10905 break; 10906 case 29: 10907 #if defined(CONFIG_USER_ONLY) 10908 tcg_gen_ld_tl(t0, tcg_env, 10909 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 10910 gen_store_gpr(t0, rt); 10911 break; 10912 #else 10913 if ((ctx->hflags & MIPS_HFLAG_CP0) || 10914 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) { 10915 tcg_gen_ld_tl(t0, tcg_env, 10916 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 10917 gen_store_gpr(t0, rt); 10918 } else { 10919 gen_reserved_instruction(ctx); 10920 } 10921 break; 10922 #endif 10923 default: /* Invalid */ 10924 MIPS_INVAL("rdhwr"); 10925 gen_reserved_instruction(ctx); 10926 break; 10927 } 10928 } 10929 10930 static inline void clear_branch_hflags(DisasContext *ctx) 10931 { 10932 ctx->hflags &= ~MIPS_HFLAG_BMASK; 10933 if (ctx->base.is_jmp == DISAS_NEXT) { 10934 save_cpu_state(ctx, 0); 10935 } else { 10936 /* 10937 * It is not safe to save ctx->hflags as hflags may be changed 10938 * in execution time by the instruction in delay / forbidden slot. 10939 */ 10940 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK); 10941 } 10942 } 10943 10944 static void gen_branch(DisasContext *ctx, int insn_bytes) 10945 { 10946 if (ctx->hflags & MIPS_HFLAG_BMASK) { 10947 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK; 10948 /* Branches completion */ 10949 clear_branch_hflags(ctx); 10950 ctx->base.is_jmp = DISAS_NORETURN; 10951 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) { 10952 case MIPS_HFLAG_FBNSLOT: 10953 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes); 10954 break; 10955 case MIPS_HFLAG_B: 10956 /* unconditional branch */ 10957 if (proc_hflags & MIPS_HFLAG_BX) { 10958 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16); 10959 } 10960 gen_goto_tb(ctx, 0, ctx->btarget); 10961 break; 10962 case MIPS_HFLAG_BL: 10963 /* blikely taken case */ 10964 gen_goto_tb(ctx, 0, ctx->btarget); 10965 break; 10966 case MIPS_HFLAG_BC: 10967 /* Conditional branch */ 10968 { 10969 TCGLabel *l1 = gen_new_label(); 10970 10971 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 10972 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); 10973 gen_set_label(l1); 10974 gen_goto_tb(ctx, 0, ctx->btarget); 10975 } 10976 break; 10977 case MIPS_HFLAG_BR: 10978 /* unconditional branch to register */ 10979 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) { 10980 TCGv t0 = tcg_temp_new(); 10981 TCGv_i32 t1 = tcg_temp_new_i32(); 10982 10983 tcg_gen_andi_tl(t0, btarget, 0x1); 10984 tcg_gen_trunc_tl_i32(t1, t0); 10985 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16); 10986 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT); 10987 tcg_gen_or_i32(hflags, hflags, t1); 10988 10989 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1); 10990 } else { 10991 tcg_gen_mov_tl(cpu_PC, btarget); 10992 } 10993 tcg_gen_lookup_and_goto_ptr(); 10994 break; 10995 default: 10996 LOG_DISAS("unknown branch 0x%x\n", proc_hflags); 10997 gen_reserved_instruction(ctx); 10998 } 10999 } 11000 } 11001 11002 /* Compact Branches */ 11003 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, 11004 int rs, int rt, int32_t offset) 11005 { 11006 int bcond_compute = 0; 11007 TCGv t0 = tcg_temp_new(); 11008 TCGv t1 = tcg_temp_new(); 11009 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; 11010 11011 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11012 #ifdef MIPS_DEBUG_DISAS 11013 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 11014 VADDR_PRIx "\n", ctx->base.pc_next); 11015 #endif 11016 gen_reserved_instruction(ctx); 11017 return; 11018 } 11019 11020 /* Load needed operands and calculate btarget */ 11021 switch (opc) { 11022 /* compact branch */ 11023 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11024 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11025 gen_load_gpr(t0, rs); 11026 gen_load_gpr(t1, rt); 11027 bcond_compute = 1; 11028 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11029 if (rs <= rt && rs == 0) { 11030 /* OPC_BEQZALC, OPC_BNEZALC */ 11031 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11032 } 11033 break; 11034 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11035 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11036 gen_load_gpr(t0, rs); 11037 gen_load_gpr(t1, rt); 11038 bcond_compute = 1; 11039 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11040 break; 11041 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11042 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11043 if (rs == 0 || rs == rt) { 11044 /* OPC_BLEZALC, OPC_BGEZALC */ 11045 /* OPC_BGTZALC, OPC_BLTZALC */ 11046 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11047 } 11048 gen_load_gpr(t0, rs); 11049 gen_load_gpr(t1, rt); 11050 bcond_compute = 1; 11051 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11052 break; 11053 case OPC_BC: 11054 case OPC_BALC: 11055 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11056 break; 11057 case OPC_BEQZC: 11058 case OPC_BNEZC: 11059 if (rs != 0) { 11060 /* OPC_BEQZC, OPC_BNEZC */ 11061 gen_load_gpr(t0, rs); 11062 bcond_compute = 1; 11063 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11064 } else { 11065 /* OPC_JIC, OPC_JIALC */ 11066 TCGv tbase = tcg_temp_new(); 11067 11068 gen_load_gpr(tbase, rt); 11069 gen_op_addr_addi(ctx, btarget, tbase, offset); 11070 } 11071 break; 11072 default: 11073 MIPS_INVAL("Compact branch/jump"); 11074 gen_reserved_instruction(ctx); 11075 return; 11076 } 11077 11078 if (bcond_compute == 0) { 11079 /* Unconditional compact branch */ 11080 switch (opc) { 11081 case OPC_JIALC: 11082 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11083 /* Fallthrough */ 11084 case OPC_JIC: 11085 ctx->hflags |= MIPS_HFLAG_BR; 11086 break; 11087 case OPC_BALC: 11088 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11089 /* Fallthrough */ 11090 case OPC_BC: 11091 ctx->hflags |= MIPS_HFLAG_B; 11092 break; 11093 default: 11094 MIPS_INVAL("Compact branch/jump"); 11095 gen_reserved_instruction(ctx); 11096 return; 11097 } 11098 11099 /* Generating branch here as compact branches don't have delay slot */ 11100 gen_branch(ctx, 4); 11101 } else { 11102 /* Conditional compact branch */ 11103 TCGLabel *fs = gen_new_label(); 11104 save_cpu_state(ctx, 0); 11105 11106 switch (opc) { 11107 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11108 if (rs == 0 && rt != 0) { 11109 /* OPC_BLEZALC */ 11110 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11111 } else if (rs != 0 && rt != 0 && rs == rt) { 11112 /* OPC_BGEZALC */ 11113 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11114 } else { 11115 /* OPC_BGEUC */ 11116 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 11117 } 11118 break; 11119 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11120 if (rs == 0 && rt != 0) { 11121 /* OPC_BGTZALC */ 11122 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11123 } else if (rs != 0 && rt != 0 && rs == rt) { 11124 /* OPC_BLTZALC */ 11125 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11126 } else { 11127 /* OPC_BLTUC */ 11128 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 11129 } 11130 break; 11131 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11132 if (rs == 0 && rt != 0) { 11133 /* OPC_BLEZC */ 11134 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11135 } else if (rs != 0 && rt != 0 && rs == rt) { 11136 /* OPC_BGEZC */ 11137 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11138 } else { 11139 /* OPC_BGEC */ 11140 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 11141 } 11142 break; 11143 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11144 if (rs == 0 && rt != 0) { 11145 /* OPC_BGTZC */ 11146 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11147 } else if (rs != 0 && rt != 0 && rs == rt) { 11148 /* OPC_BLTZC */ 11149 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11150 } else { 11151 /* OPC_BLTC */ 11152 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 11153 } 11154 break; 11155 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11156 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11157 if (rs >= rt) { 11158 /* OPC_BOVC, OPC_BNVC */ 11159 TCGv t2 = tcg_temp_new(); 11160 TCGv t3 = tcg_temp_new(); 11161 TCGv t4 = tcg_temp_new(); 11162 TCGv input_overflow = tcg_temp_new(); 11163 11164 gen_load_gpr(t0, rs); 11165 gen_load_gpr(t1, rt); 11166 tcg_gen_ext32s_tl(t2, t0); 11167 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0); 11168 tcg_gen_ext32s_tl(t3, t1); 11169 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1); 11170 tcg_gen_or_tl(input_overflow, input_overflow, t4); 11171 11172 tcg_gen_add_tl(t4, t2, t3); 11173 tcg_gen_ext32s_tl(t4, t4); 11174 tcg_gen_xor_tl(t2, t2, t3); 11175 tcg_gen_xor_tl(t3, t4, t3); 11176 tcg_gen_andc_tl(t2, t3, t2); 11177 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0); 11178 tcg_gen_or_tl(t4, t4, input_overflow); 11179 if (opc == OPC_BOVC) { 11180 /* OPC_BOVC */ 11181 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs); 11182 } else { 11183 /* OPC_BNVC */ 11184 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs); 11185 } 11186 } else if (rs < rt && rs == 0) { 11187 /* OPC_BEQZALC, OPC_BNEZALC */ 11188 if (opc == OPC_BEQZALC) { 11189 /* OPC_BEQZALC */ 11190 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs); 11191 } else { 11192 /* OPC_BNEZALC */ 11193 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs); 11194 } 11195 } else { 11196 /* OPC_BEQC, OPC_BNEC */ 11197 if (opc == OPC_BEQC) { 11198 /* OPC_BEQC */ 11199 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); 11200 } else { 11201 /* OPC_BNEC */ 11202 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); 11203 } 11204 } 11205 break; 11206 case OPC_BEQZC: 11207 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 11208 break; 11209 case OPC_BNEZC: 11210 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs); 11211 break; 11212 default: 11213 MIPS_INVAL("Compact conditional branch/jump"); 11214 gen_reserved_instruction(ctx); 11215 return; 11216 } 11217 11218 /* Generating branch here as compact branches don't have delay slot */ 11219 gen_goto_tb(ctx, 1, ctx->btarget); 11220 gen_set_label(fs); 11221 11222 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 11223 } 11224 } 11225 11226 void gen_addiupc(DisasContext *ctx, int rx, int imm, 11227 int is_64_bit, int extended) 11228 { 11229 target_ulong npc; 11230 11231 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { 11232 gen_reserved_instruction(ctx); 11233 return; 11234 } 11235 11236 npc = pc_relative_pc(ctx) + imm; 11237 if (!is_64_bit) { 11238 npc = (int32_t)npc; 11239 } 11240 tcg_gen_movi_tl(cpu_gpr[rx], npc); 11241 } 11242 11243 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, 11244 int16_t offset) 11245 { 11246 TCGv_i32 t0 = tcg_constant_i32(op); 11247 TCGv t1 = tcg_temp_new(); 11248 gen_base_offset_addr(ctx, t1, base, offset); 11249 gen_helper_cache(tcg_env, t1, t0); 11250 } 11251 11252 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code) 11253 { 11254 #ifdef CONFIG_USER_ONLY 11255 return false; 11256 #else 11257 bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM; 11258 return semihosting_enabled(is_user) && sdbbp_code == 1; 11259 #endif 11260 } 11261 11262 void gen_ldxs(DisasContext *ctx, int base, int index, int rd) 11263 { 11264 TCGv t0 = tcg_temp_new(); 11265 TCGv t1 = tcg_temp_new(); 11266 11267 gen_load_gpr(t0, base); 11268 11269 if (index != 0) { 11270 gen_load_gpr(t1, index); 11271 tcg_gen_shli_tl(t1, t1, 2); 11272 gen_op_addr_add(ctx, t0, t1, t0); 11273 } 11274 11275 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 11276 gen_store_gpr(t1, rd); 11277 } 11278 11279 static void gen_sync(int stype) 11280 { 11281 TCGBar tcg_mo = TCG_BAR_SC; 11282 11283 switch (stype) { 11284 case 0x4: /* SYNC_WMB */ 11285 tcg_mo |= TCG_MO_ST_ST; 11286 break; 11287 case 0x10: /* SYNC_MB */ 11288 tcg_mo |= TCG_MO_ALL; 11289 break; 11290 case 0x11: /* SYNC_ACQUIRE */ 11291 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; 11292 break; 11293 case 0x12: /* SYNC_RELEASE */ 11294 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; 11295 break; 11296 case 0x13: /* SYNC_RMB */ 11297 tcg_mo |= TCG_MO_LD_LD; 11298 break; 11299 default: 11300 tcg_mo |= TCG_MO_ALL; 11301 break; 11302 } 11303 11304 tcg_gen_mb(tcg_mo); 11305 } 11306 11307 /* ISA extensions (ASEs) */ 11308 11309 /* MIPS16 extension to MIPS32 */ 11310 #include "mips16e_translate.c.inc" 11311 11312 /* microMIPS extension to MIPS32/MIPS64 */ 11313 11314 /* 11315 * Values for microMIPS fmt field. Variable-width, depending on which 11316 * formats the instruction supports. 11317 */ 11318 enum { 11319 FMT_SD_S = 0, 11320 FMT_SD_D = 1, 11321 11322 FMT_SDPS_S = 0, 11323 FMT_SDPS_D = 1, 11324 FMT_SDPS_PS = 2, 11325 11326 FMT_SWL_S = 0, 11327 FMT_SWL_W = 1, 11328 FMT_SWL_L = 2, 11329 11330 FMT_DWL_D = 0, 11331 FMT_DWL_W = 1, 11332 FMT_DWL_L = 2 11333 }; 11334 11335 #include "micromips_translate.c.inc" 11336 11337 #include "nanomips_translate.c.inc" 11338 11339 /* MIPSDSP functions. */ 11340 11341 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2, 11342 int ret, int v1, int v2) 11343 { 11344 TCGv v1_t; 11345 TCGv v2_t; 11346 11347 if (ret == 0) { 11348 /* Treat as NOP. */ 11349 return; 11350 } 11351 11352 v1_t = tcg_temp_new(); 11353 v2_t = tcg_temp_new(); 11354 11355 gen_load_gpr(v1_t, v1); 11356 gen_load_gpr(v2_t, v2); 11357 11358 switch (op1) { 11359 case OPC_ADDUH_QB_DSP: 11360 check_dsp_r2(ctx); 11361 switch (op2) { 11362 case OPC_ADDUH_QB: 11363 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); 11364 break; 11365 case OPC_ADDUH_R_QB: 11366 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); 11367 break; 11368 case OPC_ADDQH_PH: 11369 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); 11370 break; 11371 case OPC_ADDQH_R_PH: 11372 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 11373 break; 11374 case OPC_ADDQH_W: 11375 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); 11376 break; 11377 case OPC_ADDQH_R_W: 11378 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); 11379 break; 11380 case OPC_SUBUH_QB: 11381 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); 11382 break; 11383 case OPC_SUBUH_R_QB: 11384 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); 11385 break; 11386 case OPC_SUBQH_PH: 11387 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); 11388 break; 11389 case OPC_SUBQH_R_PH: 11390 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 11391 break; 11392 case OPC_SUBQH_W: 11393 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); 11394 break; 11395 case OPC_SUBQH_R_W: 11396 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); 11397 break; 11398 } 11399 break; 11400 case OPC_ABSQ_S_PH_DSP: 11401 switch (op2) { 11402 case OPC_ABSQ_S_QB: 11403 check_dsp_r2(ctx); 11404 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, tcg_env); 11405 break; 11406 case OPC_ABSQ_S_PH: 11407 check_dsp(ctx); 11408 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, tcg_env); 11409 break; 11410 case OPC_ABSQ_S_W: 11411 check_dsp(ctx); 11412 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, tcg_env); 11413 break; 11414 case OPC_PRECEQ_W_PHL: 11415 check_dsp(ctx); 11416 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); 11417 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 11418 break; 11419 case OPC_PRECEQ_W_PHR: 11420 check_dsp(ctx); 11421 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); 11422 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); 11423 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 11424 break; 11425 case OPC_PRECEQU_PH_QBL: 11426 check_dsp(ctx); 11427 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); 11428 break; 11429 case OPC_PRECEQU_PH_QBR: 11430 check_dsp(ctx); 11431 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); 11432 break; 11433 case OPC_PRECEQU_PH_QBLA: 11434 check_dsp(ctx); 11435 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); 11436 break; 11437 case OPC_PRECEQU_PH_QBRA: 11438 check_dsp(ctx); 11439 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); 11440 break; 11441 case OPC_PRECEU_PH_QBL: 11442 check_dsp(ctx); 11443 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); 11444 break; 11445 case OPC_PRECEU_PH_QBR: 11446 check_dsp(ctx); 11447 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); 11448 break; 11449 case OPC_PRECEU_PH_QBLA: 11450 check_dsp(ctx); 11451 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); 11452 break; 11453 case OPC_PRECEU_PH_QBRA: 11454 check_dsp(ctx); 11455 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); 11456 break; 11457 } 11458 break; 11459 case OPC_ADDU_QB_DSP: 11460 switch (op2) { 11461 case OPC_ADDQ_PH: 11462 check_dsp(ctx); 11463 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11464 break; 11465 case OPC_ADDQ_S_PH: 11466 check_dsp(ctx); 11467 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11468 break; 11469 case OPC_ADDQ_S_W: 11470 check_dsp(ctx); 11471 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11472 break; 11473 case OPC_ADDU_QB: 11474 check_dsp(ctx); 11475 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11476 break; 11477 case OPC_ADDU_S_QB: 11478 check_dsp(ctx); 11479 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11480 break; 11481 case OPC_ADDU_PH: 11482 check_dsp_r2(ctx); 11483 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11484 break; 11485 case OPC_ADDU_S_PH: 11486 check_dsp_r2(ctx); 11487 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11488 break; 11489 case OPC_SUBQ_PH: 11490 check_dsp(ctx); 11491 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11492 break; 11493 case OPC_SUBQ_S_PH: 11494 check_dsp(ctx); 11495 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11496 break; 11497 case OPC_SUBQ_S_W: 11498 check_dsp(ctx); 11499 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11500 break; 11501 case OPC_SUBU_QB: 11502 check_dsp(ctx); 11503 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11504 break; 11505 case OPC_SUBU_S_QB: 11506 check_dsp(ctx); 11507 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11508 break; 11509 case OPC_SUBU_PH: 11510 check_dsp_r2(ctx); 11511 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11512 break; 11513 case OPC_SUBU_S_PH: 11514 check_dsp_r2(ctx); 11515 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11516 break; 11517 case OPC_ADDSC: 11518 check_dsp(ctx); 11519 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11520 break; 11521 case OPC_ADDWC: 11522 check_dsp(ctx); 11523 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11524 break; 11525 case OPC_MODSUB: 11526 check_dsp(ctx); 11527 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); 11528 break; 11529 case OPC_RADDU_W_QB: 11530 check_dsp(ctx); 11531 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); 11532 break; 11533 } 11534 break; 11535 case OPC_CMPU_EQ_QB_DSP: 11536 switch (op2) { 11537 case OPC_PRECR_QB_PH: 11538 check_dsp_r2(ctx); 11539 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); 11540 break; 11541 case OPC_PRECRQ_QB_PH: 11542 check_dsp(ctx); 11543 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); 11544 break; 11545 case OPC_PRECR_SRA_PH_W: 11546 check_dsp_r2(ctx); 11547 { 11548 TCGv_i32 sa_t = tcg_constant_i32(v2); 11549 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, 11550 cpu_gpr[ret]); 11551 break; 11552 } 11553 case OPC_PRECR_SRA_R_PH_W: 11554 check_dsp_r2(ctx); 11555 { 11556 TCGv_i32 sa_t = tcg_constant_i32(v2); 11557 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, 11558 cpu_gpr[ret]); 11559 break; 11560 } 11561 case OPC_PRECRQ_PH_W: 11562 check_dsp(ctx); 11563 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); 11564 break; 11565 case OPC_PRECRQ_RS_PH_W: 11566 check_dsp(ctx); 11567 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11568 break; 11569 case OPC_PRECRQU_S_QB_PH: 11570 check_dsp(ctx); 11571 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11572 break; 11573 } 11574 break; 11575 #ifdef TARGET_MIPS64 11576 case OPC_ABSQ_S_QH_DSP: 11577 switch (op2) { 11578 case OPC_PRECEQ_L_PWL: 11579 check_dsp(ctx); 11580 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); 11581 break; 11582 case OPC_PRECEQ_L_PWR: 11583 check_dsp(ctx); 11584 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); 11585 break; 11586 case OPC_PRECEQ_PW_QHL: 11587 check_dsp(ctx); 11588 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); 11589 break; 11590 case OPC_PRECEQ_PW_QHR: 11591 check_dsp(ctx); 11592 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); 11593 break; 11594 case OPC_PRECEQ_PW_QHLA: 11595 check_dsp(ctx); 11596 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); 11597 break; 11598 case OPC_PRECEQ_PW_QHRA: 11599 check_dsp(ctx); 11600 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); 11601 break; 11602 case OPC_PRECEQU_QH_OBL: 11603 check_dsp(ctx); 11604 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); 11605 break; 11606 case OPC_PRECEQU_QH_OBR: 11607 check_dsp(ctx); 11608 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); 11609 break; 11610 case OPC_PRECEQU_QH_OBLA: 11611 check_dsp(ctx); 11612 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); 11613 break; 11614 case OPC_PRECEQU_QH_OBRA: 11615 check_dsp(ctx); 11616 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); 11617 break; 11618 case OPC_PRECEU_QH_OBL: 11619 check_dsp(ctx); 11620 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); 11621 break; 11622 case OPC_PRECEU_QH_OBR: 11623 check_dsp(ctx); 11624 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); 11625 break; 11626 case OPC_PRECEU_QH_OBLA: 11627 check_dsp(ctx); 11628 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); 11629 break; 11630 case OPC_PRECEU_QH_OBRA: 11631 check_dsp(ctx); 11632 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); 11633 break; 11634 case OPC_ABSQ_S_OB: 11635 check_dsp_r2(ctx); 11636 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, tcg_env); 11637 break; 11638 case OPC_ABSQ_S_PW: 11639 check_dsp(ctx); 11640 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, tcg_env); 11641 break; 11642 case OPC_ABSQ_S_QH: 11643 check_dsp(ctx); 11644 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, tcg_env); 11645 break; 11646 } 11647 break; 11648 case OPC_ADDU_OB_DSP: 11649 switch (op2) { 11650 case OPC_RADDU_L_OB: 11651 check_dsp(ctx); 11652 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); 11653 break; 11654 case OPC_SUBQ_PW: 11655 check_dsp(ctx); 11656 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11657 break; 11658 case OPC_SUBQ_S_PW: 11659 check_dsp(ctx); 11660 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11661 break; 11662 case OPC_SUBQ_QH: 11663 check_dsp(ctx); 11664 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11665 break; 11666 case OPC_SUBQ_S_QH: 11667 check_dsp(ctx); 11668 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11669 break; 11670 case OPC_SUBU_OB: 11671 check_dsp(ctx); 11672 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11673 break; 11674 case OPC_SUBU_S_OB: 11675 check_dsp(ctx); 11676 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11677 break; 11678 case OPC_SUBU_QH: 11679 check_dsp_r2(ctx); 11680 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11681 break; 11682 case OPC_SUBU_S_QH: 11683 check_dsp_r2(ctx); 11684 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11685 break; 11686 case OPC_SUBUH_OB: 11687 check_dsp_r2(ctx); 11688 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); 11689 break; 11690 case OPC_SUBUH_R_OB: 11691 check_dsp_r2(ctx); 11692 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); 11693 break; 11694 case OPC_ADDQ_PW: 11695 check_dsp(ctx); 11696 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11697 break; 11698 case OPC_ADDQ_S_PW: 11699 check_dsp(ctx); 11700 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11701 break; 11702 case OPC_ADDQ_QH: 11703 check_dsp(ctx); 11704 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11705 break; 11706 case OPC_ADDQ_S_QH: 11707 check_dsp(ctx); 11708 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11709 break; 11710 case OPC_ADDU_OB: 11711 check_dsp(ctx); 11712 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11713 break; 11714 case OPC_ADDU_S_OB: 11715 check_dsp(ctx); 11716 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11717 break; 11718 case OPC_ADDU_QH: 11719 check_dsp_r2(ctx); 11720 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11721 break; 11722 case OPC_ADDU_S_QH: 11723 check_dsp_r2(ctx); 11724 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11725 break; 11726 case OPC_ADDUH_OB: 11727 check_dsp_r2(ctx); 11728 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); 11729 break; 11730 case OPC_ADDUH_R_OB: 11731 check_dsp_r2(ctx); 11732 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); 11733 break; 11734 } 11735 break; 11736 case OPC_CMPU_EQ_OB_DSP: 11737 switch (op2) { 11738 case OPC_PRECR_OB_QH: 11739 check_dsp_r2(ctx); 11740 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); 11741 break; 11742 case OPC_PRECR_SRA_QH_PW: 11743 check_dsp_r2(ctx); 11744 { 11745 TCGv_i32 ret_t = tcg_constant_i32(ret); 11746 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); 11747 break; 11748 } 11749 case OPC_PRECR_SRA_R_QH_PW: 11750 check_dsp_r2(ctx); 11751 { 11752 TCGv_i32 sa_v = tcg_constant_i32(ret); 11753 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); 11754 break; 11755 } 11756 case OPC_PRECRQ_OB_QH: 11757 check_dsp(ctx); 11758 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); 11759 break; 11760 case OPC_PRECRQ_PW_L: 11761 check_dsp(ctx); 11762 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); 11763 break; 11764 case OPC_PRECRQ_QH_PW: 11765 check_dsp(ctx); 11766 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); 11767 break; 11768 case OPC_PRECRQ_RS_QH_PW: 11769 check_dsp(ctx); 11770 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11771 break; 11772 case OPC_PRECRQU_S_OB_QH: 11773 check_dsp(ctx); 11774 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11775 break; 11776 } 11777 break; 11778 #endif 11779 } 11780 } 11781 11782 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, 11783 int ret, int v1, int v2) 11784 { 11785 uint32_t op2; 11786 TCGv t0; 11787 TCGv v1_t; 11788 TCGv v2_t; 11789 11790 if (ret == 0) { 11791 /* Treat as NOP. */ 11792 return; 11793 } 11794 11795 t0 = tcg_temp_new(); 11796 v1_t = tcg_temp_new(); 11797 v2_t = tcg_temp_new(); 11798 11799 tcg_gen_movi_tl(t0, v1); 11800 gen_load_gpr(v1_t, v1); 11801 gen_load_gpr(v2_t, v2); 11802 11803 switch (opc) { 11804 case OPC_SHLL_QB_DSP: 11805 { 11806 op2 = MASK_SHLL_QB(ctx->opcode); 11807 switch (op2) { 11808 case OPC_SHLL_QB: 11809 check_dsp(ctx); 11810 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, tcg_env); 11811 break; 11812 case OPC_SHLLV_QB: 11813 check_dsp(ctx); 11814 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11815 break; 11816 case OPC_SHLL_PH: 11817 check_dsp(ctx); 11818 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, tcg_env); 11819 break; 11820 case OPC_SHLLV_PH: 11821 check_dsp(ctx); 11822 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11823 break; 11824 case OPC_SHLL_S_PH: 11825 check_dsp(ctx); 11826 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, tcg_env); 11827 break; 11828 case OPC_SHLLV_S_PH: 11829 check_dsp(ctx); 11830 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11831 break; 11832 case OPC_SHLL_S_W: 11833 check_dsp(ctx); 11834 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, tcg_env); 11835 break; 11836 case OPC_SHLLV_S_W: 11837 check_dsp(ctx); 11838 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11839 break; 11840 case OPC_SHRL_QB: 11841 check_dsp(ctx); 11842 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); 11843 break; 11844 case OPC_SHRLV_QB: 11845 check_dsp(ctx); 11846 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); 11847 break; 11848 case OPC_SHRL_PH: 11849 check_dsp_r2(ctx); 11850 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); 11851 break; 11852 case OPC_SHRLV_PH: 11853 check_dsp_r2(ctx); 11854 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); 11855 break; 11856 case OPC_SHRA_QB: 11857 check_dsp_r2(ctx); 11858 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); 11859 break; 11860 case OPC_SHRA_R_QB: 11861 check_dsp_r2(ctx); 11862 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); 11863 break; 11864 case OPC_SHRAV_QB: 11865 check_dsp_r2(ctx); 11866 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); 11867 break; 11868 case OPC_SHRAV_R_QB: 11869 check_dsp_r2(ctx); 11870 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); 11871 break; 11872 case OPC_SHRA_PH: 11873 check_dsp(ctx); 11874 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); 11875 break; 11876 case OPC_SHRA_R_PH: 11877 check_dsp(ctx); 11878 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); 11879 break; 11880 case OPC_SHRAV_PH: 11881 check_dsp(ctx); 11882 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); 11883 break; 11884 case OPC_SHRAV_R_PH: 11885 check_dsp(ctx); 11886 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); 11887 break; 11888 case OPC_SHRA_R_W: 11889 check_dsp(ctx); 11890 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); 11891 break; 11892 case OPC_SHRAV_R_W: 11893 check_dsp(ctx); 11894 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); 11895 break; 11896 default: /* Invalid */ 11897 MIPS_INVAL("MASK SHLL.QB"); 11898 gen_reserved_instruction(ctx); 11899 break; 11900 } 11901 break; 11902 } 11903 #ifdef TARGET_MIPS64 11904 case OPC_SHLL_OB_DSP: 11905 op2 = MASK_SHLL_OB(ctx->opcode); 11906 switch (op2) { 11907 case OPC_SHLL_PW: 11908 check_dsp(ctx); 11909 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, tcg_env); 11910 break; 11911 case OPC_SHLLV_PW: 11912 check_dsp(ctx); 11913 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11914 break; 11915 case OPC_SHLL_S_PW: 11916 check_dsp(ctx); 11917 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, tcg_env); 11918 break; 11919 case OPC_SHLLV_S_PW: 11920 check_dsp(ctx); 11921 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11922 break; 11923 case OPC_SHLL_OB: 11924 check_dsp(ctx); 11925 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, tcg_env); 11926 break; 11927 case OPC_SHLLV_OB: 11928 check_dsp(ctx); 11929 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11930 break; 11931 case OPC_SHLL_QH: 11932 check_dsp(ctx); 11933 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, tcg_env); 11934 break; 11935 case OPC_SHLLV_QH: 11936 check_dsp(ctx); 11937 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11938 break; 11939 case OPC_SHLL_S_QH: 11940 check_dsp(ctx); 11941 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, tcg_env); 11942 break; 11943 case OPC_SHLLV_S_QH: 11944 check_dsp(ctx); 11945 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11946 break; 11947 case OPC_SHRA_OB: 11948 check_dsp_r2(ctx); 11949 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); 11950 break; 11951 case OPC_SHRAV_OB: 11952 check_dsp_r2(ctx); 11953 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); 11954 break; 11955 case OPC_SHRA_R_OB: 11956 check_dsp_r2(ctx); 11957 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); 11958 break; 11959 case OPC_SHRAV_R_OB: 11960 check_dsp_r2(ctx); 11961 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); 11962 break; 11963 case OPC_SHRA_PW: 11964 check_dsp(ctx); 11965 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); 11966 break; 11967 case OPC_SHRAV_PW: 11968 check_dsp(ctx); 11969 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); 11970 break; 11971 case OPC_SHRA_R_PW: 11972 check_dsp(ctx); 11973 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); 11974 break; 11975 case OPC_SHRAV_R_PW: 11976 check_dsp(ctx); 11977 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); 11978 break; 11979 case OPC_SHRA_QH: 11980 check_dsp(ctx); 11981 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); 11982 break; 11983 case OPC_SHRAV_QH: 11984 check_dsp(ctx); 11985 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); 11986 break; 11987 case OPC_SHRA_R_QH: 11988 check_dsp(ctx); 11989 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); 11990 break; 11991 case OPC_SHRAV_R_QH: 11992 check_dsp(ctx); 11993 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); 11994 break; 11995 case OPC_SHRL_OB: 11996 check_dsp(ctx); 11997 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); 11998 break; 11999 case OPC_SHRLV_OB: 12000 check_dsp(ctx); 12001 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); 12002 break; 12003 case OPC_SHRL_QH: 12004 check_dsp_r2(ctx); 12005 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); 12006 break; 12007 case OPC_SHRLV_QH: 12008 check_dsp_r2(ctx); 12009 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); 12010 break; 12011 default: /* Invalid */ 12012 MIPS_INVAL("MASK SHLL.OB"); 12013 gen_reserved_instruction(ctx); 12014 break; 12015 } 12016 break; 12017 #endif 12018 } 12019 } 12020 12021 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2, 12022 int ret, int v1, int v2, int check_ret) 12023 { 12024 TCGv_i32 t0; 12025 TCGv v1_t; 12026 TCGv v2_t; 12027 12028 if ((ret == 0) && (check_ret == 1)) { 12029 /* Treat as NOP. */ 12030 return; 12031 } 12032 12033 t0 = tcg_temp_new_i32(); 12034 v1_t = tcg_temp_new(); 12035 v2_t = tcg_temp_new(); 12036 12037 tcg_gen_movi_i32(t0, ret); 12038 gen_load_gpr(v1_t, v1); 12039 gen_load_gpr(v2_t, v2); 12040 12041 switch (op1) { 12042 case OPC_MUL_PH_DSP: 12043 check_dsp_r2(ctx); 12044 switch (op2) { 12045 case OPC_MUL_PH: 12046 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12047 break; 12048 case OPC_MUL_S_PH: 12049 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12050 break; 12051 case OPC_MULQ_S_W: 12052 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12053 break; 12054 case OPC_MULQ_RS_W: 12055 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12056 break; 12057 } 12058 break; 12059 case OPC_DPA_W_PH_DSP: 12060 switch (op2) { 12061 case OPC_DPAU_H_QBL: 12062 check_dsp(ctx); 12063 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, tcg_env); 12064 break; 12065 case OPC_DPAU_H_QBR: 12066 check_dsp(ctx); 12067 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, tcg_env); 12068 break; 12069 case OPC_DPSU_H_QBL: 12070 check_dsp(ctx); 12071 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, tcg_env); 12072 break; 12073 case OPC_DPSU_H_QBR: 12074 check_dsp(ctx); 12075 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, tcg_env); 12076 break; 12077 case OPC_DPA_W_PH: 12078 check_dsp_r2(ctx); 12079 gen_helper_dpa_w_ph(t0, v1_t, v2_t, tcg_env); 12080 break; 12081 case OPC_DPAX_W_PH: 12082 check_dsp_r2(ctx); 12083 gen_helper_dpax_w_ph(t0, v1_t, v2_t, tcg_env); 12084 break; 12085 case OPC_DPAQ_S_W_PH: 12086 check_dsp(ctx); 12087 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12088 break; 12089 case OPC_DPAQX_S_W_PH: 12090 check_dsp_r2(ctx); 12091 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, tcg_env); 12092 break; 12093 case OPC_DPAQX_SA_W_PH: 12094 check_dsp_r2(ctx); 12095 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, tcg_env); 12096 break; 12097 case OPC_DPS_W_PH: 12098 check_dsp_r2(ctx); 12099 gen_helper_dps_w_ph(t0, v1_t, v2_t, tcg_env); 12100 break; 12101 case OPC_DPSX_W_PH: 12102 check_dsp_r2(ctx); 12103 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, tcg_env); 12104 break; 12105 case OPC_DPSQ_S_W_PH: 12106 check_dsp(ctx); 12107 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12108 break; 12109 case OPC_DPSQX_S_W_PH: 12110 check_dsp_r2(ctx); 12111 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, tcg_env); 12112 break; 12113 case OPC_DPSQX_SA_W_PH: 12114 check_dsp_r2(ctx); 12115 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, tcg_env); 12116 break; 12117 case OPC_MULSAQ_S_W_PH: 12118 check_dsp(ctx); 12119 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12120 break; 12121 case OPC_DPAQ_SA_L_W: 12122 check_dsp(ctx); 12123 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, tcg_env); 12124 break; 12125 case OPC_DPSQ_SA_L_W: 12126 check_dsp(ctx); 12127 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, tcg_env); 12128 break; 12129 case OPC_MAQ_S_W_PHL: 12130 check_dsp(ctx); 12131 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, tcg_env); 12132 break; 12133 case OPC_MAQ_S_W_PHR: 12134 check_dsp(ctx); 12135 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, tcg_env); 12136 break; 12137 case OPC_MAQ_SA_W_PHL: 12138 check_dsp(ctx); 12139 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, tcg_env); 12140 break; 12141 case OPC_MAQ_SA_W_PHR: 12142 check_dsp(ctx); 12143 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, tcg_env); 12144 break; 12145 case OPC_MULSA_W_PH: 12146 check_dsp_r2(ctx); 12147 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, tcg_env); 12148 break; 12149 } 12150 break; 12151 #ifdef TARGET_MIPS64 12152 case OPC_DPAQ_W_QH_DSP: 12153 { 12154 int ac = ret & 0x03; 12155 tcg_gen_movi_i32(t0, ac); 12156 12157 switch (op2) { 12158 case OPC_DMADD: 12159 check_dsp(ctx); 12160 gen_helper_dmadd(v1_t, v2_t, t0, tcg_env); 12161 break; 12162 case OPC_DMADDU: 12163 check_dsp(ctx); 12164 gen_helper_dmaddu(v1_t, v2_t, t0, tcg_env); 12165 break; 12166 case OPC_DMSUB: 12167 check_dsp(ctx); 12168 gen_helper_dmsub(v1_t, v2_t, t0, tcg_env); 12169 break; 12170 case OPC_DMSUBU: 12171 check_dsp(ctx); 12172 gen_helper_dmsubu(v1_t, v2_t, t0, tcg_env); 12173 break; 12174 case OPC_DPA_W_QH: 12175 check_dsp_r2(ctx); 12176 gen_helper_dpa_w_qh(v1_t, v2_t, t0, tcg_env); 12177 break; 12178 case OPC_DPAQ_S_W_QH: 12179 check_dsp(ctx); 12180 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12181 break; 12182 case OPC_DPAQ_SA_L_PW: 12183 check_dsp(ctx); 12184 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, tcg_env); 12185 break; 12186 case OPC_DPAU_H_OBL: 12187 check_dsp(ctx); 12188 gen_helper_dpau_h_obl(v1_t, v2_t, t0, tcg_env); 12189 break; 12190 case OPC_DPAU_H_OBR: 12191 check_dsp(ctx); 12192 gen_helper_dpau_h_obr(v1_t, v2_t, t0, tcg_env); 12193 break; 12194 case OPC_DPS_W_QH: 12195 check_dsp_r2(ctx); 12196 gen_helper_dps_w_qh(v1_t, v2_t, t0, tcg_env); 12197 break; 12198 case OPC_DPSQ_S_W_QH: 12199 check_dsp(ctx); 12200 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12201 break; 12202 case OPC_DPSQ_SA_L_PW: 12203 check_dsp(ctx); 12204 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, tcg_env); 12205 break; 12206 case OPC_DPSU_H_OBL: 12207 check_dsp(ctx); 12208 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, tcg_env); 12209 break; 12210 case OPC_DPSU_H_OBR: 12211 check_dsp(ctx); 12212 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, tcg_env); 12213 break; 12214 case OPC_MAQ_S_L_PWL: 12215 check_dsp(ctx); 12216 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, tcg_env); 12217 break; 12218 case OPC_MAQ_S_L_PWR: 12219 check_dsp(ctx); 12220 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, tcg_env); 12221 break; 12222 case OPC_MAQ_S_W_QHLL: 12223 check_dsp(ctx); 12224 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, tcg_env); 12225 break; 12226 case OPC_MAQ_SA_W_QHLL: 12227 check_dsp(ctx); 12228 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, tcg_env); 12229 break; 12230 case OPC_MAQ_S_W_QHLR: 12231 check_dsp(ctx); 12232 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, tcg_env); 12233 break; 12234 case OPC_MAQ_SA_W_QHLR: 12235 check_dsp(ctx); 12236 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, tcg_env); 12237 break; 12238 case OPC_MAQ_S_W_QHRL: 12239 check_dsp(ctx); 12240 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, tcg_env); 12241 break; 12242 case OPC_MAQ_SA_W_QHRL: 12243 check_dsp(ctx); 12244 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, tcg_env); 12245 break; 12246 case OPC_MAQ_S_W_QHRR: 12247 check_dsp(ctx); 12248 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, tcg_env); 12249 break; 12250 case OPC_MAQ_SA_W_QHRR: 12251 check_dsp(ctx); 12252 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, tcg_env); 12253 break; 12254 case OPC_MULSAQ_S_L_PW: 12255 check_dsp(ctx); 12256 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, tcg_env); 12257 break; 12258 case OPC_MULSAQ_S_W_QH: 12259 check_dsp(ctx); 12260 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12261 break; 12262 } 12263 } 12264 break; 12265 #endif 12266 case OPC_ADDU_QB_DSP: 12267 switch (op2) { 12268 case OPC_MULEU_S_PH_QBL: 12269 check_dsp(ctx); 12270 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12271 break; 12272 case OPC_MULEU_S_PH_QBR: 12273 check_dsp(ctx); 12274 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12275 break; 12276 case OPC_MULQ_RS_PH: 12277 check_dsp(ctx); 12278 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12279 break; 12280 case OPC_MULEQ_S_W_PHL: 12281 check_dsp(ctx); 12282 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12283 break; 12284 case OPC_MULEQ_S_W_PHR: 12285 check_dsp(ctx); 12286 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12287 break; 12288 case OPC_MULQ_S_PH: 12289 check_dsp_r2(ctx); 12290 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12291 break; 12292 } 12293 break; 12294 #ifdef TARGET_MIPS64 12295 case OPC_ADDU_OB_DSP: 12296 switch (op2) { 12297 case OPC_MULEQ_S_PW_QHL: 12298 check_dsp(ctx); 12299 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12300 break; 12301 case OPC_MULEQ_S_PW_QHR: 12302 check_dsp(ctx); 12303 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12304 break; 12305 case OPC_MULEU_S_QH_OBL: 12306 check_dsp(ctx); 12307 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12308 break; 12309 case OPC_MULEU_S_QH_OBR: 12310 check_dsp(ctx); 12311 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12312 break; 12313 case OPC_MULQ_RS_QH: 12314 check_dsp(ctx); 12315 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12316 break; 12317 } 12318 break; 12319 #endif 12320 } 12321 } 12322 12323 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 12324 int ret, int val) 12325 { 12326 int16_t imm; 12327 TCGv t0; 12328 TCGv val_t; 12329 12330 if (ret == 0) { 12331 /* Treat as NOP. */ 12332 return; 12333 } 12334 12335 t0 = tcg_temp_new(); 12336 val_t = tcg_temp_new(); 12337 gen_load_gpr(val_t, val); 12338 12339 switch (op1) { 12340 case OPC_ABSQ_S_PH_DSP: 12341 switch (op2) { 12342 case OPC_BITREV: 12343 check_dsp(ctx); 12344 gen_helper_bitrev(cpu_gpr[ret], val_t); 12345 break; 12346 case OPC_REPL_QB: 12347 check_dsp(ctx); 12348 { 12349 target_long result; 12350 imm = (ctx->opcode >> 16) & 0xFF; 12351 result = (uint32_t)imm << 24 | 12352 (uint32_t)imm << 16 | 12353 (uint32_t)imm << 8 | 12354 (uint32_t)imm; 12355 result = (int32_t)result; 12356 tcg_gen_movi_tl(cpu_gpr[ret], result); 12357 } 12358 break; 12359 case OPC_REPLV_QB: 12360 check_dsp(ctx); 12361 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 12362 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 12363 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12364 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12365 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12366 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12367 break; 12368 case OPC_REPL_PH: 12369 check_dsp(ctx); 12370 { 12371 imm = (ctx->opcode >> 16) & 0x03FF; 12372 imm = (int16_t)(imm << 6) >> 6; 12373 tcg_gen_movi_tl(cpu_gpr[ret], \ 12374 (target_long)((int32_t)imm << 16 | \ 12375 (uint16_t)imm)); 12376 } 12377 break; 12378 case OPC_REPLV_PH: 12379 check_dsp(ctx); 12380 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 12381 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12382 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12383 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12384 break; 12385 } 12386 break; 12387 #ifdef TARGET_MIPS64 12388 case OPC_ABSQ_S_QH_DSP: 12389 switch (op2) { 12390 case OPC_REPL_OB: 12391 check_dsp(ctx); 12392 { 12393 target_long temp; 12394 12395 imm = (ctx->opcode >> 16) & 0xFF; 12396 temp = ((uint64_t)imm << 8) | (uint64_t)imm; 12397 temp = (temp << 16) | temp; 12398 temp = (temp << 32) | temp; 12399 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12400 break; 12401 } 12402 case OPC_REPL_PW: 12403 check_dsp(ctx); 12404 { 12405 target_long temp; 12406 12407 imm = (ctx->opcode >> 16) & 0x03FF; 12408 imm = (int16_t)(imm << 6) >> 6; 12409 temp = ((target_long)imm << 32) \ 12410 | ((target_long)imm & 0xFFFFFFFF); 12411 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12412 break; 12413 } 12414 case OPC_REPL_QH: 12415 check_dsp(ctx); 12416 { 12417 target_long temp; 12418 12419 imm = (ctx->opcode >> 16) & 0x03FF; 12420 imm = (int16_t)(imm << 6) >> 6; 12421 12422 temp = ((uint64_t)(uint16_t)imm << 48) | 12423 ((uint64_t)(uint16_t)imm << 32) | 12424 ((uint64_t)(uint16_t)imm << 16) | 12425 (uint64_t)(uint16_t)imm; 12426 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12427 break; 12428 } 12429 case OPC_REPLV_OB: 12430 check_dsp(ctx); 12431 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 12432 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 12433 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12434 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12435 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12436 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12437 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12438 break; 12439 case OPC_REPLV_PW: 12440 check_dsp(ctx); 12441 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); 12442 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12443 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12444 break; 12445 case OPC_REPLV_QH: 12446 check_dsp(ctx); 12447 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 12448 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12449 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12450 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12451 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12452 break; 12453 } 12454 break; 12455 #endif 12456 } 12457 } 12458 12459 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, 12460 uint32_t op1, uint32_t op2, 12461 int ret, int v1, int v2, int check_ret) 12462 { 12463 TCGv t1; 12464 TCGv v1_t; 12465 TCGv v2_t; 12466 12467 if ((ret == 0) && (check_ret == 1)) { 12468 /* Treat as NOP. */ 12469 return; 12470 } 12471 12472 t1 = tcg_temp_new(); 12473 v1_t = tcg_temp_new(); 12474 v2_t = tcg_temp_new(); 12475 12476 gen_load_gpr(v1_t, v1); 12477 gen_load_gpr(v2_t, v2); 12478 12479 switch (op1) { 12480 case OPC_CMPU_EQ_QB_DSP: 12481 switch (op2) { 12482 case OPC_CMPU_EQ_QB: 12483 check_dsp(ctx); 12484 gen_helper_cmpu_eq_qb(v1_t, v2_t, tcg_env); 12485 break; 12486 case OPC_CMPU_LT_QB: 12487 check_dsp(ctx); 12488 gen_helper_cmpu_lt_qb(v1_t, v2_t, tcg_env); 12489 break; 12490 case OPC_CMPU_LE_QB: 12491 check_dsp(ctx); 12492 gen_helper_cmpu_le_qb(v1_t, v2_t, tcg_env); 12493 break; 12494 case OPC_CMPGU_EQ_QB: 12495 check_dsp(ctx); 12496 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); 12497 break; 12498 case OPC_CMPGU_LT_QB: 12499 check_dsp(ctx); 12500 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); 12501 break; 12502 case OPC_CMPGU_LE_QB: 12503 check_dsp(ctx); 12504 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); 12505 break; 12506 case OPC_CMPGDU_EQ_QB: 12507 check_dsp_r2(ctx); 12508 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); 12509 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12510 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12511 tcg_gen_shli_tl(t1, t1, 24); 12512 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12513 break; 12514 case OPC_CMPGDU_LT_QB: 12515 check_dsp_r2(ctx); 12516 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); 12517 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12518 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12519 tcg_gen_shli_tl(t1, t1, 24); 12520 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12521 break; 12522 case OPC_CMPGDU_LE_QB: 12523 check_dsp_r2(ctx); 12524 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); 12525 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12526 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12527 tcg_gen_shli_tl(t1, t1, 24); 12528 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12529 break; 12530 case OPC_CMP_EQ_PH: 12531 check_dsp(ctx); 12532 gen_helper_cmp_eq_ph(v1_t, v2_t, tcg_env); 12533 break; 12534 case OPC_CMP_LT_PH: 12535 check_dsp(ctx); 12536 gen_helper_cmp_lt_ph(v1_t, v2_t, tcg_env); 12537 break; 12538 case OPC_CMP_LE_PH: 12539 check_dsp(ctx); 12540 gen_helper_cmp_le_ph(v1_t, v2_t, tcg_env); 12541 break; 12542 case OPC_PICK_QB: 12543 check_dsp(ctx); 12544 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12545 break; 12546 case OPC_PICK_PH: 12547 check_dsp(ctx); 12548 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12549 break; 12550 case OPC_PACKRL_PH: 12551 check_dsp(ctx); 12552 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); 12553 break; 12554 } 12555 break; 12556 #ifdef TARGET_MIPS64 12557 case OPC_CMPU_EQ_OB_DSP: 12558 switch (op2) { 12559 case OPC_CMP_EQ_PW: 12560 check_dsp(ctx); 12561 gen_helper_cmp_eq_pw(v1_t, v2_t, tcg_env); 12562 break; 12563 case OPC_CMP_LT_PW: 12564 check_dsp(ctx); 12565 gen_helper_cmp_lt_pw(v1_t, v2_t, tcg_env); 12566 break; 12567 case OPC_CMP_LE_PW: 12568 check_dsp(ctx); 12569 gen_helper_cmp_le_pw(v1_t, v2_t, tcg_env); 12570 break; 12571 case OPC_CMP_EQ_QH: 12572 check_dsp(ctx); 12573 gen_helper_cmp_eq_qh(v1_t, v2_t, tcg_env); 12574 break; 12575 case OPC_CMP_LT_QH: 12576 check_dsp(ctx); 12577 gen_helper_cmp_lt_qh(v1_t, v2_t, tcg_env); 12578 break; 12579 case OPC_CMP_LE_QH: 12580 check_dsp(ctx); 12581 gen_helper_cmp_le_qh(v1_t, v2_t, tcg_env); 12582 break; 12583 case OPC_CMPGDU_EQ_OB: 12584 check_dsp_r2(ctx); 12585 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12586 break; 12587 case OPC_CMPGDU_LT_OB: 12588 check_dsp_r2(ctx); 12589 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12590 break; 12591 case OPC_CMPGDU_LE_OB: 12592 check_dsp_r2(ctx); 12593 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12594 break; 12595 case OPC_CMPGU_EQ_OB: 12596 check_dsp(ctx); 12597 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); 12598 break; 12599 case OPC_CMPGU_LT_OB: 12600 check_dsp(ctx); 12601 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); 12602 break; 12603 case OPC_CMPGU_LE_OB: 12604 check_dsp(ctx); 12605 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); 12606 break; 12607 case OPC_CMPU_EQ_OB: 12608 check_dsp(ctx); 12609 gen_helper_cmpu_eq_ob(v1_t, v2_t, tcg_env); 12610 break; 12611 case OPC_CMPU_LT_OB: 12612 check_dsp(ctx); 12613 gen_helper_cmpu_lt_ob(v1_t, v2_t, tcg_env); 12614 break; 12615 case OPC_CMPU_LE_OB: 12616 check_dsp(ctx); 12617 gen_helper_cmpu_le_ob(v1_t, v2_t, tcg_env); 12618 break; 12619 case OPC_PACKRL_PW: 12620 check_dsp(ctx); 12621 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); 12622 break; 12623 case OPC_PICK_OB: 12624 check_dsp(ctx); 12625 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12626 break; 12627 case OPC_PICK_PW: 12628 check_dsp(ctx); 12629 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12630 break; 12631 case OPC_PICK_QH: 12632 check_dsp(ctx); 12633 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12634 break; 12635 } 12636 break; 12637 #endif 12638 } 12639 } 12640 12641 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, 12642 uint32_t op1, int rt, int rs, int sa) 12643 { 12644 TCGv t0; 12645 12646 check_dsp_r2(ctx); 12647 12648 if (rt == 0) { 12649 /* Treat as NOP. */ 12650 return; 12651 } 12652 12653 t0 = tcg_temp_new(); 12654 gen_load_gpr(t0, rs); 12655 12656 switch (op1) { 12657 case OPC_APPEND_DSP: 12658 switch (MASK_APPEND(ctx->opcode)) { 12659 case OPC_APPEND: 12660 if (sa != 0) { 12661 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa); 12662 } 12663 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12664 break; 12665 case OPC_PREPEND: 12666 if (sa != 0) { 12667 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); 12668 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 12669 tcg_gen_shli_tl(t0, t0, 32 - sa); 12670 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12671 } 12672 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12673 break; 12674 case OPC_BALIGN: 12675 sa &= 3; 12676 if (sa != 0 && sa != 2) { 12677 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 12678 tcg_gen_ext32u_tl(t0, t0); 12679 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); 12680 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12681 } 12682 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12683 break; 12684 default: /* Invalid */ 12685 MIPS_INVAL("MASK APPEND"); 12686 gen_reserved_instruction(ctx); 12687 break; 12688 } 12689 break; 12690 #ifdef TARGET_MIPS64 12691 case OPC_DAPPEND_DSP: 12692 switch (MASK_DAPPEND(ctx->opcode)) { 12693 case OPC_DAPPEND: 12694 if (sa != 0) { 12695 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa); 12696 } 12697 break; 12698 case OPC_PREPENDD: 12699 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); 12700 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); 12701 tcg_gen_or_tl(cpu_gpr[rt], t0, t0); 12702 break; 12703 case OPC_PREPENDW: 12704 if (sa != 0) { 12705 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 12706 tcg_gen_shli_tl(t0, t0, 64 - sa); 12707 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12708 } 12709 break; 12710 case OPC_DBALIGN: 12711 sa &= 7; 12712 if (sa != 0 && sa != 2 && sa != 4) { 12713 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 12714 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); 12715 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12716 } 12717 break; 12718 default: /* Invalid */ 12719 MIPS_INVAL("MASK DAPPEND"); 12720 gen_reserved_instruction(ctx); 12721 break; 12722 } 12723 break; 12724 #endif 12725 } 12726 } 12727 12728 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 12729 int ret, int v1, int v2, int check_ret) 12730 12731 { 12732 TCGv t0; 12733 TCGv t1; 12734 TCGv v1_t; 12735 int16_t imm; 12736 12737 if ((ret == 0) && (check_ret == 1)) { 12738 /* Treat as NOP. */ 12739 return; 12740 } 12741 12742 t0 = tcg_temp_new(); 12743 t1 = tcg_temp_new(); 12744 v1_t = tcg_temp_new(); 12745 12746 gen_load_gpr(v1_t, v1); 12747 12748 switch (op1) { 12749 case OPC_EXTR_W_DSP: 12750 check_dsp(ctx); 12751 switch (op2) { 12752 case OPC_EXTR_W: 12753 tcg_gen_movi_tl(t0, v2); 12754 tcg_gen_movi_tl(t1, v1); 12755 gen_helper_extr_w(cpu_gpr[ret], t0, t1, tcg_env); 12756 break; 12757 case OPC_EXTR_R_W: 12758 tcg_gen_movi_tl(t0, v2); 12759 tcg_gen_movi_tl(t1, v1); 12760 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, tcg_env); 12761 break; 12762 case OPC_EXTR_RS_W: 12763 tcg_gen_movi_tl(t0, v2); 12764 tcg_gen_movi_tl(t1, v1); 12765 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, tcg_env); 12766 break; 12767 case OPC_EXTR_S_H: 12768 tcg_gen_movi_tl(t0, v2); 12769 tcg_gen_movi_tl(t1, v1); 12770 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, tcg_env); 12771 break; 12772 case OPC_EXTRV_S_H: 12773 tcg_gen_movi_tl(t0, v2); 12774 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env); 12775 break; 12776 case OPC_EXTRV_W: 12777 tcg_gen_movi_tl(t0, v2); 12778 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12779 break; 12780 case OPC_EXTRV_R_W: 12781 tcg_gen_movi_tl(t0, v2); 12782 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12783 break; 12784 case OPC_EXTRV_RS_W: 12785 tcg_gen_movi_tl(t0, v2); 12786 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12787 break; 12788 case OPC_EXTP: 12789 tcg_gen_movi_tl(t0, v2); 12790 tcg_gen_movi_tl(t1, v1); 12791 gen_helper_extp(cpu_gpr[ret], t0, t1, tcg_env); 12792 break; 12793 case OPC_EXTPV: 12794 tcg_gen_movi_tl(t0, v2); 12795 gen_helper_extp(cpu_gpr[ret], t0, v1_t, tcg_env); 12796 break; 12797 case OPC_EXTPDP: 12798 tcg_gen_movi_tl(t0, v2); 12799 tcg_gen_movi_tl(t1, v1); 12800 gen_helper_extpdp(cpu_gpr[ret], t0, t1, tcg_env); 12801 break; 12802 case OPC_EXTPDPV: 12803 tcg_gen_movi_tl(t0, v2); 12804 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, tcg_env); 12805 break; 12806 case OPC_SHILO: 12807 imm = (ctx->opcode >> 20) & 0x3F; 12808 tcg_gen_movi_tl(t0, ret); 12809 tcg_gen_movi_tl(t1, imm); 12810 gen_helper_shilo(t0, t1, tcg_env); 12811 break; 12812 case OPC_SHILOV: 12813 tcg_gen_movi_tl(t0, ret); 12814 gen_helper_shilo(t0, v1_t, tcg_env); 12815 break; 12816 case OPC_MTHLIP: 12817 tcg_gen_movi_tl(t0, ret); 12818 gen_helper_mthlip(t0, v1_t, tcg_env); 12819 break; 12820 case OPC_WRDSP: 12821 imm = (ctx->opcode >> 11) & 0x3FF; 12822 tcg_gen_movi_tl(t0, imm); 12823 gen_helper_wrdsp(v1_t, t0, tcg_env); 12824 break; 12825 case OPC_RDDSP: 12826 imm = (ctx->opcode >> 16) & 0x03FF; 12827 tcg_gen_movi_tl(t0, imm); 12828 gen_helper_rddsp(cpu_gpr[ret], t0, tcg_env); 12829 break; 12830 } 12831 break; 12832 #ifdef TARGET_MIPS64 12833 case OPC_DEXTR_W_DSP: 12834 check_dsp(ctx); 12835 switch (op2) { 12836 case OPC_DMTHLIP: 12837 tcg_gen_movi_tl(t0, ret); 12838 gen_helper_dmthlip(v1_t, t0, tcg_env); 12839 break; 12840 case OPC_DSHILO: 12841 { 12842 int shift = (ctx->opcode >> 19) & 0x7F; 12843 int ac = (ctx->opcode >> 11) & 0x03; 12844 tcg_gen_movi_tl(t0, shift); 12845 tcg_gen_movi_tl(t1, ac); 12846 gen_helper_dshilo(t0, t1, tcg_env); 12847 break; 12848 } 12849 case OPC_DSHILOV: 12850 { 12851 int ac = (ctx->opcode >> 11) & 0x03; 12852 tcg_gen_movi_tl(t0, ac); 12853 gen_helper_dshilo(v1_t, t0, tcg_env); 12854 break; 12855 } 12856 case OPC_DEXTP: 12857 tcg_gen_movi_tl(t0, v2); 12858 tcg_gen_movi_tl(t1, v1); 12859 12860 gen_helper_dextp(cpu_gpr[ret], t0, t1, tcg_env); 12861 break; 12862 case OPC_DEXTPV: 12863 tcg_gen_movi_tl(t0, v2); 12864 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, tcg_env); 12865 break; 12866 case OPC_DEXTPDP: 12867 tcg_gen_movi_tl(t0, v2); 12868 tcg_gen_movi_tl(t1, v1); 12869 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, tcg_env); 12870 break; 12871 case OPC_DEXTPDPV: 12872 tcg_gen_movi_tl(t0, v2); 12873 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, tcg_env); 12874 break; 12875 case OPC_DEXTR_L: 12876 tcg_gen_movi_tl(t0, v2); 12877 tcg_gen_movi_tl(t1, v1); 12878 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, tcg_env); 12879 break; 12880 case OPC_DEXTR_R_L: 12881 tcg_gen_movi_tl(t0, v2); 12882 tcg_gen_movi_tl(t1, v1); 12883 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, tcg_env); 12884 break; 12885 case OPC_DEXTR_RS_L: 12886 tcg_gen_movi_tl(t0, v2); 12887 tcg_gen_movi_tl(t1, v1); 12888 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, tcg_env); 12889 break; 12890 case OPC_DEXTR_W: 12891 tcg_gen_movi_tl(t0, v2); 12892 tcg_gen_movi_tl(t1, v1); 12893 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, tcg_env); 12894 break; 12895 case OPC_DEXTR_R_W: 12896 tcg_gen_movi_tl(t0, v2); 12897 tcg_gen_movi_tl(t1, v1); 12898 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, tcg_env); 12899 break; 12900 case OPC_DEXTR_RS_W: 12901 tcg_gen_movi_tl(t0, v2); 12902 tcg_gen_movi_tl(t1, v1); 12903 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, tcg_env); 12904 break; 12905 case OPC_DEXTR_S_H: 12906 tcg_gen_movi_tl(t0, v2); 12907 tcg_gen_movi_tl(t1, v1); 12908 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, tcg_env); 12909 break; 12910 case OPC_DEXTRV_S_H: 12911 tcg_gen_movi_tl(t0, v2); 12912 gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env); 12913 break; 12914 case OPC_DEXTRV_L: 12915 tcg_gen_movi_tl(t0, v2); 12916 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, tcg_env); 12917 break; 12918 case OPC_DEXTRV_R_L: 12919 tcg_gen_movi_tl(t0, v2); 12920 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, tcg_env); 12921 break; 12922 case OPC_DEXTRV_RS_L: 12923 tcg_gen_movi_tl(t0, v2); 12924 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, tcg_env); 12925 break; 12926 case OPC_DEXTRV_W: 12927 tcg_gen_movi_tl(t0, v2); 12928 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12929 break; 12930 case OPC_DEXTRV_R_W: 12931 tcg_gen_movi_tl(t0, v2); 12932 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12933 break; 12934 case OPC_DEXTRV_RS_W: 12935 tcg_gen_movi_tl(t0, v2); 12936 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12937 break; 12938 } 12939 break; 12940 #endif 12941 } 12942 } 12943 12944 /* End MIPSDSP functions. */ 12945 12946 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) 12947 { 12948 int rs, rt, rd, sa; 12949 uint32_t op1, op2; 12950 12951 rs = (ctx->opcode >> 21) & 0x1f; 12952 rt = (ctx->opcode >> 16) & 0x1f; 12953 rd = (ctx->opcode >> 11) & 0x1f; 12954 sa = (ctx->opcode >> 6) & 0x1f; 12955 12956 op1 = MASK_SPECIAL(ctx->opcode); 12957 switch (op1) { 12958 case OPC_MULT: 12959 case OPC_MULTU: 12960 case OPC_DIV: 12961 case OPC_DIVU: 12962 op2 = MASK_R6_MULDIV(ctx->opcode); 12963 switch (op2) { 12964 case R6_OPC_MUL: 12965 case R6_OPC_MUH: 12966 case R6_OPC_MULU: 12967 case R6_OPC_MUHU: 12968 case R6_OPC_DIV: 12969 case R6_OPC_MOD: 12970 case R6_OPC_DIVU: 12971 case R6_OPC_MODU: 12972 gen_r6_muldiv(ctx, op2, rd, rs, rt); 12973 break; 12974 default: 12975 MIPS_INVAL("special_r6 muldiv"); 12976 gen_reserved_instruction(ctx); 12977 break; 12978 } 12979 break; 12980 case OPC_SELEQZ: 12981 case OPC_SELNEZ: 12982 gen_cond_move(ctx, op1, rd, rs, rt); 12983 break; 12984 case R6_OPC_CLO: 12985 case R6_OPC_CLZ: 12986 if (rt == 0 && sa == 1) { 12987 /* 12988 * Major opcode and function field is shared with preR6 MFHI/MTHI. 12989 * We need additionally to check other fields. 12990 */ 12991 gen_cl(ctx, op1, rd, rs); 12992 } else { 12993 gen_reserved_instruction(ctx); 12994 } 12995 break; 12996 case R6_OPC_SDBBP: 12997 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 12998 ctx->base.is_jmp = DISAS_SEMIHOST; 12999 } else { 13000 if (ctx->hflags & MIPS_HFLAG_SBRI) { 13001 gen_reserved_instruction(ctx); 13002 } else { 13003 generate_exception_end(ctx, EXCP_DBp); 13004 } 13005 } 13006 break; 13007 #if defined(TARGET_MIPS64) 13008 case R6_OPC_DCLO: 13009 case R6_OPC_DCLZ: 13010 if (rt == 0 && sa == 1) { 13011 /* 13012 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13013 * We need additionally to check other fields. 13014 */ 13015 check_mips_64(ctx); 13016 gen_cl(ctx, op1, rd, rs); 13017 } else { 13018 gen_reserved_instruction(ctx); 13019 } 13020 break; 13021 case OPC_DMULT: 13022 case OPC_DMULTU: 13023 case OPC_DDIV: 13024 case OPC_DDIVU: 13025 13026 op2 = MASK_R6_MULDIV(ctx->opcode); 13027 switch (op2) { 13028 case R6_OPC_DMUL: 13029 case R6_OPC_DMUH: 13030 case R6_OPC_DMULU: 13031 case R6_OPC_DMUHU: 13032 case R6_OPC_DDIV: 13033 case R6_OPC_DMOD: 13034 case R6_OPC_DDIVU: 13035 case R6_OPC_DMODU: 13036 check_mips_64(ctx); 13037 gen_r6_muldiv(ctx, op2, rd, rs, rt); 13038 break; 13039 default: 13040 MIPS_INVAL("special_r6 muldiv"); 13041 gen_reserved_instruction(ctx); 13042 break; 13043 } 13044 break; 13045 #endif 13046 default: /* Invalid */ 13047 MIPS_INVAL("special_r6"); 13048 gen_reserved_instruction(ctx); 13049 break; 13050 } 13051 } 13052 13053 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) 13054 { 13055 int rs = extract32(ctx->opcode, 21, 5); 13056 int rt = extract32(ctx->opcode, 16, 5); 13057 int rd = extract32(ctx->opcode, 11, 5); 13058 uint32_t op1 = MASK_SPECIAL(ctx->opcode); 13059 13060 switch (op1) { 13061 case OPC_MOVN: /* Conditional move */ 13062 case OPC_MOVZ: 13063 gen_cond_move(ctx, op1, rd, rs, rt); 13064 break; 13065 case OPC_MFHI: /* Move from HI/LO */ 13066 case OPC_MFLO: 13067 gen_HILO(ctx, op1, 0, rd); 13068 break; 13069 case OPC_MTHI: 13070 case OPC_MTLO: /* Move to HI/LO */ 13071 gen_HILO(ctx, op1, 0, rs); 13072 break; 13073 case OPC_MULT: 13074 case OPC_MULTU: 13075 gen_mul_txx9(ctx, op1, rd, rs, rt); 13076 break; 13077 case OPC_DIV: 13078 case OPC_DIVU: 13079 gen_muldiv(ctx, op1, 0, rs, rt); 13080 break; 13081 #if defined(TARGET_MIPS64) 13082 case OPC_DMULT: 13083 case OPC_DMULTU: 13084 case OPC_DDIV: 13085 case OPC_DDIVU: 13086 check_insn_opc_user_only(ctx, INSN_R5900); 13087 gen_muldiv(ctx, op1, 0, rs, rt); 13088 break; 13089 #endif 13090 case OPC_JR: 13091 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13092 break; 13093 default: /* Invalid */ 13094 MIPS_INVAL("special_tx79"); 13095 gen_reserved_instruction(ctx); 13096 break; 13097 } 13098 } 13099 13100 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) 13101 { 13102 int rs, rt, rd; 13103 uint32_t op1; 13104 13105 rs = (ctx->opcode >> 21) & 0x1f; 13106 rt = (ctx->opcode >> 16) & 0x1f; 13107 rd = (ctx->opcode >> 11) & 0x1f; 13108 13109 op1 = MASK_SPECIAL(ctx->opcode); 13110 switch (op1) { 13111 case OPC_MOVN: /* Conditional move */ 13112 case OPC_MOVZ: 13113 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | 13114 INSN_LOONGSON2E | INSN_LOONGSON2F); 13115 gen_cond_move(ctx, op1, rd, rs, rt); 13116 break; 13117 case OPC_MFHI: /* Move from HI/LO */ 13118 case OPC_MFLO: 13119 gen_HILO(ctx, op1, rs & 3, rd); 13120 break; 13121 case OPC_MTHI: 13122 case OPC_MTLO: /* Move to HI/LO */ 13123 gen_HILO(ctx, op1, rd & 3, rs); 13124 break; 13125 case OPC_MOVCI: 13126 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 13127 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 13128 check_cp1_enabled(ctx); 13129 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 13130 (ctx->opcode >> 16) & 1); 13131 } else { 13132 generate_exception_err(ctx, EXCP_CpU, 1); 13133 } 13134 break; 13135 case OPC_MULT: 13136 case OPC_MULTU: 13137 gen_muldiv(ctx, op1, rd & 3, rs, rt); 13138 break; 13139 case OPC_DIV: 13140 case OPC_DIVU: 13141 gen_muldiv(ctx, op1, 0, rs, rt); 13142 break; 13143 #if defined(TARGET_MIPS64) 13144 case OPC_DMULT: 13145 case OPC_DMULTU: 13146 case OPC_DDIV: 13147 case OPC_DDIVU: 13148 check_insn(ctx, ISA_MIPS3); 13149 check_mips_64(ctx); 13150 gen_muldiv(ctx, op1, 0, rs, rt); 13151 break; 13152 #endif 13153 case OPC_JR: 13154 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13155 break; 13156 case OPC_SPIM: 13157 #ifdef MIPS_STRICT_STANDARD 13158 MIPS_INVAL("SPIM"); 13159 gen_reserved_instruction(ctx); 13160 #else 13161 /* Implemented as RI exception for now. */ 13162 MIPS_INVAL("spim (unofficial)"); 13163 gen_reserved_instruction(ctx); 13164 #endif 13165 break; 13166 default: /* Invalid */ 13167 MIPS_INVAL("special_legacy"); 13168 gen_reserved_instruction(ctx); 13169 break; 13170 } 13171 } 13172 13173 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) 13174 { 13175 int rs, rt, rd, sa; 13176 uint32_t op1; 13177 13178 rs = (ctx->opcode >> 21) & 0x1f; 13179 rt = (ctx->opcode >> 16) & 0x1f; 13180 rd = (ctx->opcode >> 11) & 0x1f; 13181 sa = (ctx->opcode >> 6) & 0x1f; 13182 13183 op1 = MASK_SPECIAL(ctx->opcode); 13184 switch (op1) { 13185 case OPC_SLL: /* Shift with immediate */ 13186 if (sa == 5 && rd == 0 && 13187 rs == 0 && rt == 0) { /* PAUSE */ 13188 if ((ctx->insn_flags & ISA_MIPS_R6) && 13189 (ctx->hflags & MIPS_HFLAG_BMASK)) { 13190 gen_reserved_instruction(ctx); 13191 break; 13192 } 13193 } 13194 /* Fallthrough */ 13195 case OPC_SRA: 13196 gen_shift_imm(ctx, op1, rd, rt, sa); 13197 break; 13198 case OPC_SRL: 13199 switch ((ctx->opcode >> 21) & 0x1f) { 13200 case 1: 13201 /* rotr is decoded as srl on non-R2 CPUs */ 13202 if (ctx->insn_flags & ISA_MIPS_R2) { 13203 op1 = OPC_ROTR; 13204 } 13205 /* Fallthrough */ 13206 case 0: 13207 gen_shift_imm(ctx, op1, rd, rt, sa); 13208 break; 13209 default: 13210 gen_reserved_instruction(ctx); 13211 break; 13212 } 13213 break; 13214 case OPC_ADD: 13215 case OPC_ADDU: 13216 case OPC_SUB: 13217 case OPC_SUBU: 13218 gen_arith(ctx, op1, rd, rs, rt); 13219 break; 13220 case OPC_SLLV: /* Shifts */ 13221 case OPC_SRAV: 13222 gen_shift(ctx, op1, rd, rs, rt); 13223 break; 13224 case OPC_SRLV: 13225 switch ((ctx->opcode >> 6) & 0x1f) { 13226 case 1: 13227 /* rotrv is decoded as srlv on non-R2 CPUs */ 13228 if (ctx->insn_flags & ISA_MIPS_R2) { 13229 op1 = OPC_ROTRV; 13230 } 13231 /* Fallthrough */ 13232 case 0: 13233 gen_shift(ctx, op1, rd, rs, rt); 13234 break; 13235 default: 13236 gen_reserved_instruction(ctx); 13237 break; 13238 } 13239 break; 13240 case OPC_SLT: /* Set on less than */ 13241 case OPC_SLTU: 13242 gen_slt(ctx, op1, rd, rs, rt); 13243 break; 13244 case OPC_AND: /* Logic*/ 13245 case OPC_OR: 13246 case OPC_NOR: 13247 case OPC_XOR: 13248 gen_logic(ctx, op1, rd, rs, rt); 13249 break; 13250 case OPC_JALR: 13251 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 13252 break; 13253 case OPC_TGE: /* Traps */ 13254 case OPC_TGEU: 13255 case OPC_TLT: 13256 case OPC_TLTU: 13257 case OPC_TEQ: 13258 case OPC_TNE: 13259 check_insn(ctx, ISA_MIPS2); 13260 gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10)); 13261 break; 13262 case OPC_PMON: 13263 /* Pmon entry point, also R4010 selsl */ 13264 #ifdef MIPS_STRICT_STANDARD 13265 MIPS_INVAL("PMON / selsl"); 13266 gen_reserved_instruction(ctx); 13267 #else 13268 gen_helper_pmon(tcg_env, tcg_constant_i32(sa)); 13269 #endif 13270 break; 13271 case OPC_SYSCALL: 13272 generate_exception_end(ctx, EXCP_SYSCALL); 13273 break; 13274 case OPC_BREAK: 13275 generate_exception_break(ctx, extract32(ctx->opcode, 6, 20)); 13276 break; 13277 case OPC_SYNC: 13278 check_insn(ctx, ISA_MIPS2); 13279 gen_sync(extract32(ctx->opcode, 6, 5)); 13280 break; 13281 13282 #if defined(TARGET_MIPS64) 13283 /* MIPS64 specific opcodes */ 13284 case OPC_DSLL: 13285 case OPC_DSRA: 13286 case OPC_DSLL32: 13287 case OPC_DSRA32: 13288 check_insn(ctx, ISA_MIPS3); 13289 check_mips_64(ctx); 13290 gen_shift_imm(ctx, op1, rd, rt, sa); 13291 break; 13292 case OPC_DSRL: 13293 switch ((ctx->opcode >> 21) & 0x1f) { 13294 case 1: 13295 /* drotr is decoded as dsrl on non-R2 CPUs */ 13296 if (ctx->insn_flags & ISA_MIPS_R2) { 13297 op1 = OPC_DROTR; 13298 } 13299 /* Fallthrough */ 13300 case 0: 13301 check_insn(ctx, ISA_MIPS3); 13302 check_mips_64(ctx); 13303 gen_shift_imm(ctx, op1, rd, rt, sa); 13304 break; 13305 default: 13306 gen_reserved_instruction(ctx); 13307 break; 13308 } 13309 break; 13310 case OPC_DSRL32: 13311 switch ((ctx->opcode >> 21) & 0x1f) { 13312 case 1: 13313 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 13314 if (ctx->insn_flags & ISA_MIPS_R2) { 13315 op1 = OPC_DROTR32; 13316 } 13317 /* Fallthrough */ 13318 case 0: 13319 check_insn(ctx, ISA_MIPS3); 13320 check_mips_64(ctx); 13321 gen_shift_imm(ctx, op1, rd, rt, sa); 13322 break; 13323 default: 13324 gen_reserved_instruction(ctx); 13325 break; 13326 } 13327 break; 13328 case OPC_DADD: 13329 case OPC_DADDU: 13330 case OPC_DSUB: 13331 case OPC_DSUBU: 13332 check_insn(ctx, ISA_MIPS3); 13333 check_mips_64(ctx); 13334 gen_arith(ctx, op1, rd, rs, rt); 13335 break; 13336 case OPC_DSLLV: 13337 case OPC_DSRAV: 13338 check_insn(ctx, ISA_MIPS3); 13339 check_mips_64(ctx); 13340 gen_shift(ctx, op1, rd, rs, rt); 13341 break; 13342 case OPC_DSRLV: 13343 switch ((ctx->opcode >> 6) & 0x1f) { 13344 case 1: 13345 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 13346 if (ctx->insn_flags & ISA_MIPS_R2) { 13347 op1 = OPC_DROTRV; 13348 } 13349 /* Fallthrough */ 13350 case 0: 13351 check_insn(ctx, ISA_MIPS3); 13352 check_mips_64(ctx); 13353 gen_shift(ctx, op1, rd, rs, rt); 13354 break; 13355 default: 13356 gen_reserved_instruction(ctx); 13357 break; 13358 } 13359 break; 13360 #endif 13361 default: 13362 if (ctx->insn_flags & ISA_MIPS_R6) { 13363 decode_opc_special_r6(env, ctx); 13364 } else if (ctx->insn_flags & INSN_R5900) { 13365 decode_opc_special_tx79(env, ctx); 13366 } else { 13367 decode_opc_special_legacy(env, ctx); 13368 } 13369 } 13370 } 13371 13372 13373 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) 13374 { 13375 int rs, rt, rd; 13376 uint32_t op1; 13377 13378 rs = (ctx->opcode >> 21) & 0x1f; 13379 rt = (ctx->opcode >> 16) & 0x1f; 13380 rd = (ctx->opcode >> 11) & 0x1f; 13381 13382 op1 = MASK_SPECIAL2(ctx->opcode); 13383 switch (op1) { 13384 case OPC_MADD: /* Multiply and add/sub */ 13385 case OPC_MADDU: 13386 case OPC_MSUB: 13387 case OPC_MSUBU: 13388 check_insn(ctx, ISA_MIPS_R1); 13389 gen_muldiv(ctx, op1, rd & 3, rs, rt); 13390 break; 13391 case OPC_MUL: 13392 gen_arith(ctx, op1, rd, rs, rt); 13393 break; 13394 case OPC_CLO: 13395 case OPC_CLZ: 13396 check_insn(ctx, ISA_MIPS_R1); 13397 gen_cl(ctx, op1, rd, rs); 13398 break; 13399 case OPC_SDBBP: 13400 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 13401 ctx->base.is_jmp = DISAS_SEMIHOST; 13402 } else { 13403 /* 13404 * XXX: not clear which exception should be raised 13405 * when in debug mode... 13406 */ 13407 check_insn(ctx, ISA_MIPS_R1); 13408 generate_exception_end(ctx, EXCP_DBp); 13409 } 13410 break; 13411 #if defined(TARGET_MIPS64) 13412 case OPC_DCLO: 13413 case OPC_DCLZ: 13414 check_insn(ctx, ISA_MIPS_R1); 13415 check_mips_64(ctx); 13416 gen_cl(ctx, op1, rd, rs); 13417 break; 13418 #endif 13419 default: /* Invalid */ 13420 MIPS_INVAL("special2_legacy"); 13421 gen_reserved_instruction(ctx); 13422 break; 13423 } 13424 } 13425 13426 void gen_crc32(DisasContext *ctx, int rd, int rs, int rt, int sz, 13427 int crc32c) 13428 { 13429 TCGv t0; 13430 TCGv t1; 13431 TCGv_i32 tsz = tcg_constant_i32(1 << sz); 13432 if (rd == 0) { 13433 /* Treat as NOP. */ 13434 return; 13435 } 13436 t0 = tcg_temp_new(); 13437 t1 = tcg_temp_new(); 13438 13439 gen_load_gpr(t0, rt); 13440 gen_load_gpr(t1, rs); 13441 13442 if (crc32c) { 13443 gen_helper_crc32c(cpu_gpr[rd], t0, t1, tsz); 13444 } else { 13445 gen_helper_crc32(cpu_gpr[rd], t0, t1, tsz); 13446 } 13447 } 13448 13449 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) 13450 { 13451 int rs, rt, rd, sa; 13452 uint32_t op1, op2; 13453 int16_t imm; 13454 13455 rs = (ctx->opcode >> 21) & 0x1f; 13456 rt = (ctx->opcode >> 16) & 0x1f; 13457 rd = (ctx->opcode >> 11) & 0x1f; 13458 sa = (ctx->opcode >> 6) & 0x1f; 13459 imm = (int16_t)ctx->opcode >> 7; 13460 13461 op1 = MASK_SPECIAL3(ctx->opcode); 13462 switch (op1) { 13463 case R6_OPC_PREF: 13464 if (rt >= 24) { 13465 /* hint codes 24-31 are reserved and signal RI */ 13466 gen_reserved_instruction(ctx); 13467 } 13468 /* Treat as NOP. */ 13469 break; 13470 case R6_OPC_CACHE: 13471 check_cp0_enabled(ctx); 13472 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 13473 gen_cache_operation(ctx, rt, rs, imm); 13474 } 13475 break; 13476 case R6_OPC_SC: 13477 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false); 13478 break; 13479 case R6_OPC_LL: 13480 gen_ld(ctx, op1, rt, rs, imm); 13481 break; 13482 case OPC_BSHFL: 13483 { 13484 if (rd == 0) { 13485 /* Treat as NOP. */ 13486 break; 13487 } 13488 op2 = MASK_BSHFL(ctx->opcode); 13489 switch (op2) { 13490 case OPC_ALIGN: 13491 case OPC_ALIGN_1: 13492 case OPC_ALIGN_2: 13493 case OPC_ALIGN_3: 13494 gen_align(ctx, 32, rd, rs, rt, sa & 3); 13495 break; 13496 case OPC_BITSWAP: 13497 gen_bitswap(ctx, op2, rd, rt); 13498 break; 13499 } 13500 } 13501 break; 13502 #ifndef CONFIG_USER_ONLY 13503 case OPC_GINV: 13504 if (unlikely(ctx->gi <= 1)) { 13505 gen_reserved_instruction(ctx); 13506 } 13507 check_cp0_enabled(ctx); 13508 switch ((ctx->opcode >> 6) & 3) { 13509 case 0: /* GINVI */ 13510 /* Treat as NOP. */ 13511 break; 13512 case 2: /* GINVT */ 13513 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); 13514 break; 13515 default: 13516 gen_reserved_instruction(ctx); 13517 break; 13518 } 13519 break; 13520 #endif 13521 #if defined(TARGET_MIPS64) 13522 case R6_OPC_SCD: 13523 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false); 13524 break; 13525 case R6_OPC_LLD: 13526 gen_ld(ctx, op1, rt, rs, imm); 13527 break; 13528 case OPC_DBSHFL: 13529 check_mips_64(ctx); 13530 { 13531 if (rd == 0) { 13532 /* Treat as NOP. */ 13533 break; 13534 } 13535 op2 = MASK_DBSHFL(ctx->opcode); 13536 switch (op2) { 13537 case OPC_DALIGN: 13538 case OPC_DALIGN_1: 13539 case OPC_DALIGN_2: 13540 case OPC_DALIGN_3: 13541 case OPC_DALIGN_4: 13542 case OPC_DALIGN_5: 13543 case OPC_DALIGN_6: 13544 case OPC_DALIGN_7: 13545 gen_align(ctx, 64, rd, rs, rt, sa & 7); 13546 break; 13547 case OPC_DBITSWAP: 13548 gen_bitswap(ctx, op2, rd, rt); 13549 break; 13550 } 13551 13552 } 13553 break; 13554 #endif 13555 default: /* Invalid */ 13556 MIPS_INVAL("special3_r6"); 13557 gen_reserved_instruction(ctx); 13558 break; 13559 } 13560 } 13561 13562 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) 13563 { 13564 int rs, rt, rd; 13565 uint32_t op1, op2; 13566 13567 rs = (ctx->opcode >> 21) & 0x1f; 13568 rt = (ctx->opcode >> 16) & 0x1f; 13569 rd = (ctx->opcode >> 11) & 0x1f; 13570 13571 op1 = MASK_SPECIAL3(ctx->opcode); 13572 switch (op1) { 13573 case OPC_MUL_PH_DSP: 13574 /* 13575 * OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 13576 * the same mask and op1. 13577 */ 13578 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MUL_PH_DSP)) { 13579 op2 = MASK_ADDUH_QB(ctx->opcode); 13580 switch (op2) { 13581 case OPC_ADDUH_QB: 13582 case OPC_ADDUH_R_QB: 13583 case OPC_ADDQH_PH: 13584 case OPC_ADDQH_R_PH: 13585 case OPC_ADDQH_W: 13586 case OPC_ADDQH_R_W: 13587 case OPC_SUBUH_QB: 13588 case OPC_SUBUH_R_QB: 13589 case OPC_SUBQH_PH: 13590 case OPC_SUBQH_R_PH: 13591 case OPC_SUBQH_W: 13592 case OPC_SUBQH_R_W: 13593 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13594 break; 13595 case OPC_MUL_PH: 13596 case OPC_MUL_S_PH: 13597 case OPC_MULQ_S_W: 13598 case OPC_MULQ_RS_W: 13599 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13600 break; 13601 default: 13602 MIPS_INVAL("MASK ADDUH.QB"); 13603 gen_reserved_instruction(ctx); 13604 break; 13605 } 13606 } else { 13607 gen_reserved_instruction(ctx); 13608 } 13609 break; 13610 case OPC_LX_DSP: 13611 check_dsp(ctx); 13612 op2 = MASK_LX(ctx->opcode); 13613 switch (op2) { 13614 #if defined(TARGET_MIPS64) 13615 case OPC_LDX: 13616 gen_lx(ctx, rd, rs, rt, MO_UQ); 13617 break; 13618 #endif 13619 case OPC_LBUX: 13620 gen_lx(ctx, rd, rs, rt, MO_UB); 13621 break; 13622 case OPC_LHX: 13623 gen_lx(ctx, rd, rs, rt, MO_SW); 13624 break; 13625 case OPC_LWX: 13626 gen_lx(ctx, rd, rs, rt, MO_SL); 13627 break; 13628 default: /* Invalid */ 13629 MIPS_INVAL("MASK LX"); 13630 gen_reserved_instruction(ctx); 13631 break; 13632 } 13633 break; 13634 case OPC_ABSQ_S_PH_DSP: 13635 op2 = MASK_ABSQ_S_PH(ctx->opcode); 13636 switch (op2) { 13637 case OPC_ABSQ_S_QB: 13638 case OPC_ABSQ_S_PH: 13639 case OPC_ABSQ_S_W: 13640 case OPC_PRECEQ_W_PHL: 13641 case OPC_PRECEQ_W_PHR: 13642 case OPC_PRECEQU_PH_QBL: 13643 case OPC_PRECEQU_PH_QBR: 13644 case OPC_PRECEQU_PH_QBLA: 13645 case OPC_PRECEQU_PH_QBRA: 13646 case OPC_PRECEU_PH_QBL: 13647 case OPC_PRECEU_PH_QBR: 13648 case OPC_PRECEU_PH_QBLA: 13649 case OPC_PRECEU_PH_QBRA: 13650 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13651 break; 13652 case OPC_BITREV: 13653 case OPC_REPL_QB: 13654 case OPC_REPLV_QB: 13655 case OPC_REPL_PH: 13656 case OPC_REPLV_PH: 13657 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 13658 break; 13659 default: 13660 MIPS_INVAL("MASK ABSQ_S.PH"); 13661 gen_reserved_instruction(ctx); 13662 break; 13663 } 13664 break; 13665 case OPC_ADDU_QB_DSP: 13666 op2 = MASK_ADDU_QB(ctx->opcode); 13667 switch (op2) { 13668 case OPC_ADDQ_PH: 13669 case OPC_ADDQ_S_PH: 13670 case OPC_ADDQ_S_W: 13671 case OPC_ADDU_QB: 13672 case OPC_ADDU_S_QB: 13673 case OPC_ADDU_PH: 13674 case OPC_ADDU_S_PH: 13675 case OPC_SUBQ_PH: 13676 case OPC_SUBQ_S_PH: 13677 case OPC_SUBQ_S_W: 13678 case OPC_SUBU_QB: 13679 case OPC_SUBU_S_QB: 13680 case OPC_SUBU_PH: 13681 case OPC_SUBU_S_PH: 13682 case OPC_ADDSC: 13683 case OPC_ADDWC: 13684 case OPC_MODSUB: 13685 case OPC_RADDU_W_QB: 13686 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13687 break; 13688 case OPC_MULEU_S_PH_QBL: 13689 case OPC_MULEU_S_PH_QBR: 13690 case OPC_MULQ_RS_PH: 13691 case OPC_MULEQ_S_W_PHL: 13692 case OPC_MULEQ_S_W_PHR: 13693 case OPC_MULQ_S_PH: 13694 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13695 break; 13696 default: /* Invalid */ 13697 MIPS_INVAL("MASK ADDU.QB"); 13698 gen_reserved_instruction(ctx); 13699 break; 13700 13701 } 13702 break; 13703 case OPC_CMPU_EQ_QB_DSP: 13704 op2 = MASK_CMPU_EQ_QB(ctx->opcode); 13705 switch (op2) { 13706 case OPC_PRECR_SRA_PH_W: 13707 case OPC_PRECR_SRA_R_PH_W: 13708 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 13709 break; 13710 case OPC_PRECR_QB_PH: 13711 case OPC_PRECRQ_QB_PH: 13712 case OPC_PRECRQ_PH_W: 13713 case OPC_PRECRQ_RS_PH_W: 13714 case OPC_PRECRQU_S_QB_PH: 13715 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13716 break; 13717 case OPC_CMPU_EQ_QB: 13718 case OPC_CMPU_LT_QB: 13719 case OPC_CMPU_LE_QB: 13720 case OPC_CMP_EQ_PH: 13721 case OPC_CMP_LT_PH: 13722 case OPC_CMP_LE_PH: 13723 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 13724 break; 13725 case OPC_CMPGU_EQ_QB: 13726 case OPC_CMPGU_LT_QB: 13727 case OPC_CMPGU_LE_QB: 13728 case OPC_CMPGDU_EQ_QB: 13729 case OPC_CMPGDU_LT_QB: 13730 case OPC_CMPGDU_LE_QB: 13731 case OPC_PICK_QB: 13732 case OPC_PICK_PH: 13733 case OPC_PACKRL_PH: 13734 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 13735 break; 13736 default: /* Invalid */ 13737 MIPS_INVAL("MASK CMPU.EQ.QB"); 13738 gen_reserved_instruction(ctx); 13739 break; 13740 } 13741 break; 13742 case OPC_SHLL_QB_DSP: 13743 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 13744 break; 13745 case OPC_DPA_W_PH_DSP: 13746 op2 = MASK_DPA_W_PH(ctx->opcode); 13747 switch (op2) { 13748 case OPC_DPAU_H_QBL: 13749 case OPC_DPAU_H_QBR: 13750 case OPC_DPSU_H_QBL: 13751 case OPC_DPSU_H_QBR: 13752 case OPC_DPA_W_PH: 13753 case OPC_DPAX_W_PH: 13754 case OPC_DPAQ_S_W_PH: 13755 case OPC_DPAQX_S_W_PH: 13756 case OPC_DPAQX_SA_W_PH: 13757 case OPC_DPS_W_PH: 13758 case OPC_DPSX_W_PH: 13759 case OPC_DPSQ_S_W_PH: 13760 case OPC_DPSQX_S_W_PH: 13761 case OPC_DPSQX_SA_W_PH: 13762 case OPC_MULSAQ_S_W_PH: 13763 case OPC_DPAQ_SA_L_W: 13764 case OPC_DPSQ_SA_L_W: 13765 case OPC_MAQ_S_W_PHL: 13766 case OPC_MAQ_S_W_PHR: 13767 case OPC_MAQ_SA_W_PHL: 13768 case OPC_MAQ_SA_W_PHR: 13769 case OPC_MULSA_W_PH: 13770 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 13771 break; 13772 default: /* Invalid */ 13773 MIPS_INVAL("MASK DPAW.PH"); 13774 gen_reserved_instruction(ctx); 13775 break; 13776 } 13777 break; 13778 case OPC_INSV_DSP: 13779 op2 = MASK_INSV(ctx->opcode); 13780 switch (op2) { 13781 case OPC_INSV: 13782 check_dsp(ctx); 13783 { 13784 TCGv t0, t1; 13785 13786 if (rt == 0) { 13787 break; 13788 } 13789 13790 t0 = tcg_temp_new(); 13791 t1 = tcg_temp_new(); 13792 13793 gen_load_gpr(t0, rt); 13794 gen_load_gpr(t1, rs); 13795 13796 gen_helper_insv(cpu_gpr[rt], tcg_env, t1, t0); 13797 break; 13798 } 13799 default: /* Invalid */ 13800 MIPS_INVAL("MASK INSV"); 13801 gen_reserved_instruction(ctx); 13802 break; 13803 } 13804 break; 13805 case OPC_APPEND_DSP: 13806 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 13807 break; 13808 case OPC_EXTR_W_DSP: 13809 op2 = MASK_EXTR_W(ctx->opcode); 13810 switch (op2) { 13811 case OPC_EXTR_W: 13812 case OPC_EXTR_R_W: 13813 case OPC_EXTR_RS_W: 13814 case OPC_EXTR_S_H: 13815 case OPC_EXTRV_S_H: 13816 case OPC_EXTRV_W: 13817 case OPC_EXTRV_R_W: 13818 case OPC_EXTRV_RS_W: 13819 case OPC_EXTP: 13820 case OPC_EXTPV: 13821 case OPC_EXTPDP: 13822 case OPC_EXTPDPV: 13823 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 13824 break; 13825 case OPC_RDDSP: 13826 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1); 13827 break; 13828 case OPC_SHILO: 13829 case OPC_SHILOV: 13830 case OPC_MTHLIP: 13831 case OPC_WRDSP: 13832 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 13833 break; 13834 default: /* Invalid */ 13835 MIPS_INVAL("MASK EXTR.W"); 13836 gen_reserved_instruction(ctx); 13837 break; 13838 } 13839 break; 13840 #if defined(TARGET_MIPS64) 13841 case OPC_ABSQ_S_QH_DSP: 13842 op2 = MASK_ABSQ_S_QH(ctx->opcode); 13843 switch (op2) { 13844 case OPC_PRECEQ_L_PWL: 13845 case OPC_PRECEQ_L_PWR: 13846 case OPC_PRECEQ_PW_QHL: 13847 case OPC_PRECEQ_PW_QHR: 13848 case OPC_PRECEQ_PW_QHLA: 13849 case OPC_PRECEQ_PW_QHRA: 13850 case OPC_PRECEQU_QH_OBL: 13851 case OPC_PRECEQU_QH_OBR: 13852 case OPC_PRECEQU_QH_OBLA: 13853 case OPC_PRECEQU_QH_OBRA: 13854 case OPC_PRECEU_QH_OBL: 13855 case OPC_PRECEU_QH_OBR: 13856 case OPC_PRECEU_QH_OBLA: 13857 case OPC_PRECEU_QH_OBRA: 13858 case OPC_ABSQ_S_OB: 13859 case OPC_ABSQ_S_PW: 13860 case OPC_ABSQ_S_QH: 13861 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13862 break; 13863 case OPC_REPL_OB: 13864 case OPC_REPL_PW: 13865 case OPC_REPL_QH: 13866 case OPC_REPLV_OB: 13867 case OPC_REPLV_PW: 13868 case OPC_REPLV_QH: 13869 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 13870 break; 13871 default: /* Invalid */ 13872 MIPS_INVAL("MASK ABSQ_S.QH"); 13873 gen_reserved_instruction(ctx); 13874 break; 13875 } 13876 break; 13877 case OPC_ADDU_OB_DSP: 13878 op2 = MASK_ADDU_OB(ctx->opcode); 13879 switch (op2) { 13880 case OPC_RADDU_L_OB: 13881 case OPC_SUBQ_PW: 13882 case OPC_SUBQ_S_PW: 13883 case OPC_SUBQ_QH: 13884 case OPC_SUBQ_S_QH: 13885 case OPC_SUBU_OB: 13886 case OPC_SUBU_S_OB: 13887 case OPC_SUBU_QH: 13888 case OPC_SUBU_S_QH: 13889 case OPC_SUBUH_OB: 13890 case OPC_SUBUH_R_OB: 13891 case OPC_ADDQ_PW: 13892 case OPC_ADDQ_S_PW: 13893 case OPC_ADDQ_QH: 13894 case OPC_ADDQ_S_QH: 13895 case OPC_ADDU_OB: 13896 case OPC_ADDU_S_OB: 13897 case OPC_ADDU_QH: 13898 case OPC_ADDU_S_QH: 13899 case OPC_ADDUH_OB: 13900 case OPC_ADDUH_R_OB: 13901 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13902 break; 13903 case OPC_MULEQ_S_PW_QHL: 13904 case OPC_MULEQ_S_PW_QHR: 13905 case OPC_MULEU_S_QH_OBL: 13906 case OPC_MULEU_S_QH_OBR: 13907 case OPC_MULQ_RS_QH: 13908 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13909 break; 13910 default: /* Invalid */ 13911 MIPS_INVAL("MASK ADDU.OB"); 13912 gen_reserved_instruction(ctx); 13913 break; 13914 } 13915 break; 13916 case OPC_CMPU_EQ_OB_DSP: 13917 op2 = MASK_CMPU_EQ_OB(ctx->opcode); 13918 switch (op2) { 13919 case OPC_PRECR_SRA_QH_PW: 13920 case OPC_PRECR_SRA_R_QH_PW: 13921 /* Return value is rt. */ 13922 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 13923 break; 13924 case OPC_PRECR_OB_QH: 13925 case OPC_PRECRQ_OB_QH: 13926 case OPC_PRECRQ_PW_L: 13927 case OPC_PRECRQ_QH_PW: 13928 case OPC_PRECRQ_RS_QH_PW: 13929 case OPC_PRECRQU_S_OB_QH: 13930 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13931 break; 13932 case OPC_CMPU_EQ_OB: 13933 case OPC_CMPU_LT_OB: 13934 case OPC_CMPU_LE_OB: 13935 case OPC_CMP_EQ_QH: 13936 case OPC_CMP_LT_QH: 13937 case OPC_CMP_LE_QH: 13938 case OPC_CMP_EQ_PW: 13939 case OPC_CMP_LT_PW: 13940 case OPC_CMP_LE_PW: 13941 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 13942 break; 13943 case OPC_CMPGDU_EQ_OB: 13944 case OPC_CMPGDU_LT_OB: 13945 case OPC_CMPGDU_LE_OB: 13946 case OPC_CMPGU_EQ_OB: 13947 case OPC_CMPGU_LT_OB: 13948 case OPC_CMPGU_LE_OB: 13949 case OPC_PACKRL_PW: 13950 case OPC_PICK_OB: 13951 case OPC_PICK_PW: 13952 case OPC_PICK_QH: 13953 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 13954 break; 13955 default: /* Invalid */ 13956 MIPS_INVAL("MASK CMPU_EQ.OB"); 13957 gen_reserved_instruction(ctx); 13958 break; 13959 } 13960 break; 13961 case OPC_DAPPEND_DSP: 13962 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 13963 break; 13964 case OPC_DEXTR_W_DSP: 13965 op2 = MASK_DEXTR_W(ctx->opcode); 13966 switch (op2) { 13967 case OPC_DEXTP: 13968 case OPC_DEXTPDP: 13969 case OPC_DEXTPDPV: 13970 case OPC_DEXTPV: 13971 case OPC_DEXTR_L: 13972 case OPC_DEXTR_R_L: 13973 case OPC_DEXTR_RS_L: 13974 case OPC_DEXTR_W: 13975 case OPC_DEXTR_R_W: 13976 case OPC_DEXTR_RS_W: 13977 case OPC_DEXTR_S_H: 13978 case OPC_DEXTRV_L: 13979 case OPC_DEXTRV_R_L: 13980 case OPC_DEXTRV_RS_L: 13981 case OPC_DEXTRV_S_H: 13982 case OPC_DEXTRV_W: 13983 case OPC_DEXTRV_R_W: 13984 case OPC_DEXTRV_RS_W: 13985 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 13986 break; 13987 case OPC_DMTHLIP: 13988 case OPC_DSHILO: 13989 case OPC_DSHILOV: 13990 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 13991 break; 13992 default: /* Invalid */ 13993 MIPS_INVAL("MASK EXTR.W"); 13994 gen_reserved_instruction(ctx); 13995 break; 13996 } 13997 break; 13998 case OPC_DPAQ_W_QH_DSP: 13999 op2 = MASK_DPAQ_W_QH(ctx->opcode); 14000 switch (op2) { 14001 case OPC_DPAU_H_OBL: 14002 case OPC_DPAU_H_OBR: 14003 case OPC_DPSU_H_OBL: 14004 case OPC_DPSU_H_OBR: 14005 case OPC_DPA_W_QH: 14006 case OPC_DPAQ_S_W_QH: 14007 case OPC_DPS_W_QH: 14008 case OPC_DPSQ_S_W_QH: 14009 case OPC_MULSAQ_S_W_QH: 14010 case OPC_DPAQ_SA_L_PW: 14011 case OPC_DPSQ_SA_L_PW: 14012 case OPC_MULSAQ_S_L_PW: 14013 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14014 break; 14015 case OPC_MAQ_S_W_QHLL: 14016 case OPC_MAQ_S_W_QHLR: 14017 case OPC_MAQ_S_W_QHRL: 14018 case OPC_MAQ_S_W_QHRR: 14019 case OPC_MAQ_SA_W_QHLL: 14020 case OPC_MAQ_SA_W_QHLR: 14021 case OPC_MAQ_SA_W_QHRL: 14022 case OPC_MAQ_SA_W_QHRR: 14023 case OPC_MAQ_S_L_PWL: 14024 case OPC_MAQ_S_L_PWR: 14025 case OPC_DMADD: 14026 case OPC_DMADDU: 14027 case OPC_DMSUB: 14028 case OPC_DMSUBU: 14029 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14030 break; 14031 default: /* Invalid */ 14032 MIPS_INVAL("MASK DPAQ.W.QH"); 14033 gen_reserved_instruction(ctx); 14034 break; 14035 } 14036 break; 14037 case OPC_DINSV_DSP: 14038 op2 = MASK_INSV(ctx->opcode); 14039 switch (op2) { 14040 case OPC_DINSV: 14041 { 14042 TCGv t0, t1; 14043 14044 check_dsp(ctx); 14045 14046 if (rt == 0) { 14047 break; 14048 } 14049 14050 t0 = tcg_temp_new(); 14051 t1 = tcg_temp_new(); 14052 14053 gen_load_gpr(t0, rt); 14054 gen_load_gpr(t1, rs); 14055 14056 gen_helper_dinsv(cpu_gpr[rt], tcg_env, t1, t0); 14057 break; 14058 } 14059 default: /* Invalid */ 14060 MIPS_INVAL("MASK DINSV"); 14061 gen_reserved_instruction(ctx); 14062 break; 14063 } 14064 break; 14065 case OPC_SHLL_OB_DSP: 14066 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14067 break; 14068 #endif 14069 default: /* Invalid */ 14070 MIPS_INVAL("special3_legacy"); 14071 gen_reserved_instruction(ctx); 14072 break; 14073 } 14074 } 14075 14076 14077 #if defined(TARGET_MIPS64) 14078 14079 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) 14080 { 14081 uint32_t opc = MASK_MMI(ctx->opcode); 14082 int rs = extract32(ctx->opcode, 21, 5); 14083 int rt = extract32(ctx->opcode, 16, 5); 14084 int rd = extract32(ctx->opcode, 11, 5); 14085 14086 switch (opc) { 14087 case MMI_OPC_MULT1: 14088 case MMI_OPC_MULTU1: 14089 case MMI_OPC_MADD: 14090 case MMI_OPC_MADDU: 14091 case MMI_OPC_MADD1: 14092 case MMI_OPC_MADDU1: 14093 gen_mul_txx9(ctx, opc, rd, rs, rt); 14094 break; 14095 case MMI_OPC_DIV1: 14096 case MMI_OPC_DIVU1: 14097 gen_div1_tx79(ctx, opc, rs, rt); 14098 break; 14099 default: 14100 MIPS_INVAL("TX79 MMI class"); 14101 gen_reserved_instruction(ctx); 14102 break; 14103 } 14104 } 14105 14106 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset) 14107 { 14108 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */ 14109 } 14110 14111 /* 14112 * The TX79-specific instruction Store Quadword 14113 * 14114 * +--------+-------+-------+------------------------+ 14115 * | 011111 | base | rt | offset | SQ 14116 * +--------+-------+-------+------------------------+ 14117 * 6 5 5 16 14118 * 14119 * has the same opcode as the Read Hardware Register instruction 14120 * 14121 * +--------+-------+-------+-------+-------+--------+ 14122 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR 14123 * +--------+-------+-------+-------+-------+--------+ 14124 * 6 5 5 5 5 6 14125 * 14126 * that is required, trapped and emulated by the Linux kernel. However, all 14127 * RDHWR encodings yield address error exceptions on the TX79 since the SQ 14128 * offset is odd. Therefore all valid SQ instructions can execute normally. 14129 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish 14130 * between SQ and RDHWR, as the Linux kernel does. 14131 */ 14132 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx) 14133 { 14134 int base = extract32(ctx->opcode, 21, 5); 14135 int rt = extract32(ctx->opcode, 16, 5); 14136 int offset = extract32(ctx->opcode, 0, 16); 14137 14138 #ifdef CONFIG_USER_ONLY 14139 uint32_t op1 = MASK_SPECIAL3(ctx->opcode); 14140 uint32_t op2 = extract32(ctx->opcode, 6, 5); 14141 14142 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) { 14143 int rd = extract32(ctx->opcode, 11, 5); 14144 14145 gen_rdhwr(ctx, rt, rd, 0); 14146 return; 14147 } 14148 #endif 14149 14150 gen_mmi_sq(ctx, base, rt, offset); 14151 } 14152 14153 #endif 14154 14155 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) 14156 { 14157 int rs, rt, rd, sa; 14158 uint32_t op1, op2; 14159 int16_t imm; 14160 14161 rs = (ctx->opcode >> 21) & 0x1f; 14162 rt = (ctx->opcode >> 16) & 0x1f; 14163 rd = (ctx->opcode >> 11) & 0x1f; 14164 sa = (ctx->opcode >> 6) & 0x1f; 14165 imm = sextract32(ctx->opcode, 7, 9); 14166 14167 op1 = MASK_SPECIAL3(ctx->opcode); 14168 14169 /* 14170 * EVA loads and stores overlap Loongson 2E instructions decoded by 14171 * decode_opc_special3_legacy(), so be careful to allow their decoding when 14172 * EVA is absent. 14173 */ 14174 if (ctx->eva) { 14175 switch (op1) { 14176 case OPC_LWLE: 14177 case OPC_LWRE: 14178 case OPC_LBUE: 14179 case OPC_LHUE: 14180 case OPC_LBE: 14181 case OPC_LHE: 14182 case OPC_LLE: 14183 case OPC_LWE: 14184 check_cp0_enabled(ctx); 14185 gen_ld(ctx, op1, rt, rs, imm); 14186 return; 14187 case OPC_SWLE: 14188 case OPC_SWRE: 14189 case OPC_SBE: 14190 case OPC_SHE: 14191 case OPC_SWE: 14192 check_cp0_enabled(ctx); 14193 gen_st(ctx, op1, rt, rs, imm); 14194 return; 14195 case OPC_SCE: 14196 check_cp0_enabled(ctx); 14197 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, true); 14198 return; 14199 case OPC_CACHEE: 14200 check_eva(ctx); 14201 check_cp0_enabled(ctx); 14202 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14203 gen_cache_operation(ctx, rt, rs, imm); 14204 } 14205 return; 14206 case OPC_PREFE: 14207 check_cp0_enabled(ctx); 14208 /* Treat as NOP. */ 14209 return; 14210 } 14211 } 14212 14213 switch (op1) { 14214 case OPC_EXT: 14215 case OPC_INS: 14216 check_insn(ctx, ISA_MIPS_R2); 14217 gen_bitops(ctx, op1, rt, rs, sa, rd); 14218 break; 14219 case OPC_BSHFL: 14220 op2 = MASK_BSHFL(ctx->opcode); 14221 switch (op2) { 14222 case OPC_ALIGN: 14223 case OPC_ALIGN_1: 14224 case OPC_ALIGN_2: 14225 case OPC_ALIGN_3: 14226 case OPC_BITSWAP: 14227 check_insn(ctx, ISA_MIPS_R6); 14228 decode_opc_special3_r6(env, ctx); 14229 break; 14230 default: 14231 check_insn(ctx, ISA_MIPS_R2); 14232 gen_bshfl(ctx, op2, rt, rd); 14233 break; 14234 } 14235 break; 14236 #if defined(TARGET_MIPS64) 14237 case OPC_DEXTM: 14238 case OPC_DEXTU: 14239 case OPC_DEXT: 14240 case OPC_DINSM: 14241 case OPC_DINSU: 14242 case OPC_DINS: 14243 check_insn(ctx, ISA_MIPS_R2); 14244 check_mips_64(ctx); 14245 gen_bitops(ctx, op1, rt, rs, sa, rd); 14246 break; 14247 case OPC_DBSHFL: 14248 op2 = MASK_DBSHFL(ctx->opcode); 14249 switch (op2) { 14250 case OPC_DALIGN: 14251 case OPC_DALIGN_1: 14252 case OPC_DALIGN_2: 14253 case OPC_DALIGN_3: 14254 case OPC_DALIGN_4: 14255 case OPC_DALIGN_5: 14256 case OPC_DALIGN_6: 14257 case OPC_DALIGN_7: 14258 case OPC_DBITSWAP: 14259 check_insn(ctx, ISA_MIPS_R6); 14260 decode_opc_special3_r6(env, ctx); 14261 break; 14262 default: 14263 check_insn(ctx, ISA_MIPS_R2); 14264 check_mips_64(ctx); 14265 op2 = MASK_DBSHFL(ctx->opcode); 14266 gen_bshfl(ctx, op2, rt, rd); 14267 break; 14268 } 14269 break; 14270 #endif 14271 case OPC_RDHWR: 14272 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3)); 14273 break; 14274 case OPC_FORK: 14275 check_mt(ctx); 14276 { 14277 TCGv t0 = tcg_temp_new(); 14278 TCGv t1 = tcg_temp_new(); 14279 14280 gen_load_gpr(t0, rt); 14281 gen_load_gpr(t1, rs); 14282 gen_helper_fork(t0, t1); 14283 } 14284 break; 14285 case OPC_YIELD: 14286 check_mt(ctx); 14287 { 14288 TCGv t0 = tcg_temp_new(); 14289 14290 gen_load_gpr(t0, rs); 14291 gen_helper_yield(t0, tcg_env, t0); 14292 gen_store_gpr(t0, rd); 14293 } 14294 break; 14295 default: 14296 if (ctx->insn_flags & ISA_MIPS_R6) { 14297 decode_opc_special3_r6(env, ctx); 14298 } else { 14299 decode_opc_special3_legacy(env, ctx); 14300 } 14301 } 14302 } 14303 14304 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) 14305 { 14306 int32_t offset; 14307 int rs, rt, rd, sa; 14308 uint32_t op, op1; 14309 int16_t imm; 14310 14311 op = MASK_OP_MAJOR(ctx->opcode); 14312 rs = (ctx->opcode >> 21) & 0x1f; 14313 rt = (ctx->opcode >> 16) & 0x1f; 14314 rd = (ctx->opcode >> 11) & 0x1f; 14315 sa = (ctx->opcode >> 6) & 0x1f; 14316 imm = (int16_t)ctx->opcode; 14317 switch (op) { 14318 case OPC_SPECIAL: 14319 decode_opc_special(env, ctx); 14320 break; 14321 case OPC_SPECIAL2: 14322 #if defined(TARGET_MIPS64) 14323 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { 14324 decode_mmi(env, ctx); 14325 break; 14326 } 14327 #endif 14328 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) { 14329 if (decode_ase_mxu(ctx, ctx->opcode)) { 14330 break; 14331 } 14332 } 14333 decode_opc_special2_legacy(env, ctx); 14334 break; 14335 case OPC_SPECIAL3: 14336 #if defined(TARGET_MIPS64) 14337 if (ctx->insn_flags & INSN_R5900) { 14338 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ 14339 } else { 14340 decode_opc_special3(env, ctx); 14341 } 14342 #else 14343 decode_opc_special3(env, ctx); 14344 #endif 14345 break; 14346 case OPC_REGIMM: 14347 op1 = MASK_REGIMM(ctx->opcode); 14348 switch (op1) { 14349 case OPC_BLTZL: /* REGIMM branches */ 14350 case OPC_BGEZL: 14351 case OPC_BLTZALL: 14352 case OPC_BGEZALL: 14353 check_insn(ctx, ISA_MIPS2); 14354 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14355 /* Fallthrough */ 14356 case OPC_BLTZ: 14357 case OPC_BGEZ: 14358 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 14359 break; 14360 case OPC_BLTZAL: 14361 case OPC_BGEZAL: 14362 if (ctx->insn_flags & ISA_MIPS_R6) { 14363 if (rs == 0) { 14364 /* OPC_NAL, OPC_BAL */ 14365 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); 14366 } else { 14367 gen_reserved_instruction(ctx); 14368 } 14369 } else { 14370 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 14371 } 14372 break; 14373 case OPC_TGEI: /* REGIMM traps */ 14374 case OPC_TGEIU: 14375 case OPC_TLTI: 14376 case OPC_TLTIU: 14377 case OPC_TEQI: 14378 case OPC_TNEI: 14379 check_insn(ctx, ISA_MIPS2); 14380 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14381 gen_trap(ctx, op1, rs, -1, imm, 0); 14382 break; 14383 case OPC_SIGRIE: 14384 check_insn(ctx, ISA_MIPS_R6); 14385 gen_reserved_instruction(ctx); 14386 break; 14387 case OPC_SYNCI: 14388 check_insn(ctx, ISA_MIPS_R2); 14389 /* 14390 * Break the TB to be able to sync copied instructions 14391 * immediately. 14392 */ 14393 ctx->base.is_jmp = DISAS_STOP; 14394 break; 14395 case OPC_BPOSGE32: /* MIPS DSP branch */ 14396 #if defined(TARGET_MIPS64) 14397 case OPC_BPOSGE64: 14398 #endif 14399 check_dsp(ctx); 14400 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); 14401 break; 14402 #if defined(TARGET_MIPS64) 14403 case OPC_DAHI: 14404 check_insn(ctx, ISA_MIPS_R6); 14405 check_mips_64(ctx); 14406 if (rs != 0) { 14407 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); 14408 } 14409 break; 14410 case OPC_DATI: 14411 check_insn(ctx, ISA_MIPS_R6); 14412 check_mips_64(ctx); 14413 if (rs != 0) { 14414 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); 14415 } 14416 break; 14417 #endif 14418 default: /* Invalid */ 14419 MIPS_INVAL("regimm"); 14420 gen_reserved_instruction(ctx); 14421 break; 14422 } 14423 break; 14424 case OPC_CP0: 14425 check_cp0_enabled(ctx); 14426 op1 = MASK_CP0(ctx->opcode); 14427 switch (op1) { 14428 case OPC_MFC0: 14429 case OPC_MTC0: 14430 case OPC_MFTR: 14431 case OPC_MTTR: 14432 case OPC_MFHC0: 14433 case OPC_MTHC0: 14434 #if defined(TARGET_MIPS64) 14435 case OPC_DMFC0: 14436 case OPC_DMTC0: 14437 #endif 14438 #ifndef CONFIG_USER_ONLY 14439 gen_cp0(env, ctx, op1, rt, rd); 14440 #endif /* !CONFIG_USER_ONLY */ 14441 break; 14442 case OPC_C0: 14443 case OPC_C0_1: 14444 case OPC_C0_2: 14445 case OPC_C0_3: 14446 case OPC_C0_4: 14447 case OPC_C0_5: 14448 case OPC_C0_6: 14449 case OPC_C0_7: 14450 case OPC_C0_8: 14451 case OPC_C0_9: 14452 case OPC_C0_A: 14453 case OPC_C0_B: 14454 case OPC_C0_C: 14455 case OPC_C0_D: 14456 case OPC_C0_E: 14457 case OPC_C0_F: 14458 #ifndef CONFIG_USER_ONLY 14459 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 14460 #endif /* !CONFIG_USER_ONLY */ 14461 break; 14462 case OPC_MFMC0: 14463 #ifndef CONFIG_USER_ONLY 14464 { 14465 uint32_t op2; 14466 TCGv t0 = tcg_temp_new(); 14467 14468 op2 = MASK_MFMC0(ctx->opcode); 14469 switch (op2) { 14470 case OPC_DMT: 14471 check_cp0_mt(ctx); 14472 gen_helper_dmt(t0); 14473 gen_store_gpr(t0, rt); 14474 break; 14475 case OPC_EMT: 14476 check_cp0_mt(ctx); 14477 gen_helper_emt(t0); 14478 gen_store_gpr(t0, rt); 14479 break; 14480 case OPC_DVPE: 14481 check_cp0_mt(ctx); 14482 gen_helper_dvpe(t0, tcg_env); 14483 gen_store_gpr(t0, rt); 14484 break; 14485 case OPC_EVPE: 14486 check_cp0_mt(ctx); 14487 gen_helper_evpe(t0, tcg_env); 14488 gen_store_gpr(t0, rt); 14489 break; 14490 case OPC_DVP: 14491 check_insn(ctx, ISA_MIPS_R6); 14492 if (ctx->vp) { 14493 gen_helper_dvp(t0, tcg_env); 14494 gen_store_gpr(t0, rt); 14495 } 14496 break; 14497 case OPC_EVP: 14498 check_insn(ctx, ISA_MIPS_R6); 14499 if (ctx->vp) { 14500 gen_helper_evp(t0, tcg_env); 14501 gen_store_gpr(t0, rt); 14502 } 14503 break; 14504 case OPC_DI: 14505 check_insn(ctx, ISA_MIPS_R2); 14506 save_cpu_state(ctx, 1); 14507 gen_helper_di(t0, tcg_env); 14508 gen_store_gpr(t0, rt); 14509 /* 14510 * Stop translation as we may have switched 14511 * the execution mode. 14512 */ 14513 ctx->base.is_jmp = DISAS_STOP; 14514 break; 14515 case OPC_EI: 14516 check_insn(ctx, ISA_MIPS_R2); 14517 save_cpu_state(ctx, 1); 14518 gen_helper_ei(t0, tcg_env); 14519 gen_store_gpr(t0, rt); 14520 /* 14521 * DISAS_STOP isn't sufficient, we need to ensure we break 14522 * out of translated code to check for pending interrupts. 14523 */ 14524 gen_save_pc(ctx->base.pc_next + 4); 14525 ctx->base.is_jmp = DISAS_EXIT; 14526 break; 14527 default: /* Invalid */ 14528 MIPS_INVAL("mfmc0"); 14529 gen_reserved_instruction(ctx); 14530 break; 14531 } 14532 } 14533 #endif /* !CONFIG_USER_ONLY */ 14534 break; 14535 case OPC_RDPGPR: 14536 check_insn(ctx, ISA_MIPS_R2); 14537 gen_load_srsgpr(rt, rd); 14538 break; 14539 case OPC_WRPGPR: 14540 check_insn(ctx, ISA_MIPS_R2); 14541 gen_store_srsgpr(rt, rd); 14542 break; 14543 default: 14544 MIPS_INVAL("cp0"); 14545 gen_reserved_instruction(ctx); 14546 break; 14547 } 14548 break; 14549 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */ 14550 if (ctx->insn_flags & ISA_MIPS_R6) { 14551 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */ 14552 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14553 } else { 14554 /* OPC_ADDI */ 14555 /* Arithmetic with immediate opcode */ 14556 gen_arith_imm(ctx, op, rt, rs, imm); 14557 } 14558 break; 14559 case OPC_ADDIU: 14560 gen_arith_imm(ctx, op, rt, rs, imm); 14561 break; 14562 case OPC_SLTI: /* Set on less than with immediate opcode */ 14563 case OPC_SLTIU: 14564 gen_slt_imm(ctx, op, rt, rs, imm); 14565 break; 14566 case OPC_ANDI: /* Arithmetic with immediate opcode */ 14567 case OPC_LUI: /* OPC_AUI */ 14568 case OPC_ORI: 14569 case OPC_XORI: 14570 gen_logic_imm(ctx, op, rt, rs, imm); 14571 break; 14572 case OPC_J: /* Jump */ 14573 case OPC_JAL: 14574 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 14575 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 14576 break; 14577 /* Branch */ 14578 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ 14579 if (ctx->insn_flags & ISA_MIPS_R6) { 14580 if (rt == 0) { 14581 gen_reserved_instruction(ctx); 14582 break; 14583 } 14584 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */ 14585 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14586 } else { 14587 /* OPC_BLEZL */ 14588 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14589 } 14590 break; 14591 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ 14592 if (ctx->insn_flags & ISA_MIPS_R6) { 14593 if (rt == 0) { 14594 gen_reserved_instruction(ctx); 14595 break; 14596 } 14597 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */ 14598 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14599 } else { 14600 /* OPC_BGTZL */ 14601 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14602 } 14603 break; 14604 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */ 14605 if (rt == 0) { 14606 /* OPC_BLEZ */ 14607 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14608 } else { 14609 check_insn(ctx, ISA_MIPS_R6); 14610 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */ 14611 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14612 } 14613 break; 14614 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */ 14615 if (rt == 0) { 14616 /* OPC_BGTZ */ 14617 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14618 } else { 14619 check_insn(ctx, ISA_MIPS_R6); 14620 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */ 14621 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14622 } 14623 break; 14624 case OPC_BEQL: 14625 case OPC_BNEL: 14626 check_insn(ctx, ISA_MIPS2); 14627 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14628 /* Fallthrough */ 14629 case OPC_BEQ: 14630 case OPC_BNE: 14631 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14632 break; 14633 case OPC_LL: /* Load and stores */ 14634 check_insn(ctx, ISA_MIPS2); 14635 if (ctx->insn_flags & INSN_R5900) { 14636 check_insn_opc_user_only(ctx, INSN_R5900); 14637 } 14638 /* Fallthrough */ 14639 case OPC_LWL: 14640 case OPC_LWR: 14641 case OPC_LB: 14642 case OPC_LH: 14643 case OPC_LW: 14644 case OPC_LWPC: 14645 case OPC_LBU: 14646 case OPC_LHU: 14647 gen_ld(ctx, op, rt, rs, imm); 14648 break; 14649 case OPC_SWL: 14650 case OPC_SWR: 14651 case OPC_SB: 14652 case OPC_SH: 14653 case OPC_SW: 14654 gen_st(ctx, op, rt, rs, imm); 14655 break; 14656 case OPC_SC: 14657 check_insn(ctx, ISA_MIPS2); 14658 if (ctx->insn_flags & INSN_R5900) { 14659 check_insn_opc_user_only(ctx, INSN_R5900); 14660 } 14661 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false); 14662 break; 14663 case OPC_CACHE: 14664 check_cp0_enabled(ctx); 14665 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 14666 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14667 gen_cache_operation(ctx, rt, rs, imm); 14668 } 14669 /* Treat as NOP. */ 14670 break; 14671 case OPC_PREF: 14672 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900); 14673 /* Treat as NOP. */ 14674 break; 14675 14676 /* Floating point (COP1). */ 14677 case OPC_LWC1: 14678 case OPC_LDC1: 14679 case OPC_SWC1: 14680 case OPC_SDC1: 14681 gen_cop1_ldst(ctx, op, rt, rs, imm); 14682 break; 14683 14684 case OPC_CP1: 14685 op1 = MASK_CP1(ctx->opcode); 14686 14687 switch (op1) { 14688 case OPC_MFHC1: 14689 case OPC_MTHC1: 14690 check_cp1_enabled(ctx); 14691 check_insn(ctx, ISA_MIPS_R2); 14692 /* fall through */ 14693 case OPC_MFC1: 14694 case OPC_CFC1: 14695 case OPC_MTC1: 14696 case OPC_CTC1: 14697 check_cp1_enabled(ctx); 14698 gen_cp1(ctx, op1, rt, rd); 14699 break; 14700 #if defined(TARGET_MIPS64) 14701 case OPC_DMFC1: 14702 case OPC_DMTC1: 14703 check_cp1_enabled(ctx); 14704 check_insn(ctx, ISA_MIPS3); 14705 check_mips_64(ctx); 14706 gen_cp1(ctx, op1, rt, rd); 14707 break; 14708 #endif 14709 case OPC_BC1EQZ: /* OPC_BC1ANY2 */ 14710 check_cp1_enabled(ctx); 14711 if (ctx->insn_flags & ISA_MIPS_R6) { 14712 /* OPC_BC1EQZ */ 14713 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 14714 rt, imm << 2, 4); 14715 } else { 14716 /* OPC_BC1ANY2 */ 14717 check_cop1x(ctx); 14718 if (!ase_3d_available(env)) { 14719 return false; 14720 } 14721 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 14722 (rt >> 2) & 0x7, imm << 2); 14723 } 14724 break; 14725 case OPC_BC1NEZ: 14726 check_cp1_enabled(ctx); 14727 check_insn(ctx, ISA_MIPS_R6); 14728 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 14729 rt, imm << 2, 4); 14730 break; 14731 case OPC_BC1ANY4: 14732 check_cp1_enabled(ctx); 14733 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14734 check_cop1x(ctx); 14735 if (!ase_3d_available(env)) { 14736 return false; 14737 } 14738 /* fall through */ 14739 case OPC_BC1: 14740 check_cp1_enabled(ctx); 14741 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14742 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 14743 (rt >> 2) & 0x7, imm << 2); 14744 break; 14745 case OPC_PS_FMT: 14746 check_ps(ctx); 14747 /* fall through */ 14748 case OPC_S_FMT: 14749 case OPC_D_FMT: 14750 check_cp1_enabled(ctx); 14751 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 14752 (imm >> 8) & 0x7); 14753 break; 14754 case OPC_W_FMT: 14755 case OPC_L_FMT: 14756 { 14757 int r6_op = ctx->opcode & FOP(0x3f, 0x1f); 14758 check_cp1_enabled(ctx); 14759 if (ctx->insn_flags & ISA_MIPS_R6) { 14760 switch (r6_op) { 14761 case R6_OPC_CMP_AF_S: 14762 case R6_OPC_CMP_UN_S: 14763 case R6_OPC_CMP_EQ_S: 14764 case R6_OPC_CMP_UEQ_S: 14765 case R6_OPC_CMP_LT_S: 14766 case R6_OPC_CMP_ULT_S: 14767 case R6_OPC_CMP_LE_S: 14768 case R6_OPC_CMP_ULE_S: 14769 case R6_OPC_CMP_SAF_S: 14770 case R6_OPC_CMP_SUN_S: 14771 case R6_OPC_CMP_SEQ_S: 14772 case R6_OPC_CMP_SEUQ_S: 14773 case R6_OPC_CMP_SLT_S: 14774 case R6_OPC_CMP_SULT_S: 14775 case R6_OPC_CMP_SLE_S: 14776 case R6_OPC_CMP_SULE_S: 14777 case R6_OPC_CMP_OR_S: 14778 case R6_OPC_CMP_UNE_S: 14779 case R6_OPC_CMP_NE_S: 14780 case R6_OPC_CMP_SOR_S: 14781 case R6_OPC_CMP_SUNE_S: 14782 case R6_OPC_CMP_SNE_S: 14783 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa); 14784 break; 14785 case R6_OPC_CMP_AF_D: 14786 case R6_OPC_CMP_UN_D: 14787 case R6_OPC_CMP_EQ_D: 14788 case R6_OPC_CMP_UEQ_D: 14789 case R6_OPC_CMP_LT_D: 14790 case R6_OPC_CMP_ULT_D: 14791 case R6_OPC_CMP_LE_D: 14792 case R6_OPC_CMP_ULE_D: 14793 case R6_OPC_CMP_SAF_D: 14794 case R6_OPC_CMP_SUN_D: 14795 case R6_OPC_CMP_SEQ_D: 14796 case R6_OPC_CMP_SEUQ_D: 14797 case R6_OPC_CMP_SLT_D: 14798 case R6_OPC_CMP_SULT_D: 14799 case R6_OPC_CMP_SLE_D: 14800 case R6_OPC_CMP_SULE_D: 14801 case R6_OPC_CMP_OR_D: 14802 case R6_OPC_CMP_UNE_D: 14803 case R6_OPC_CMP_NE_D: 14804 case R6_OPC_CMP_SOR_D: 14805 case R6_OPC_CMP_SUNE_D: 14806 case R6_OPC_CMP_SNE_D: 14807 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa); 14808 break; 14809 default: 14810 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), 14811 rt, rd, sa, (imm >> 8) & 0x7); 14812 14813 break; 14814 } 14815 } else { 14816 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 14817 (imm >> 8) & 0x7); 14818 } 14819 break; 14820 } 14821 default: 14822 MIPS_INVAL("cp1"); 14823 gen_reserved_instruction(ctx); 14824 break; 14825 } 14826 break; 14827 14828 /* Compact branches [R6] and COP2 [non-R6] */ 14829 case OPC_BC: /* OPC_LWC2 */ 14830 case OPC_BALC: /* OPC_SWC2 */ 14831 if (ctx->insn_flags & ISA_MIPS_R6) { 14832 /* OPC_BC, OPC_BALC */ 14833 gen_compute_compact_branch(ctx, op, 0, 0, 14834 sextract32(ctx->opcode << 2, 0, 28)); 14835 } else if (ctx->insn_flags & ASE_LEXT) { 14836 gen_loongson_lswc2(ctx, rt, rs, rd); 14837 } else { 14838 /* OPC_LWC2, OPC_SWC2 */ 14839 /* COP2: Not implemented. */ 14840 generate_exception_err(ctx, EXCP_CpU, 2); 14841 } 14842 break; 14843 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */ 14844 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */ 14845 if (ctx->insn_flags & ISA_MIPS_R6) { 14846 if (rs != 0) { 14847 /* OPC_BEQZC, OPC_BNEZC */ 14848 gen_compute_compact_branch(ctx, op, rs, 0, 14849 sextract32(ctx->opcode << 2, 0, 23)); 14850 } else { 14851 /* OPC_JIC, OPC_JIALC */ 14852 gen_compute_compact_branch(ctx, op, 0, rt, imm); 14853 } 14854 } else if (ctx->insn_flags & ASE_LEXT) { 14855 gen_loongson_lsdc2(ctx, rt, rs, rd); 14856 } else { 14857 /* OPC_LWC2, OPC_SWC2 */ 14858 /* COP2: Not implemented. */ 14859 generate_exception_err(ctx, EXCP_CpU, 2); 14860 } 14861 break; 14862 case OPC_CP2: 14863 check_insn(ctx, ASE_LMMI); 14864 /* Note that these instructions use different fields. */ 14865 gen_loongson_multimedia(ctx, sa, rd, rt); 14866 break; 14867 14868 case OPC_CP3: 14869 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 14870 check_cp1_enabled(ctx); 14871 op1 = MASK_CP3(ctx->opcode); 14872 switch (op1) { 14873 case OPC_LUXC1: 14874 case OPC_SUXC1: 14875 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 14876 /* Fallthrough */ 14877 case OPC_LWXC1: 14878 case OPC_LDXC1: 14879 case OPC_SWXC1: 14880 case OPC_SDXC1: 14881 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14882 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 14883 break; 14884 case OPC_PREFX: 14885 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14886 /* Treat as NOP. */ 14887 break; 14888 case OPC_ALNV_PS: 14889 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 14890 /* Fallthrough */ 14891 case OPC_MADD_S: 14892 case OPC_MADD_D: 14893 case OPC_MADD_PS: 14894 case OPC_MSUB_S: 14895 case OPC_MSUB_D: 14896 case OPC_MSUB_PS: 14897 case OPC_NMADD_S: 14898 case OPC_NMADD_D: 14899 case OPC_NMADD_PS: 14900 case OPC_NMSUB_S: 14901 case OPC_NMSUB_D: 14902 case OPC_NMSUB_PS: 14903 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14904 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 14905 break; 14906 default: 14907 MIPS_INVAL("cp3"); 14908 gen_reserved_instruction(ctx); 14909 break; 14910 } 14911 } else { 14912 generate_exception_err(ctx, EXCP_CpU, 1); 14913 } 14914 break; 14915 14916 #if defined(TARGET_MIPS64) 14917 /* MIPS64 opcodes */ 14918 case OPC_LLD: 14919 if (ctx->insn_flags & INSN_R5900) { 14920 check_insn_opc_user_only(ctx, INSN_R5900); 14921 } 14922 /* fall through */ 14923 case OPC_LDL: 14924 case OPC_LDR: 14925 case OPC_LWU: 14926 case OPC_LD: 14927 check_insn(ctx, ISA_MIPS3); 14928 check_mips_64(ctx); 14929 gen_ld(ctx, op, rt, rs, imm); 14930 break; 14931 case OPC_SDL: 14932 case OPC_SDR: 14933 case OPC_SD: 14934 check_insn(ctx, ISA_MIPS3); 14935 check_mips_64(ctx); 14936 gen_st(ctx, op, rt, rs, imm); 14937 break; 14938 case OPC_SCD: 14939 check_insn(ctx, ISA_MIPS3); 14940 if (ctx->insn_flags & INSN_R5900) { 14941 check_insn_opc_user_only(ctx, INSN_R5900); 14942 } 14943 check_mips_64(ctx); 14944 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false); 14945 break; 14946 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ 14947 if (ctx->insn_flags & ISA_MIPS_R6) { 14948 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */ 14949 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14950 } else { 14951 /* OPC_DADDI */ 14952 check_insn(ctx, ISA_MIPS3); 14953 check_mips_64(ctx); 14954 gen_arith_imm(ctx, op, rt, rs, imm); 14955 } 14956 break; 14957 case OPC_DADDIU: 14958 check_insn(ctx, ISA_MIPS3); 14959 check_mips_64(ctx); 14960 gen_arith_imm(ctx, op, rt, rs, imm); 14961 break; 14962 #else 14963 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 14964 if (ctx->insn_flags & ISA_MIPS_R6) { 14965 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14966 } else { 14967 MIPS_INVAL("major opcode"); 14968 gen_reserved_instruction(ctx); 14969 } 14970 break; 14971 #endif 14972 case OPC_DAUI: /* OPC_JALX */ 14973 if (ctx->insn_flags & ISA_MIPS_R6) { 14974 #if defined(TARGET_MIPS64) 14975 /* OPC_DAUI */ 14976 check_mips_64(ctx); 14977 if (rs == 0) { 14978 generate_exception(ctx, EXCP_RI); 14979 } else if (rt != 0) { 14980 TCGv t0 = tcg_temp_new(); 14981 gen_load_gpr(t0, rs); 14982 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16); 14983 } 14984 #else 14985 gen_reserved_instruction(ctx); 14986 MIPS_INVAL("major opcode"); 14987 #endif 14988 } else { 14989 /* OPC_JALX */ 14990 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS); 14991 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 14992 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 14993 } 14994 break; 14995 case OPC_MDMX: 14996 /* MDMX: Not implemented. */ 14997 break; 14998 case OPC_PCREL: 14999 check_insn(ctx, ISA_MIPS_R6); 15000 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs); 15001 break; 15002 default: /* Invalid */ 15003 MIPS_INVAL("major opcode"); 15004 return false; 15005 } 15006 return true; 15007 } 15008 15009 static void decode_opc(CPUMIPSState *env, DisasContext *ctx) 15010 { 15011 /* make sure instructions are on a word boundary */ 15012 if (ctx->base.pc_next & 0x3) { 15013 env->CP0_BadVAddr = ctx->base.pc_next; 15014 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); 15015 return; 15016 } 15017 15018 /* Handle blikely not taken case */ 15019 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { 15020 TCGLabel *l1 = gen_new_label(); 15021 15022 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 15023 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 15024 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); 15025 gen_set_label(l1); 15026 } 15027 15028 /* Transition to the auto-generated decoder. */ 15029 15030 /* Vendor specific extensions */ 15031 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { 15032 return; 15033 } 15034 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) { 15035 return; 15036 } 15037 if (TARGET_LONG_BITS == 64 && decode_ext_loongson(ctx, ctx->opcode)) { 15038 return; 15039 } 15040 #if defined(TARGET_MIPS64) 15041 if (ase_lcsr_available(env) && decode_ase_lcsr(ctx, ctx->opcode)) { 15042 return; 15043 } 15044 if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) { 15045 return; 15046 } 15047 #endif 15048 15049 /* ISA extensions */ 15050 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) { 15051 return; 15052 } 15053 15054 /* ISA (from latest to oldest) */ 15055 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) { 15056 return; 15057 } 15058 15059 if (decode_opc_legacy(env, ctx)) { 15060 return; 15061 } 15062 15063 gen_reserved_instruction(ctx); 15064 } 15065 15066 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 15067 { 15068 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15069 CPUMIPSState *env = cpu_env(cs); 15070 15071 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; 15072 ctx->saved_pc = -1; 15073 ctx->insn_flags = env->insn_flags; 15074 ctx->CP0_Config0 = env->CP0_Config0; 15075 ctx->CP0_Config1 = env->CP0_Config1; 15076 ctx->CP0_Config2 = env->CP0_Config2; 15077 ctx->CP0_Config3 = env->CP0_Config3; 15078 ctx->CP0_Config5 = env->CP0_Config5; 15079 ctx->btarget = 0; 15080 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; 15081 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; 15082 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3; 15083 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1; 15084 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1; 15085 ctx->PAMask = env->PAMask; 15086 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; 15087 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; 15088 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1; 15089 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift; 15090 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; 15091 /* Restore delay slot state from the tb context. */ 15092 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ 15093 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; 15094 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || 15095 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); 15096 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1; 15097 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; 15098 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; 15099 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; 15100 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1; 15101 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3; 15102 ctx->crcp = (env->CP0_Config5 >> CP0C5_CRCP) & 1; 15103 restore_cpu_state(env, ctx); 15104 #ifdef CONFIG_USER_ONLY 15105 ctx->mem_idx = MIPS_HFLAG_UM; 15106 #else 15107 ctx->mem_idx = hflags_mmu_index(ctx->hflags); 15108 #endif 15109 ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) && 15110 (ctx->insn_flags & (ISA_MIPS_R6 | 15111 INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN; 15112 15113 /* 15114 * Execute a branch and its delay slot as a single instruction. 15115 * This is what GDB expects and is consistent with what the 15116 * hardware does (e.g. if a delay slot instruction faults, the 15117 * reported PC is the PC of the branch). 15118 */ 15119 if ((tb_cflags(ctx->base.tb) & CF_SINGLE_STEP) && 15120 (ctx->hflags & MIPS_HFLAG_BMASK)) { 15121 ctx->base.max_insns = 2; 15122 } 15123 15124 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, 15125 ctx->hflags); 15126 } 15127 15128 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) 15129 { 15130 } 15131 15132 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 15133 { 15134 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15135 15136 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, 15137 ctx->btarget); 15138 } 15139 15140 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 15141 { 15142 CPUMIPSState *env = cpu_env(cs); 15143 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15144 int insn_bytes; 15145 int is_slot; 15146 15147 is_slot = ctx->hflags & MIPS_HFLAG_BMASK; 15148 if (ctx->insn_flags & ISA_NANOMIPS32) { 15149 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15150 insn_bytes = decode_isa_nanomips(env, ctx); 15151 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) { 15152 ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next); 15153 insn_bytes = 4; 15154 decode_opc(env, ctx); 15155 } else if (ctx->insn_flags & ASE_MICROMIPS) { 15156 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15157 insn_bytes = decode_isa_micromips(env, ctx); 15158 } else if (ctx->insn_flags & ASE_MIPS16) { 15159 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15160 insn_bytes = decode_ase_mips16e(env, ctx); 15161 } else { 15162 gen_reserved_instruction(ctx); 15163 g_assert(ctx->base.is_jmp == DISAS_NORETURN); 15164 return; 15165 } 15166 15167 if (ctx->hflags & MIPS_HFLAG_BMASK) { 15168 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 | 15169 MIPS_HFLAG_FBNSLOT))) { 15170 /* 15171 * Force to generate branch as there is neither delay nor 15172 * forbidden slot. 15173 */ 15174 is_slot = 1; 15175 } 15176 if ((ctx->hflags & MIPS_HFLAG_M16) && 15177 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) { 15178 /* 15179 * Force to generate branch as microMIPS R6 doesn't restrict 15180 * branches in the forbidden slot. 15181 */ 15182 is_slot = 1; 15183 } 15184 } 15185 if (is_slot) { 15186 gen_branch(ctx, insn_bytes); 15187 } 15188 if (ctx->base.is_jmp == DISAS_SEMIHOST) { 15189 generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes); 15190 } 15191 ctx->base.pc_next += insn_bytes; 15192 15193 if (ctx->base.is_jmp != DISAS_NEXT) { 15194 return; 15195 } 15196 15197 /* 15198 * End the TB on (most) page crossings. 15199 * See mips_tr_init_disas_context about single-stepping a branch 15200 * together with its delay slot. 15201 */ 15202 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE 15203 && !(tb_cflags(ctx->base.tb) & CF_SINGLE_STEP)) { 15204 ctx->base.is_jmp = DISAS_TOO_MANY; 15205 } 15206 } 15207 15208 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 15209 { 15210 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15211 15212 switch (ctx->base.is_jmp) { 15213 case DISAS_STOP: 15214 gen_save_pc(ctx->base.pc_next); 15215 tcg_gen_lookup_and_goto_ptr(); 15216 break; 15217 case DISAS_NEXT: 15218 case DISAS_TOO_MANY: 15219 save_cpu_state(ctx, 0); 15220 gen_goto_tb(ctx, 0, ctx->base.pc_next); 15221 break; 15222 case DISAS_EXIT: 15223 tcg_gen_exit_tb(NULL, 0); 15224 break; 15225 case DISAS_NORETURN: 15226 break; 15227 default: 15228 g_assert_not_reached(); 15229 } 15230 } 15231 15232 static const TranslatorOps mips_tr_ops = { 15233 .init_disas_context = mips_tr_init_disas_context, 15234 .tb_start = mips_tr_tb_start, 15235 .insn_start = mips_tr_insn_start, 15236 .translate_insn = mips_tr_translate_insn, 15237 .tb_stop = mips_tr_tb_stop, 15238 }; 15239 15240 void mips_translate_code(CPUState *cs, TranslationBlock *tb, 15241 int *max_insns, vaddr pc, void *host_pc) 15242 { 15243 DisasContext ctx; 15244 15245 translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base); 15246 } 15247 15248 void mips_tcg_init(void) 15249 { 15250 cpu_gpr[0] = NULL; 15251 for (unsigned i = 1; i < 32; i++) 15252 cpu_gpr[i] = tcg_global_mem_new(tcg_env, 15253 offsetof(CPUMIPSState, 15254 active_tc.gpr[i]), 15255 regnames[i]); 15256 #if defined(TARGET_MIPS64) 15257 cpu_gpr_hi[0] = NULL; 15258 15259 for (unsigned i = 1; i < 32; i++) { 15260 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]); 15261 15262 cpu_gpr_hi[i] = tcg_global_mem_new_i64(tcg_env, 15263 offsetof(CPUMIPSState, 15264 active_tc.gpr_hi[i]), 15265 rname); 15266 } 15267 #endif /* !TARGET_MIPS64 */ 15268 for (unsigned i = 0; i < 32; i++) { 15269 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); 15270 15271 fpu_f64[i] = tcg_global_mem_new_i64(tcg_env, off, fregnames[i]); 15272 } 15273 msa_translate_init(); 15274 cpu_PC = tcg_global_mem_new(tcg_env, 15275 offsetof(CPUMIPSState, active_tc.PC), "PC"); 15276 for (unsigned i = 0; i < MIPS_DSP_ACC; i++) { 15277 cpu_HI[i] = tcg_global_mem_new(tcg_env, 15278 offsetof(CPUMIPSState, active_tc.HI[i]), 15279 regnames_HI[i]); 15280 cpu_LO[i] = tcg_global_mem_new(tcg_env, 15281 offsetof(CPUMIPSState, active_tc.LO[i]), 15282 regnames_LO[i]); 15283 } 15284 cpu_dspctrl = tcg_global_mem_new(tcg_env, 15285 offsetof(CPUMIPSState, 15286 active_tc.DSPControl), 15287 "DSPControl"); 15288 bcond = tcg_global_mem_new(tcg_env, 15289 offsetof(CPUMIPSState, bcond), "bcond"); 15290 btarget = tcg_global_mem_new(tcg_env, 15291 offsetof(CPUMIPSState, btarget), "btarget"); 15292 hflags = tcg_global_mem_new_i32(tcg_env, 15293 offsetof(CPUMIPSState, hflags), "hflags"); 15294 15295 fpu_fcr0 = tcg_global_mem_new_i32(tcg_env, 15296 offsetof(CPUMIPSState, active_fpu.fcr0), 15297 "fcr0"); 15298 fpu_fcr31 = tcg_global_mem_new_i32(tcg_env, 15299 offsetof(CPUMIPSState, active_fpu.fcr31), 15300 "fcr31"); 15301 cpu_lladdr = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, lladdr), 15302 "lladdr"); 15303 cpu_llval = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, llval), 15304 "llval"); 15305 15306 if (TARGET_LONG_BITS == 32) { 15307 mxu_translate_init(); 15308 } 15309 } 15310 15311 void mips_restore_state_to_opc(CPUState *cs, 15312 const TranslationBlock *tb, 15313 const uint64_t *data) 15314 { 15315 CPUMIPSState *env = cpu_env(cs); 15316 15317 env->active_tc.PC = data[0]; 15318 env->hflags &= ~MIPS_HFLAG_BMASK; 15319 env->hflags |= data[1]; 15320 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) { 15321 case MIPS_HFLAG_BR: 15322 break; 15323 case MIPS_HFLAG_BC: 15324 case MIPS_HFLAG_BL: 15325 case MIPS_HFLAG_B: 15326 env->btarget = data[2]; 15327 break; 15328 } 15329 } 15330