1 /* 2 * MIPS emulation for QEMU - main translation routines 3 * 4 * Copyright (c) 2004-2005 Jocelyn Mayer 5 * Copyright (c) 2006 Marius Groeger (FPU operations) 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) 9 * Copyright (c) 2020 Philippe Mathieu-Daudé 10 * 11 * This library is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU Lesser General Public 13 * License as published by the Free Software Foundation; either 14 * version 2.1 of the License, or (at your option) any later version. 15 * 16 * This library is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "translate.h" 27 #include "internal.h" 28 #include "exec/helper-proto.h" 29 #include "exec/translation-block.h" 30 #include "semihosting/semihost.h" 31 #include "trace.h" 32 #include "fpu_helper.h" 33 34 #define HELPER_H "helper.h" 35 #include "exec/helper-info.c.inc" 36 #undef HELPER_H 37 38 39 /* 40 * Many sysemu-only helpers are not reachable for user-only. 41 * Define stub generators here, so that we need not either sprinkle 42 * ifdefs through the translator, nor provide the helper function. 43 */ 44 #define STUB_HELPER(NAME, ...) \ 45 static inline void gen_helper_##NAME(__VA_ARGS__) \ 46 { g_assert_not_reached(); } 47 48 #ifdef CONFIG_USER_ONLY 49 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg) 50 #endif 51 52 enum { 53 /* indirect opcode tables */ 54 OPC_SPECIAL = (0x00 << 26), 55 OPC_REGIMM = (0x01 << 26), 56 OPC_CP0 = (0x10 << 26), 57 OPC_CP2 = (0x12 << 26), 58 OPC_CP3 = (0x13 << 26), 59 OPC_SPECIAL2 = (0x1C << 26), 60 OPC_SPECIAL3 = (0x1F << 26), 61 /* arithmetic with immediate */ 62 OPC_ADDI = (0x08 << 26), 63 OPC_ADDIU = (0x09 << 26), 64 OPC_SLTI = (0x0A << 26), 65 OPC_SLTIU = (0x0B << 26), 66 /* logic with immediate */ 67 OPC_ANDI = (0x0C << 26), 68 OPC_ORI = (0x0D << 26), 69 OPC_XORI = (0x0E << 26), 70 OPC_LUI = (0x0F << 26), 71 /* arithmetic with immediate */ 72 OPC_DADDI = (0x18 << 26), 73 OPC_DADDIU = (0x19 << 26), 74 /* Jump and branches */ 75 OPC_J = (0x02 << 26), 76 OPC_JAL = (0x03 << 26), 77 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */ 78 OPC_BEQL = (0x14 << 26), 79 OPC_BNE = (0x05 << 26), 80 OPC_BNEL = (0x15 << 26), 81 OPC_BLEZ = (0x06 << 26), 82 OPC_BLEZL = (0x16 << 26), 83 OPC_BGTZ = (0x07 << 26), 84 OPC_BGTZL = (0x17 << 26), 85 OPC_JALX = (0x1D << 26), 86 OPC_DAUI = (0x1D << 26), 87 /* Load and stores */ 88 OPC_LDL = (0x1A << 26), 89 OPC_LDR = (0x1B << 26), 90 OPC_LB = (0x20 << 26), 91 OPC_LH = (0x21 << 26), 92 OPC_LWL = (0x22 << 26), 93 OPC_LW = (0x23 << 26), 94 OPC_LWPC = OPC_LW | 0x5, 95 OPC_LBU = (0x24 << 26), 96 OPC_LHU = (0x25 << 26), 97 OPC_LWR = (0x26 << 26), 98 OPC_LWU = (0x27 << 26), 99 OPC_SB = (0x28 << 26), 100 OPC_SH = (0x29 << 26), 101 OPC_SWL = (0x2A << 26), 102 OPC_SW = (0x2B << 26), 103 OPC_SDL = (0x2C << 26), 104 OPC_SDR = (0x2D << 26), 105 OPC_SWR = (0x2E << 26), 106 OPC_LL = (0x30 << 26), 107 OPC_LLD = (0x34 << 26), 108 OPC_LD = (0x37 << 26), 109 OPC_LDPC = OPC_LD | 0x5, 110 OPC_SC = (0x38 << 26), 111 OPC_SCD = (0x3C << 26), 112 OPC_SD = (0x3F << 26), 113 /* Floating point load/store */ 114 OPC_LWC1 = (0x31 << 26), 115 OPC_LWC2 = (0x32 << 26), 116 OPC_LDC1 = (0x35 << 26), 117 OPC_LDC2 = (0x36 << 26), 118 OPC_SWC1 = (0x39 << 26), 119 OPC_SWC2 = (0x3A << 26), 120 OPC_SDC1 = (0x3D << 26), 121 OPC_SDC2 = (0x3E << 26), 122 /* Compact Branches */ 123 OPC_BLEZALC = (0x06 << 26), 124 OPC_BGEZALC = (0x06 << 26), 125 OPC_BGEUC = (0x06 << 26), 126 OPC_BGTZALC = (0x07 << 26), 127 OPC_BLTZALC = (0x07 << 26), 128 OPC_BLTUC = (0x07 << 26), 129 OPC_BOVC = (0x08 << 26), 130 OPC_BEQZALC = (0x08 << 26), 131 OPC_BEQC = (0x08 << 26), 132 OPC_BLEZC = (0x16 << 26), 133 OPC_BGEZC = (0x16 << 26), 134 OPC_BGEC = (0x16 << 26), 135 OPC_BGTZC = (0x17 << 26), 136 OPC_BLTZC = (0x17 << 26), 137 OPC_BLTC = (0x17 << 26), 138 OPC_BNVC = (0x18 << 26), 139 OPC_BNEZALC = (0x18 << 26), 140 OPC_BNEC = (0x18 << 26), 141 OPC_BC = (0x32 << 26), 142 OPC_BEQZC = (0x36 << 26), 143 OPC_JIC = (0x36 << 26), 144 OPC_BALC = (0x3A << 26), 145 OPC_BNEZC = (0x3E << 26), 146 OPC_JIALC = (0x3E << 26), 147 /* MDMX ASE specific */ 148 OPC_MDMX = (0x1E << 26), 149 /* Cache and prefetch */ 150 OPC_CACHE = (0x2F << 26), 151 OPC_PREF = (0x33 << 26), 152 /* PC-relative address computation / loads */ 153 OPC_PCREL = (0x3B << 26), 154 }; 155 156 /* PC-relative address computation / loads */ 157 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19))) 158 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16))) 159 enum { 160 /* Instructions determined by bits 19 and 20 */ 161 OPC_ADDIUPC = OPC_PCREL | (0 << 19), 162 R6_OPC_LWPC = OPC_PCREL | (1 << 19), 163 OPC_LWUPC = OPC_PCREL | (2 << 19), 164 165 /* Instructions determined by bits 16 ... 20 */ 166 OPC_AUIPC = OPC_PCREL | (0x1e << 16), 167 OPC_ALUIPC = OPC_PCREL | (0x1f << 16), 168 169 /* Other */ 170 R6_OPC_LDPC = OPC_PCREL | (6 << 18), 171 }; 172 173 /* MIPS special opcodes */ 174 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 175 176 enum { 177 /* Shifts */ 178 OPC_SLL = 0x00 | OPC_SPECIAL, 179 /* NOP is SLL r0, r0, 0 */ 180 /* SSNOP is SLL r0, r0, 1 */ 181 /* EHB is SLL r0, r0, 3 */ 182 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */ 183 OPC_ROTR = OPC_SRL | (1 << 21), 184 OPC_SRA = 0x03 | OPC_SPECIAL, 185 OPC_SLLV = 0x04 | OPC_SPECIAL, 186 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */ 187 OPC_ROTRV = OPC_SRLV | (1 << 6), 188 OPC_SRAV = 0x07 | OPC_SPECIAL, 189 OPC_DSLLV = 0x14 | OPC_SPECIAL, 190 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */ 191 OPC_DROTRV = OPC_DSRLV | (1 << 6), 192 OPC_DSRAV = 0x17 | OPC_SPECIAL, 193 OPC_DSLL = 0x38 | OPC_SPECIAL, 194 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */ 195 OPC_DROTR = OPC_DSRL | (1 << 21), 196 OPC_DSRA = 0x3B | OPC_SPECIAL, 197 OPC_DSLL32 = 0x3C | OPC_SPECIAL, 198 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */ 199 OPC_DROTR32 = OPC_DSRL32 | (1 << 21), 200 OPC_DSRA32 = 0x3F | OPC_SPECIAL, 201 /* Multiplication / division */ 202 OPC_MULT = 0x18 | OPC_SPECIAL, 203 OPC_MULTU = 0x19 | OPC_SPECIAL, 204 OPC_DIV = 0x1A | OPC_SPECIAL, 205 OPC_DIVU = 0x1B | OPC_SPECIAL, 206 OPC_DMULT = 0x1C | OPC_SPECIAL, 207 OPC_DMULTU = 0x1D | OPC_SPECIAL, 208 OPC_DDIV = 0x1E | OPC_SPECIAL, 209 OPC_DDIVU = 0x1F | OPC_SPECIAL, 210 211 /* 2 registers arithmetic / logic */ 212 OPC_ADD = 0x20 | OPC_SPECIAL, 213 OPC_ADDU = 0x21 | OPC_SPECIAL, 214 OPC_SUB = 0x22 | OPC_SPECIAL, 215 OPC_SUBU = 0x23 | OPC_SPECIAL, 216 OPC_AND = 0x24 | OPC_SPECIAL, 217 OPC_OR = 0x25 | OPC_SPECIAL, 218 OPC_XOR = 0x26 | OPC_SPECIAL, 219 OPC_NOR = 0x27 | OPC_SPECIAL, 220 OPC_SLT = 0x2A | OPC_SPECIAL, 221 OPC_SLTU = 0x2B | OPC_SPECIAL, 222 OPC_DADD = 0x2C | OPC_SPECIAL, 223 OPC_DADDU = 0x2D | OPC_SPECIAL, 224 OPC_DSUB = 0x2E | OPC_SPECIAL, 225 OPC_DSUBU = 0x2F | OPC_SPECIAL, 226 /* Jumps */ 227 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ 228 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ 229 /* Traps */ 230 OPC_TGE = 0x30 | OPC_SPECIAL, 231 OPC_TGEU = 0x31 | OPC_SPECIAL, 232 OPC_TLT = 0x32 | OPC_SPECIAL, 233 OPC_TLTU = 0x33 | OPC_SPECIAL, 234 OPC_TEQ = 0x34 | OPC_SPECIAL, 235 OPC_TNE = 0x36 | OPC_SPECIAL, 236 /* HI / LO registers load & stores */ 237 OPC_MFHI = 0x10 | OPC_SPECIAL, 238 OPC_MTHI = 0x11 | OPC_SPECIAL, 239 OPC_MFLO = 0x12 | OPC_SPECIAL, 240 OPC_MTLO = 0x13 | OPC_SPECIAL, 241 /* Conditional moves */ 242 OPC_MOVZ = 0x0A | OPC_SPECIAL, 243 OPC_MOVN = 0x0B | OPC_SPECIAL, 244 245 OPC_SELEQZ = 0x35 | OPC_SPECIAL, 246 OPC_SELNEZ = 0x37 | OPC_SPECIAL, 247 248 OPC_MOVCI = 0x01 | OPC_SPECIAL, 249 250 /* Special */ 251 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */ 252 OPC_SYSCALL = 0x0C | OPC_SPECIAL, 253 OPC_BREAK = 0x0D | OPC_SPECIAL, 254 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */ 255 OPC_SYNC = 0x0F | OPC_SPECIAL, 256 257 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, 258 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, 259 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, 260 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, 261 }; 262 263 /* 264 * R6 Multiply and Divide instructions have the same opcode 265 * and function field as legacy OPC_MULT[U]/OPC_DIV[U] 266 */ 267 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff))) 268 269 enum { 270 R6_OPC_MUL = OPC_MULT | (2 << 6), 271 R6_OPC_MUH = OPC_MULT | (3 << 6), 272 R6_OPC_MULU = OPC_MULTU | (2 << 6), 273 R6_OPC_MUHU = OPC_MULTU | (3 << 6), 274 R6_OPC_DIV = OPC_DIV | (2 << 6), 275 R6_OPC_MOD = OPC_DIV | (3 << 6), 276 R6_OPC_DIVU = OPC_DIVU | (2 << 6), 277 R6_OPC_MODU = OPC_DIVU | (3 << 6), 278 279 R6_OPC_DMUL = OPC_DMULT | (2 << 6), 280 R6_OPC_DMUH = OPC_DMULT | (3 << 6), 281 R6_OPC_DMULU = OPC_DMULTU | (2 << 6), 282 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6), 283 R6_OPC_DDIV = OPC_DDIV | (2 << 6), 284 R6_OPC_DMOD = OPC_DDIV | (3 << 6), 285 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6), 286 R6_OPC_DMODU = OPC_DDIVU | (3 << 6), 287 288 R6_OPC_CLZ = 0x10 | OPC_SPECIAL, 289 R6_OPC_CLO = 0x11 | OPC_SPECIAL, 290 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL, 291 R6_OPC_DCLO = 0x13 | OPC_SPECIAL, 292 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL, 293 }; 294 295 /* REGIMM (rt field) opcodes */ 296 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16))) 297 298 enum { 299 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM, 300 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM, 301 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM, 302 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM, 303 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM, 304 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM, 305 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM, 306 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM, 307 OPC_TGEI = (0x08 << 16) | OPC_REGIMM, 308 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM, 309 OPC_TLTI = (0x0A << 16) | OPC_REGIMM, 310 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM, 311 OPC_TEQI = (0x0C << 16) | OPC_REGIMM, 312 OPC_TNEI = (0x0E << 16) | OPC_REGIMM, 313 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM, 314 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM, 315 316 OPC_DAHI = (0x06 << 16) | OPC_REGIMM, 317 OPC_DATI = (0x1e << 16) | OPC_REGIMM, 318 }; 319 320 /* Special2 opcodes */ 321 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 322 323 enum { 324 /* Multiply & xxx operations */ 325 OPC_MADD = 0x00 | OPC_SPECIAL2, 326 OPC_MADDU = 0x01 | OPC_SPECIAL2, 327 OPC_MUL = 0x02 | OPC_SPECIAL2, 328 OPC_MSUB = 0x04 | OPC_SPECIAL2, 329 OPC_MSUBU = 0x05 | OPC_SPECIAL2, 330 /* Loongson 2F */ 331 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2, 332 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2, 333 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2, 334 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2, 335 /* Misc */ 336 OPC_CLZ = 0x20 | OPC_SPECIAL2, 337 OPC_CLO = 0x21 | OPC_SPECIAL2, 338 OPC_DCLZ = 0x24 | OPC_SPECIAL2, 339 OPC_DCLO = 0x25 | OPC_SPECIAL2, 340 /* Special */ 341 OPC_SDBBP = 0x3F | OPC_SPECIAL2, 342 }; 343 344 /* Special3 opcodes */ 345 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 346 347 enum { 348 OPC_EXT = 0x00 | OPC_SPECIAL3, 349 OPC_DEXTM = 0x01 | OPC_SPECIAL3, 350 OPC_DEXTU = 0x02 | OPC_SPECIAL3, 351 OPC_DEXT = 0x03 | OPC_SPECIAL3, 352 OPC_INS = 0x04 | OPC_SPECIAL3, 353 OPC_DINSM = 0x05 | OPC_SPECIAL3, 354 OPC_DINSU = 0x06 | OPC_SPECIAL3, 355 OPC_DINS = 0x07 | OPC_SPECIAL3, 356 OPC_FORK = 0x08 | OPC_SPECIAL3, 357 OPC_YIELD = 0x09 | OPC_SPECIAL3, 358 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 359 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 360 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 361 OPC_GINV = 0x3D | OPC_SPECIAL3, 362 363 /* Loongson 2E */ 364 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3, 365 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3, 366 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3, 367 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3, 368 369 /* MIPS DSP Load */ 370 OPC_LX_DSP = 0x0A | OPC_SPECIAL3, 371 /* MIPS DSP Arithmetic */ 372 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3, 373 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3, 374 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3, 375 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3, 376 OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, 377 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3, 378 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3, 379 /* MIPS DSP GPR-Based Shift Sub-class */ 380 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3, 381 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3, 382 /* MIPS DSP Multiply Sub-class insns */ 383 OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, 384 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3, 385 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3, 386 /* DSP Bit/Manipulation Sub-class */ 387 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, 388 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3, 389 /* MIPS DSP Append Sub-class */ 390 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3, 391 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3, 392 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 393 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, 394 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, 395 396 /* EVA */ 397 OPC_LWLE = 0x19 | OPC_SPECIAL3, 398 OPC_LWRE = 0x1A | OPC_SPECIAL3, 399 OPC_CACHEE = 0x1B | OPC_SPECIAL3, 400 OPC_SBE = 0x1C | OPC_SPECIAL3, 401 OPC_SHE = 0x1D | OPC_SPECIAL3, 402 OPC_SCE = 0x1E | OPC_SPECIAL3, 403 OPC_SWE = 0x1F | OPC_SPECIAL3, 404 OPC_SWLE = 0x21 | OPC_SPECIAL3, 405 OPC_SWRE = 0x22 | OPC_SPECIAL3, 406 OPC_PREFE = 0x23 | OPC_SPECIAL3, 407 OPC_LBUE = 0x28 | OPC_SPECIAL3, 408 OPC_LHUE = 0x29 | OPC_SPECIAL3, 409 OPC_LBE = 0x2C | OPC_SPECIAL3, 410 OPC_LHE = 0x2D | OPC_SPECIAL3, 411 OPC_LLE = 0x2E | OPC_SPECIAL3, 412 OPC_LWE = 0x2F | OPC_SPECIAL3, 413 414 /* R6 */ 415 R6_OPC_PREF = 0x35 | OPC_SPECIAL3, 416 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, 417 R6_OPC_LL = 0x36 | OPC_SPECIAL3, 418 R6_OPC_SC = 0x26 | OPC_SPECIAL3, 419 R6_OPC_LLD = 0x37 | OPC_SPECIAL3, 420 R6_OPC_SCD = 0x27 | OPC_SPECIAL3, 421 }; 422 423 /* Loongson EXT load/store quad word opcodes */ 424 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020)) 425 enum { 426 OPC_GSLQ = 0x0020 | OPC_LWC2, 427 OPC_GSLQC1 = 0x8020 | OPC_LWC2, 428 OPC_GSSHFL = OPC_LWC2, 429 OPC_GSSQ = 0x0020 | OPC_SWC2, 430 OPC_GSSQC1 = 0x8020 | OPC_SWC2, 431 OPC_GSSHFS = OPC_SWC2, 432 }; 433 434 /* Loongson EXT shifted load/store opcodes */ 435 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f)) 436 enum { 437 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL, 438 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL, 439 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL, 440 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL, 441 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS, 442 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS, 443 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS, 444 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS, 445 }; 446 447 /* Loongson EXT LDC2/SDC2 opcodes */ 448 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7)) 449 450 enum { 451 OPC_GSLBX = 0x0 | OPC_LDC2, 452 OPC_GSLHX = 0x1 | OPC_LDC2, 453 OPC_GSLWX = 0x2 | OPC_LDC2, 454 OPC_GSLDX = 0x3 | OPC_LDC2, 455 OPC_GSLWXC1 = 0x6 | OPC_LDC2, 456 OPC_GSLDXC1 = 0x7 | OPC_LDC2, 457 OPC_GSSBX = 0x0 | OPC_SDC2, 458 OPC_GSSHX = 0x1 | OPC_SDC2, 459 OPC_GSSWX = 0x2 | OPC_SDC2, 460 OPC_GSSDX = 0x3 | OPC_SDC2, 461 OPC_GSSWXC1 = 0x6 | OPC_SDC2, 462 OPC_GSSDXC1 = 0x7 | OPC_SDC2, 463 }; 464 465 /* BSHFL opcodes */ 466 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 467 468 enum { 469 OPC_WSBH = (0x02 << 6) | OPC_BSHFL, 470 OPC_SEB = (0x10 << 6) | OPC_BSHFL, 471 OPC_SEH = (0x18 << 6) | OPC_BSHFL, 472 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */ 473 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL, 474 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL, 475 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL, 476 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */ 477 }; 478 479 /* DBSHFL opcodes */ 480 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 481 482 enum { 483 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, 484 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, 485 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */ 486 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL, 487 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL, 488 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL, 489 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL, 490 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL, 491 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL, 492 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL, 493 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */ 494 }; 495 496 /* MIPS DSP REGIMM opcodes */ 497 enum { 498 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM, 499 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM, 500 }; 501 502 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 503 /* MIPS DSP Load */ 504 enum { 505 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP, 506 OPC_LHX = (0x04 << 6) | OPC_LX_DSP, 507 OPC_LWX = (0x00 << 6) | OPC_LX_DSP, 508 OPC_LDX = (0x08 << 6) | OPC_LX_DSP, 509 }; 510 511 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 512 enum { 513 /* MIPS DSP Arithmetic Sub-class */ 514 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP, 515 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP, 516 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP, 517 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP, 518 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP, 519 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP, 520 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP, 521 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP, 522 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP, 523 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP, 524 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP, 525 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP, 526 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP, 527 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP, 528 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP, 529 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP, 530 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP, 531 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP, 532 /* MIPS DSP Multiply Sub-class insns */ 533 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP, 534 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP, 535 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP, 536 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP, 537 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP, 538 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP, 539 }; 540 541 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 542 enum { 543 /* MIPS DSP Arithmetic Sub-class */ 544 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP, 545 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP, 546 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP, 547 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP, 548 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP, 549 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP, 550 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP, 551 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP, 552 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP, 553 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP, 554 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP, 555 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP, 556 /* MIPS DSP Multiply Sub-class insns */ 557 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP, 558 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP, 559 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP, 560 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP, 561 }; 562 563 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 564 enum { 565 /* MIPS DSP Arithmetic Sub-class */ 566 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP, 567 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP, 568 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP, 569 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP, 570 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP, 571 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP, 572 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP, 573 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP, 574 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP, 575 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP, 576 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP, 577 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP, 578 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP, 579 /* DSP Bit/Manipulation Sub-class */ 580 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP, 581 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP, 582 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP, 583 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP, 584 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP, 585 }; 586 587 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 588 enum { 589 /* MIPS DSP Arithmetic Sub-class */ 590 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP, 591 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP, 592 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP, 593 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP, 594 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP, 595 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP, 596 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP, 597 /* DSP Compare-Pick Sub-class */ 598 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP, 599 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP, 600 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP, 601 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP, 602 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP, 603 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP, 604 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP, 605 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP, 606 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP, 607 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP, 608 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP, 609 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP, 610 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, 611 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, 612 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, 613 }; 614 615 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 616 enum { 617 /* MIPS DSP GPR-Based Shift Sub-class */ 618 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP, 619 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP, 620 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP, 621 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP, 622 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP, 623 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP, 624 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP, 625 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP, 626 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP, 627 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP, 628 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP, 629 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP, 630 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP, 631 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP, 632 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP, 633 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP, 634 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP, 635 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP, 636 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP, 637 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP, 638 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP, 639 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP, 640 }; 641 642 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 643 enum { 644 /* MIPS DSP Multiply Sub-class insns */ 645 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP, 646 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP, 647 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP, 648 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP, 649 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP, 650 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP, 651 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP, 652 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP, 653 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP, 654 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP, 655 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP, 656 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP, 657 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP, 658 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP, 659 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP, 660 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP, 661 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP, 662 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP, 663 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP, 664 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP, 665 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP, 666 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP, 667 }; 668 669 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 670 enum { 671 /* DSP Bit/Manipulation Sub-class */ 672 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP, 673 }; 674 675 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 676 enum { 677 /* MIPS DSP Append Sub-class */ 678 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP, 679 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP, 680 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP, 681 }; 682 683 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 684 enum { 685 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 686 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP, 687 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP, 688 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP, 689 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP, 690 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP, 691 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP, 692 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP, 693 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP, 694 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP, 695 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP, 696 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP, 697 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP, 698 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP, 699 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP, 700 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP, 701 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP, 702 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP, 703 }; 704 705 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 706 enum { 707 /* MIPS DSP Arithmetic Sub-class */ 708 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP, 709 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP, 710 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP, 711 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP, 712 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP, 713 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP, 714 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP, 715 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP, 716 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP, 717 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP, 718 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP, 719 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP, 720 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP, 721 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP, 722 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP, 723 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP, 724 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP, 725 /* DSP Bit/Manipulation Sub-class */ 726 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP, 727 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP, 728 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP, 729 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP, 730 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP, 731 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP, 732 }; 733 734 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 735 enum { 736 /* MIPS DSP Multiply Sub-class insns */ 737 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP, 738 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP, 739 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP, 740 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP, 741 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP, 742 /* MIPS DSP Arithmetic Sub-class */ 743 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP, 744 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP, 745 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP, 746 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP, 747 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP, 748 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP, 749 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP, 750 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP, 751 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP, 752 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP, 753 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP, 754 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP, 755 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP, 756 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP, 757 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP, 758 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP, 759 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP, 760 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP, 761 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP, 762 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP, 763 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP, 764 }; 765 766 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 767 enum { 768 /* DSP Compare-Pick Sub-class */ 769 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP, 770 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP, 771 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP, 772 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP, 773 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP, 774 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP, 775 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP, 776 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP, 777 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP, 778 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP, 779 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP, 780 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP, 781 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP, 782 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP, 783 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP, 784 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP, 785 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP, 786 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP, 787 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP, 788 /* MIPS DSP Arithmetic Sub-class */ 789 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP, 790 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP, 791 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP, 792 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP, 793 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP, 794 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP, 795 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP, 796 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP, 797 }; 798 799 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 800 enum { 801 /* DSP Append Sub-class */ 802 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP, 803 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP, 804 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP, 805 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP, 806 }; 807 808 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 809 enum { 810 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 811 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP, 812 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP, 813 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP, 814 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP, 815 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP, 816 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP, 817 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP, 818 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP, 819 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP, 820 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP, 821 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP, 822 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP, 823 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP, 824 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP, 825 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP, 826 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP, 827 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP, 828 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP, 829 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP, 830 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP, 831 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP, 832 }; 833 834 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 835 enum { 836 /* DSP Bit/Manipulation Sub-class */ 837 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP, 838 }; 839 840 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 841 enum { 842 /* MIPS DSP Multiply Sub-class insns */ 843 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP, 844 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP, 845 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP, 846 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP, 847 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP, 848 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP, 849 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP, 850 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP, 851 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP, 852 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP, 853 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP, 854 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP, 855 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP, 856 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP, 857 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP, 858 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP, 859 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP, 860 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP, 861 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP, 862 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP, 863 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP, 864 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP, 865 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP, 866 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP, 867 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP, 868 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP, 869 }; 870 871 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 872 enum { 873 /* MIPS DSP GPR-Based Shift Sub-class */ 874 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP, 875 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP, 876 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP, 877 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP, 878 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP, 879 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP, 880 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP, 881 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP, 882 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP, 883 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP, 884 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP, 885 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP, 886 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP, 887 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP, 888 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP, 889 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP, 890 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP, 891 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP, 892 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP, 893 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP, 894 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP, 895 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP, 896 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP, 897 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP, 898 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP, 899 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP, 900 }; 901 902 /* Coprocessor 0 (rs field) */ 903 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 904 905 enum { 906 OPC_MFC0 = (0x00 << 21) | OPC_CP0, 907 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 908 OPC_MFHC0 = (0x02 << 21) | OPC_CP0, 909 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 910 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 911 OPC_MTHC0 = (0x06 << 21) | OPC_CP0, 912 OPC_MFTR = (0x08 << 21) | OPC_CP0, 913 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 914 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 915 OPC_MTTR = (0x0C << 21) | OPC_CP0, 916 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 917 OPC_C0 = (0x10 << 21) | OPC_CP0, 918 OPC_C0_1 = (0x11 << 21) | OPC_CP0, 919 OPC_C0_2 = (0x12 << 21) | OPC_CP0, 920 OPC_C0_3 = (0x13 << 21) | OPC_CP0, 921 OPC_C0_4 = (0x14 << 21) | OPC_CP0, 922 OPC_C0_5 = (0x15 << 21) | OPC_CP0, 923 OPC_C0_6 = (0x16 << 21) | OPC_CP0, 924 OPC_C0_7 = (0x17 << 21) | OPC_CP0, 925 OPC_C0_8 = (0x18 << 21) | OPC_CP0, 926 OPC_C0_9 = (0x19 << 21) | OPC_CP0, 927 OPC_C0_A = (0x1A << 21) | OPC_CP0, 928 OPC_C0_B = (0x1B << 21) | OPC_CP0, 929 OPC_C0_C = (0x1C << 21) | OPC_CP0, 930 OPC_C0_D = (0x1D << 21) | OPC_CP0, 931 OPC_C0_E = (0x1E << 21) | OPC_CP0, 932 OPC_C0_F = (0x1F << 21) | OPC_CP0, 933 }; 934 935 /* MFMC0 opcodes */ 936 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF)) 937 938 enum { 939 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 940 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 941 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0, 942 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0, 943 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 944 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 945 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0, 946 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0, 947 }; 948 949 /* Coprocessor 0 (with rs == C0) */ 950 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F)) 951 952 enum { 953 OPC_TLBR = 0x01 | OPC_C0, 954 OPC_TLBWI = 0x02 | OPC_C0, 955 OPC_TLBINV = 0x03 | OPC_C0, 956 OPC_TLBINVF = 0x04 | OPC_C0, 957 OPC_TLBWR = 0x06 | OPC_C0, 958 OPC_TLBP = 0x08 | OPC_C0, 959 OPC_RFE = 0x10 | OPC_C0, 960 OPC_ERET = 0x18 | OPC_C0, 961 OPC_DERET = 0x1F | OPC_C0, 962 OPC_WAIT = 0x20 | OPC_C0, 963 }; 964 965 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 966 967 enum { 968 OPC_MFC2 = (0x00 << 21) | OPC_CP2, 969 OPC_DMFC2 = (0x01 << 21) | OPC_CP2, 970 OPC_CFC2 = (0x02 << 21) | OPC_CP2, 971 OPC_MFHC2 = (0x03 << 21) | OPC_CP2, 972 OPC_MTC2 = (0x04 << 21) | OPC_CP2, 973 OPC_DMTC2 = (0x05 << 21) | OPC_CP2, 974 OPC_CTC2 = (0x06 << 21) | OPC_CP2, 975 OPC_MTHC2 = (0x07 << 21) | OPC_CP2, 976 OPC_BC2 = (0x08 << 21) | OPC_CP2, 977 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2, 978 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2, 979 }; 980 981 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F)) 982 983 enum { 984 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2, 985 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2, 986 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2, 987 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2, 988 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2, 989 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2, 990 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2, 991 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2, 992 993 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2, 994 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2, 995 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2, 996 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2, 997 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2, 998 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2, 999 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2, 1000 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2, 1001 1002 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2, 1003 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2, 1004 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2, 1005 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2, 1006 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2, 1007 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2, 1008 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2, 1009 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2, 1010 1011 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2, 1012 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2, 1013 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2, 1014 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2, 1015 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2, 1016 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2, 1017 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2, 1018 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2, 1019 1020 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2, 1021 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2, 1022 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2, 1023 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2, 1024 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2, 1025 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2, 1026 1027 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2, 1028 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2, 1029 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2, 1030 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2, 1031 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2, 1032 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2, 1033 1034 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2, 1035 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2, 1036 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2, 1037 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2, 1038 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2, 1039 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2, 1040 1041 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2, 1042 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2, 1043 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2, 1044 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2, 1045 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2, 1046 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2, 1047 1048 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2, 1049 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2, 1050 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2, 1051 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2, 1052 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2, 1053 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2, 1054 1055 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2, 1056 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2, 1057 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2, 1058 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2, 1059 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2, 1060 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2, 1061 1062 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2, 1063 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2, 1064 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2, 1065 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2, 1066 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2, 1067 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2, 1068 1069 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2, 1070 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2, 1071 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2, 1072 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2, 1073 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2, 1074 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2, 1075 }; 1076 1077 1078 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 1079 1080 enum { 1081 OPC_LWXC1 = 0x00 | OPC_CP3, 1082 OPC_LDXC1 = 0x01 | OPC_CP3, 1083 OPC_LUXC1 = 0x05 | OPC_CP3, 1084 OPC_SWXC1 = 0x08 | OPC_CP3, 1085 OPC_SDXC1 = 0x09 | OPC_CP3, 1086 OPC_SUXC1 = 0x0D | OPC_CP3, 1087 OPC_PREFX = 0x0F | OPC_CP3, 1088 OPC_ALNV_PS = 0x1E | OPC_CP3, 1089 OPC_MADD_S = 0x20 | OPC_CP3, 1090 OPC_MADD_D = 0x21 | OPC_CP3, 1091 OPC_MADD_PS = 0x26 | OPC_CP3, 1092 OPC_MSUB_S = 0x28 | OPC_CP3, 1093 OPC_MSUB_D = 0x29 | OPC_CP3, 1094 OPC_MSUB_PS = 0x2E | OPC_CP3, 1095 OPC_NMADD_S = 0x30 | OPC_CP3, 1096 OPC_NMADD_D = 0x31 | OPC_CP3, 1097 OPC_NMADD_PS = 0x36 | OPC_CP3, 1098 OPC_NMSUB_S = 0x38 | OPC_CP3, 1099 OPC_NMSUB_D = 0x39 | OPC_CP3, 1100 OPC_NMSUB_PS = 0x3E | OPC_CP3, 1101 }; 1102 1103 /* 1104 * MMI (MultiMedia Instruction) encodings 1105 * ====================================== 1106 * 1107 * MMI instructions encoding table keys: 1108 * 1109 * * This code is reserved for future use. An attempt to execute it 1110 * causes a Reserved Instruction exception. 1111 * % This code indicates an instruction class. The instruction word 1112 * must be further decoded by examining additional tables that show 1113 * the values for other instruction fields. 1114 * # This code is reserved for the unsupported instructions DMULT, 1115 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt 1116 * to execute it causes a Reserved Instruction exception. 1117 * 1118 * MMI instructions encoded by opcode field (MMI, LQ, SQ): 1119 * 1120 * 31 26 0 1121 * +--------+----------------------------------------+ 1122 * | opcode | | 1123 * +--------+----------------------------------------+ 1124 * 1125 * opcode bits 28..26 1126 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1127 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1128 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1129 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ 1130 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI 1131 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL 1132 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ 1133 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU 1134 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE 1135 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD 1136 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD 1137 */ 1138 1139 enum { 1140 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */ 1141 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */ 1142 }; 1143 1144 /* 1145 * MMI instructions with opcode field = MMI: 1146 * 1147 * 31 26 5 0 1148 * +--------+-------------------------------+--------+ 1149 * | MMI | |function| 1150 * +--------+-------------------------------+--------+ 1151 * 1152 * function bits 2..0 1153 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1154 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1155 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1156 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * 1157 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * 1158 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * 1159 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * 1160 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * 1161 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * 1162 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH 1163 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW 1164 */ 1165 1166 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) 1167 enum { 1168 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */ 1169 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */ 1170 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */ 1171 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */ 1172 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */ 1173 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */ 1174 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI, 1175 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI, 1176 }; 1177 1178 /* global register indices */ 1179 TCGv cpu_gpr[32], cpu_PC; 1180 /* 1181 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[]) 1182 * and the upper halves in cpu_gpr_hi[]. 1183 */ 1184 TCGv_i64 cpu_gpr_hi[32]; 1185 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; 1186 static TCGv cpu_dspctrl, btarget; 1187 TCGv bcond; 1188 static TCGv cpu_lladdr, cpu_llval; 1189 static TCGv_i32 hflags; 1190 TCGv_i32 fpu_fcr0, fpu_fcr31; 1191 TCGv_i64 fpu_f64[32]; 1192 1193 static const char regnames_HI[][4] = { 1194 "HI0", "HI1", "HI2", "HI3", 1195 }; 1196 1197 static const char regnames_LO[][4] = { 1198 "LO0", "LO1", "LO2", "LO3", 1199 }; 1200 1201 /* General purpose registers moves. */ 1202 void gen_load_gpr(TCGv t, int reg) 1203 { 1204 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr)); 1205 if (reg == 0) { 1206 tcg_gen_movi_tl(t, 0); 1207 } else { 1208 tcg_gen_mov_tl(t, cpu_gpr[reg]); 1209 } 1210 } 1211 1212 void gen_store_gpr(TCGv t, int reg) 1213 { 1214 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr)); 1215 if (reg != 0) { 1216 tcg_gen_mov_tl(cpu_gpr[reg], t); 1217 } 1218 } 1219 1220 #if defined(TARGET_MIPS64) 1221 void gen_load_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_movi_i64(t, 0); 1226 } else { 1227 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]); 1228 } 1229 } 1230 1231 void gen_store_gpr_hi(TCGv_i64 t, int reg) 1232 { 1233 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi)); 1234 if (reg != 0) { 1235 tcg_gen_mov_i64(cpu_gpr_hi[reg], t); 1236 } 1237 } 1238 #endif /* TARGET_MIPS64 */ 1239 1240 /* Moves to/from shadow registers. */ 1241 static inline void gen_load_srsgpr(int from, int to) 1242 { 1243 TCGv t0 = tcg_temp_new(); 1244 1245 if (from == 0) { 1246 tcg_gen_movi_tl(t0, 0); 1247 } else { 1248 TCGv_i32 t2 = tcg_temp_new_i32(); 1249 TCGv_ptr addr = tcg_temp_new_ptr(); 1250 1251 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1252 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1253 tcg_gen_andi_i32(t2, t2, 0xf); 1254 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1255 tcg_gen_ext_i32_ptr(addr, t2); 1256 tcg_gen_add_ptr(addr, tcg_env, addr); 1257 1258 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 1259 } 1260 gen_store_gpr(t0, to); 1261 } 1262 1263 static inline void gen_store_srsgpr(int from, int to) 1264 { 1265 if (to != 0) { 1266 TCGv t0 = tcg_temp_new(); 1267 TCGv_i32 t2 = tcg_temp_new_i32(); 1268 TCGv_ptr addr = tcg_temp_new_ptr(); 1269 1270 gen_load_gpr(t0, from); 1271 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1272 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1273 tcg_gen_andi_i32(t2, t2, 0xf); 1274 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1275 tcg_gen_ext_i32_ptr(addr, t2); 1276 tcg_gen_add_ptr(addr, tcg_env, addr); 1277 1278 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 1279 } 1280 } 1281 1282 /* Tests */ 1283 static inline void gen_save_pc(target_ulong pc) 1284 { 1285 tcg_gen_movi_tl(cpu_PC, pc); 1286 } 1287 1288 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) 1289 { 1290 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 1291 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { 1292 gen_save_pc(ctx->base.pc_next); 1293 ctx->saved_pc = ctx->base.pc_next; 1294 } 1295 if (ctx->hflags != ctx->saved_hflags) { 1296 tcg_gen_movi_i32(hflags, ctx->hflags); 1297 ctx->saved_hflags = ctx->hflags; 1298 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1299 case MIPS_HFLAG_BR: 1300 break; 1301 case MIPS_HFLAG_BC: 1302 case MIPS_HFLAG_BL: 1303 case MIPS_HFLAG_B: 1304 tcg_gen_movi_tl(btarget, ctx->btarget); 1305 break; 1306 } 1307 } 1308 } 1309 1310 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) 1311 { 1312 ctx->saved_hflags = ctx->hflags; 1313 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1314 case MIPS_HFLAG_BR: 1315 break; 1316 case MIPS_HFLAG_BC: 1317 case MIPS_HFLAG_BL: 1318 case MIPS_HFLAG_B: 1319 ctx->btarget = env->btarget; 1320 break; 1321 } 1322 } 1323 1324 void generate_exception_err(DisasContext *ctx, int excp, int err) 1325 { 1326 save_cpu_state(ctx, 1); 1327 gen_helper_raise_exception_err(tcg_env, tcg_constant_i32(excp), 1328 tcg_constant_i32(err)); 1329 ctx->base.is_jmp = DISAS_NORETURN; 1330 } 1331 1332 void generate_exception(DisasContext *ctx, int excp) 1333 { 1334 gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp)); 1335 } 1336 1337 void generate_exception_end(DisasContext *ctx, int excp) 1338 { 1339 generate_exception_err(ctx, excp, 0); 1340 } 1341 1342 void generate_exception_break(DisasContext *ctx, int code) 1343 { 1344 #ifdef CONFIG_USER_ONLY 1345 /* Pass the break code along to cpu_loop. */ 1346 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 1347 offsetof(CPUMIPSState, error_code)); 1348 #endif 1349 generate_exception_end(ctx, EXCP_BREAK); 1350 } 1351 1352 void gen_reserved_instruction(DisasContext *ctx) 1353 { 1354 generate_exception_end(ctx, EXCP_RI); 1355 } 1356 1357 /* Floating point register moves. */ 1358 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1359 { 1360 if (ctx->hflags & MIPS_HFLAG_FRE) { 1361 generate_exception(ctx, EXCP_RI); 1362 } 1363 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); 1364 } 1365 1366 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1367 { 1368 TCGv_i64 t64; 1369 if (ctx->hflags & MIPS_HFLAG_FRE) { 1370 generate_exception(ctx, EXCP_RI); 1371 } 1372 t64 = tcg_temp_new_i64(); 1373 tcg_gen_extu_i32_i64(t64, t); 1374 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); 1375 } 1376 1377 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1378 { 1379 if (ctx->hflags & MIPS_HFLAG_F64) { 1380 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); 1381 } else { 1382 gen_load_fpr32(ctx, t, reg | 1); 1383 } 1384 } 1385 1386 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1387 { 1388 if (ctx->hflags & MIPS_HFLAG_F64) { 1389 TCGv_i64 t64 = tcg_temp_new_i64(); 1390 tcg_gen_extu_i32_i64(t64, t); 1391 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); 1392 } else { 1393 gen_store_fpr32(ctx, t, reg | 1); 1394 } 1395 } 1396 1397 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1398 { 1399 if (ctx->hflags & MIPS_HFLAG_F64) { 1400 tcg_gen_mov_i64(t, fpu_f64[reg]); 1401 } else { 1402 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]); 1403 } 1404 } 1405 1406 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1407 { 1408 if (ctx->hflags & MIPS_HFLAG_F64) { 1409 tcg_gen_mov_i64(fpu_f64[reg], t); 1410 } else { 1411 TCGv_i64 t0; 1412 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32); 1413 t0 = tcg_temp_new_i64(); 1414 tcg_gen_shri_i64(t0, t, 32); 1415 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32); 1416 } 1417 } 1418 1419 int get_fp_bit(int cc) 1420 { 1421 if (cc) { 1422 return 24 + cc; 1423 } else { 1424 return 23; 1425 } 1426 } 1427 1428 /* Addresses computation */ 1429 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 1430 { 1431 tcg_gen_add_tl(ret, arg0, arg1); 1432 1433 #if defined(TARGET_MIPS64) 1434 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1435 tcg_gen_ext32s_i64(ret, ret); 1436 } 1437 #endif 1438 } 1439 1440 void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, target_long ofs) 1441 { 1442 tcg_gen_addi_tl(ret, base, ofs); 1443 1444 #if defined(TARGET_MIPS64) 1445 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1446 tcg_gen_ext32s_i64(ret, ret); 1447 } 1448 #endif 1449 } 1450 1451 /* Addresses computation (translation time) */ 1452 static target_long addr_add(DisasContext *ctx, target_long base, 1453 target_long offset) 1454 { 1455 target_long sum = base + offset; 1456 1457 #if defined(TARGET_MIPS64) 1458 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1459 sum = (int32_t)sum; 1460 } 1461 #endif 1462 return sum; 1463 } 1464 1465 /* Sign-extract the low 32-bits to a target_long. */ 1466 void gen_move_low32(TCGv ret, TCGv_i64 arg) 1467 { 1468 #if defined(TARGET_MIPS64) 1469 tcg_gen_ext32s_i64(ret, arg); 1470 #else 1471 tcg_gen_extrl_i64_i32(ret, arg); 1472 #endif 1473 } 1474 1475 /* Sign-extract the high 32-bits to a target_long. */ 1476 void gen_move_high32(TCGv ret, TCGv_i64 arg) 1477 { 1478 #if defined(TARGET_MIPS64) 1479 tcg_gen_sari_i64(ret, arg, 32); 1480 #else 1481 tcg_gen_extrh_i64_i32(ret, arg); 1482 #endif 1483 } 1484 1485 bool check_cp0_enabled(DisasContext *ctx) 1486 { 1487 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1488 generate_exception_end(ctx, EXCP_CpU); 1489 return false; 1490 } 1491 return true; 1492 } 1493 1494 void check_cp1_enabled(DisasContext *ctx) 1495 { 1496 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) { 1497 generate_exception_err(ctx, EXCP_CpU, 1); 1498 } 1499 } 1500 1501 /* 1502 * Verify that the processor is running with COP1X instructions enabled. 1503 * This is associated with the nabla symbol in the MIPS32 and MIPS64 1504 * opcode tables. 1505 */ 1506 void check_cop1x(DisasContext *ctx) 1507 { 1508 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { 1509 gen_reserved_instruction(ctx); 1510 } 1511 } 1512 1513 /* 1514 * Verify that the processor is running with 64-bit floating-point 1515 * operations enabled. 1516 */ 1517 void check_cp1_64bitmode(DisasContext *ctx) 1518 { 1519 if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) { 1520 gen_reserved_instruction(ctx); 1521 } 1522 } 1523 1524 /* 1525 * Verify if floating point register is valid; an operation is not defined 1526 * if bit 0 of any register specification is set and the FR bit in the 1527 * Status register equals zero, since the register numbers specify an 1528 * even-odd pair of adjacent coprocessor general registers. When the FR bit 1529 * in the Status register equals one, both even and odd register numbers 1530 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 1531 * 1532 * Multiple 64 bit wide registers can be checked by calling 1533 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 1534 */ 1535 void check_cp1_registers(DisasContext *ctx, int regs) 1536 { 1537 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { 1538 gen_reserved_instruction(ctx); 1539 } 1540 } 1541 1542 /* 1543 * Verify that the processor is running with DSP instructions enabled. 1544 * This is enabled by CP0 Status register MX(24) bit. 1545 */ 1546 static inline void check_dsp(DisasContext *ctx) 1547 { 1548 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { 1549 if (ctx->insn_flags & ASE_DSP) { 1550 generate_exception_end(ctx, EXCP_DSPDIS); 1551 } else { 1552 gen_reserved_instruction(ctx); 1553 } 1554 } 1555 } 1556 1557 static inline void check_dsp_r2(DisasContext *ctx) 1558 { 1559 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { 1560 if (ctx->insn_flags & ASE_DSP) { 1561 generate_exception_end(ctx, EXCP_DSPDIS); 1562 } else { 1563 gen_reserved_instruction(ctx); 1564 } 1565 } 1566 } 1567 1568 static inline void check_dsp_r3(DisasContext *ctx) 1569 { 1570 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { 1571 if (ctx->insn_flags & ASE_DSP) { 1572 generate_exception_end(ctx, EXCP_DSPDIS); 1573 } else { 1574 gen_reserved_instruction(ctx); 1575 } 1576 } 1577 } 1578 1579 /* 1580 * This code generates a "reserved instruction" exception if the 1581 * CPU does not support the instruction set corresponding to flags. 1582 */ 1583 void check_insn(DisasContext *ctx, uint64_t flags) 1584 { 1585 if (unlikely(!(ctx->insn_flags & flags))) { 1586 gen_reserved_instruction(ctx); 1587 } 1588 } 1589 1590 /* 1591 * This code generates a "reserved instruction" exception if the 1592 * CPU has corresponding flag set which indicates that the instruction 1593 * has been removed. 1594 */ 1595 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) 1596 { 1597 if (unlikely(ctx->insn_flags & flags)) { 1598 gen_reserved_instruction(ctx); 1599 } 1600 } 1601 1602 /* 1603 * The Linux kernel traps certain reserved instruction exceptions to 1604 * emulate the corresponding instructions. QEMU is the kernel in user 1605 * mode, so those traps are emulated by accepting the instructions. 1606 * 1607 * A reserved instruction exception is generated for flagged CPUs if 1608 * QEMU runs in system mode. 1609 */ 1610 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) 1611 { 1612 #ifndef CONFIG_USER_ONLY 1613 check_insn_opc_removed(ctx, flags); 1614 #endif 1615 } 1616 1617 /* 1618 * This code generates a "reserved instruction" exception if the 1619 * CPU does not support 64-bit paired-single (PS) floating point data type. 1620 */ 1621 static inline void check_ps(DisasContext *ctx) 1622 { 1623 if (unlikely(!ctx->ps)) { 1624 generate_exception(ctx, EXCP_RI); 1625 } 1626 check_cp1_64bitmode(ctx); 1627 } 1628 1629 bool decode_64bit_enabled(DisasContext *ctx) 1630 { 1631 return ctx->hflags & MIPS_HFLAG_64; 1632 } 1633 1634 /* 1635 * This code generates a "reserved instruction" exception if cpu is not 1636 * 64-bit or 64-bit instructions are not enabled. 1637 */ 1638 void check_mips_64(DisasContext *ctx) 1639 { 1640 if (unlikely((TARGET_LONG_BITS != 64) || !decode_64bit_enabled(ctx))) { 1641 gen_reserved_instruction(ctx); 1642 } 1643 } 1644 1645 #ifndef CONFIG_USER_ONLY 1646 static inline void check_mvh(DisasContext *ctx) 1647 { 1648 if (unlikely(!ctx->mvh)) { 1649 generate_exception(ctx, EXCP_RI); 1650 } 1651 } 1652 #endif 1653 1654 /* 1655 * This code generates a "reserved instruction" exception if the 1656 * Config5 XNP bit is set. 1657 */ 1658 static inline void check_xnp(DisasContext *ctx) 1659 { 1660 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) { 1661 gen_reserved_instruction(ctx); 1662 } 1663 } 1664 1665 #ifndef CONFIG_USER_ONLY 1666 /* 1667 * This code generates a "reserved instruction" exception if the 1668 * Config3 PW bit is NOT set. 1669 */ 1670 static inline void check_pw(DisasContext *ctx) 1671 { 1672 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) { 1673 gen_reserved_instruction(ctx); 1674 } 1675 } 1676 #endif 1677 1678 /* 1679 * This code generates a "reserved instruction" exception if the 1680 * Config3 MT bit is NOT set. 1681 */ 1682 static inline void check_mt(DisasContext *ctx) 1683 { 1684 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1685 gen_reserved_instruction(ctx); 1686 } 1687 } 1688 1689 #ifndef CONFIG_USER_ONLY 1690 /* 1691 * This code generates a "coprocessor unusable" exception if CP0 is not 1692 * available, and, if that is not the case, generates a "reserved instruction" 1693 * exception if the Config5 MT bit is NOT set. This is needed for availability 1694 * control of some of MT ASE instructions. 1695 */ 1696 static inline void check_cp0_mt(DisasContext *ctx) 1697 { 1698 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1699 generate_exception_end(ctx, EXCP_CpU); 1700 } else { 1701 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1702 gen_reserved_instruction(ctx); 1703 } 1704 } 1705 } 1706 #endif 1707 1708 /* 1709 * This code generates a "reserved instruction" exception if the 1710 * Config5 NMS bit is set. 1711 */ 1712 static inline void check_nms(DisasContext *ctx) 1713 { 1714 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) { 1715 gen_reserved_instruction(ctx); 1716 } 1717 } 1718 1719 /* 1720 * This code generates a "reserved instruction" exception if the 1721 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, 1722 * Config2 TL, and Config5 L2C are unset. 1723 */ 1724 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) 1725 { 1726 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) && 1727 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) && 1728 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) && 1729 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && 1730 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && 1731 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) { 1732 gen_reserved_instruction(ctx); 1733 } 1734 } 1735 1736 /* 1737 * This code generates a "reserved instruction" exception if the 1738 * Config5 EVA bit is NOT set. 1739 */ 1740 static inline void check_eva(DisasContext *ctx) 1741 { 1742 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) { 1743 gen_reserved_instruction(ctx); 1744 } 1745 } 1746 1747 1748 /* 1749 * Define small wrappers for gen_load_fpr* so that we have a uniform 1750 * calling interface for 32 and 64-bit FPRs. No sense in changing 1751 * all callers for gen_load_fpr32 when we need the CTX parameter for 1752 * this one use. 1753 */ 1754 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) 1755 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) 1756 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \ 1757 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ 1758 int ft, int fs, int cc) \ 1759 { \ 1760 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ 1761 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ 1762 switch (ifmt) { \ 1763 case FMT_PS: \ 1764 check_ps(ctx); \ 1765 break; \ 1766 case FMT_D: \ 1767 if (abs) { \ 1768 check_cop1x(ctx); \ 1769 } \ 1770 check_cp1_registers(ctx, fs | ft); \ 1771 break; \ 1772 case FMT_S: \ 1773 if (abs) { \ 1774 check_cop1x(ctx); \ 1775 } \ 1776 break; \ 1777 } \ 1778 gen_ldcmp_fpr##bits(ctx, fp0, fs); \ 1779 gen_ldcmp_fpr##bits(ctx, fp1, ft); \ 1780 switch (n) { \ 1781 case 0: \ 1782 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \ 1783 break; \ 1784 case 1: \ 1785 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \ 1786 break; \ 1787 case 2: \ 1788 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \ 1789 break; \ 1790 case 3: \ 1791 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \ 1792 break; \ 1793 case 4: \ 1794 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \ 1795 break; \ 1796 case 5: \ 1797 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \ 1798 break; \ 1799 case 6: \ 1800 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \ 1801 break; \ 1802 case 7: \ 1803 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \ 1804 break; \ 1805 case 8: \ 1806 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \ 1807 break; \ 1808 case 9: \ 1809 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \ 1810 break; \ 1811 case 10: \ 1812 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \ 1813 break; \ 1814 case 11: \ 1815 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \ 1816 break; \ 1817 case 12: \ 1818 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \ 1819 break; \ 1820 case 13: \ 1821 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \ 1822 break; \ 1823 case 14: \ 1824 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \ 1825 break; \ 1826 case 15: \ 1827 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \ 1828 break; \ 1829 default: \ 1830 abort(); \ 1831 } \ 1832 } 1833 1834 FOP_CONDS(, 0, d, FMT_D, 64) 1835 FOP_CONDS(abs, 1, d, FMT_D, 64) 1836 FOP_CONDS(, 0, s, FMT_S, 32) 1837 FOP_CONDS(abs, 1, s, FMT_S, 32) 1838 FOP_CONDS(, 0, ps, FMT_PS, 64) 1839 FOP_CONDS(abs, 1, ps, FMT_PS, 64) 1840 #undef FOP_CONDS 1841 1842 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \ 1843 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \ 1844 int ft, int fs, int fd) \ 1845 { \ 1846 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ 1847 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ 1848 if (ifmt == FMT_D) { \ 1849 check_cp1_registers(ctx, fs | ft | fd); \ 1850 } \ 1851 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ 1852 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ 1853 switch (n) { \ 1854 case 0: \ 1855 gen_helper_r6_cmp_ ## fmt ## _af(fp0, tcg_env, fp0, fp1); \ 1856 break; \ 1857 case 1: \ 1858 gen_helper_r6_cmp_ ## fmt ## _un(fp0, tcg_env, fp0, fp1); \ 1859 break; \ 1860 case 2: \ 1861 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, tcg_env, fp0, fp1); \ 1862 break; \ 1863 case 3: \ 1864 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, tcg_env, fp0, fp1); \ 1865 break; \ 1866 case 4: \ 1867 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, tcg_env, fp0, fp1); \ 1868 break; \ 1869 case 5: \ 1870 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, tcg_env, fp0, fp1); \ 1871 break; \ 1872 case 6: \ 1873 gen_helper_r6_cmp_ ## fmt ## _le(fp0, tcg_env, fp0, fp1); \ 1874 break; \ 1875 case 7: \ 1876 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, tcg_env, fp0, fp1); \ 1877 break; \ 1878 case 8: \ 1879 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, tcg_env, fp0, fp1); \ 1880 break; \ 1881 case 9: \ 1882 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, tcg_env, fp0, fp1); \ 1883 break; \ 1884 case 10: \ 1885 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, tcg_env, fp0, fp1); \ 1886 break; \ 1887 case 11: \ 1888 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, tcg_env, fp0, fp1); \ 1889 break; \ 1890 case 12: \ 1891 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, tcg_env, fp0, fp1); \ 1892 break; \ 1893 case 13: \ 1894 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, tcg_env, fp0, fp1); \ 1895 break; \ 1896 case 14: \ 1897 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, tcg_env, fp0, fp1); \ 1898 break; \ 1899 case 15: \ 1900 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, tcg_env, fp0, fp1); \ 1901 break; \ 1902 case 17: \ 1903 gen_helper_r6_cmp_ ## fmt ## _or(fp0, tcg_env, fp0, fp1); \ 1904 break; \ 1905 case 18: \ 1906 gen_helper_r6_cmp_ ## fmt ## _une(fp0, tcg_env, fp0, fp1); \ 1907 break; \ 1908 case 19: \ 1909 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, tcg_env, fp0, fp1); \ 1910 break; \ 1911 case 25: \ 1912 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, tcg_env, fp0, fp1); \ 1913 break; \ 1914 case 26: \ 1915 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, tcg_env, fp0, fp1); \ 1916 break; \ 1917 case 27: \ 1918 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, tcg_env, fp0, fp1); \ 1919 break; \ 1920 default: \ 1921 abort(); \ 1922 } \ 1923 STORE; \ 1924 } 1925 1926 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) 1927 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd)) 1928 #undef FOP_CONDNS 1929 #undef gen_ldcmp_fpr32 1930 #undef gen_ldcmp_fpr64 1931 1932 /* load/store instructions. */ 1933 #ifdef CONFIG_USER_ONLY 1934 #define OP_LD_ATOMIC(insn, memop) \ 1935 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1936 DisasContext *ctx) \ 1937 { \ 1938 TCGv t0 = tcg_temp_new(); \ 1939 tcg_gen_mov_tl(t0, arg1); \ 1940 tcg_gen_qemu_ld_tl(ret, arg1, ctx->mem_idx, memop); \ 1941 tcg_gen_st_tl(t0, tcg_env, offsetof(CPUMIPSState, lladdr)); \ 1942 tcg_gen_st_tl(ret, tcg_env, offsetof(CPUMIPSState, llval)); \ 1943 } 1944 #else 1945 #define OP_LD_ATOMIC(insn, ignored_memop) \ 1946 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 1947 DisasContext *ctx) \ 1948 { \ 1949 gen_helper_##insn(ret, tcg_env, arg1, tcg_constant_i32(mem_idx)); \ 1950 } 1951 #endif 1952 OP_LD_ATOMIC(ll, mo_endian(ctx) | MO_SL); 1953 #if defined(TARGET_MIPS64) 1954 OP_LD_ATOMIC(lld, mo_endian(ctx) | MO_UQ); 1955 #endif 1956 #undef OP_LD_ATOMIC 1957 1958 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset) 1959 { 1960 if (base == 0) { 1961 tcg_gen_movi_tl(addr, offset); 1962 } else if (offset == 0) { 1963 gen_load_gpr(addr, base); 1964 } else { 1965 tcg_gen_movi_tl(addr, offset); 1966 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); 1967 } 1968 } 1969 1970 static target_ulong pc_relative_pc(DisasContext *ctx) 1971 { 1972 target_ulong pc = ctx->base.pc_next; 1973 1974 if (ctx->hflags & MIPS_HFLAG_BMASK) { 1975 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4; 1976 1977 pc -= branch_bytes; 1978 } 1979 1980 pc &= ~(target_ulong)3; 1981 return pc; 1982 } 1983 1984 /* LWL or LDL, depending on MemOp. */ 1985 static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr, 1986 int mem_idx, MemOp mop) 1987 { 1988 int sizem1 = memop_size(mop) - 1; 1989 TCGv t0 = tcg_temp_new(); 1990 TCGv t1 = tcg_temp_new(); 1991 1992 /* 1993 * Do a byte access to possibly trigger a page 1994 * fault with the unaligned address. 1995 */ 1996 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); 1997 tcg_gen_andi_tl(t1, addr, sizem1); 1998 if (!disas_is_bigendian(ctx)) { 1999 tcg_gen_xori_tl(t1, t1, sizem1); 2000 } 2001 tcg_gen_shli_tl(t1, t1, 3); 2002 tcg_gen_andi_tl(t0, addr, ~sizem1); 2003 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); 2004 tcg_gen_shl_tl(t0, t0, t1); 2005 tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1); 2006 tcg_gen_andc_tl(t1, reg, t1); 2007 tcg_gen_or_tl(reg, t0, t1); 2008 } 2009 2010 /* LWR or LDR, depending on MemOp. */ 2011 static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr, 2012 int mem_idx, MemOp mop) 2013 { 2014 int size = memop_size(mop); 2015 int sizem1 = size - 1; 2016 TCGv t0 = tcg_temp_new(); 2017 TCGv t1 = tcg_temp_new(); 2018 2019 /* 2020 * Do a byte access to possibly trigger a page 2021 * fault with the unaligned address. 2022 */ 2023 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB); 2024 tcg_gen_andi_tl(t1, addr, sizem1); 2025 if (disas_is_bigendian(ctx)) { 2026 tcg_gen_xori_tl(t1, t1, sizem1); 2027 } 2028 tcg_gen_shli_tl(t1, t1, 3); 2029 tcg_gen_andi_tl(t0, addr, ~sizem1); 2030 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop); 2031 tcg_gen_shr_tl(t0, t0, t1); 2032 tcg_gen_xori_tl(t1, t1, size * 8 - 1); 2033 tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1); 2034 tcg_gen_and_tl(t1, reg, t1); 2035 tcg_gen_or_tl(reg, t0, t1); 2036 } 2037 2038 /* Load */ 2039 static void gen_ld(DisasContext *ctx, uint32_t opc, 2040 int rt, int base, int offset) 2041 { 2042 TCGv t0, t1; 2043 int mem_idx = ctx->mem_idx; 2044 2045 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F | 2046 INSN_LOONGSON3A)) { 2047 /* 2048 * Loongson CPU uses a load to zero register for prefetch. 2049 * We emulate it as a NOP. On other CPU we must perform the 2050 * actual memory access. 2051 */ 2052 return; 2053 } 2054 2055 t0 = tcg_temp_new(); 2056 gen_base_offset_addr(ctx, t0, base, offset); 2057 2058 switch (opc) { 2059 #if defined(TARGET_MIPS64) 2060 case OPC_LWU: 2061 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UL | 2062 ctx->default_tcg_memop_mask); 2063 gen_store_gpr(t0, rt); 2064 break; 2065 case OPC_LD: 2066 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ | 2067 ctx->default_tcg_memop_mask); 2068 gen_store_gpr(t0, rt); 2069 break; 2070 case OPC_LLD: 2071 case R6_OPC_LLD: 2072 op_ld_lld(t0, t0, mem_idx, ctx); 2073 gen_store_gpr(t0, rt); 2074 break; 2075 case OPC_LDL: 2076 t1 = tcg_temp_new(); 2077 gen_load_gpr(t1, rt); 2078 gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2079 gen_store_gpr(t1, rt); 2080 break; 2081 case OPC_LDR: 2082 t1 = tcg_temp_new(); 2083 gen_load_gpr(t1, rt); 2084 gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2085 gen_store_gpr(t1, rt); 2086 break; 2087 case OPC_LDPC: 2088 t1 = tcg_constant_tl(pc_relative_pc(ctx)); 2089 gen_op_addr_add(ctx, t0, t0, t1); 2090 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ); 2091 gen_store_gpr(t0, rt); 2092 break; 2093 #endif 2094 case OPC_LWPC: 2095 t1 = tcg_constant_tl(pc_relative_pc(ctx)); 2096 gen_op_addr_add(ctx, t0, t0, t1); 2097 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL); 2098 gen_store_gpr(t0, rt); 2099 break; 2100 case OPC_LWE: 2101 mem_idx = MIPS_HFLAG_UM; 2102 /* fall through */ 2103 case OPC_LW: 2104 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL | 2105 ctx->default_tcg_memop_mask); 2106 gen_store_gpr(t0, rt); 2107 break; 2108 case OPC_LHE: 2109 mem_idx = MIPS_HFLAG_UM; 2110 /* fall through */ 2111 case OPC_LH: 2112 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SW | 2113 ctx->default_tcg_memop_mask); 2114 gen_store_gpr(t0, rt); 2115 break; 2116 case OPC_LHUE: 2117 mem_idx = MIPS_HFLAG_UM; 2118 /* fall through */ 2119 case OPC_LHU: 2120 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UW | 2121 ctx->default_tcg_memop_mask); 2122 gen_store_gpr(t0, rt); 2123 break; 2124 case OPC_LBE: 2125 mem_idx = MIPS_HFLAG_UM; 2126 /* fall through */ 2127 case OPC_LB: 2128 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); 2129 gen_store_gpr(t0, rt); 2130 break; 2131 case OPC_LBUE: 2132 mem_idx = MIPS_HFLAG_UM; 2133 /* fall through */ 2134 case OPC_LBU: 2135 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); 2136 gen_store_gpr(t0, rt); 2137 break; 2138 case OPC_LWLE: 2139 mem_idx = MIPS_HFLAG_UM; 2140 /* fall through */ 2141 case OPC_LWL: 2142 t1 = tcg_temp_new(); 2143 gen_load_gpr(t1, rt); 2144 gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL); 2145 tcg_gen_ext32s_tl(t1, t1); 2146 gen_store_gpr(t1, rt); 2147 break; 2148 case OPC_LWRE: 2149 mem_idx = MIPS_HFLAG_UM; 2150 /* fall through */ 2151 case OPC_LWR: 2152 t1 = tcg_temp_new(); 2153 gen_load_gpr(t1, rt); 2154 gen_lxr(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_LLE: 2159 mem_idx = MIPS_HFLAG_UM; 2160 /* fall through */ 2161 case OPC_LL: 2162 case R6_OPC_LL: 2163 op_ld_ll(t0, t0, mem_idx, ctx); 2164 gen_store_gpr(t0, rt); 2165 break; 2166 } 2167 } 2168 2169 /* Store */ 2170 static void gen_st(DisasContext *ctx, uint32_t opc, int rt, 2171 int base, int offset) 2172 { 2173 TCGv t0 = tcg_temp_new(); 2174 TCGv t1 = tcg_temp_new(); 2175 int mem_idx = ctx->mem_idx; 2176 2177 gen_base_offset_addr(ctx, t0, base, offset); 2178 gen_load_gpr(t1, rt); 2179 switch (opc) { 2180 #if defined(TARGET_MIPS64) 2181 case OPC_SD: 2182 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UQ | 2183 ctx->default_tcg_memop_mask); 2184 break; 2185 case OPC_SDL: 2186 gen_helper_0e2i(sdl, t1, t0, mem_idx); 2187 break; 2188 case OPC_SDR: 2189 gen_helper_0e2i(sdr, t1, t0, mem_idx); 2190 break; 2191 #endif 2192 case OPC_SWE: 2193 mem_idx = MIPS_HFLAG_UM; 2194 /* fall through */ 2195 case OPC_SW: 2196 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UL | 2197 ctx->default_tcg_memop_mask); 2198 break; 2199 case OPC_SHE: 2200 mem_idx = MIPS_HFLAG_UM; 2201 /* fall through */ 2202 case OPC_SH: 2203 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UW | 2204 ctx->default_tcg_memop_mask); 2205 break; 2206 case OPC_SBE: 2207 mem_idx = MIPS_HFLAG_UM; 2208 /* fall through */ 2209 case OPC_SB: 2210 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); 2211 break; 2212 case OPC_SWLE: 2213 mem_idx = MIPS_HFLAG_UM; 2214 /* fall through */ 2215 case OPC_SWL: 2216 gen_helper_0e2i(swl, t1, t0, mem_idx); 2217 break; 2218 case OPC_SWRE: 2219 mem_idx = MIPS_HFLAG_UM; 2220 /* fall through */ 2221 case OPC_SWR: 2222 gen_helper_0e2i(swr, t1, t0, mem_idx); 2223 break; 2224 } 2225 } 2226 2227 2228 /* Store conditional */ 2229 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, 2230 MemOp tcg_mo, bool eva) 2231 { 2232 TCGv addr, t0, val; 2233 TCGLabel *l1 = gen_new_label(); 2234 TCGLabel *done = gen_new_label(); 2235 2236 t0 = tcg_temp_new(); 2237 addr = tcg_temp_new(); 2238 /* compare the address against that of the preceding LL */ 2239 gen_base_offset_addr(ctx, addr, base, offset); 2240 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); 2241 gen_store_gpr(tcg_constant_tl(0), rt); 2242 tcg_gen_br(done); 2243 2244 gen_set_label(l1); 2245 /* generate cmpxchg */ 2246 val = tcg_temp_new(); 2247 gen_load_gpr(val, rt); 2248 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, 2249 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo); 2250 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); 2251 gen_store_gpr(t0, rt); 2252 2253 gen_set_label(done); 2254 } 2255 2256 /* Load and store */ 2257 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, 2258 TCGv t0) 2259 { 2260 /* 2261 * Don't do NOP if destination is zero: we must perform the actual 2262 * memory access. 2263 */ 2264 switch (opc) { 2265 case OPC_LWC1: 2266 { 2267 TCGv_i32 fp0 = tcg_temp_new_i32(); 2268 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 2269 ctx->default_tcg_memop_mask); 2270 gen_store_fpr32(ctx, fp0, ft); 2271 } 2272 break; 2273 case OPC_SWC1: 2274 { 2275 TCGv_i32 fp0 = tcg_temp_new_i32(); 2276 gen_load_fpr32(ctx, fp0, ft); 2277 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 2278 ctx->default_tcg_memop_mask); 2279 } 2280 break; 2281 case OPC_LDC1: 2282 { 2283 TCGv_i64 fp0 = tcg_temp_new_i64(); 2284 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 2285 ctx->default_tcg_memop_mask); 2286 gen_store_fpr64(ctx, fp0, ft); 2287 } 2288 break; 2289 case OPC_SDC1: 2290 { 2291 TCGv_i64 fp0 = tcg_temp_new_i64(); 2292 gen_load_fpr64(ctx, fp0, ft); 2293 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 2294 ctx->default_tcg_memop_mask); 2295 } 2296 break; 2297 default: 2298 MIPS_INVAL("flt_ldst"); 2299 gen_reserved_instruction(ctx); 2300 break; 2301 } 2302 } 2303 2304 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, 2305 int rs, int16_t imm) 2306 { 2307 TCGv t0 = tcg_temp_new(); 2308 2309 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2310 check_cp1_enabled(ctx); 2311 switch (op) { 2312 case OPC_LDC1: 2313 case OPC_SDC1: 2314 check_insn(ctx, ISA_MIPS2); 2315 /* Fallthrough */ 2316 default: 2317 gen_base_offset_addr(ctx, t0, rs, imm); 2318 gen_flt_ldst(ctx, op, rt, t0); 2319 } 2320 } else { 2321 generate_exception_err(ctx, EXCP_CpU, 1); 2322 } 2323 } 2324 2325 /* Arithmetic with immediate operand */ 2326 static void gen_arith_imm(DisasContext *ctx, uint32_t opc, 2327 int rt, int rs, int imm) 2328 { 2329 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2330 2331 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 2332 /* 2333 * If no destination, treat it as a NOP. 2334 * For addi, we must generate the overflow exception when needed. 2335 */ 2336 return; 2337 } 2338 switch (opc) { 2339 case OPC_ADDI: 2340 { 2341 TCGv t0 = tcg_temp_new(); 2342 TCGv t1 = tcg_temp_new(); 2343 TCGv t2 = tcg_temp_new(); 2344 TCGLabel *l1 = gen_new_label(); 2345 2346 gen_load_gpr(t1, rs); 2347 tcg_gen_addi_tl(t0, t1, uimm); 2348 tcg_gen_ext32s_tl(t0, t0); 2349 2350 tcg_gen_xori_tl(t1, t1, ~uimm); 2351 tcg_gen_xori_tl(t2, t0, uimm); 2352 tcg_gen_and_tl(t1, t1, t2); 2353 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2354 /* operands of same sign, result different sign */ 2355 generate_exception(ctx, EXCP_OVERFLOW); 2356 gen_set_label(l1); 2357 tcg_gen_ext32s_tl(t0, t0); 2358 gen_store_gpr(t0, rt); 2359 } 2360 break; 2361 case OPC_ADDIU: 2362 if (rs != 0) { 2363 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2364 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2365 } else { 2366 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2367 } 2368 break; 2369 #if defined(TARGET_MIPS64) 2370 case OPC_DADDI: 2371 { 2372 TCGv t0 = tcg_temp_new(); 2373 TCGv t1 = tcg_temp_new(); 2374 TCGv t2 = tcg_temp_new(); 2375 TCGLabel *l1 = gen_new_label(); 2376 2377 gen_load_gpr(t1, rs); 2378 tcg_gen_addi_tl(t0, t1, uimm); 2379 2380 tcg_gen_xori_tl(t1, t1, ~uimm); 2381 tcg_gen_xori_tl(t2, t0, uimm); 2382 tcg_gen_and_tl(t1, t1, t2); 2383 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2384 /* operands of same sign, result different sign */ 2385 generate_exception(ctx, EXCP_OVERFLOW); 2386 gen_set_label(l1); 2387 gen_store_gpr(t0, rt); 2388 } 2389 break; 2390 case OPC_DADDIU: 2391 if (rs != 0) { 2392 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2393 } else { 2394 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2395 } 2396 break; 2397 #endif 2398 } 2399 } 2400 2401 /* Logic with immediate operand */ 2402 static void gen_logic_imm(DisasContext *ctx, uint32_t opc, 2403 int rt, int rs, int16_t imm) 2404 { 2405 target_ulong uimm; 2406 2407 if (rt == 0) { 2408 /* If no destination, treat it as a NOP. */ 2409 return; 2410 } 2411 uimm = (uint16_t)imm; 2412 switch (opc) { 2413 case OPC_ANDI: 2414 if (likely(rs != 0)) { 2415 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2416 } else { 2417 tcg_gen_movi_tl(cpu_gpr[rt], 0); 2418 } 2419 break; 2420 case OPC_ORI: 2421 if (rs != 0) { 2422 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2423 } else { 2424 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2425 } 2426 break; 2427 case OPC_XORI: 2428 if (likely(rs != 0)) { 2429 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2430 } else { 2431 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2432 } 2433 break; 2434 case OPC_LUI: 2435 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) { 2436 /* OPC_AUI */ 2437 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16); 2438 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2439 } else { 2440 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 2441 } 2442 break; 2443 2444 default: 2445 break; 2446 } 2447 } 2448 2449 /* Set on less than with immediate operand */ 2450 static void gen_slt_imm(DisasContext *ctx, uint32_t opc, 2451 int rt, int rs, int16_t imm) 2452 { 2453 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2454 TCGv t0; 2455 2456 if (rt == 0) { 2457 /* If no destination, treat it as a NOP. */ 2458 return; 2459 } 2460 t0 = tcg_temp_new(); 2461 gen_load_gpr(t0, rs); 2462 switch (opc) { 2463 case OPC_SLTI: 2464 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); 2465 break; 2466 case OPC_SLTIU: 2467 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); 2468 break; 2469 } 2470 } 2471 2472 /* Shifts with immediate operand */ 2473 static void gen_shift_imm(DisasContext *ctx, uint32_t opc, 2474 int rt, int rs, int16_t imm) 2475 { 2476 target_ulong uimm = ((uint16_t)imm) & 0x1f; 2477 TCGv t0; 2478 2479 if (rt == 0) { 2480 /* If no destination, treat it as a NOP. */ 2481 return; 2482 } 2483 2484 t0 = tcg_temp_new(); 2485 gen_load_gpr(t0, rs); 2486 switch (opc) { 2487 case OPC_SLL: 2488 tcg_gen_shli_tl(t0, t0, uimm); 2489 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2490 break; 2491 case OPC_SRA: 2492 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2493 break; 2494 case OPC_SRL: 2495 if (uimm != 0) { 2496 tcg_gen_ext32u_tl(t0, t0); 2497 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2498 } else { 2499 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2500 } 2501 break; 2502 case OPC_ROTR: 2503 if (uimm != 0) { 2504 TCGv_i32 t1 = tcg_temp_new_i32(); 2505 2506 tcg_gen_trunc_tl_i32(t1, t0); 2507 tcg_gen_rotri_i32(t1, t1, uimm); 2508 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 2509 } else { 2510 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2511 } 2512 break; 2513 #if defined(TARGET_MIPS64) 2514 case OPC_DSLL: 2515 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 2516 break; 2517 case OPC_DSRA: 2518 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2519 break; 2520 case OPC_DSRL: 2521 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2522 break; 2523 case OPC_DROTR: 2524 if (uimm != 0) { 2525 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 2526 } else { 2527 tcg_gen_mov_tl(cpu_gpr[rt], t0); 2528 } 2529 break; 2530 case OPC_DSLL32: 2531 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 2532 break; 2533 case OPC_DSRA32: 2534 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 2535 break; 2536 case OPC_DSRL32: 2537 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 2538 break; 2539 case OPC_DROTR32: 2540 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 2541 break; 2542 #endif 2543 } 2544 } 2545 2546 /* Arithmetic */ 2547 static void gen_arith(DisasContext *ctx, uint32_t opc, 2548 int rd, int rs, int rt) 2549 { 2550 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 2551 && opc != OPC_DADD && opc != OPC_DSUB) { 2552 /* 2553 * If no destination, treat it as a NOP. 2554 * For add & sub, we must generate the overflow exception when needed. 2555 */ 2556 return; 2557 } 2558 2559 switch (opc) { 2560 case OPC_ADD: 2561 { 2562 TCGv t0 = tcg_temp_new(); 2563 TCGv t1 = tcg_temp_new(); 2564 TCGv t2 = tcg_temp_new(); 2565 TCGLabel *l1 = gen_new_label(); 2566 2567 gen_load_gpr(t1, rs); 2568 gen_load_gpr(t2, rt); 2569 tcg_gen_add_tl(t0, t1, t2); 2570 tcg_gen_ext32s_tl(t0, t0); 2571 tcg_gen_xor_tl(t1, t1, t2); 2572 tcg_gen_xor_tl(t2, t0, t2); 2573 tcg_gen_andc_tl(t1, t2, t1); 2574 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2575 /* operands of same sign, result different sign */ 2576 generate_exception(ctx, EXCP_OVERFLOW); 2577 gen_set_label(l1); 2578 gen_store_gpr(t0, rd); 2579 } 2580 break; 2581 case OPC_ADDU: 2582 if (rs != 0 && rt != 0) { 2583 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2584 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2585 } else if (rs == 0 && rt != 0) { 2586 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2587 } else if (rs != 0 && rt == 0) { 2588 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2589 } else { 2590 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2591 } 2592 break; 2593 case OPC_SUB: 2594 { 2595 TCGv t0 = tcg_temp_new(); 2596 TCGv t1 = tcg_temp_new(); 2597 TCGv t2 = tcg_temp_new(); 2598 TCGLabel *l1 = gen_new_label(); 2599 2600 gen_load_gpr(t1, rs); 2601 gen_load_gpr(t2, rt); 2602 tcg_gen_sub_tl(t0, t1, t2); 2603 tcg_gen_ext32s_tl(t0, t0); 2604 tcg_gen_xor_tl(t2, t1, t2); 2605 tcg_gen_xor_tl(t1, t0, t1); 2606 tcg_gen_and_tl(t1, t1, t2); 2607 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2608 /* 2609 * operands of different sign, first operand and the result 2610 * of different sign 2611 */ 2612 generate_exception(ctx, EXCP_OVERFLOW); 2613 gen_set_label(l1); 2614 gen_store_gpr(t0, rd); 2615 } 2616 break; 2617 case OPC_SUBU: 2618 if (rs != 0 && rt != 0) { 2619 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2620 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2621 } else if (rs == 0 && rt != 0) { 2622 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2623 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2624 } else if (rs != 0 && rt == 0) { 2625 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2626 } else { 2627 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2628 } 2629 break; 2630 #if defined(TARGET_MIPS64) 2631 case OPC_DADD: 2632 { 2633 TCGv t0 = tcg_temp_new(); 2634 TCGv t1 = tcg_temp_new(); 2635 TCGv t2 = tcg_temp_new(); 2636 TCGLabel *l1 = gen_new_label(); 2637 2638 gen_load_gpr(t1, rs); 2639 gen_load_gpr(t2, rt); 2640 tcg_gen_add_tl(t0, t1, t2); 2641 tcg_gen_xor_tl(t1, t1, t2); 2642 tcg_gen_xor_tl(t2, t0, t2); 2643 tcg_gen_andc_tl(t1, t2, t1); 2644 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2645 /* operands of same sign, result different sign */ 2646 generate_exception(ctx, EXCP_OVERFLOW); 2647 gen_set_label(l1); 2648 gen_store_gpr(t0, rd); 2649 } 2650 break; 2651 case OPC_DADDU: 2652 if (rs != 0 && rt != 0) { 2653 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2654 } else if (rs == 0 && rt != 0) { 2655 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2656 } else if (rs != 0 && rt == 0) { 2657 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2658 } else { 2659 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2660 } 2661 break; 2662 case OPC_DSUB: 2663 { 2664 TCGv t0 = tcg_temp_new(); 2665 TCGv t1 = tcg_temp_new(); 2666 TCGv t2 = tcg_temp_new(); 2667 TCGLabel *l1 = gen_new_label(); 2668 2669 gen_load_gpr(t1, rs); 2670 gen_load_gpr(t2, rt); 2671 tcg_gen_sub_tl(t0, t1, t2); 2672 tcg_gen_xor_tl(t2, t1, t2); 2673 tcg_gen_xor_tl(t1, t0, t1); 2674 tcg_gen_and_tl(t1, t1, t2); 2675 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2676 /* 2677 * Operands of different sign, first operand and result different 2678 * sign. 2679 */ 2680 generate_exception(ctx, EXCP_OVERFLOW); 2681 gen_set_label(l1); 2682 gen_store_gpr(t0, rd); 2683 } 2684 break; 2685 case OPC_DSUBU: 2686 if (rs != 0 && rt != 0) { 2687 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2688 } else if (rs == 0 && rt != 0) { 2689 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2690 } else if (rs != 0 && rt == 0) { 2691 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2692 } else { 2693 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2694 } 2695 break; 2696 #endif 2697 case OPC_MUL: 2698 if (likely(rs != 0 && rt != 0)) { 2699 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2700 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2701 } else { 2702 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2703 } 2704 break; 2705 } 2706 } 2707 2708 /* Conditional move */ 2709 static void gen_cond_move(DisasContext *ctx, uint32_t opc, 2710 int rd, int rs, int rt) 2711 { 2712 TCGv t0, t1, t2; 2713 2714 if (rd == 0) { 2715 /* If no destination, treat it as a NOP. */ 2716 return; 2717 } 2718 2719 t0 = tcg_temp_new(); 2720 gen_load_gpr(t0, rt); 2721 t1 = tcg_constant_tl(0); 2722 t2 = tcg_temp_new(); 2723 gen_load_gpr(t2, rs); 2724 switch (opc) { 2725 case OPC_MOVN: 2726 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2727 break; 2728 case OPC_MOVZ: 2729 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2730 break; 2731 case OPC_SELNEZ: 2732 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); 2733 break; 2734 case OPC_SELEQZ: 2735 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); 2736 break; 2737 } 2738 } 2739 2740 /* Logic */ 2741 static void gen_logic(DisasContext *ctx, uint32_t opc, 2742 int rd, int rs, int rt) 2743 { 2744 if (rd == 0) { 2745 /* If no destination, treat it as a NOP. */ 2746 return; 2747 } 2748 2749 switch (opc) { 2750 case OPC_AND: 2751 if (likely(rs != 0 && rt != 0)) { 2752 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2753 } else { 2754 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2755 } 2756 break; 2757 case OPC_NOR: 2758 if (rs != 0 && rt != 0) { 2759 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2760 } else if (rs == 0 && rt != 0) { 2761 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 2762 } else if (rs != 0 && rt == 0) { 2763 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 2764 } else { 2765 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 2766 } 2767 break; 2768 case OPC_OR: 2769 if (likely(rs != 0 && rt != 0)) { 2770 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2771 } else if (rs == 0 && rt != 0) { 2772 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2773 } else if (rs != 0 && rt == 0) { 2774 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2775 } else { 2776 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2777 } 2778 break; 2779 case OPC_XOR: 2780 if (likely(rs != 0 && rt != 0)) { 2781 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2782 } else if (rs == 0 && rt != 0) { 2783 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2784 } else if (rs != 0 && rt == 0) { 2785 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2786 } else { 2787 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2788 } 2789 break; 2790 } 2791 } 2792 2793 /* Set on lower than */ 2794 static void gen_slt(DisasContext *ctx, uint32_t opc, 2795 int rd, int rs, int rt) 2796 { 2797 TCGv t0, t1; 2798 2799 if (rd == 0) { 2800 /* If no destination, treat it as a NOP. */ 2801 return; 2802 } 2803 2804 t0 = tcg_temp_new(); 2805 t1 = tcg_temp_new(); 2806 gen_load_gpr(t0, rs); 2807 gen_load_gpr(t1, rt); 2808 switch (opc) { 2809 case OPC_SLT: 2810 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); 2811 break; 2812 case OPC_SLTU: 2813 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); 2814 break; 2815 } 2816 } 2817 2818 /* Shifts */ 2819 static void gen_shift(DisasContext *ctx, uint32_t opc, 2820 int rd, int rs, int rt) 2821 { 2822 TCGv t0, t1; 2823 2824 if (rd == 0) { 2825 /* 2826 * If no destination, treat it as a NOP. 2827 * For add & sub, we must generate the overflow exception when needed. 2828 */ 2829 return; 2830 } 2831 2832 t0 = tcg_temp_new(); 2833 t1 = tcg_temp_new(); 2834 gen_load_gpr(t0, rs); 2835 gen_load_gpr(t1, rt); 2836 switch (opc) { 2837 case OPC_SLLV: 2838 tcg_gen_andi_tl(t0, t0, 0x1f); 2839 tcg_gen_shl_tl(t0, t1, t0); 2840 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2841 break; 2842 case OPC_SRAV: 2843 tcg_gen_andi_tl(t0, t0, 0x1f); 2844 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2845 break; 2846 case OPC_SRLV: 2847 tcg_gen_ext32u_tl(t1, t1); 2848 tcg_gen_andi_tl(t0, t0, 0x1f); 2849 tcg_gen_shr_tl(t0, t1, t0); 2850 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2851 break; 2852 case OPC_ROTRV: 2853 { 2854 TCGv_i32 t2 = tcg_temp_new_i32(); 2855 TCGv_i32 t3 = tcg_temp_new_i32(); 2856 2857 tcg_gen_trunc_tl_i32(t2, t0); 2858 tcg_gen_trunc_tl_i32(t3, t1); 2859 tcg_gen_andi_i32(t2, t2, 0x1f); 2860 tcg_gen_rotr_i32(t2, t3, t2); 2861 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 2862 } 2863 break; 2864 #if defined(TARGET_MIPS64) 2865 case OPC_DSLLV: 2866 tcg_gen_andi_tl(t0, t0, 0x3f); 2867 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 2868 break; 2869 case OPC_DSRAV: 2870 tcg_gen_andi_tl(t0, t0, 0x3f); 2871 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2872 break; 2873 case OPC_DSRLV: 2874 tcg_gen_andi_tl(t0, t0, 0x3f); 2875 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 2876 break; 2877 case OPC_DROTRV: 2878 tcg_gen_andi_tl(t0, t0, 0x3f); 2879 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 2880 break; 2881 #endif 2882 } 2883 } 2884 2885 /* Arithmetic on HI/LO registers */ 2886 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) 2887 { 2888 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 2889 /* Treat as NOP. */ 2890 return; 2891 } 2892 2893 if (acc != 0) { 2894 check_dsp(ctx); 2895 } 2896 2897 switch (opc) { 2898 case OPC_MFHI: 2899 #if defined(TARGET_MIPS64) 2900 if (acc != 0) { 2901 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); 2902 } else 2903 #endif 2904 { 2905 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); 2906 } 2907 break; 2908 case OPC_MFLO: 2909 #if defined(TARGET_MIPS64) 2910 if (acc != 0) { 2911 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); 2912 } else 2913 #endif 2914 { 2915 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); 2916 } 2917 break; 2918 case OPC_MTHI: 2919 if (reg != 0) { 2920 #if defined(TARGET_MIPS64) 2921 if (acc != 0) { 2922 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); 2923 } else 2924 #endif 2925 { 2926 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); 2927 } 2928 } else { 2929 tcg_gen_movi_tl(cpu_HI[acc], 0); 2930 } 2931 break; 2932 case OPC_MTLO: 2933 if (reg != 0) { 2934 #if defined(TARGET_MIPS64) 2935 if (acc != 0) { 2936 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); 2937 } else 2938 #endif 2939 { 2940 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); 2941 } 2942 } else { 2943 tcg_gen_movi_tl(cpu_LO[acc], 0); 2944 } 2945 break; 2946 } 2947 } 2948 2949 static inline void gen_r6_ld(target_long addr, int reg, int memidx, 2950 MemOp memop) 2951 { 2952 TCGv t0 = tcg_temp_new(); 2953 tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop); 2954 gen_store_gpr(t0, reg); 2955 } 2956 2957 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, 2958 int rs) 2959 { 2960 target_long offset; 2961 target_long addr; 2962 2963 switch (MASK_OPC_PCREL_TOP2BITS(opc)) { 2964 case OPC_ADDIUPC: 2965 if (rs != 0) { 2966 offset = sextract32(ctx->opcode << 2, 0, 21); 2967 addr = addr_add(ctx, pc, offset); 2968 tcg_gen_movi_tl(cpu_gpr[rs], addr); 2969 } 2970 break; 2971 case R6_OPC_LWPC: 2972 offset = sextract32(ctx->opcode << 2, 0, 21); 2973 addr = addr_add(ctx, pc, offset); 2974 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_SL); 2975 break; 2976 #if defined(TARGET_MIPS64) 2977 case OPC_LWUPC: 2978 check_mips_64(ctx); 2979 offset = sextract32(ctx->opcode << 2, 0, 21); 2980 addr = addr_add(ctx, pc, offset); 2981 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UL); 2982 break; 2983 #endif 2984 default: 2985 switch (MASK_OPC_PCREL_TOP5BITS(opc)) { 2986 case OPC_AUIPC: 2987 if (rs != 0) { 2988 offset = sextract32(ctx->opcode, 0, 16) << 16; 2989 addr = addr_add(ctx, pc, offset); 2990 tcg_gen_movi_tl(cpu_gpr[rs], addr); 2991 } 2992 break; 2993 case OPC_ALUIPC: 2994 if (rs != 0) { 2995 offset = sextract32(ctx->opcode, 0, 16) << 16; 2996 addr = ~0xFFFF & addr_add(ctx, pc, offset); 2997 tcg_gen_movi_tl(cpu_gpr[rs], addr); 2998 } 2999 break; 3000 #if defined(TARGET_MIPS64) 3001 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */ 3002 case R6_OPC_LDPC + (1 << 16): 3003 case R6_OPC_LDPC + (2 << 16): 3004 case R6_OPC_LDPC + (3 << 16): 3005 check_mips_64(ctx); 3006 offset = sextract32(ctx->opcode << 3, 0, 21); 3007 addr = addr_add(ctx, (pc & ~0x7), offset); 3008 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 3009 break; 3010 #endif 3011 default: 3012 MIPS_INVAL("OPC_PCREL"); 3013 gen_reserved_instruction(ctx); 3014 break; 3015 } 3016 break; 3017 } 3018 } 3019 3020 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) 3021 { 3022 TCGv t0, t1; 3023 3024 if (rd == 0) { 3025 /* Treat as NOP. */ 3026 return; 3027 } 3028 3029 t0 = tcg_temp_new(); 3030 t1 = tcg_temp_new(); 3031 3032 gen_load_gpr(t0, rs); 3033 gen_load_gpr(t1, rt); 3034 3035 switch (opc) { 3036 case R6_OPC_DIV: 3037 { 3038 TCGv t2 = tcg_temp_new(); 3039 TCGv t3 = tcg_temp_new(); 3040 tcg_gen_ext32s_tl(t0, t0); 3041 tcg_gen_ext32s_tl(t1, t1); 3042 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3043 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3044 tcg_gen_and_tl(t2, t2, t3); 3045 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3046 tcg_gen_or_tl(t2, t2, t3); 3047 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3048 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3049 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3050 } 3051 break; 3052 case R6_OPC_MOD: 3053 { 3054 TCGv t2 = tcg_temp_new(); 3055 TCGv t3 = tcg_temp_new(); 3056 tcg_gen_ext32s_tl(t0, t0); 3057 tcg_gen_ext32s_tl(t1, t1); 3058 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3059 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3060 tcg_gen_and_tl(t2, t2, t3); 3061 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3062 tcg_gen_or_tl(t2, t2, t3); 3063 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3064 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3065 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3066 } 3067 break; 3068 case R6_OPC_DIVU: 3069 { 3070 tcg_gen_ext32u_tl(t0, t0); 3071 tcg_gen_ext32u_tl(t1, t1); 3072 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3073 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3074 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3075 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3076 } 3077 break; 3078 case R6_OPC_MODU: 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_remu_tl(cpu_gpr[rd], t0, t1); 3085 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3086 } 3087 break; 3088 case R6_OPC_MUL: 3089 { 3090 TCGv_i32 t2 = tcg_temp_new_i32(); 3091 TCGv_i32 t3 = tcg_temp_new_i32(); 3092 tcg_gen_trunc_tl_i32(t2, t0); 3093 tcg_gen_trunc_tl_i32(t3, t1); 3094 tcg_gen_mul_i32(t2, t2, t3); 3095 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3096 } 3097 break; 3098 case R6_OPC_MUH: 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_muls2_i32(t2, t3, t2, t3); 3105 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3106 } 3107 break; 3108 case R6_OPC_MULU: 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_mul_i32(t2, t2, t3); 3115 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3116 } 3117 break; 3118 case R6_OPC_MUHU: 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_mulu2_i32(t2, t3, t2, t3); 3125 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3126 } 3127 break; 3128 #if defined(TARGET_MIPS64) 3129 case R6_OPC_DDIV: 3130 { 3131 TCGv t2 = tcg_temp_new(); 3132 TCGv t3 = tcg_temp_new(); 3133 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3134 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3135 tcg_gen_and_tl(t2, t2, t3); 3136 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3137 tcg_gen_or_tl(t2, t2, t3); 3138 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3139 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3140 } 3141 break; 3142 case R6_OPC_DMOD: 3143 { 3144 TCGv t2 = tcg_temp_new(); 3145 TCGv t3 = tcg_temp_new(); 3146 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3147 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3148 tcg_gen_and_tl(t2, t2, t3); 3149 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3150 tcg_gen_or_tl(t2, t2, t3); 3151 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3152 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3153 } 3154 break; 3155 case R6_OPC_DDIVU: 3156 { 3157 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3158 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3159 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); 3160 } 3161 break; 3162 case R6_OPC_DMODU: 3163 { 3164 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3165 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3166 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); 3167 } 3168 break; 3169 case R6_OPC_DMUL: 3170 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3171 break; 3172 case R6_OPC_DMUH: 3173 { 3174 TCGv t2 = tcg_temp_new(); 3175 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); 3176 } 3177 break; 3178 case R6_OPC_DMULU: 3179 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3180 break; 3181 case R6_OPC_DMUHU: 3182 { 3183 TCGv t2 = tcg_temp_new(); 3184 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); 3185 } 3186 break; 3187 #endif 3188 default: 3189 MIPS_INVAL("r6 mul/div"); 3190 gen_reserved_instruction(ctx); 3191 break; 3192 } 3193 } 3194 3195 #if defined(TARGET_MIPS64) 3196 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) 3197 { 3198 TCGv t0, t1; 3199 3200 t0 = tcg_temp_new(); 3201 t1 = tcg_temp_new(); 3202 3203 gen_load_gpr(t0, rs); 3204 gen_load_gpr(t1, rt); 3205 3206 switch (opc) { 3207 case MMI_OPC_DIV1: 3208 { 3209 TCGv t2 = tcg_temp_new(); 3210 TCGv t3 = tcg_temp_new(); 3211 tcg_gen_ext32s_tl(t0, t0); 3212 tcg_gen_ext32s_tl(t1, t1); 3213 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3214 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3215 tcg_gen_and_tl(t2, t2, t3); 3216 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3217 tcg_gen_or_tl(t2, t2, t3); 3218 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3219 tcg_gen_div_tl(cpu_LO[1], t0, t1); 3220 tcg_gen_rem_tl(cpu_HI[1], t0, t1); 3221 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3222 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3223 } 3224 break; 3225 case MMI_OPC_DIVU1: 3226 { 3227 TCGv t2 = tcg_constant_tl(0); 3228 TCGv t3 = tcg_constant_tl(1); 3229 tcg_gen_ext32u_tl(t0, t0); 3230 tcg_gen_ext32u_tl(t1, t1); 3231 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3232 tcg_gen_divu_tl(cpu_LO[1], t0, t1); 3233 tcg_gen_remu_tl(cpu_HI[1], t0, t1); 3234 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3235 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3236 } 3237 break; 3238 default: 3239 MIPS_INVAL("div1 TX79"); 3240 gen_reserved_instruction(ctx); 3241 break; 3242 } 3243 } 3244 #endif 3245 3246 static void gen_muldiv(DisasContext *ctx, uint32_t opc, 3247 int acc, int rs, int rt) 3248 { 3249 TCGv t0, t1; 3250 3251 t0 = tcg_temp_new(); 3252 t1 = tcg_temp_new(); 3253 3254 gen_load_gpr(t0, rs); 3255 gen_load_gpr(t1, rt); 3256 3257 if (acc != 0) { 3258 check_dsp(ctx); 3259 } 3260 3261 switch (opc) { 3262 case OPC_DIV: 3263 { 3264 TCGv t2 = tcg_temp_new(); 3265 TCGv t3 = tcg_temp_new(); 3266 tcg_gen_ext32s_tl(t0, t0); 3267 tcg_gen_ext32s_tl(t1, t1); 3268 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3269 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3270 tcg_gen_and_tl(t2, t2, t3); 3271 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3272 tcg_gen_or_tl(t2, t2, t3); 3273 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3274 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3275 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3276 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3277 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3278 } 3279 break; 3280 case OPC_DIVU: 3281 { 3282 TCGv t2 = tcg_constant_tl(0); 3283 TCGv t3 = tcg_constant_tl(1); 3284 tcg_gen_ext32u_tl(t0, t0); 3285 tcg_gen_ext32u_tl(t1, t1); 3286 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3287 tcg_gen_divu_tl(cpu_LO[acc], t0, t1); 3288 tcg_gen_remu_tl(cpu_HI[acc], t0, t1); 3289 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3290 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3291 } 3292 break; 3293 case OPC_MULT: 3294 { 3295 TCGv_i32 t2 = tcg_temp_new_i32(); 3296 TCGv_i32 t3 = tcg_temp_new_i32(); 3297 tcg_gen_trunc_tl_i32(t2, t0); 3298 tcg_gen_trunc_tl_i32(t3, t1); 3299 tcg_gen_muls2_i32(t2, t3, t2, t3); 3300 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3301 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3302 } 3303 break; 3304 case OPC_MULTU: 3305 { 3306 TCGv_i32 t2 = tcg_temp_new_i32(); 3307 TCGv_i32 t3 = tcg_temp_new_i32(); 3308 tcg_gen_trunc_tl_i32(t2, t0); 3309 tcg_gen_trunc_tl_i32(t3, t1); 3310 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3311 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3312 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3313 } 3314 break; 3315 #if defined(TARGET_MIPS64) 3316 case OPC_DDIV: 3317 { 3318 TCGv t2 = tcg_temp_new(); 3319 TCGv t3 = tcg_temp_new(); 3320 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3321 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3322 tcg_gen_and_tl(t2, t2, t3); 3323 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3324 tcg_gen_or_tl(t2, t2, t3); 3325 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1); 3326 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3327 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3328 } 3329 break; 3330 case OPC_DDIVU: 3331 { 3332 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, 3333 tcg_constant_tl(0), tcg_constant_tl(1), t1); 3334 tcg_gen_divu_i64(cpu_LO[acc], t0, t1); 3335 tcg_gen_remu_i64(cpu_HI[acc], t0, t1); 3336 } 3337 break; 3338 case OPC_DMULT: 3339 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3340 break; 3341 case OPC_DMULTU: 3342 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3343 break; 3344 #endif 3345 case OPC_MADD: 3346 { 3347 TCGv_i64 t2 = tcg_temp_new_i64(); 3348 TCGv_i64 t3 = tcg_temp_new_i64(); 3349 3350 tcg_gen_ext_tl_i64(t2, t0); 3351 tcg_gen_ext_tl_i64(t3, t1); 3352 tcg_gen_mul_i64(t2, t2, t3); 3353 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3354 tcg_gen_add_i64(t2, t2, t3); 3355 gen_move_low32(cpu_LO[acc], t2); 3356 gen_move_high32(cpu_HI[acc], t2); 3357 } 3358 break; 3359 case OPC_MADDU: 3360 { 3361 TCGv_i64 t2 = tcg_temp_new_i64(); 3362 TCGv_i64 t3 = tcg_temp_new_i64(); 3363 3364 tcg_gen_ext32u_tl(t0, t0); 3365 tcg_gen_ext32u_tl(t1, t1); 3366 tcg_gen_extu_tl_i64(t2, t0); 3367 tcg_gen_extu_tl_i64(t3, t1); 3368 tcg_gen_mul_i64(t2, t2, t3); 3369 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3370 tcg_gen_add_i64(t2, t2, t3); 3371 gen_move_low32(cpu_LO[acc], t2); 3372 gen_move_high32(cpu_HI[acc], t2); 3373 } 3374 break; 3375 case OPC_MSUB: 3376 { 3377 TCGv_i64 t2 = tcg_temp_new_i64(); 3378 TCGv_i64 t3 = tcg_temp_new_i64(); 3379 3380 tcg_gen_ext_tl_i64(t2, t0); 3381 tcg_gen_ext_tl_i64(t3, t1); 3382 tcg_gen_mul_i64(t2, t2, t3); 3383 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3384 tcg_gen_sub_i64(t2, t3, t2); 3385 gen_move_low32(cpu_LO[acc], t2); 3386 gen_move_high32(cpu_HI[acc], t2); 3387 } 3388 break; 3389 case OPC_MSUBU: 3390 { 3391 TCGv_i64 t2 = tcg_temp_new_i64(); 3392 TCGv_i64 t3 = tcg_temp_new_i64(); 3393 3394 tcg_gen_ext32u_tl(t0, t0); 3395 tcg_gen_ext32u_tl(t1, t1); 3396 tcg_gen_extu_tl_i64(t2, t0); 3397 tcg_gen_extu_tl_i64(t3, t1); 3398 tcg_gen_mul_i64(t2, t2, t3); 3399 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3400 tcg_gen_sub_i64(t2, t3, t2); 3401 gen_move_low32(cpu_LO[acc], t2); 3402 gen_move_high32(cpu_HI[acc], t2); 3403 } 3404 break; 3405 default: 3406 MIPS_INVAL("mul/div"); 3407 gen_reserved_instruction(ctx); 3408 break; 3409 } 3410 } 3411 3412 /* 3413 * These MULT[U] and MADD[U] instructions implemented in for example 3414 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core 3415 * architectures are special three-operand variants with the syntax 3416 * 3417 * MULT[U][1] rd, rs, rt 3418 * 3419 * such that 3420 * 3421 * (rd, LO, HI) <- rs * rt 3422 * 3423 * and 3424 * 3425 * MADD[U][1] rd, rs, rt 3426 * 3427 * such that 3428 * 3429 * (rd, LO, HI) <- (LO, HI) + rs * rt 3430 * 3431 * where the low-order 32-bits of the result is placed into both the 3432 * GPR rd and the special register LO. The high-order 32-bits of the 3433 * result is placed into the special register HI. 3434 * 3435 * If the GPR rd is omitted in assembly language, it is taken to be 0, 3436 * which is the zero register that always reads as 0. 3437 */ 3438 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, 3439 int rd, int rs, int rt) 3440 { 3441 TCGv t0 = tcg_temp_new(); 3442 TCGv t1 = tcg_temp_new(); 3443 int acc = 0; 3444 3445 gen_load_gpr(t0, rs); 3446 gen_load_gpr(t1, rt); 3447 3448 switch (opc) { 3449 case MMI_OPC_MULT1: 3450 acc = 1; 3451 /* Fall through */ 3452 case OPC_MULT: 3453 { 3454 TCGv_i32 t2 = tcg_temp_new_i32(); 3455 TCGv_i32 t3 = tcg_temp_new_i32(); 3456 tcg_gen_trunc_tl_i32(t2, t0); 3457 tcg_gen_trunc_tl_i32(t3, t1); 3458 tcg_gen_muls2_i32(t2, t3, t2, t3); 3459 if (rd) { 3460 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3461 } 3462 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3463 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3464 } 3465 break; 3466 case MMI_OPC_MULTU1: 3467 acc = 1; 3468 /* Fall through */ 3469 case OPC_MULTU: 3470 { 3471 TCGv_i32 t2 = tcg_temp_new_i32(); 3472 TCGv_i32 t3 = tcg_temp_new_i32(); 3473 tcg_gen_trunc_tl_i32(t2, t0); 3474 tcg_gen_trunc_tl_i32(t3, t1); 3475 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3476 if (rd) { 3477 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3478 } 3479 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3480 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3481 } 3482 break; 3483 case MMI_OPC_MADD1: 3484 acc = 1; 3485 /* Fall through */ 3486 case MMI_OPC_MADD: 3487 { 3488 TCGv_i64 t2 = tcg_temp_new_i64(); 3489 TCGv_i64 t3 = tcg_temp_new_i64(); 3490 3491 tcg_gen_ext_tl_i64(t2, t0); 3492 tcg_gen_ext_tl_i64(t3, t1); 3493 tcg_gen_mul_i64(t2, t2, t3); 3494 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3495 tcg_gen_add_i64(t2, t2, t3); 3496 gen_move_low32(cpu_LO[acc], t2); 3497 gen_move_high32(cpu_HI[acc], t2); 3498 if (rd) { 3499 gen_move_low32(cpu_gpr[rd], t2); 3500 } 3501 } 3502 break; 3503 case MMI_OPC_MADDU1: 3504 acc = 1; 3505 /* Fall through */ 3506 case MMI_OPC_MADDU: 3507 { 3508 TCGv_i64 t2 = tcg_temp_new_i64(); 3509 TCGv_i64 t3 = tcg_temp_new_i64(); 3510 3511 tcg_gen_ext32u_tl(t0, t0); 3512 tcg_gen_ext32u_tl(t1, t1); 3513 tcg_gen_extu_tl_i64(t2, t0); 3514 tcg_gen_extu_tl_i64(t3, t1); 3515 tcg_gen_mul_i64(t2, t2, t3); 3516 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3517 tcg_gen_add_i64(t2, t2, t3); 3518 gen_move_low32(cpu_LO[acc], t2); 3519 gen_move_high32(cpu_HI[acc], t2); 3520 if (rd) { 3521 gen_move_low32(cpu_gpr[rd], t2); 3522 } 3523 } 3524 break; 3525 default: 3526 MIPS_INVAL("mul/madd TXx9"); 3527 gen_reserved_instruction(ctx); 3528 break; 3529 } 3530 } 3531 3532 static void gen_cl(DisasContext *ctx, uint32_t opc, 3533 int rd, int rs) 3534 { 3535 TCGv t0; 3536 3537 if (rd == 0) { 3538 /* Treat as NOP. */ 3539 return; 3540 } 3541 t0 = cpu_gpr[rd]; 3542 gen_load_gpr(t0, rs); 3543 3544 switch (opc) { 3545 case OPC_CLO: 3546 case R6_OPC_CLO: 3547 #if defined(TARGET_MIPS64) 3548 case OPC_DCLO: 3549 case R6_OPC_DCLO: 3550 #endif 3551 tcg_gen_not_tl(t0, t0); 3552 break; 3553 } 3554 3555 switch (opc) { 3556 case OPC_CLO: 3557 case R6_OPC_CLO: 3558 case OPC_CLZ: 3559 case R6_OPC_CLZ: 3560 tcg_gen_ext32u_tl(t0, t0); 3561 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); 3562 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); 3563 break; 3564 #if defined(TARGET_MIPS64) 3565 case OPC_DCLO: 3566 case R6_OPC_DCLO: 3567 case OPC_DCLZ: 3568 case R6_OPC_DCLZ: 3569 tcg_gen_clzi_i64(t0, t0, 64); 3570 break; 3571 #endif 3572 } 3573 } 3574 3575 /* Godson integer instructions */ 3576 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc, 3577 int rd, int rs, int rt) 3578 { 3579 TCGv t0, t1; 3580 3581 if (rd == 0) { 3582 /* Treat as NOP. */ 3583 return; 3584 } 3585 3586 t0 = tcg_temp_new(); 3587 t1 = tcg_temp_new(); 3588 gen_load_gpr(t0, rs); 3589 gen_load_gpr(t1, rt); 3590 3591 switch (opc) { 3592 case OPC_MULT_G_2E: 3593 case OPC_MULT_G_2F: 3594 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3595 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3596 break; 3597 case OPC_MULTU_G_2E: 3598 case OPC_MULTU_G_2F: 3599 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3600 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3601 break; 3602 #if defined(TARGET_MIPS64) 3603 case OPC_DMULT_G_2E: 3604 case OPC_DMULT_G_2F: 3605 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3606 break; 3607 case OPC_DMULTU_G_2E: 3608 case OPC_DMULTU_G_2F: 3609 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3610 break; 3611 #endif 3612 } 3613 } 3614 3615 /* Loongson multimedia instructions */ 3616 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) 3617 { 3618 uint32_t opc, shift_max; 3619 TCGv_i64 t0, t1; 3620 TCGCond cond; 3621 3622 opc = MASK_LMMI(ctx->opcode); 3623 check_cp1_enabled(ctx); 3624 3625 t0 = tcg_temp_new_i64(); 3626 t1 = tcg_temp_new_i64(); 3627 gen_load_fpr64(ctx, t0, rs); 3628 gen_load_fpr64(ctx, t1, rt); 3629 3630 switch (opc) { 3631 case OPC_PADDSH: 3632 gen_helper_paddsh(t0, t0, t1); 3633 break; 3634 case OPC_PADDUSH: 3635 gen_helper_paddush(t0, t0, t1); 3636 break; 3637 case OPC_PADDH: 3638 gen_helper_paddh(t0, t0, t1); 3639 break; 3640 case OPC_PADDW: 3641 gen_helper_paddw(t0, t0, t1); 3642 break; 3643 case OPC_PADDSB: 3644 gen_helper_paddsb(t0, t0, t1); 3645 break; 3646 case OPC_PADDUSB: 3647 gen_helper_paddusb(t0, t0, t1); 3648 break; 3649 case OPC_PADDB: 3650 gen_helper_paddb(t0, t0, t1); 3651 break; 3652 3653 case OPC_PSUBSH: 3654 gen_helper_psubsh(t0, t0, t1); 3655 break; 3656 case OPC_PSUBUSH: 3657 gen_helper_psubush(t0, t0, t1); 3658 break; 3659 case OPC_PSUBH: 3660 gen_helper_psubh(t0, t0, t1); 3661 break; 3662 case OPC_PSUBW: 3663 gen_helper_psubw(t0, t0, t1); 3664 break; 3665 case OPC_PSUBSB: 3666 gen_helper_psubsb(t0, t0, t1); 3667 break; 3668 case OPC_PSUBUSB: 3669 gen_helper_psubusb(t0, t0, t1); 3670 break; 3671 case OPC_PSUBB: 3672 gen_helper_psubb(t0, t0, t1); 3673 break; 3674 3675 case OPC_PSHUFH: 3676 gen_helper_pshufh(t0, t0, t1); 3677 break; 3678 case OPC_PACKSSWH: 3679 gen_helper_packsswh(t0, t0, t1); 3680 break; 3681 case OPC_PACKSSHB: 3682 gen_helper_packsshb(t0, t0, t1); 3683 break; 3684 case OPC_PACKUSHB: 3685 gen_helper_packushb(t0, t0, t1); 3686 break; 3687 3688 case OPC_PUNPCKLHW: 3689 gen_helper_punpcklhw(t0, t0, t1); 3690 break; 3691 case OPC_PUNPCKHHW: 3692 gen_helper_punpckhhw(t0, t0, t1); 3693 break; 3694 case OPC_PUNPCKLBH: 3695 gen_helper_punpcklbh(t0, t0, t1); 3696 break; 3697 case OPC_PUNPCKHBH: 3698 gen_helper_punpckhbh(t0, t0, t1); 3699 break; 3700 case OPC_PUNPCKLWD: 3701 gen_helper_punpcklwd(t0, t0, t1); 3702 break; 3703 case OPC_PUNPCKHWD: 3704 gen_helper_punpckhwd(t0, t0, t1); 3705 break; 3706 3707 case OPC_PAVGH: 3708 gen_helper_pavgh(t0, t0, t1); 3709 break; 3710 case OPC_PAVGB: 3711 gen_helper_pavgb(t0, t0, t1); 3712 break; 3713 case OPC_PMAXSH: 3714 gen_helper_pmaxsh(t0, t0, t1); 3715 break; 3716 case OPC_PMINSH: 3717 gen_helper_pminsh(t0, t0, t1); 3718 break; 3719 case OPC_PMAXUB: 3720 gen_helper_pmaxub(t0, t0, t1); 3721 break; 3722 case OPC_PMINUB: 3723 gen_helper_pminub(t0, t0, t1); 3724 break; 3725 3726 case OPC_PCMPEQW: 3727 gen_helper_pcmpeqw(t0, t0, t1); 3728 break; 3729 case OPC_PCMPGTW: 3730 gen_helper_pcmpgtw(t0, t0, t1); 3731 break; 3732 case OPC_PCMPEQH: 3733 gen_helper_pcmpeqh(t0, t0, t1); 3734 break; 3735 case OPC_PCMPGTH: 3736 gen_helper_pcmpgth(t0, t0, t1); 3737 break; 3738 case OPC_PCMPEQB: 3739 gen_helper_pcmpeqb(t0, t0, t1); 3740 break; 3741 case OPC_PCMPGTB: 3742 gen_helper_pcmpgtb(t0, t0, t1); 3743 break; 3744 3745 case OPC_PSLLW: 3746 gen_helper_psllw(t0, t0, t1); 3747 break; 3748 case OPC_PSLLH: 3749 gen_helper_psllh(t0, t0, t1); 3750 break; 3751 case OPC_PSRLW: 3752 gen_helper_psrlw(t0, t0, t1); 3753 break; 3754 case OPC_PSRLH: 3755 gen_helper_psrlh(t0, t0, t1); 3756 break; 3757 case OPC_PSRAW: 3758 gen_helper_psraw(t0, t0, t1); 3759 break; 3760 case OPC_PSRAH: 3761 gen_helper_psrah(t0, t0, t1); 3762 break; 3763 3764 case OPC_PMULLH: 3765 gen_helper_pmullh(t0, t0, t1); 3766 break; 3767 case OPC_PMULHH: 3768 gen_helper_pmulhh(t0, t0, t1); 3769 break; 3770 case OPC_PMULHUH: 3771 gen_helper_pmulhuh(t0, t0, t1); 3772 break; 3773 case OPC_PMADDHW: 3774 gen_helper_pmaddhw(t0, t0, t1); 3775 break; 3776 3777 case OPC_PASUBUB: 3778 gen_helper_pasubub(t0, t0, t1); 3779 break; 3780 case OPC_BIADD: 3781 gen_helper_biadd(t0, t0); 3782 break; 3783 case OPC_PMOVMSKB: 3784 gen_helper_pmovmskb(t0, t0); 3785 break; 3786 3787 case OPC_PADDD: 3788 tcg_gen_add_i64(t0, t0, t1); 3789 break; 3790 case OPC_PSUBD: 3791 tcg_gen_sub_i64(t0, t0, t1); 3792 break; 3793 case OPC_XOR_CP2: 3794 tcg_gen_xor_i64(t0, t0, t1); 3795 break; 3796 case OPC_NOR_CP2: 3797 tcg_gen_nor_i64(t0, t0, t1); 3798 break; 3799 case OPC_AND_CP2: 3800 tcg_gen_and_i64(t0, t0, t1); 3801 break; 3802 case OPC_OR_CP2: 3803 tcg_gen_or_i64(t0, t0, t1); 3804 break; 3805 3806 case OPC_PANDN: 3807 tcg_gen_andc_i64(t0, t1, t0); 3808 break; 3809 3810 case OPC_PINSRH_0: 3811 tcg_gen_deposit_i64(t0, t0, t1, 0, 16); 3812 break; 3813 case OPC_PINSRH_1: 3814 tcg_gen_deposit_i64(t0, t0, t1, 16, 16); 3815 break; 3816 case OPC_PINSRH_2: 3817 tcg_gen_deposit_i64(t0, t0, t1, 32, 16); 3818 break; 3819 case OPC_PINSRH_3: 3820 tcg_gen_deposit_i64(t0, t0, t1, 48, 16); 3821 break; 3822 3823 case OPC_PEXTRH: 3824 tcg_gen_andi_i64(t1, t1, 3); 3825 tcg_gen_shli_i64(t1, t1, 4); 3826 tcg_gen_shr_i64(t0, t0, t1); 3827 tcg_gen_ext16u_i64(t0, t0); 3828 break; 3829 3830 case OPC_ADDU_CP2: 3831 tcg_gen_add_i64(t0, t0, t1); 3832 tcg_gen_ext32s_i64(t0, t0); 3833 break; 3834 case OPC_SUBU_CP2: 3835 tcg_gen_sub_i64(t0, t0, t1); 3836 tcg_gen_ext32s_i64(t0, t0); 3837 break; 3838 3839 case OPC_SLL_CP2: 3840 shift_max = 32; 3841 goto do_shift; 3842 case OPC_SRL_CP2: 3843 shift_max = 32; 3844 goto do_shift; 3845 case OPC_SRA_CP2: 3846 shift_max = 32; 3847 goto do_shift; 3848 case OPC_DSLL_CP2: 3849 shift_max = 64; 3850 goto do_shift; 3851 case OPC_DSRL_CP2: 3852 shift_max = 64; 3853 goto do_shift; 3854 case OPC_DSRA_CP2: 3855 shift_max = 64; 3856 goto do_shift; 3857 do_shift: 3858 /* Make sure shift count isn't TCG undefined behaviour. */ 3859 tcg_gen_andi_i64(t1, t1, shift_max - 1); 3860 3861 switch (opc) { 3862 case OPC_SLL_CP2: 3863 case OPC_DSLL_CP2: 3864 tcg_gen_shl_i64(t0, t0, t1); 3865 break; 3866 case OPC_SRA_CP2: 3867 case OPC_DSRA_CP2: 3868 /* 3869 * Since SRA is UndefinedResult without sign-extended inputs, 3870 * we can treat SRA and DSRA the same. 3871 */ 3872 tcg_gen_sar_i64(t0, t0, t1); 3873 break; 3874 case OPC_SRL_CP2: 3875 /* We want to shift in zeros for SRL; zero-extend first. */ 3876 tcg_gen_ext32u_i64(t0, t0); 3877 /* FALLTHRU */ 3878 case OPC_DSRL_CP2: 3879 tcg_gen_shr_i64(t0, t0, t1); 3880 break; 3881 } 3882 3883 if (shift_max == 32) { 3884 tcg_gen_ext32s_i64(t0, t0); 3885 } 3886 3887 /* Shifts larger than MAX produce zero. */ 3888 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); 3889 tcg_gen_neg_i64(t1, t1); 3890 tcg_gen_and_i64(t0, t0, t1); 3891 break; 3892 3893 case OPC_ADD_CP2: 3894 case OPC_DADD_CP2: 3895 { 3896 TCGv_i64 t2 = tcg_temp_new_i64(); 3897 TCGLabel *lab = gen_new_label(); 3898 3899 tcg_gen_mov_i64(t2, t0); 3900 tcg_gen_add_i64(t0, t1, t2); 3901 if (opc == OPC_ADD_CP2) { 3902 tcg_gen_ext32s_i64(t0, t0); 3903 } 3904 tcg_gen_xor_i64(t1, t1, t2); 3905 tcg_gen_xor_i64(t2, t2, t0); 3906 tcg_gen_andc_i64(t1, t2, t1); 3907 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 3908 generate_exception(ctx, EXCP_OVERFLOW); 3909 gen_set_label(lab); 3910 break; 3911 } 3912 3913 case OPC_SUB_CP2: 3914 case OPC_DSUB_CP2: 3915 { 3916 TCGv_i64 t2 = tcg_temp_new_i64(); 3917 TCGLabel *lab = gen_new_label(); 3918 3919 tcg_gen_mov_i64(t2, t0); 3920 tcg_gen_sub_i64(t0, t1, t2); 3921 if (opc == OPC_SUB_CP2) { 3922 tcg_gen_ext32s_i64(t0, t0); 3923 } 3924 tcg_gen_xor_i64(t1, t1, t2); 3925 tcg_gen_xor_i64(t2, t2, t0); 3926 tcg_gen_and_i64(t1, t1, t2); 3927 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 3928 generate_exception(ctx, EXCP_OVERFLOW); 3929 gen_set_label(lab); 3930 break; 3931 } 3932 3933 case OPC_PMULUW: 3934 tcg_gen_ext32u_i64(t0, t0); 3935 tcg_gen_ext32u_i64(t1, t1); 3936 tcg_gen_mul_i64(t0, t0, t1); 3937 break; 3938 3939 case OPC_SEQU_CP2: 3940 case OPC_SEQ_CP2: 3941 cond = TCG_COND_EQ; 3942 goto do_cc_cond; 3943 break; 3944 case OPC_SLTU_CP2: 3945 cond = TCG_COND_LTU; 3946 goto do_cc_cond; 3947 break; 3948 case OPC_SLT_CP2: 3949 cond = TCG_COND_LT; 3950 goto do_cc_cond; 3951 break; 3952 case OPC_SLEU_CP2: 3953 cond = TCG_COND_LEU; 3954 goto do_cc_cond; 3955 break; 3956 case OPC_SLE_CP2: 3957 cond = TCG_COND_LE; 3958 do_cc_cond: 3959 { 3960 int cc = (ctx->opcode >> 8) & 0x7; 3961 TCGv_i64 t64 = tcg_temp_new_i64(); 3962 TCGv_i32 t32 = tcg_temp_new_i32(); 3963 3964 tcg_gen_setcond_i64(cond, t64, t0, t1); 3965 tcg_gen_extrl_i64_i32(t32, t64); 3966 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, 3967 get_fp_bit(cc), 1); 3968 } 3969 return; 3970 default: 3971 MIPS_INVAL("loongson_cp2"); 3972 gen_reserved_instruction(ctx); 3973 return; 3974 } 3975 3976 gen_store_fpr64(ctx, t0, rd); 3977 } 3978 3979 static void gen_loongson_lswc2(DisasContext *ctx, int rt, 3980 int rs, int rd) 3981 { 3982 TCGv t0, t1; 3983 TCGv_i32 fp0; 3984 #if defined(TARGET_MIPS64) 3985 int lsq_rt1 = ctx->opcode & 0x1f; 3986 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4; 3987 #endif 3988 int shf_offset = sextract32(ctx->opcode, 6, 8); 3989 3990 t0 = tcg_temp_new(); 3991 3992 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { 3993 #if defined(TARGET_MIPS64) 3994 case OPC_GSLQ: 3995 t1 = tcg_temp_new(); 3996 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 3997 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 3998 ctx->default_tcg_memop_mask); 3999 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4000 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4001 ctx->default_tcg_memop_mask); 4002 gen_store_gpr(t1, rt); 4003 gen_store_gpr(t0, lsq_rt1); 4004 break; 4005 case OPC_GSLQC1: 4006 check_cp1_enabled(ctx); 4007 t1 = tcg_temp_new(); 4008 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4009 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4010 ctx->default_tcg_memop_mask); 4011 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4012 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4013 ctx->default_tcg_memop_mask); 4014 gen_store_fpr64(ctx, t1, rt); 4015 gen_store_fpr64(ctx, t0, lsq_rt1); 4016 break; 4017 case OPC_GSSQ: 4018 t1 = tcg_temp_new(); 4019 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4020 gen_load_gpr(t1, rt); 4021 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4022 ctx->default_tcg_memop_mask); 4023 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4024 gen_load_gpr(t1, lsq_rt1); 4025 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4026 ctx->default_tcg_memop_mask); 4027 break; 4028 case OPC_GSSQC1: 4029 check_cp1_enabled(ctx); 4030 t1 = tcg_temp_new(); 4031 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4032 gen_load_fpr64(ctx, t1, rt); 4033 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4034 ctx->default_tcg_memop_mask); 4035 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4036 gen_load_fpr64(ctx, t1, lsq_rt1); 4037 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4038 ctx->default_tcg_memop_mask); 4039 break; 4040 #endif 4041 case OPC_GSSHFL: 4042 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4043 case OPC_GSLWLC1: 4044 check_cp1_enabled(ctx); 4045 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4046 fp0 = tcg_temp_new_i32(); 4047 gen_load_fpr32(ctx, fp0, rt); 4048 t1 = tcg_temp_new(); 4049 tcg_gen_ext_i32_tl(t1, fp0); 4050 gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 4051 tcg_gen_trunc_tl_i32(fp0, t1); 4052 gen_store_fpr32(ctx, fp0, rt); 4053 break; 4054 case OPC_GSLWRC1: 4055 check_cp1_enabled(ctx); 4056 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4057 fp0 = tcg_temp_new_i32(); 4058 gen_load_fpr32(ctx, fp0, rt); 4059 t1 = tcg_temp_new(); 4060 tcg_gen_ext_i32_tl(t1, fp0); 4061 gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 4062 tcg_gen_trunc_tl_i32(fp0, t1); 4063 gen_store_fpr32(ctx, fp0, rt); 4064 break; 4065 #if defined(TARGET_MIPS64) 4066 case OPC_GSLDLC1: 4067 check_cp1_enabled(ctx); 4068 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4069 t1 = tcg_temp_new(); 4070 gen_load_fpr64(ctx, t1, rt); 4071 gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 4072 gen_store_fpr64(ctx, t1, rt); 4073 break; 4074 case OPC_GSLDRC1: 4075 check_cp1_enabled(ctx); 4076 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4077 t1 = tcg_temp_new(); 4078 gen_load_fpr64(ctx, t1, rt); 4079 gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 4080 gen_store_fpr64(ctx, t1, rt); 4081 break; 4082 #endif 4083 default: 4084 MIPS_INVAL("loongson_gsshfl"); 4085 gen_reserved_instruction(ctx); 4086 break; 4087 } 4088 break; 4089 case OPC_GSSHFS: 4090 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4091 case OPC_GSSWLC1: 4092 check_cp1_enabled(ctx); 4093 t1 = tcg_temp_new(); 4094 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4095 fp0 = tcg_temp_new_i32(); 4096 gen_load_fpr32(ctx, fp0, rt); 4097 tcg_gen_ext_i32_tl(t1, fp0); 4098 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); 4099 break; 4100 case OPC_GSSWRC1: 4101 check_cp1_enabled(ctx); 4102 t1 = tcg_temp_new(); 4103 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4104 fp0 = tcg_temp_new_i32(); 4105 gen_load_fpr32(ctx, fp0, rt); 4106 tcg_gen_ext_i32_tl(t1, fp0); 4107 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); 4108 break; 4109 #if defined(TARGET_MIPS64) 4110 case OPC_GSSDLC1: 4111 check_cp1_enabled(ctx); 4112 t1 = tcg_temp_new(); 4113 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4114 gen_load_fpr64(ctx, t1, rt); 4115 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); 4116 break; 4117 case OPC_GSSDRC1: 4118 check_cp1_enabled(ctx); 4119 t1 = tcg_temp_new(); 4120 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4121 gen_load_fpr64(ctx, t1, rt); 4122 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); 4123 break; 4124 #endif 4125 default: 4126 MIPS_INVAL("loongson_gsshfs"); 4127 gen_reserved_instruction(ctx); 4128 break; 4129 } 4130 break; 4131 default: 4132 MIPS_INVAL("loongson_gslsq"); 4133 gen_reserved_instruction(ctx); 4134 break; 4135 } 4136 } 4137 4138 /* Loongson EXT LDC2/SDC2 */ 4139 static void gen_loongson_lsdc2(DisasContext *ctx, int rt, 4140 int rs, int rd) 4141 { 4142 int offset = sextract32(ctx->opcode, 3, 8); 4143 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode); 4144 TCGv t0, t1; 4145 TCGv_i32 fp0; 4146 4147 /* Pre-conditions */ 4148 switch (opc) { 4149 case OPC_GSLBX: 4150 case OPC_GSLHX: 4151 case OPC_GSLWX: 4152 case OPC_GSLDX: 4153 /* prefetch, implement as NOP */ 4154 if (rt == 0) { 4155 return; 4156 } 4157 break; 4158 case OPC_GSSBX: 4159 case OPC_GSSHX: 4160 case OPC_GSSWX: 4161 case OPC_GSSDX: 4162 break; 4163 case OPC_GSLWXC1: 4164 #if defined(TARGET_MIPS64) 4165 case OPC_GSLDXC1: 4166 #endif 4167 check_cp1_enabled(ctx); 4168 /* prefetch, implement as NOP */ 4169 if (rt == 0) { 4170 return; 4171 } 4172 break; 4173 case OPC_GSSWXC1: 4174 #if defined(TARGET_MIPS64) 4175 case OPC_GSSDXC1: 4176 #endif 4177 check_cp1_enabled(ctx); 4178 break; 4179 default: 4180 MIPS_INVAL("loongson_lsdc2"); 4181 gen_reserved_instruction(ctx); 4182 return; 4183 break; 4184 } 4185 4186 t0 = tcg_temp_new(); 4187 4188 gen_base_offset_addr(ctx, t0, rs, offset); 4189 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4190 4191 switch (opc) { 4192 case OPC_GSLBX: 4193 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); 4194 gen_store_gpr(t0, rt); 4195 break; 4196 case OPC_GSLHX: 4197 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW | 4198 ctx->default_tcg_memop_mask); 4199 gen_store_gpr(t0, rt); 4200 break; 4201 case OPC_GSLWX: 4202 gen_base_offset_addr(ctx, t0, rs, offset); 4203 if (rd) { 4204 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4205 } 4206 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 4207 ctx->default_tcg_memop_mask); 4208 gen_store_gpr(t0, rt); 4209 break; 4210 #if defined(TARGET_MIPS64) 4211 case OPC_GSLDX: 4212 gen_base_offset_addr(ctx, t0, rs, offset); 4213 if (rd) { 4214 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4215 } 4216 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4217 ctx->default_tcg_memop_mask); 4218 gen_store_gpr(t0, rt); 4219 break; 4220 #endif 4221 case OPC_GSLWXC1: 4222 gen_base_offset_addr(ctx, t0, rs, offset); 4223 if (rd) { 4224 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4225 } 4226 fp0 = tcg_temp_new_i32(); 4227 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL | 4228 ctx->default_tcg_memop_mask); 4229 gen_store_fpr32(ctx, fp0, rt); 4230 break; 4231 #if defined(TARGET_MIPS64) 4232 case OPC_GSLDXC1: 4233 gen_base_offset_addr(ctx, t0, rs, offset); 4234 if (rd) { 4235 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4236 } 4237 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4238 ctx->default_tcg_memop_mask); 4239 gen_store_fpr64(ctx, t0, rt); 4240 break; 4241 #endif 4242 case OPC_GSSBX: 4243 t1 = tcg_temp_new(); 4244 gen_load_gpr(t1, rt); 4245 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); 4246 break; 4247 case OPC_GSSHX: 4248 t1 = tcg_temp_new(); 4249 gen_load_gpr(t1, rt); 4250 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UW | 4251 ctx->default_tcg_memop_mask); 4252 break; 4253 case OPC_GSSWX: 4254 t1 = tcg_temp_new(); 4255 gen_load_gpr(t1, rt); 4256 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 4257 ctx->default_tcg_memop_mask); 4258 break; 4259 #if defined(TARGET_MIPS64) 4260 case OPC_GSSDX: 4261 t1 = tcg_temp_new(); 4262 gen_load_gpr(t1, rt); 4263 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4264 ctx->default_tcg_memop_mask); 4265 break; 4266 #endif 4267 case OPC_GSSWXC1: 4268 fp0 = tcg_temp_new_i32(); 4269 gen_load_fpr32(ctx, fp0, rt); 4270 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL | 4271 ctx->default_tcg_memop_mask); 4272 break; 4273 #if defined(TARGET_MIPS64) 4274 case OPC_GSSDXC1: 4275 t1 = tcg_temp_new(); 4276 gen_load_fpr64(ctx, t1, rt); 4277 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ | 4278 ctx->default_tcg_memop_mask); 4279 break; 4280 #endif 4281 default: 4282 break; 4283 } 4284 } 4285 4286 /* Traps */ 4287 static void gen_trap(DisasContext *ctx, uint32_t opc, 4288 int rs, int rt, int16_t imm, int code) 4289 { 4290 int cond; 4291 TCGv t0 = tcg_temp_new(); 4292 TCGv t1 = tcg_temp_new(); 4293 4294 cond = 0; 4295 /* Load needed operands */ 4296 switch (opc) { 4297 case OPC_TEQ: 4298 case OPC_TGE: 4299 case OPC_TGEU: 4300 case OPC_TLT: 4301 case OPC_TLTU: 4302 case OPC_TNE: 4303 /* Compare two registers */ 4304 if (rs != rt) { 4305 gen_load_gpr(t0, rs); 4306 gen_load_gpr(t1, rt); 4307 cond = 1; 4308 } 4309 break; 4310 case OPC_TEQI: 4311 case OPC_TGEI: 4312 case OPC_TGEIU: 4313 case OPC_TLTI: 4314 case OPC_TLTIU: 4315 case OPC_TNEI: 4316 /* Compare register to immediate */ 4317 if (rs != 0 || imm != 0) { 4318 gen_load_gpr(t0, rs); 4319 tcg_gen_movi_tl(t1, (int32_t)imm); 4320 cond = 1; 4321 } 4322 break; 4323 } 4324 if (cond == 0) { 4325 switch (opc) { 4326 case OPC_TEQ: /* rs == rs */ 4327 case OPC_TEQI: /* r0 == 0 */ 4328 case OPC_TGE: /* rs >= rs */ 4329 case OPC_TGEI: /* r0 >= 0 */ 4330 case OPC_TGEU: /* rs >= rs unsigned */ 4331 case OPC_TGEIU: /* r0 >= 0 unsigned */ 4332 /* Always trap */ 4333 #ifdef CONFIG_USER_ONLY 4334 /* Pass the break code along to cpu_loop. */ 4335 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 4336 offsetof(CPUMIPSState, error_code)); 4337 #endif 4338 generate_exception_end(ctx, EXCP_TRAP); 4339 break; 4340 case OPC_TLT: /* rs < rs */ 4341 case OPC_TLTI: /* r0 < 0 */ 4342 case OPC_TLTU: /* rs < rs unsigned */ 4343 case OPC_TLTIU: /* r0 < 0 unsigned */ 4344 case OPC_TNE: /* rs != rs */ 4345 case OPC_TNEI: /* r0 != 0 */ 4346 /* Never trap: treat as NOP. */ 4347 break; 4348 } 4349 } else { 4350 TCGLabel *l1 = gen_new_label(); 4351 4352 switch (opc) { 4353 case OPC_TEQ: 4354 case OPC_TEQI: 4355 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 4356 break; 4357 case OPC_TGE: 4358 case OPC_TGEI: 4359 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 4360 break; 4361 case OPC_TGEU: 4362 case OPC_TGEIU: 4363 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 4364 break; 4365 case OPC_TLT: 4366 case OPC_TLTI: 4367 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 4368 break; 4369 case OPC_TLTU: 4370 case OPC_TLTIU: 4371 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 4372 break; 4373 case OPC_TNE: 4374 case OPC_TNEI: 4375 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 4376 break; 4377 } 4378 #ifdef CONFIG_USER_ONLY 4379 /* Pass the break code along to cpu_loop. */ 4380 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env, 4381 offsetof(CPUMIPSState, error_code)); 4382 #endif 4383 /* Like save_cpu_state, only don't update saved values. */ 4384 if (ctx->base.pc_next != ctx->saved_pc) { 4385 gen_save_pc(ctx->base.pc_next); 4386 } 4387 if (ctx->hflags != ctx->saved_hflags) { 4388 tcg_gen_movi_i32(hflags, ctx->hflags); 4389 } 4390 generate_exception(ctx, EXCP_TRAP); 4391 gen_set_label(l1); 4392 } 4393 } 4394 4395 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 4396 { 4397 if (translator_use_goto_tb(&ctx->base, dest)) { 4398 tcg_gen_goto_tb(n); 4399 gen_save_pc(dest); 4400 tcg_gen_exit_tb(ctx->base.tb, n); 4401 } else { 4402 gen_save_pc(dest); 4403 tcg_gen_lookup_and_goto_ptr(); 4404 } 4405 } 4406 4407 /* Branches (before delay slot) */ 4408 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, 4409 int insn_bytes, 4410 int rs, int rt, int32_t offset, 4411 int delayslot_size) 4412 { 4413 target_ulong btgt = -1; 4414 int blink = 0; 4415 int bcond_compute = 0; 4416 TCGv t0 = tcg_temp_new(); 4417 TCGv t1 = tcg_temp_new(); 4418 4419 if (ctx->hflags & MIPS_HFLAG_BMASK) { 4420 #ifdef MIPS_DEBUG_DISAS 4421 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 4422 VADDR_PRIx "\n", ctx->base.pc_next); 4423 #endif 4424 gen_reserved_instruction(ctx); 4425 goto out; 4426 } 4427 4428 /* Load needed operands */ 4429 switch (opc) { 4430 case OPC_BEQ: 4431 case OPC_BEQL: 4432 case OPC_BNE: 4433 case OPC_BNEL: 4434 /* Compare two registers */ 4435 if (rs != rt) { 4436 gen_load_gpr(t0, rs); 4437 gen_load_gpr(t1, rt); 4438 bcond_compute = 1; 4439 } 4440 btgt = ctx->base.pc_next + insn_bytes + offset; 4441 break; 4442 case OPC_BGEZ: 4443 case OPC_BGEZAL: 4444 case OPC_BGEZALL: 4445 case OPC_BGEZL: 4446 case OPC_BGTZ: 4447 case OPC_BGTZL: 4448 case OPC_BLEZ: 4449 case OPC_BLEZL: 4450 case OPC_BLTZ: 4451 case OPC_BLTZAL: 4452 case OPC_BLTZALL: 4453 case OPC_BLTZL: 4454 /* Compare to zero */ 4455 if (rs != 0) { 4456 gen_load_gpr(t0, rs); 4457 bcond_compute = 1; 4458 } 4459 btgt = ctx->base.pc_next + insn_bytes + offset; 4460 break; 4461 case OPC_BPOSGE32: 4462 #if defined(TARGET_MIPS64) 4463 case OPC_BPOSGE64: 4464 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F); 4465 #else 4466 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 4467 #endif 4468 bcond_compute = 1; 4469 btgt = ctx->base.pc_next + insn_bytes + offset; 4470 break; 4471 case OPC_J: 4472 case OPC_JAL: 4473 { 4474 /* Jump to immediate */ 4475 int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000 4476 : 0xF0000000; 4477 btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask) 4478 | (uint32_t)offset; 4479 break; 4480 } 4481 case OPC_JALX: 4482 /* Jump to immediate */ 4483 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) | 4484 (uint32_t)offset; 4485 break; 4486 case OPC_JR: 4487 case OPC_JALR: 4488 /* Jump to register */ 4489 if (offset != 0 && offset != 16) { 4490 /* 4491 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 4492 * others are reserved. 4493 */ 4494 MIPS_INVAL("jump hint"); 4495 gen_reserved_instruction(ctx); 4496 goto out; 4497 } 4498 gen_load_gpr(btarget, rs); 4499 break; 4500 default: 4501 MIPS_INVAL("branch/jump"); 4502 gen_reserved_instruction(ctx); 4503 goto out; 4504 } 4505 if (bcond_compute == 0) { 4506 /* No condition to be computed */ 4507 switch (opc) { 4508 case OPC_BEQ: /* rx == rx */ 4509 case OPC_BEQL: /* rx == rx likely */ 4510 case OPC_BGEZ: /* 0 >= 0 */ 4511 case OPC_BGEZL: /* 0 >= 0 likely */ 4512 case OPC_BLEZ: /* 0 <= 0 */ 4513 case OPC_BLEZL: /* 0 <= 0 likely */ 4514 /* Always take */ 4515 ctx->hflags |= MIPS_HFLAG_B; 4516 break; 4517 case OPC_BGEZAL: /* 0 >= 0 */ 4518 case OPC_BGEZALL: /* 0 >= 0 likely */ 4519 /* Always take and link */ 4520 blink = 31; 4521 ctx->hflags |= MIPS_HFLAG_B; 4522 break; 4523 case OPC_BNE: /* rx != rx */ 4524 case OPC_BGTZ: /* 0 > 0 */ 4525 case OPC_BLTZ: /* 0 < 0 */ 4526 /* Treat as NOP. */ 4527 goto out; 4528 case OPC_BLTZAL: /* 0 < 0 */ 4529 /* 4530 * Handle as an unconditional branch to get correct delay 4531 * slot checking. 4532 */ 4533 blink = 31; 4534 btgt = ctx->base.pc_next + insn_bytes + delayslot_size; 4535 ctx->hflags |= MIPS_HFLAG_B; 4536 break; 4537 case OPC_BLTZALL: /* 0 < 0 likely */ 4538 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 4539 /* Skip the instruction in the delay slot */ 4540 ctx->base.pc_next += 4; 4541 goto out; 4542 case OPC_BNEL: /* rx != rx likely */ 4543 case OPC_BGTZL: /* 0 > 0 likely */ 4544 case OPC_BLTZL: /* 0 < 0 likely */ 4545 /* Skip the instruction in the delay slot */ 4546 ctx->base.pc_next += 4; 4547 goto out; 4548 case OPC_J: 4549 ctx->hflags |= MIPS_HFLAG_B; 4550 break; 4551 case OPC_JALX: 4552 ctx->hflags |= MIPS_HFLAG_BX; 4553 /* Fallthrough */ 4554 case OPC_JAL: 4555 blink = 31; 4556 ctx->hflags |= MIPS_HFLAG_B; 4557 break; 4558 case OPC_JR: 4559 ctx->hflags |= MIPS_HFLAG_BR; 4560 break; 4561 case OPC_JALR: 4562 blink = rt; 4563 ctx->hflags |= MIPS_HFLAG_BR; 4564 break; 4565 default: 4566 MIPS_INVAL("branch/jump"); 4567 gen_reserved_instruction(ctx); 4568 goto out; 4569 } 4570 } else { 4571 switch (opc) { 4572 case OPC_BEQ: 4573 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 4574 goto not_likely; 4575 case OPC_BEQL: 4576 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 4577 goto likely; 4578 case OPC_BNE: 4579 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 4580 goto not_likely; 4581 case OPC_BNEL: 4582 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 4583 goto likely; 4584 case OPC_BGEZ: 4585 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4586 goto not_likely; 4587 case OPC_BGEZL: 4588 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4589 goto likely; 4590 case OPC_BGEZAL: 4591 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4592 blink = 31; 4593 goto not_likely; 4594 case OPC_BGEZALL: 4595 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 4596 blink = 31; 4597 goto likely; 4598 case OPC_BGTZ: 4599 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 4600 goto not_likely; 4601 case OPC_BGTZL: 4602 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 4603 goto likely; 4604 case OPC_BLEZ: 4605 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 4606 goto not_likely; 4607 case OPC_BLEZL: 4608 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 4609 goto likely; 4610 case OPC_BLTZ: 4611 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4612 goto not_likely; 4613 case OPC_BLTZL: 4614 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4615 goto likely; 4616 case OPC_BPOSGE32: 4617 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 4618 goto not_likely; 4619 #if defined(TARGET_MIPS64) 4620 case OPC_BPOSGE64: 4621 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64); 4622 goto not_likely; 4623 #endif 4624 case OPC_BLTZAL: 4625 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4626 blink = 31; 4627 not_likely: 4628 ctx->hflags |= MIPS_HFLAG_BC; 4629 break; 4630 case OPC_BLTZALL: 4631 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 4632 blink = 31; 4633 likely: 4634 ctx->hflags |= MIPS_HFLAG_BL; 4635 break; 4636 default: 4637 MIPS_INVAL("conditional branch/jump"); 4638 gen_reserved_instruction(ctx); 4639 goto out; 4640 } 4641 } 4642 4643 ctx->btarget = btgt; 4644 4645 switch (delayslot_size) { 4646 case 2: 4647 ctx->hflags |= MIPS_HFLAG_BDS16; 4648 break; 4649 case 4: 4650 ctx->hflags |= MIPS_HFLAG_BDS32; 4651 break; 4652 } 4653 4654 if (blink > 0) { 4655 int post_delay = insn_bytes + delayslot_size; 4656 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); 4657 4658 tcg_gen_movi_tl(cpu_gpr[blink], 4659 ctx->base.pc_next + post_delay + lowbit); 4660 } 4661 4662 out: 4663 if (insn_bytes == 2) { 4664 ctx->hflags |= MIPS_HFLAG_B16; 4665 } 4666 } 4667 4668 4669 /* special3 bitfield operations */ 4670 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, 4671 int rs, int lsb, int msb) 4672 { 4673 TCGv t0 = tcg_temp_new(); 4674 TCGv t1 = tcg_temp_new(); 4675 4676 gen_load_gpr(t1, rs); 4677 switch (opc) { 4678 case OPC_EXT: 4679 if (lsb + msb > 31) { 4680 goto fail; 4681 } 4682 if (msb != 31) { 4683 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 4684 } else { 4685 /* 4686 * The two checks together imply that lsb == 0, 4687 * so this is a simple sign-extension. 4688 */ 4689 tcg_gen_ext32s_tl(t0, t1); 4690 } 4691 break; 4692 #if defined(TARGET_MIPS64) 4693 case OPC_DEXTU: 4694 lsb += 32; 4695 goto do_dext; 4696 case OPC_DEXTM: 4697 msb += 32; 4698 goto do_dext; 4699 case OPC_DEXT: 4700 do_dext: 4701 if (lsb + msb > 63) { 4702 goto fail; 4703 } 4704 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 4705 break; 4706 #endif 4707 case OPC_INS: 4708 if (lsb > msb) { 4709 goto fail; 4710 } 4711 gen_load_gpr(t0, rt); 4712 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 4713 tcg_gen_ext32s_tl(t0, t0); 4714 break; 4715 #if defined(TARGET_MIPS64) 4716 case OPC_DINSU: 4717 lsb += 32; 4718 /* FALLTHRU */ 4719 case OPC_DINSM: 4720 msb += 32; 4721 /* FALLTHRU */ 4722 case OPC_DINS: 4723 if (lsb > msb) { 4724 goto fail; 4725 } 4726 gen_load_gpr(t0, rt); 4727 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 4728 break; 4729 #endif 4730 default: 4731 fail: 4732 MIPS_INVAL("bitops"); 4733 gen_reserved_instruction(ctx); 4734 return; 4735 } 4736 gen_store_gpr(t0, rt); 4737 } 4738 4739 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) 4740 { 4741 TCGv t0; 4742 4743 if (rd == 0) { 4744 /* If no destination, treat it as a NOP. */ 4745 return; 4746 } 4747 4748 t0 = tcg_temp_new(); 4749 gen_load_gpr(t0, rt); 4750 switch (op2) { 4751 case OPC_WSBH: 4752 { 4753 TCGv t1 = tcg_temp_new(); 4754 TCGv t2 = tcg_constant_tl(0x00FF00FF); 4755 4756 tcg_gen_shri_tl(t1, t0, 8); 4757 tcg_gen_and_tl(t1, t1, t2); 4758 tcg_gen_and_tl(t0, t0, t2); 4759 tcg_gen_shli_tl(t0, t0, 8); 4760 tcg_gen_or_tl(t0, t0, t1); 4761 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 4762 } 4763 break; 4764 case OPC_SEB: 4765 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 4766 break; 4767 case OPC_SEH: 4768 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 4769 break; 4770 #if defined(TARGET_MIPS64) 4771 case OPC_DSBH: 4772 { 4773 TCGv t1 = tcg_temp_new(); 4774 TCGv t2 = tcg_constant_tl(0x00FF00FF00FF00FFULL); 4775 4776 tcg_gen_shri_tl(t1, t0, 8); 4777 tcg_gen_and_tl(t1, t1, t2); 4778 tcg_gen_and_tl(t0, t0, t2); 4779 tcg_gen_shli_tl(t0, t0, 8); 4780 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 4781 } 4782 break; 4783 case OPC_DSHD: 4784 { 4785 TCGv t1 = tcg_temp_new(); 4786 TCGv t2 = tcg_constant_tl(0x0000FFFF0000FFFFULL); 4787 4788 tcg_gen_shri_tl(t1, t0, 16); 4789 tcg_gen_and_tl(t1, t1, t2); 4790 tcg_gen_and_tl(t0, t0, t2); 4791 tcg_gen_shli_tl(t0, t0, 16); 4792 tcg_gen_or_tl(t0, t0, t1); 4793 tcg_gen_shri_tl(t1, t0, 32); 4794 tcg_gen_shli_tl(t0, t0, 32); 4795 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 4796 } 4797 break; 4798 #endif 4799 default: 4800 MIPS_INVAL("bsfhl"); 4801 gen_reserved_instruction(ctx); 4802 return; 4803 } 4804 } 4805 4806 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, 4807 int rt, int bits) 4808 { 4809 TCGv t0; 4810 if (rd == 0) { 4811 /* Treat as NOP. */ 4812 return; 4813 } 4814 t0 = tcg_temp_new(); 4815 if (bits == 0 || bits == wordsz) { 4816 if (bits == 0) { 4817 gen_load_gpr(t0, rt); 4818 } else { 4819 gen_load_gpr(t0, rs); 4820 } 4821 switch (wordsz) { 4822 case 32: 4823 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 4824 break; 4825 #if defined(TARGET_MIPS64) 4826 case 64: 4827 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4828 break; 4829 #endif 4830 } 4831 } else { 4832 TCGv t1 = tcg_temp_new(); 4833 gen_load_gpr(t0, rt); 4834 gen_load_gpr(t1, rs); 4835 switch (wordsz) { 4836 case 32: 4837 { 4838 TCGv_i64 t2 = tcg_temp_new_i64(); 4839 tcg_gen_concat_tl_i64(t2, t1, t0); 4840 tcg_gen_shri_i64(t2, t2, 32 - bits); 4841 gen_move_low32(cpu_gpr[rd], t2); 4842 } 4843 break; 4844 #if defined(TARGET_MIPS64) 4845 case 64: 4846 tcg_gen_shli_tl(t0, t0, bits); 4847 tcg_gen_shri_tl(t1, t1, 64 - bits); 4848 tcg_gen_or_tl(cpu_gpr[rd], t1, t0); 4849 break; 4850 #endif 4851 } 4852 } 4853 } 4854 4855 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp) 4856 { 4857 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); 4858 } 4859 4860 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) 4861 { 4862 TCGv t0; 4863 if (rd == 0) { 4864 /* Treat as NOP. */ 4865 return; 4866 } 4867 t0 = tcg_temp_new(); 4868 gen_load_gpr(t0, rt); 4869 switch (opc) { 4870 case OPC_BITSWAP: 4871 gen_helper_bitswap(cpu_gpr[rd], t0); 4872 break; 4873 #if defined(TARGET_MIPS64) 4874 case OPC_DBITSWAP: 4875 gen_helper_dbitswap(cpu_gpr[rd], t0); 4876 break; 4877 #endif 4878 } 4879 } 4880 4881 #ifndef CONFIG_USER_ONLY 4882 /* CP0 (MMU and control) */ 4883 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off) 4884 { 4885 TCGv_i64 t0 = tcg_temp_new_i64(); 4886 TCGv_i64 t1 = tcg_temp_new_i64(); 4887 4888 tcg_gen_ext_tl_i64(t0, arg); 4889 tcg_gen_ld_i64(t1, tcg_env, off); 4890 #if defined(TARGET_MIPS64) 4891 tcg_gen_deposit_i64(t1, t1, t0, 30, 32); 4892 #else 4893 tcg_gen_concat32_i64(t1, t1, t0); 4894 #endif 4895 tcg_gen_st_i64(t1, tcg_env, off); 4896 } 4897 4898 static inline void gen_mthc0_store64(TCGv arg, target_ulong off) 4899 { 4900 TCGv_i64 t0 = tcg_temp_new_i64(); 4901 TCGv_i64 t1 = tcg_temp_new_i64(); 4902 4903 tcg_gen_ext_tl_i64(t0, arg); 4904 tcg_gen_ld_i64(t1, tcg_env, off); 4905 tcg_gen_concat32_i64(t1, t1, t0); 4906 tcg_gen_st_i64(t1, tcg_env, off); 4907 } 4908 4909 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off) 4910 { 4911 TCGv_i64 t0 = tcg_temp_new_i64(); 4912 4913 tcg_gen_ld_i64(t0, tcg_env, off); 4914 #if defined(TARGET_MIPS64) 4915 tcg_gen_shri_i64(t0, t0, 30); 4916 #else 4917 tcg_gen_shri_i64(t0, t0, 32); 4918 #endif 4919 gen_move_low32(arg, t0); 4920 } 4921 4922 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift) 4923 { 4924 TCGv_i64 t0 = tcg_temp_new_i64(); 4925 4926 tcg_gen_ld_i64(t0, tcg_env, off); 4927 tcg_gen_shri_i64(t0, t0, 32 + shift); 4928 gen_move_low32(arg, t0); 4929 } 4930 4931 static inline void gen_mfc0_load32(TCGv arg, target_ulong off) 4932 { 4933 TCGv_i32 t0 = tcg_temp_new_i32(); 4934 4935 tcg_gen_ld_i32(t0, tcg_env, off); 4936 tcg_gen_ext_i32_tl(arg, t0); 4937 } 4938 4939 static inline void gen_mfc0_load64(TCGv arg, target_ulong off) 4940 { 4941 tcg_gen_ld_tl(arg, tcg_env, off); 4942 tcg_gen_ext32s_tl(arg, arg); 4943 } 4944 4945 static inline void gen_mtc0_store32(TCGv arg, target_ulong off) 4946 { 4947 TCGv_i32 t0 = tcg_temp_new_i32(); 4948 4949 tcg_gen_trunc_tl_i32(t0, arg); 4950 tcg_gen_st_i32(t0, tcg_env, off); 4951 } 4952 4953 #define CP0_CHECK(c) \ 4954 do { \ 4955 if (!(c)) { \ 4956 goto cp0_unimplemented; \ 4957 } \ 4958 } while (0) 4959 4960 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) 4961 { 4962 const char *register_name = "invalid"; 4963 4964 switch (reg) { 4965 case CP0_REGISTER_02: 4966 switch (sel) { 4967 case 0: 4968 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 4969 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 4970 register_name = "EntryLo0"; 4971 break; 4972 default: 4973 goto cp0_unimplemented; 4974 } 4975 break; 4976 case CP0_REGISTER_03: 4977 switch (sel) { 4978 case CP0_REG03__ENTRYLO1: 4979 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 4980 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 4981 register_name = "EntryLo1"; 4982 break; 4983 default: 4984 goto cp0_unimplemented; 4985 } 4986 break; 4987 case CP0_REGISTER_17: 4988 switch (sel) { 4989 case CP0_REG17__LLADDR: 4990 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr), 4991 ctx->CP0_LLAddr_shift); 4992 register_name = "LLAddr"; 4993 break; 4994 case CP0_REG17__MAAR: 4995 CP0_CHECK(ctx->mrp); 4996 gen_helper_mfhc0_maar(arg, tcg_env); 4997 register_name = "MAAR"; 4998 break; 4999 default: 5000 goto cp0_unimplemented; 5001 } 5002 break; 5003 case CP0_REGISTER_19: 5004 switch (sel) { 5005 case CP0_REG19__WATCHHI0: 5006 case CP0_REG19__WATCHHI1: 5007 case CP0_REG19__WATCHHI2: 5008 case CP0_REG19__WATCHHI3: 5009 case CP0_REG19__WATCHHI4: 5010 case CP0_REG19__WATCHHI5: 5011 case CP0_REG19__WATCHHI6: 5012 case CP0_REG19__WATCHHI7: 5013 /* upper 32 bits are only available when Config5MI != 0 */ 5014 CP0_CHECK(ctx->mi); 5015 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0); 5016 register_name = "WatchHi"; 5017 break; 5018 default: 5019 goto cp0_unimplemented; 5020 } 5021 break; 5022 case CP0_REGISTER_28: 5023 switch (sel) { 5024 case 0: 5025 case 2: 5026 case 4: 5027 case 6: 5028 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0); 5029 register_name = "TagLo"; 5030 break; 5031 default: 5032 goto cp0_unimplemented; 5033 } 5034 break; 5035 default: 5036 goto cp0_unimplemented; 5037 } 5038 trace_mips_translate_c0("mfhc0", register_name, reg, sel); 5039 return; 5040 5041 cp0_unimplemented: 5042 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", 5043 register_name, reg, sel); 5044 tcg_gen_movi_tl(arg, 0); 5045 } 5046 5047 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5048 { 5049 const char *register_name = "invalid"; 5050 uint64_t mask = ctx->PAMask >> 36; 5051 5052 switch (reg) { 5053 case CP0_REGISTER_02: 5054 switch (sel) { 5055 case 0: 5056 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5057 tcg_gen_andi_tl(arg, arg, mask); 5058 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5059 register_name = "EntryLo0"; 5060 break; 5061 default: 5062 goto cp0_unimplemented; 5063 } 5064 break; 5065 case CP0_REGISTER_03: 5066 switch (sel) { 5067 case CP0_REG03__ENTRYLO1: 5068 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5069 tcg_gen_andi_tl(arg, arg, mask); 5070 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5071 register_name = "EntryLo1"; 5072 break; 5073 default: 5074 goto cp0_unimplemented; 5075 } 5076 break; 5077 case CP0_REGISTER_17: 5078 switch (sel) { 5079 case CP0_REG17__LLADDR: 5080 /* 5081 * LLAddr is read-only (the only exception is bit 0 if LLB is 5082 * supported); the CP0_LLAddr_rw_bitmask does not seem to be 5083 * relevant for modern MIPS cores supporting MTHC0, therefore 5084 * treating MTHC0 to LLAddr as NOP. 5085 */ 5086 register_name = "LLAddr"; 5087 break; 5088 case CP0_REG17__MAAR: 5089 CP0_CHECK(ctx->mrp); 5090 gen_helper_mthc0_maar(tcg_env, arg); 5091 register_name = "MAAR"; 5092 break; 5093 default: 5094 goto cp0_unimplemented; 5095 } 5096 break; 5097 case CP0_REGISTER_19: 5098 switch (sel) { 5099 case CP0_REG19__WATCHHI0: 5100 case CP0_REG19__WATCHHI1: 5101 case CP0_REG19__WATCHHI2: 5102 case CP0_REG19__WATCHHI3: 5103 case CP0_REG19__WATCHHI4: 5104 case CP0_REG19__WATCHHI5: 5105 case CP0_REG19__WATCHHI6: 5106 case CP0_REG19__WATCHHI7: 5107 /* upper 32 bits are only available when Config5MI != 0 */ 5108 CP0_CHECK(ctx->mi); 5109 gen_helper_0e1i(mthc0_watchhi, arg, sel); 5110 register_name = "WatchHi"; 5111 break; 5112 default: 5113 goto cp0_unimplemented; 5114 } 5115 break; 5116 case CP0_REGISTER_28: 5117 switch (sel) { 5118 case 0: 5119 case 2: 5120 case 4: 5121 case 6: 5122 tcg_gen_andi_tl(arg, arg, mask); 5123 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo)); 5124 register_name = "TagLo"; 5125 break; 5126 default: 5127 goto cp0_unimplemented; 5128 } 5129 break; 5130 default: 5131 goto cp0_unimplemented; 5132 } 5133 trace_mips_translate_c0("mthc0", register_name, reg, sel); 5134 return; 5135 5136 cp0_unimplemented: 5137 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", 5138 register_name, reg, sel); 5139 } 5140 5141 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg) 5142 { 5143 if (ctx->insn_flags & ISA_MIPS_R6) { 5144 tcg_gen_movi_tl(arg, 0); 5145 } else { 5146 tcg_gen_movi_tl(arg, ~0); 5147 } 5148 } 5149 5150 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5151 { 5152 const char *register_name = "invalid"; 5153 5154 if (sel != 0) { 5155 check_insn(ctx, ISA_MIPS_R1); 5156 } 5157 5158 switch (reg) { 5159 case CP0_REGISTER_00: 5160 switch (sel) { 5161 case CP0_REG00__INDEX: 5162 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 5163 register_name = "Index"; 5164 break; 5165 case CP0_REG00__MVPCONTROL: 5166 CP0_CHECK(ctx->insn_flags & ASE_MT); 5167 gen_helper_mfc0_mvpcontrol(arg, tcg_env); 5168 register_name = "MVPControl"; 5169 break; 5170 case CP0_REG00__MVPCONF0: 5171 CP0_CHECK(ctx->insn_flags & ASE_MT); 5172 gen_helper_mfc0_mvpconf0(arg, tcg_env); 5173 register_name = "MVPConf0"; 5174 break; 5175 case CP0_REG00__MVPCONF1: 5176 CP0_CHECK(ctx->insn_flags & ASE_MT); 5177 gen_helper_mfc0_mvpconf1(arg, tcg_env); 5178 register_name = "MVPConf1"; 5179 break; 5180 case CP0_REG00__VPCONTROL: 5181 CP0_CHECK(ctx->vp); 5182 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 5183 register_name = "VPControl"; 5184 break; 5185 default: 5186 goto cp0_unimplemented; 5187 } 5188 break; 5189 case CP0_REGISTER_01: 5190 switch (sel) { 5191 case CP0_REG01__RANDOM: 5192 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5193 gen_helper_mfc0_random(arg, tcg_env); 5194 register_name = "Random"; 5195 break; 5196 case CP0_REG01__VPECONTROL: 5197 CP0_CHECK(ctx->insn_flags & ASE_MT); 5198 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 5199 register_name = "VPEControl"; 5200 break; 5201 case CP0_REG01__VPECONF0: 5202 CP0_CHECK(ctx->insn_flags & ASE_MT); 5203 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 5204 register_name = "VPEConf0"; 5205 break; 5206 case CP0_REG01__VPECONF1: 5207 CP0_CHECK(ctx->insn_flags & ASE_MT); 5208 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 5209 register_name = "VPEConf1"; 5210 break; 5211 case CP0_REG01__YQMASK: 5212 CP0_CHECK(ctx->insn_flags & ASE_MT); 5213 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 5214 register_name = "YQMask"; 5215 break; 5216 case CP0_REG01__VPESCHEDULE: 5217 CP0_CHECK(ctx->insn_flags & ASE_MT); 5218 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 5219 register_name = "VPESchedule"; 5220 break; 5221 case CP0_REG01__VPESCHEFBACK: 5222 CP0_CHECK(ctx->insn_flags & ASE_MT); 5223 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5224 register_name = "VPEScheFBack"; 5225 break; 5226 case CP0_REG01__VPEOPT: 5227 CP0_CHECK(ctx->insn_flags & ASE_MT); 5228 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 5229 register_name = "VPEOpt"; 5230 break; 5231 default: 5232 goto cp0_unimplemented; 5233 } 5234 break; 5235 case CP0_REGISTER_02: 5236 switch (sel) { 5237 case CP0_REG02__ENTRYLO0: 5238 { 5239 TCGv_i64 tmp = tcg_temp_new_i64(); 5240 tcg_gen_ld_i64(tmp, tcg_env, 5241 offsetof(CPUMIPSState, CP0_EntryLo0)); 5242 #if defined(TARGET_MIPS64) 5243 if (ctx->rxi) { 5244 /* Move RI/XI fields to bits 31:30 */ 5245 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5246 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5247 } 5248 #endif 5249 gen_move_low32(arg, tmp); 5250 } 5251 register_name = "EntryLo0"; 5252 break; 5253 case CP0_REG02__TCSTATUS: 5254 CP0_CHECK(ctx->insn_flags & ASE_MT); 5255 gen_helper_mfc0_tcstatus(arg, tcg_env); 5256 register_name = "TCStatus"; 5257 break; 5258 case CP0_REG02__TCBIND: 5259 CP0_CHECK(ctx->insn_flags & ASE_MT); 5260 gen_helper_mfc0_tcbind(arg, tcg_env); 5261 register_name = "TCBind"; 5262 break; 5263 case CP0_REG02__TCRESTART: 5264 CP0_CHECK(ctx->insn_flags & ASE_MT); 5265 gen_helper_mfc0_tcrestart(arg, tcg_env); 5266 register_name = "TCRestart"; 5267 break; 5268 case CP0_REG02__TCHALT: 5269 CP0_CHECK(ctx->insn_flags & ASE_MT); 5270 gen_helper_mfc0_tchalt(arg, tcg_env); 5271 register_name = "TCHalt"; 5272 break; 5273 case CP0_REG02__TCCONTEXT: 5274 CP0_CHECK(ctx->insn_flags & ASE_MT); 5275 gen_helper_mfc0_tccontext(arg, tcg_env); 5276 register_name = "TCContext"; 5277 break; 5278 case CP0_REG02__TCSCHEDULE: 5279 CP0_CHECK(ctx->insn_flags & ASE_MT); 5280 gen_helper_mfc0_tcschedule(arg, tcg_env); 5281 register_name = "TCSchedule"; 5282 break; 5283 case CP0_REG02__TCSCHEFBACK: 5284 CP0_CHECK(ctx->insn_flags & ASE_MT); 5285 gen_helper_mfc0_tcschefback(arg, tcg_env); 5286 register_name = "TCScheFBack"; 5287 break; 5288 default: 5289 goto cp0_unimplemented; 5290 } 5291 break; 5292 case CP0_REGISTER_03: 5293 switch (sel) { 5294 case CP0_REG03__ENTRYLO1: 5295 { 5296 TCGv_i64 tmp = tcg_temp_new_i64(); 5297 tcg_gen_ld_i64(tmp, tcg_env, 5298 offsetof(CPUMIPSState, CP0_EntryLo1)); 5299 #if defined(TARGET_MIPS64) 5300 if (ctx->rxi) { 5301 /* Move RI/XI fields to bits 31:30 */ 5302 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5303 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5304 } 5305 #endif 5306 gen_move_low32(arg, tmp); 5307 } 5308 register_name = "EntryLo1"; 5309 break; 5310 case CP0_REG03__GLOBALNUM: 5311 CP0_CHECK(ctx->vp); 5312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 5313 register_name = "GlobalNumber"; 5314 break; 5315 default: 5316 goto cp0_unimplemented; 5317 } 5318 break; 5319 case CP0_REGISTER_04: 5320 switch (sel) { 5321 case CP0_REG04__CONTEXT: 5322 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context)); 5323 tcg_gen_ext32s_tl(arg, arg); 5324 register_name = "Context"; 5325 break; 5326 case CP0_REG04__CONTEXTCONFIG: 5327 /* SmartMIPS ASE */ 5328 /* gen_helper_mfc0_contextconfig(arg); */ 5329 register_name = "ContextConfig"; 5330 goto cp0_unimplemented; 5331 case CP0_REG04__USERLOCAL: 5332 CP0_CHECK(ctx->ulri); 5333 tcg_gen_ld_tl(arg, tcg_env, 5334 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 5335 tcg_gen_ext32s_tl(arg, arg); 5336 register_name = "UserLocal"; 5337 break; 5338 case CP0_REG04__MMID: 5339 CP0_CHECK(ctx->mi); 5340 gen_helper_mtc0_memorymapid(tcg_env, arg); 5341 register_name = "MMID"; 5342 break; 5343 default: 5344 goto cp0_unimplemented; 5345 } 5346 break; 5347 case CP0_REGISTER_05: 5348 switch (sel) { 5349 case CP0_REG05__PAGEMASK: 5350 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 5351 register_name = "PageMask"; 5352 break; 5353 case CP0_REG05__PAGEGRAIN: 5354 check_insn(ctx, ISA_MIPS_R2); 5355 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 5356 register_name = "PageGrain"; 5357 break; 5358 case CP0_REG05__SEGCTL0: 5359 CP0_CHECK(ctx->sc); 5360 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 5361 tcg_gen_ext32s_tl(arg, arg); 5362 register_name = "SegCtl0"; 5363 break; 5364 case CP0_REG05__SEGCTL1: 5365 CP0_CHECK(ctx->sc); 5366 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 5367 tcg_gen_ext32s_tl(arg, arg); 5368 register_name = "SegCtl1"; 5369 break; 5370 case CP0_REG05__SEGCTL2: 5371 CP0_CHECK(ctx->sc); 5372 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 5373 tcg_gen_ext32s_tl(arg, arg); 5374 register_name = "SegCtl2"; 5375 break; 5376 case CP0_REG05__PWBASE: 5377 check_pw(ctx); 5378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 5379 register_name = "PWBase"; 5380 break; 5381 case CP0_REG05__PWFIELD: 5382 check_pw(ctx); 5383 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField)); 5384 register_name = "PWField"; 5385 break; 5386 case CP0_REG05__PWSIZE: 5387 check_pw(ctx); 5388 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize)); 5389 register_name = "PWSize"; 5390 break; 5391 default: 5392 goto cp0_unimplemented; 5393 } 5394 break; 5395 case CP0_REGISTER_06: 5396 switch (sel) { 5397 case CP0_REG06__WIRED: 5398 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 5399 register_name = "Wired"; 5400 break; 5401 case CP0_REG06__SRSCONF0: 5402 check_insn(ctx, ISA_MIPS_R2); 5403 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 5404 register_name = "SRSConf0"; 5405 break; 5406 case CP0_REG06__SRSCONF1: 5407 check_insn(ctx, ISA_MIPS_R2); 5408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 5409 register_name = "SRSConf1"; 5410 break; 5411 case CP0_REG06__SRSCONF2: 5412 check_insn(ctx, ISA_MIPS_R2); 5413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 5414 register_name = "SRSConf2"; 5415 break; 5416 case CP0_REG06__SRSCONF3: 5417 check_insn(ctx, ISA_MIPS_R2); 5418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 5419 register_name = "SRSConf3"; 5420 break; 5421 case CP0_REG06__SRSCONF4: 5422 check_insn(ctx, ISA_MIPS_R2); 5423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 5424 register_name = "SRSConf4"; 5425 break; 5426 case CP0_REG06__PWCTL: 5427 check_pw(ctx); 5428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 5429 register_name = "PWCtl"; 5430 break; 5431 default: 5432 goto cp0_unimplemented; 5433 } 5434 break; 5435 case CP0_REGISTER_07: 5436 switch (sel) { 5437 case CP0_REG07__HWRENA: 5438 check_insn(ctx, ISA_MIPS_R2); 5439 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 5440 register_name = "HWREna"; 5441 break; 5442 default: 5443 goto cp0_unimplemented; 5444 } 5445 break; 5446 case CP0_REGISTER_08: 5447 switch (sel) { 5448 case CP0_REG08__BADVADDR: 5449 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 5450 tcg_gen_ext32s_tl(arg, arg); 5451 register_name = "BadVAddr"; 5452 break; 5453 case CP0_REG08__BADINSTR: 5454 CP0_CHECK(ctx->bi); 5455 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 5456 register_name = "BadInstr"; 5457 break; 5458 case CP0_REG08__BADINSTRP: 5459 CP0_CHECK(ctx->bp); 5460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 5461 register_name = "BadInstrP"; 5462 break; 5463 case CP0_REG08__BADINSTRX: 5464 CP0_CHECK(ctx->bi); 5465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 5466 tcg_gen_andi_tl(arg, arg, ~0xffff); 5467 register_name = "BadInstrX"; 5468 break; 5469 default: 5470 goto cp0_unimplemented; 5471 } 5472 break; 5473 case CP0_REGISTER_09: 5474 switch (sel) { 5475 case CP0_REG09__COUNT: 5476 /* Mark as an IO operation because we read the time. */ 5477 translator_io_start(&ctx->base); 5478 5479 gen_helper_mfc0_count(arg, tcg_env); 5480 /* 5481 * Break the TB to be able to take timer interrupts immediately 5482 * after reading count. DISAS_STOP isn't sufficient, we need to 5483 * ensure we break completely out of translated code. 5484 */ 5485 gen_save_pc(ctx->base.pc_next + 4); 5486 ctx->base.is_jmp = DISAS_EXIT; 5487 register_name = "Count"; 5488 break; 5489 default: 5490 goto cp0_unimplemented; 5491 } 5492 break; 5493 case CP0_REGISTER_10: 5494 switch (sel) { 5495 case CP0_REG10__ENTRYHI: 5496 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi)); 5497 tcg_gen_ext32s_tl(arg, arg); 5498 register_name = "EntryHi"; 5499 break; 5500 default: 5501 goto cp0_unimplemented; 5502 } 5503 break; 5504 case CP0_REGISTER_11: 5505 switch (sel) { 5506 case CP0_REG11__COMPARE: 5507 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 5508 register_name = "Compare"; 5509 break; 5510 /* 6,7 are implementation dependent */ 5511 default: 5512 goto cp0_unimplemented; 5513 } 5514 break; 5515 case CP0_REGISTER_12: 5516 switch (sel) { 5517 case CP0_REG12__STATUS: 5518 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 5519 register_name = "Status"; 5520 break; 5521 case CP0_REG12__INTCTL: 5522 check_insn(ctx, ISA_MIPS_R2); 5523 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 5524 register_name = "IntCtl"; 5525 break; 5526 case CP0_REG12__SRSCTL: 5527 check_insn(ctx, ISA_MIPS_R2); 5528 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 5529 register_name = "SRSCtl"; 5530 break; 5531 case CP0_REG12__SRSMAP: 5532 check_insn(ctx, ISA_MIPS_R2); 5533 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 5534 register_name = "SRSMap"; 5535 break; 5536 default: 5537 goto cp0_unimplemented; 5538 } 5539 break; 5540 case CP0_REGISTER_13: 5541 switch (sel) { 5542 case CP0_REG13__CAUSE: 5543 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 5544 register_name = "Cause"; 5545 break; 5546 default: 5547 goto cp0_unimplemented; 5548 } 5549 break; 5550 case CP0_REGISTER_14: 5551 switch (sel) { 5552 case CP0_REG14__EPC: 5553 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 5554 tcg_gen_ext32s_tl(arg, arg); 5555 register_name = "EPC"; 5556 break; 5557 default: 5558 goto cp0_unimplemented; 5559 } 5560 break; 5561 case CP0_REGISTER_15: 5562 switch (sel) { 5563 case CP0_REG15__PRID: 5564 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 5565 register_name = "PRid"; 5566 break; 5567 case CP0_REG15__EBASE: 5568 check_insn(ctx, ISA_MIPS_R2); 5569 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase)); 5570 tcg_gen_ext32s_tl(arg, arg); 5571 register_name = "EBase"; 5572 break; 5573 case CP0_REG15__CMGCRBASE: 5574 check_insn(ctx, ISA_MIPS_R2); 5575 CP0_CHECK(ctx->cmgcr); 5576 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 5577 tcg_gen_ext32s_tl(arg, arg); 5578 register_name = "CMGCRBase"; 5579 break; 5580 default: 5581 goto cp0_unimplemented; 5582 } 5583 break; 5584 case CP0_REGISTER_16: 5585 switch (sel) { 5586 case CP0_REG16__CONFIG: 5587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 5588 register_name = "Config"; 5589 break; 5590 case CP0_REG16__CONFIG1: 5591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 5592 register_name = "Config1"; 5593 break; 5594 case CP0_REG16__CONFIG2: 5595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 5596 register_name = "Config2"; 5597 break; 5598 case CP0_REG16__CONFIG3: 5599 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 5600 register_name = "Config3"; 5601 break; 5602 case CP0_REG16__CONFIG4: 5603 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 5604 register_name = "Config4"; 5605 break; 5606 case CP0_REG16__CONFIG5: 5607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 5608 register_name = "Config5"; 5609 break; 5610 /* 6,7 are implementation dependent */ 5611 case CP0_REG16__CONFIG6: 5612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 5613 register_name = "Config6"; 5614 break; 5615 case CP0_REG16__CONFIG7: 5616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 5617 register_name = "Config7"; 5618 break; 5619 default: 5620 goto cp0_unimplemented; 5621 } 5622 break; 5623 case CP0_REGISTER_17: 5624 switch (sel) { 5625 case CP0_REG17__LLADDR: 5626 gen_helper_mfc0_lladdr(arg, tcg_env); 5627 register_name = "LLAddr"; 5628 break; 5629 case CP0_REG17__MAAR: 5630 CP0_CHECK(ctx->mrp); 5631 gen_helper_mfc0_maar(arg, tcg_env); 5632 register_name = "MAAR"; 5633 break; 5634 case CP0_REG17__MAARI: 5635 CP0_CHECK(ctx->mrp); 5636 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 5637 register_name = "MAARI"; 5638 break; 5639 default: 5640 goto cp0_unimplemented; 5641 } 5642 break; 5643 case CP0_REGISTER_18: 5644 switch (sel) { 5645 case CP0_REG18__WATCHLO0: 5646 case CP0_REG18__WATCHLO1: 5647 case CP0_REG18__WATCHLO2: 5648 case CP0_REG18__WATCHLO3: 5649 case CP0_REG18__WATCHLO4: 5650 case CP0_REG18__WATCHLO5: 5651 case CP0_REG18__WATCHLO6: 5652 case CP0_REG18__WATCHLO7: 5653 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 5654 gen_helper_1e0i(mfc0_watchlo, arg, sel); 5655 register_name = "WatchLo"; 5656 break; 5657 default: 5658 goto cp0_unimplemented; 5659 } 5660 break; 5661 case CP0_REGISTER_19: 5662 switch (sel) { 5663 case CP0_REG19__WATCHHI0: 5664 case CP0_REG19__WATCHHI1: 5665 case CP0_REG19__WATCHHI2: 5666 case CP0_REG19__WATCHHI3: 5667 case CP0_REG19__WATCHHI4: 5668 case CP0_REG19__WATCHHI5: 5669 case CP0_REG19__WATCHHI6: 5670 case CP0_REG19__WATCHHI7: 5671 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 5672 gen_helper_1e0i(mfc0_watchhi, arg, sel); 5673 register_name = "WatchHi"; 5674 break; 5675 default: 5676 goto cp0_unimplemented; 5677 } 5678 break; 5679 case CP0_REGISTER_20: 5680 switch (sel) { 5681 case CP0_REG20__XCONTEXT: 5682 #if defined(TARGET_MIPS64) 5683 check_insn(ctx, ISA_MIPS3); 5684 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext)); 5685 tcg_gen_ext32s_tl(arg, arg); 5686 register_name = "XContext"; 5687 break; 5688 #endif 5689 default: 5690 goto cp0_unimplemented; 5691 } 5692 break; 5693 case CP0_REGISTER_21: 5694 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 5695 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5696 switch (sel) { 5697 case 0: 5698 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 5699 register_name = "Framemask"; 5700 break; 5701 default: 5702 goto cp0_unimplemented; 5703 } 5704 break; 5705 case CP0_REGISTER_22: 5706 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 5707 register_name = "'Diagnostic"; /* implementation dependent */ 5708 break; 5709 case CP0_REGISTER_23: 5710 switch (sel) { 5711 case CP0_REG23__DEBUG: 5712 gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */ 5713 register_name = "Debug"; 5714 break; 5715 case CP0_REG23__TRACECONTROL: 5716 /* PDtrace support */ 5717 /* gen_helper_mfc0_tracecontrol(arg); */ 5718 register_name = "TraceControl"; 5719 goto cp0_unimplemented; 5720 case CP0_REG23__TRACECONTROL2: 5721 /* PDtrace support */ 5722 /* gen_helper_mfc0_tracecontrol2(arg); */ 5723 register_name = "TraceControl2"; 5724 goto cp0_unimplemented; 5725 case CP0_REG23__USERTRACEDATA1: 5726 /* PDtrace support */ 5727 /* gen_helper_mfc0_usertracedata1(arg);*/ 5728 register_name = "UserTraceData1"; 5729 goto cp0_unimplemented; 5730 case CP0_REG23__TRACEIBPC: 5731 /* PDtrace support */ 5732 /* gen_helper_mfc0_traceibpc(arg); */ 5733 register_name = "TraceIBPC"; 5734 goto cp0_unimplemented; 5735 case CP0_REG23__TRACEDBPC: 5736 /* PDtrace support */ 5737 /* gen_helper_mfc0_tracedbpc(arg); */ 5738 register_name = "TraceDBPC"; 5739 goto cp0_unimplemented; 5740 default: 5741 goto cp0_unimplemented; 5742 } 5743 break; 5744 case CP0_REGISTER_24: 5745 switch (sel) { 5746 case CP0_REG24__DEPC: 5747 /* EJTAG support */ 5748 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 5749 tcg_gen_ext32s_tl(arg, arg); 5750 register_name = "DEPC"; 5751 break; 5752 default: 5753 goto cp0_unimplemented; 5754 } 5755 break; 5756 case CP0_REGISTER_25: 5757 switch (sel) { 5758 case CP0_REG25__PERFCTL0: 5759 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 5760 register_name = "Performance0"; 5761 break; 5762 case CP0_REG25__PERFCNT0: 5763 /* gen_helper_mfc0_performance1(arg); */ 5764 register_name = "Performance1"; 5765 goto cp0_unimplemented; 5766 case CP0_REG25__PERFCTL1: 5767 /* gen_helper_mfc0_performance2(arg); */ 5768 register_name = "Performance2"; 5769 goto cp0_unimplemented; 5770 case CP0_REG25__PERFCNT1: 5771 /* gen_helper_mfc0_performance3(arg); */ 5772 register_name = "Performance3"; 5773 goto cp0_unimplemented; 5774 case CP0_REG25__PERFCTL2: 5775 /* gen_helper_mfc0_performance4(arg); */ 5776 register_name = "Performance4"; 5777 goto cp0_unimplemented; 5778 case CP0_REG25__PERFCNT2: 5779 /* gen_helper_mfc0_performance5(arg); */ 5780 register_name = "Performance5"; 5781 goto cp0_unimplemented; 5782 case CP0_REG25__PERFCTL3: 5783 /* gen_helper_mfc0_performance6(arg); */ 5784 register_name = "Performance6"; 5785 goto cp0_unimplemented; 5786 case CP0_REG25__PERFCNT3: 5787 /* gen_helper_mfc0_performance7(arg); */ 5788 register_name = "Performance7"; 5789 goto cp0_unimplemented; 5790 default: 5791 goto cp0_unimplemented; 5792 } 5793 break; 5794 case CP0_REGISTER_26: 5795 switch (sel) { 5796 case CP0_REG26__ERRCTL: 5797 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 5798 register_name = "ErrCtl"; 5799 break; 5800 default: 5801 goto cp0_unimplemented; 5802 } 5803 break; 5804 case CP0_REGISTER_27: 5805 switch (sel) { 5806 case CP0_REG27__CACHERR: 5807 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 5808 register_name = "CacheErr"; 5809 break; 5810 default: 5811 goto cp0_unimplemented; 5812 } 5813 break; 5814 case CP0_REGISTER_28: 5815 switch (sel) { 5816 case CP0_REG28__TAGLO: 5817 case CP0_REG28__TAGLO1: 5818 case CP0_REG28__TAGLO2: 5819 case CP0_REG28__TAGLO3: 5820 { 5821 TCGv_i64 tmp = tcg_temp_new_i64(); 5822 tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPUMIPSState, CP0_TagLo)); 5823 gen_move_low32(arg, tmp); 5824 } 5825 register_name = "TagLo"; 5826 break; 5827 case CP0_REG28__DATALO: 5828 case CP0_REG28__DATALO1: 5829 case CP0_REG28__DATALO2: 5830 case CP0_REG28__DATALO3: 5831 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 5832 register_name = "DataLo"; 5833 break; 5834 default: 5835 goto cp0_unimplemented; 5836 } 5837 break; 5838 case CP0_REGISTER_29: 5839 switch (sel) { 5840 case CP0_REG29__TAGHI: 5841 case CP0_REG29__TAGHI1: 5842 case CP0_REG29__TAGHI2: 5843 case CP0_REG29__TAGHI3: 5844 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 5845 register_name = "TagHi"; 5846 break; 5847 case CP0_REG29__DATAHI: 5848 case CP0_REG29__DATAHI1: 5849 case CP0_REG29__DATAHI2: 5850 case CP0_REG29__DATAHI3: 5851 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 5852 register_name = "DataHi"; 5853 break; 5854 default: 5855 goto cp0_unimplemented; 5856 } 5857 break; 5858 case CP0_REGISTER_30: 5859 switch (sel) { 5860 case CP0_REG30__ERROREPC: 5861 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 5862 tcg_gen_ext32s_tl(arg, arg); 5863 register_name = "ErrorEPC"; 5864 break; 5865 default: 5866 goto cp0_unimplemented; 5867 } 5868 break; 5869 case CP0_REGISTER_31: 5870 switch (sel) { 5871 case CP0_REG31__DESAVE: 5872 /* EJTAG support */ 5873 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 5874 register_name = "DESAVE"; 5875 break; 5876 case CP0_REG31__KSCRATCH1: 5877 case CP0_REG31__KSCRATCH2: 5878 case CP0_REG31__KSCRATCH3: 5879 case CP0_REG31__KSCRATCH4: 5880 case CP0_REG31__KSCRATCH5: 5881 case CP0_REG31__KSCRATCH6: 5882 CP0_CHECK(ctx->kscrexist & (1 << sel)); 5883 tcg_gen_ld_tl(arg, tcg_env, 5884 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 5885 tcg_gen_ext32s_tl(arg, arg); 5886 register_name = "KScratch"; 5887 break; 5888 default: 5889 goto cp0_unimplemented; 5890 } 5891 break; 5892 default: 5893 goto cp0_unimplemented; 5894 } 5895 trace_mips_translate_c0("mfc0", register_name, reg, sel); 5896 return; 5897 5898 cp0_unimplemented: 5899 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", 5900 register_name, reg, sel); 5901 gen_mfc0_unimplemented(ctx, arg); 5902 } 5903 5904 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5905 { 5906 const char *register_name = "invalid"; 5907 bool icount; 5908 5909 if (sel != 0) { 5910 check_insn(ctx, ISA_MIPS_R1); 5911 } 5912 5913 icount = translator_io_start(&ctx->base); 5914 5915 switch (reg) { 5916 case CP0_REGISTER_00: 5917 switch (sel) { 5918 case CP0_REG00__INDEX: 5919 gen_helper_mtc0_index(tcg_env, arg); 5920 register_name = "Index"; 5921 break; 5922 case CP0_REG00__MVPCONTROL: 5923 CP0_CHECK(ctx->insn_flags & ASE_MT); 5924 gen_helper_mtc0_mvpcontrol(tcg_env, arg); 5925 register_name = "MVPControl"; 5926 break; 5927 case CP0_REG00__MVPCONF0: 5928 CP0_CHECK(ctx->insn_flags & ASE_MT); 5929 /* ignored */ 5930 register_name = "MVPConf0"; 5931 break; 5932 case CP0_REG00__MVPCONF1: 5933 CP0_CHECK(ctx->insn_flags & ASE_MT); 5934 /* ignored */ 5935 register_name = "MVPConf1"; 5936 break; 5937 case CP0_REG00__VPCONTROL: 5938 CP0_CHECK(ctx->vp); 5939 /* ignored */ 5940 register_name = "VPControl"; 5941 break; 5942 default: 5943 goto cp0_unimplemented; 5944 } 5945 break; 5946 case CP0_REGISTER_01: 5947 switch (sel) { 5948 case CP0_REG01__RANDOM: 5949 /* ignored */ 5950 register_name = "Random"; 5951 break; 5952 case CP0_REG01__VPECONTROL: 5953 CP0_CHECK(ctx->insn_flags & ASE_MT); 5954 gen_helper_mtc0_vpecontrol(tcg_env, arg); 5955 register_name = "VPEControl"; 5956 break; 5957 case CP0_REG01__VPECONF0: 5958 CP0_CHECK(ctx->insn_flags & ASE_MT); 5959 gen_helper_mtc0_vpeconf0(tcg_env, arg); 5960 register_name = "VPEConf0"; 5961 break; 5962 case CP0_REG01__VPECONF1: 5963 CP0_CHECK(ctx->insn_flags & ASE_MT); 5964 gen_helper_mtc0_vpeconf1(tcg_env, arg); 5965 register_name = "VPEConf1"; 5966 break; 5967 case CP0_REG01__YQMASK: 5968 CP0_CHECK(ctx->insn_flags & ASE_MT); 5969 gen_helper_mtc0_yqmask(tcg_env, arg); 5970 register_name = "YQMask"; 5971 break; 5972 case CP0_REG01__VPESCHEDULE: 5973 CP0_CHECK(ctx->insn_flags & ASE_MT); 5974 tcg_gen_st_tl(arg, tcg_env, 5975 offsetof(CPUMIPSState, CP0_VPESchedule)); 5976 register_name = "VPESchedule"; 5977 break; 5978 case CP0_REG01__VPESCHEFBACK: 5979 CP0_CHECK(ctx->insn_flags & ASE_MT); 5980 tcg_gen_st_tl(arg, tcg_env, 5981 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5982 register_name = "VPEScheFBack"; 5983 break; 5984 case CP0_REG01__VPEOPT: 5985 CP0_CHECK(ctx->insn_flags & ASE_MT); 5986 gen_helper_mtc0_vpeopt(tcg_env, arg); 5987 register_name = "VPEOpt"; 5988 break; 5989 default: 5990 goto cp0_unimplemented; 5991 } 5992 break; 5993 case CP0_REGISTER_02: 5994 switch (sel) { 5995 case CP0_REG02__ENTRYLO0: 5996 gen_helper_mtc0_entrylo0(tcg_env, arg); 5997 register_name = "EntryLo0"; 5998 break; 5999 case CP0_REG02__TCSTATUS: 6000 CP0_CHECK(ctx->insn_flags & ASE_MT); 6001 gen_helper_mtc0_tcstatus(tcg_env, arg); 6002 register_name = "TCStatus"; 6003 break; 6004 case CP0_REG02__TCBIND: 6005 CP0_CHECK(ctx->insn_flags & ASE_MT); 6006 gen_helper_mtc0_tcbind(tcg_env, arg); 6007 register_name = "TCBind"; 6008 break; 6009 case CP0_REG02__TCRESTART: 6010 CP0_CHECK(ctx->insn_flags & ASE_MT); 6011 gen_helper_mtc0_tcrestart(tcg_env, arg); 6012 register_name = "TCRestart"; 6013 break; 6014 case CP0_REG02__TCHALT: 6015 CP0_CHECK(ctx->insn_flags & ASE_MT); 6016 gen_helper_mtc0_tchalt(tcg_env, arg); 6017 register_name = "TCHalt"; 6018 break; 6019 case CP0_REG02__TCCONTEXT: 6020 CP0_CHECK(ctx->insn_flags & ASE_MT); 6021 gen_helper_mtc0_tccontext(tcg_env, arg); 6022 register_name = "TCContext"; 6023 break; 6024 case CP0_REG02__TCSCHEDULE: 6025 CP0_CHECK(ctx->insn_flags & ASE_MT); 6026 gen_helper_mtc0_tcschedule(tcg_env, arg); 6027 register_name = "TCSchedule"; 6028 break; 6029 case CP0_REG02__TCSCHEFBACK: 6030 CP0_CHECK(ctx->insn_flags & ASE_MT); 6031 gen_helper_mtc0_tcschefback(tcg_env, arg); 6032 register_name = "TCScheFBack"; 6033 break; 6034 default: 6035 goto cp0_unimplemented; 6036 } 6037 break; 6038 case CP0_REGISTER_03: 6039 switch (sel) { 6040 case CP0_REG03__ENTRYLO1: 6041 gen_helper_mtc0_entrylo1(tcg_env, arg); 6042 register_name = "EntryLo1"; 6043 break; 6044 case CP0_REG03__GLOBALNUM: 6045 CP0_CHECK(ctx->vp); 6046 /* ignored */ 6047 register_name = "GlobalNumber"; 6048 break; 6049 default: 6050 goto cp0_unimplemented; 6051 } 6052 break; 6053 case CP0_REGISTER_04: 6054 switch (sel) { 6055 case CP0_REG04__CONTEXT: 6056 gen_helper_mtc0_context(tcg_env, arg); 6057 register_name = "Context"; 6058 break; 6059 case CP0_REG04__CONTEXTCONFIG: 6060 /* SmartMIPS ASE */ 6061 /* gen_helper_mtc0_contextconfig(arg); */ 6062 register_name = "ContextConfig"; 6063 goto cp0_unimplemented; 6064 case CP0_REG04__USERLOCAL: 6065 CP0_CHECK(ctx->ulri); 6066 tcg_gen_st_tl(arg, tcg_env, 6067 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6068 register_name = "UserLocal"; 6069 break; 6070 case CP0_REG04__MMID: 6071 CP0_CHECK(ctx->mi); 6072 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 6073 register_name = "MMID"; 6074 break; 6075 default: 6076 goto cp0_unimplemented; 6077 } 6078 break; 6079 case CP0_REGISTER_05: 6080 switch (sel) { 6081 case CP0_REG05__PAGEMASK: 6082 gen_helper_mtc0_pagemask(tcg_env, arg); 6083 register_name = "PageMask"; 6084 break; 6085 case CP0_REG05__PAGEGRAIN: 6086 check_insn(ctx, ISA_MIPS_R2); 6087 gen_helper_mtc0_pagegrain(tcg_env, arg); 6088 register_name = "PageGrain"; 6089 ctx->base.is_jmp = DISAS_STOP; 6090 break; 6091 case CP0_REG05__SEGCTL0: 6092 CP0_CHECK(ctx->sc); 6093 gen_helper_mtc0_segctl0(tcg_env, arg); 6094 register_name = "SegCtl0"; 6095 break; 6096 case CP0_REG05__SEGCTL1: 6097 CP0_CHECK(ctx->sc); 6098 gen_helper_mtc0_segctl1(tcg_env, arg); 6099 register_name = "SegCtl1"; 6100 break; 6101 case CP0_REG05__SEGCTL2: 6102 CP0_CHECK(ctx->sc); 6103 gen_helper_mtc0_segctl2(tcg_env, arg); 6104 register_name = "SegCtl2"; 6105 break; 6106 case CP0_REG05__PWBASE: 6107 check_pw(ctx); 6108 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 6109 register_name = "PWBase"; 6110 break; 6111 case CP0_REG05__PWFIELD: 6112 check_pw(ctx); 6113 gen_helper_mtc0_pwfield(tcg_env, arg); 6114 register_name = "PWField"; 6115 break; 6116 case CP0_REG05__PWSIZE: 6117 check_pw(ctx); 6118 gen_helper_mtc0_pwsize(tcg_env, arg); 6119 register_name = "PWSize"; 6120 break; 6121 default: 6122 goto cp0_unimplemented; 6123 } 6124 break; 6125 case CP0_REGISTER_06: 6126 switch (sel) { 6127 case CP0_REG06__WIRED: 6128 gen_helper_mtc0_wired(tcg_env, arg); 6129 register_name = "Wired"; 6130 break; 6131 case CP0_REG06__SRSCONF0: 6132 check_insn(ctx, ISA_MIPS_R2); 6133 gen_helper_mtc0_srsconf0(tcg_env, arg); 6134 register_name = "SRSConf0"; 6135 break; 6136 case CP0_REG06__SRSCONF1: 6137 check_insn(ctx, ISA_MIPS_R2); 6138 gen_helper_mtc0_srsconf1(tcg_env, arg); 6139 register_name = "SRSConf1"; 6140 break; 6141 case CP0_REG06__SRSCONF2: 6142 check_insn(ctx, ISA_MIPS_R2); 6143 gen_helper_mtc0_srsconf2(tcg_env, arg); 6144 register_name = "SRSConf2"; 6145 break; 6146 case CP0_REG06__SRSCONF3: 6147 check_insn(ctx, ISA_MIPS_R2); 6148 gen_helper_mtc0_srsconf3(tcg_env, arg); 6149 register_name = "SRSConf3"; 6150 break; 6151 case CP0_REG06__SRSCONF4: 6152 check_insn(ctx, ISA_MIPS_R2); 6153 gen_helper_mtc0_srsconf4(tcg_env, arg); 6154 register_name = "SRSConf4"; 6155 break; 6156 case CP0_REG06__PWCTL: 6157 check_pw(ctx); 6158 gen_helper_mtc0_pwctl(tcg_env, arg); 6159 register_name = "PWCtl"; 6160 break; 6161 default: 6162 goto cp0_unimplemented; 6163 } 6164 break; 6165 case CP0_REGISTER_07: 6166 switch (sel) { 6167 case CP0_REG07__HWRENA: 6168 check_insn(ctx, ISA_MIPS_R2); 6169 gen_helper_mtc0_hwrena(tcg_env, arg); 6170 ctx->base.is_jmp = DISAS_STOP; 6171 register_name = "HWREna"; 6172 break; 6173 default: 6174 goto cp0_unimplemented; 6175 } 6176 break; 6177 case CP0_REGISTER_08: 6178 switch (sel) { 6179 case CP0_REG08__BADVADDR: 6180 /* ignored */ 6181 register_name = "BadVAddr"; 6182 break; 6183 case CP0_REG08__BADINSTR: 6184 /* ignored */ 6185 register_name = "BadInstr"; 6186 break; 6187 case CP0_REG08__BADINSTRP: 6188 /* ignored */ 6189 register_name = "BadInstrP"; 6190 break; 6191 case CP0_REG08__BADINSTRX: 6192 /* ignored */ 6193 register_name = "BadInstrX"; 6194 break; 6195 default: 6196 goto cp0_unimplemented; 6197 } 6198 break; 6199 case CP0_REGISTER_09: 6200 switch (sel) { 6201 case CP0_REG09__COUNT: 6202 gen_helper_mtc0_count(tcg_env, arg); 6203 register_name = "Count"; 6204 break; 6205 default: 6206 goto cp0_unimplemented; 6207 } 6208 break; 6209 case CP0_REGISTER_10: 6210 switch (sel) { 6211 case CP0_REG10__ENTRYHI: 6212 gen_helper_mtc0_entryhi(tcg_env, arg); 6213 register_name = "EntryHi"; 6214 break; 6215 default: 6216 goto cp0_unimplemented; 6217 } 6218 break; 6219 case CP0_REGISTER_11: 6220 switch (sel) { 6221 case CP0_REG11__COMPARE: 6222 gen_helper_mtc0_compare(tcg_env, arg); 6223 register_name = "Compare"; 6224 break; 6225 /* 6,7 are implementation dependent */ 6226 default: 6227 goto cp0_unimplemented; 6228 } 6229 break; 6230 case CP0_REGISTER_12: 6231 switch (sel) { 6232 case CP0_REG12__STATUS: 6233 save_cpu_state(ctx, 1); 6234 gen_helper_mtc0_status(tcg_env, arg); 6235 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6236 gen_save_pc(ctx->base.pc_next + 4); 6237 ctx->base.is_jmp = DISAS_EXIT; 6238 register_name = "Status"; 6239 break; 6240 case CP0_REG12__INTCTL: 6241 check_insn(ctx, ISA_MIPS_R2); 6242 gen_helper_mtc0_intctl(tcg_env, arg); 6243 /* Stop translation as we may have switched the execution mode */ 6244 ctx->base.is_jmp = DISAS_STOP; 6245 register_name = "IntCtl"; 6246 break; 6247 case CP0_REG12__SRSCTL: 6248 check_insn(ctx, ISA_MIPS_R2); 6249 gen_helper_mtc0_srsctl(tcg_env, arg); 6250 /* Stop translation as we may have switched the execution mode */ 6251 ctx->base.is_jmp = DISAS_STOP; 6252 register_name = "SRSCtl"; 6253 break; 6254 case CP0_REG12__SRSMAP: 6255 check_insn(ctx, ISA_MIPS_R2); 6256 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6257 /* Stop translation as we may have switched the execution mode */ 6258 ctx->base.is_jmp = DISAS_STOP; 6259 register_name = "SRSMap"; 6260 break; 6261 default: 6262 goto cp0_unimplemented; 6263 } 6264 break; 6265 case CP0_REGISTER_13: 6266 switch (sel) { 6267 case CP0_REG13__CAUSE: 6268 save_cpu_state(ctx, 1); 6269 gen_helper_mtc0_cause(tcg_env, arg); 6270 /* 6271 * Stop translation as we may have triggered an interrupt. 6272 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6273 * translated code to check for pending interrupts. 6274 */ 6275 gen_save_pc(ctx->base.pc_next + 4); 6276 ctx->base.is_jmp = DISAS_EXIT; 6277 register_name = "Cause"; 6278 break; 6279 default: 6280 goto cp0_unimplemented; 6281 } 6282 break; 6283 case CP0_REGISTER_14: 6284 switch (sel) { 6285 case CP0_REG14__EPC: 6286 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 6287 register_name = "EPC"; 6288 break; 6289 default: 6290 goto cp0_unimplemented; 6291 } 6292 break; 6293 case CP0_REGISTER_15: 6294 switch (sel) { 6295 case CP0_REG15__PRID: 6296 /* ignored */ 6297 register_name = "PRid"; 6298 break; 6299 case CP0_REG15__EBASE: 6300 check_insn(ctx, ISA_MIPS_R2); 6301 gen_helper_mtc0_ebase(tcg_env, arg); 6302 register_name = "EBase"; 6303 break; 6304 default: 6305 goto cp0_unimplemented; 6306 } 6307 break; 6308 case CP0_REGISTER_16: 6309 switch (sel) { 6310 case CP0_REG16__CONFIG: 6311 gen_helper_mtc0_config0(tcg_env, arg); 6312 register_name = "Config"; 6313 /* Stop translation as we may have switched the execution mode */ 6314 ctx->base.is_jmp = DISAS_STOP; 6315 break; 6316 case CP0_REG16__CONFIG1: 6317 /* ignored, read only */ 6318 register_name = "Config1"; 6319 break; 6320 case CP0_REG16__CONFIG2: 6321 gen_helper_mtc0_config2(tcg_env, arg); 6322 register_name = "Config2"; 6323 /* Stop translation as we may have switched the execution mode */ 6324 ctx->base.is_jmp = DISAS_STOP; 6325 break; 6326 case CP0_REG16__CONFIG3: 6327 gen_helper_mtc0_config3(tcg_env, arg); 6328 register_name = "Config3"; 6329 /* Stop translation as we may have switched the execution mode */ 6330 ctx->base.is_jmp = DISAS_STOP; 6331 break; 6332 case CP0_REG16__CONFIG4: 6333 gen_helper_mtc0_config4(tcg_env, arg); 6334 register_name = "Config4"; 6335 ctx->base.is_jmp = DISAS_STOP; 6336 break; 6337 case CP0_REG16__CONFIG5: 6338 gen_helper_mtc0_config5(tcg_env, arg); 6339 register_name = "Config5"; 6340 /* Stop translation as we may have switched the execution mode */ 6341 ctx->base.is_jmp = DISAS_STOP; 6342 break; 6343 /* 6,7 are implementation dependent */ 6344 case CP0_REG16__CONFIG6: 6345 /* ignored */ 6346 register_name = "Config6"; 6347 break; 6348 case CP0_REG16__CONFIG7: 6349 /* ignored */ 6350 register_name = "Config7"; 6351 break; 6352 default: 6353 register_name = "Invalid config selector"; 6354 goto cp0_unimplemented; 6355 } 6356 break; 6357 case CP0_REGISTER_17: 6358 switch (sel) { 6359 case CP0_REG17__LLADDR: 6360 gen_helper_mtc0_lladdr(tcg_env, arg); 6361 register_name = "LLAddr"; 6362 break; 6363 case CP0_REG17__MAAR: 6364 CP0_CHECK(ctx->mrp); 6365 gen_helper_mtc0_maar(tcg_env, arg); 6366 register_name = "MAAR"; 6367 break; 6368 case CP0_REG17__MAARI: 6369 CP0_CHECK(ctx->mrp); 6370 gen_helper_mtc0_maari(tcg_env, arg); 6371 register_name = "MAARI"; 6372 break; 6373 default: 6374 goto cp0_unimplemented; 6375 } 6376 break; 6377 case CP0_REGISTER_18: 6378 switch (sel) { 6379 case CP0_REG18__WATCHLO0: 6380 case CP0_REG18__WATCHLO1: 6381 case CP0_REG18__WATCHLO2: 6382 case CP0_REG18__WATCHLO3: 6383 case CP0_REG18__WATCHLO4: 6384 case CP0_REG18__WATCHLO5: 6385 case CP0_REG18__WATCHLO6: 6386 case CP0_REG18__WATCHLO7: 6387 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6388 gen_helper_0e1i(mtc0_watchlo, arg, sel); 6389 register_name = "WatchLo"; 6390 break; 6391 default: 6392 goto cp0_unimplemented; 6393 } 6394 break; 6395 case CP0_REGISTER_19: 6396 switch (sel) { 6397 case CP0_REG19__WATCHHI0: 6398 case CP0_REG19__WATCHHI1: 6399 case CP0_REG19__WATCHHI2: 6400 case CP0_REG19__WATCHHI3: 6401 case CP0_REG19__WATCHHI4: 6402 case CP0_REG19__WATCHHI5: 6403 case CP0_REG19__WATCHHI6: 6404 case CP0_REG19__WATCHHI7: 6405 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6406 gen_helper_0e1i(mtc0_watchhi, arg, sel); 6407 register_name = "WatchHi"; 6408 break; 6409 default: 6410 goto cp0_unimplemented; 6411 } 6412 break; 6413 case CP0_REGISTER_20: 6414 switch (sel) { 6415 case CP0_REG20__XCONTEXT: 6416 #if defined(TARGET_MIPS64) 6417 check_insn(ctx, ISA_MIPS3); 6418 gen_helper_mtc0_xcontext(tcg_env, arg); 6419 register_name = "XContext"; 6420 break; 6421 #endif 6422 default: 6423 goto cp0_unimplemented; 6424 } 6425 break; 6426 case CP0_REGISTER_21: 6427 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6428 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6429 switch (sel) { 6430 case 0: 6431 gen_helper_mtc0_framemask(tcg_env, arg); 6432 register_name = "Framemask"; 6433 break; 6434 default: 6435 goto cp0_unimplemented; 6436 } 6437 break; 6438 case CP0_REGISTER_22: 6439 /* ignored */ 6440 register_name = "Diagnostic"; /* implementation dependent */ 6441 break; 6442 case CP0_REGISTER_23: 6443 switch (sel) { 6444 case CP0_REG23__DEBUG: 6445 gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */ 6446 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6447 gen_save_pc(ctx->base.pc_next + 4); 6448 ctx->base.is_jmp = DISAS_EXIT; 6449 register_name = "Debug"; 6450 break; 6451 case CP0_REG23__TRACECONTROL: 6452 /* PDtrace support */ 6453 /* gen_helper_mtc0_tracecontrol(tcg_env, arg); */ 6454 register_name = "TraceControl"; 6455 /* Stop translation as we may have switched the execution mode */ 6456 ctx->base.is_jmp = DISAS_STOP; 6457 goto cp0_unimplemented; 6458 case CP0_REG23__TRACECONTROL2: 6459 /* PDtrace support */ 6460 /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */ 6461 register_name = "TraceControl2"; 6462 /* Stop translation as we may have switched the execution mode */ 6463 ctx->base.is_jmp = DISAS_STOP; 6464 goto cp0_unimplemented; 6465 case CP0_REG23__USERTRACEDATA1: 6466 /* Stop translation as we may have switched the execution mode */ 6467 ctx->base.is_jmp = DISAS_STOP; 6468 /* PDtrace support */ 6469 /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/ 6470 register_name = "UserTraceData"; 6471 /* Stop translation as we may have switched the execution mode */ 6472 ctx->base.is_jmp = DISAS_STOP; 6473 goto cp0_unimplemented; 6474 case CP0_REG23__TRACEIBPC: 6475 /* PDtrace support */ 6476 /* gen_helper_mtc0_traceibpc(tcg_env, arg); */ 6477 /* Stop translation as we may have switched the execution mode */ 6478 ctx->base.is_jmp = DISAS_STOP; 6479 register_name = "TraceIBPC"; 6480 goto cp0_unimplemented; 6481 case CP0_REG23__TRACEDBPC: 6482 /* PDtrace support */ 6483 /* gen_helper_mtc0_tracedbpc(tcg_env, arg); */ 6484 /* Stop translation as we may have switched the execution mode */ 6485 ctx->base.is_jmp = DISAS_STOP; 6486 register_name = "TraceDBPC"; 6487 goto cp0_unimplemented; 6488 default: 6489 goto cp0_unimplemented; 6490 } 6491 break; 6492 case CP0_REGISTER_24: 6493 switch (sel) { 6494 case CP0_REG24__DEPC: 6495 /* EJTAG support */ 6496 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 6497 register_name = "DEPC"; 6498 break; 6499 default: 6500 goto cp0_unimplemented; 6501 } 6502 break; 6503 case CP0_REGISTER_25: 6504 switch (sel) { 6505 case CP0_REG25__PERFCTL0: 6506 gen_helper_mtc0_performance0(tcg_env, arg); 6507 register_name = "Performance0"; 6508 break; 6509 case CP0_REG25__PERFCNT0: 6510 /* gen_helper_mtc0_performance1(arg); */ 6511 register_name = "Performance1"; 6512 goto cp0_unimplemented; 6513 case CP0_REG25__PERFCTL1: 6514 /* gen_helper_mtc0_performance2(arg); */ 6515 register_name = "Performance2"; 6516 goto cp0_unimplemented; 6517 case CP0_REG25__PERFCNT1: 6518 /* gen_helper_mtc0_performance3(arg); */ 6519 register_name = "Performance3"; 6520 goto cp0_unimplemented; 6521 case CP0_REG25__PERFCTL2: 6522 /* gen_helper_mtc0_performance4(arg); */ 6523 register_name = "Performance4"; 6524 goto cp0_unimplemented; 6525 case CP0_REG25__PERFCNT2: 6526 /* gen_helper_mtc0_performance5(arg); */ 6527 register_name = "Performance5"; 6528 goto cp0_unimplemented; 6529 case CP0_REG25__PERFCTL3: 6530 /* gen_helper_mtc0_performance6(arg); */ 6531 register_name = "Performance6"; 6532 goto cp0_unimplemented; 6533 case CP0_REG25__PERFCNT3: 6534 /* gen_helper_mtc0_performance7(arg); */ 6535 register_name = "Performance7"; 6536 goto cp0_unimplemented; 6537 default: 6538 goto cp0_unimplemented; 6539 } 6540 break; 6541 case CP0_REGISTER_26: 6542 switch (sel) { 6543 case CP0_REG26__ERRCTL: 6544 gen_helper_mtc0_errctl(tcg_env, arg); 6545 ctx->base.is_jmp = DISAS_STOP; 6546 register_name = "ErrCtl"; 6547 break; 6548 default: 6549 goto cp0_unimplemented; 6550 } 6551 break; 6552 case CP0_REGISTER_27: 6553 switch (sel) { 6554 case CP0_REG27__CACHERR: 6555 /* ignored */ 6556 register_name = "CacheErr"; 6557 break; 6558 default: 6559 goto cp0_unimplemented; 6560 } 6561 break; 6562 case CP0_REGISTER_28: 6563 switch (sel) { 6564 case CP0_REG28__TAGLO: 6565 case CP0_REG28__TAGLO1: 6566 case CP0_REG28__TAGLO2: 6567 case CP0_REG28__TAGLO3: 6568 gen_helper_mtc0_taglo(tcg_env, arg); 6569 register_name = "TagLo"; 6570 break; 6571 case CP0_REG28__DATALO: 6572 case CP0_REG28__DATALO1: 6573 case CP0_REG28__DATALO2: 6574 case CP0_REG28__DATALO3: 6575 gen_helper_mtc0_datalo(tcg_env, arg); 6576 register_name = "DataLo"; 6577 break; 6578 default: 6579 goto cp0_unimplemented; 6580 } 6581 break; 6582 case CP0_REGISTER_29: 6583 switch (sel) { 6584 case CP0_REG29__TAGHI: 6585 case CP0_REG29__TAGHI1: 6586 case CP0_REG29__TAGHI2: 6587 case CP0_REG29__TAGHI3: 6588 gen_helper_mtc0_taghi(tcg_env, arg); 6589 register_name = "TagHi"; 6590 break; 6591 case CP0_REG29__DATAHI: 6592 case CP0_REG29__DATAHI1: 6593 case CP0_REG29__DATAHI2: 6594 case CP0_REG29__DATAHI3: 6595 gen_helper_mtc0_datahi(tcg_env, arg); 6596 register_name = "DataHi"; 6597 break; 6598 default: 6599 register_name = "invalid sel"; 6600 goto cp0_unimplemented; 6601 } 6602 break; 6603 case CP0_REGISTER_30: 6604 switch (sel) { 6605 case CP0_REG30__ERROREPC: 6606 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 6607 register_name = "ErrorEPC"; 6608 break; 6609 default: 6610 goto cp0_unimplemented; 6611 } 6612 break; 6613 case CP0_REGISTER_31: 6614 switch (sel) { 6615 case CP0_REG31__DESAVE: 6616 /* EJTAG support */ 6617 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 6618 register_name = "DESAVE"; 6619 break; 6620 case CP0_REG31__KSCRATCH1: 6621 case CP0_REG31__KSCRATCH2: 6622 case CP0_REG31__KSCRATCH3: 6623 case CP0_REG31__KSCRATCH4: 6624 case CP0_REG31__KSCRATCH5: 6625 case CP0_REG31__KSCRATCH6: 6626 CP0_CHECK(ctx->kscrexist & (1 << sel)); 6627 tcg_gen_st_tl(arg, tcg_env, 6628 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 6629 register_name = "KScratch"; 6630 break; 6631 default: 6632 goto cp0_unimplemented; 6633 } 6634 break; 6635 default: 6636 goto cp0_unimplemented; 6637 } 6638 trace_mips_translate_c0("mtc0", register_name, reg, sel); 6639 6640 /* For simplicity assume that all writes can cause interrupts. */ 6641 if (icount) { 6642 /* 6643 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6644 * translated code to check for pending interrupts. 6645 */ 6646 gen_save_pc(ctx->base.pc_next + 4); 6647 ctx->base.is_jmp = DISAS_EXIT; 6648 } 6649 return; 6650 6651 cp0_unimplemented: 6652 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", 6653 register_name, reg, sel); 6654 } 6655 6656 #if defined(TARGET_MIPS64) 6657 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 6658 { 6659 const char *register_name = "invalid"; 6660 6661 if (sel != 0) { 6662 check_insn(ctx, ISA_MIPS_R1); 6663 } 6664 6665 switch (reg) { 6666 case CP0_REGISTER_00: 6667 switch (sel) { 6668 case CP0_REG00__INDEX: 6669 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 6670 register_name = "Index"; 6671 break; 6672 case CP0_REG00__MVPCONTROL: 6673 CP0_CHECK(ctx->insn_flags & ASE_MT); 6674 gen_helper_mfc0_mvpcontrol(arg, tcg_env); 6675 register_name = "MVPControl"; 6676 break; 6677 case CP0_REG00__MVPCONF0: 6678 CP0_CHECK(ctx->insn_flags & ASE_MT); 6679 gen_helper_mfc0_mvpconf0(arg, tcg_env); 6680 register_name = "MVPConf0"; 6681 break; 6682 case CP0_REG00__MVPCONF1: 6683 CP0_CHECK(ctx->insn_flags & ASE_MT); 6684 gen_helper_mfc0_mvpconf1(arg, tcg_env); 6685 register_name = "MVPConf1"; 6686 break; 6687 case CP0_REG00__VPCONTROL: 6688 CP0_CHECK(ctx->vp); 6689 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 6690 register_name = "VPControl"; 6691 break; 6692 default: 6693 goto cp0_unimplemented; 6694 } 6695 break; 6696 case CP0_REGISTER_01: 6697 switch (sel) { 6698 case CP0_REG01__RANDOM: 6699 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6700 gen_helper_mfc0_random(arg, tcg_env); 6701 register_name = "Random"; 6702 break; 6703 case CP0_REG01__VPECONTROL: 6704 CP0_CHECK(ctx->insn_flags & ASE_MT); 6705 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 6706 register_name = "VPEControl"; 6707 break; 6708 case CP0_REG01__VPECONF0: 6709 CP0_CHECK(ctx->insn_flags & ASE_MT); 6710 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 6711 register_name = "VPEConf0"; 6712 break; 6713 case CP0_REG01__VPECONF1: 6714 CP0_CHECK(ctx->insn_flags & ASE_MT); 6715 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 6716 register_name = "VPEConf1"; 6717 break; 6718 case CP0_REG01__YQMASK: 6719 CP0_CHECK(ctx->insn_flags & ASE_MT); 6720 tcg_gen_ld_tl(arg, tcg_env, 6721 offsetof(CPUMIPSState, CP0_YQMask)); 6722 register_name = "YQMask"; 6723 break; 6724 case CP0_REG01__VPESCHEDULE: 6725 CP0_CHECK(ctx->insn_flags & ASE_MT); 6726 tcg_gen_ld_tl(arg, tcg_env, 6727 offsetof(CPUMIPSState, CP0_VPESchedule)); 6728 register_name = "VPESchedule"; 6729 break; 6730 case CP0_REG01__VPESCHEFBACK: 6731 CP0_CHECK(ctx->insn_flags & ASE_MT); 6732 tcg_gen_ld_tl(arg, tcg_env, 6733 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6734 register_name = "VPEScheFBack"; 6735 break; 6736 case CP0_REG01__VPEOPT: 6737 CP0_CHECK(ctx->insn_flags & ASE_MT); 6738 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 6739 register_name = "VPEOpt"; 6740 break; 6741 default: 6742 goto cp0_unimplemented; 6743 } 6744 break; 6745 case CP0_REGISTER_02: 6746 switch (sel) { 6747 case CP0_REG02__ENTRYLO0: 6748 tcg_gen_ld_tl(arg, tcg_env, 6749 offsetof(CPUMIPSState, CP0_EntryLo0)); 6750 register_name = "EntryLo0"; 6751 break; 6752 case CP0_REG02__TCSTATUS: 6753 CP0_CHECK(ctx->insn_flags & ASE_MT); 6754 gen_helper_mfc0_tcstatus(arg, tcg_env); 6755 register_name = "TCStatus"; 6756 break; 6757 case CP0_REG02__TCBIND: 6758 CP0_CHECK(ctx->insn_flags & ASE_MT); 6759 gen_helper_mfc0_tcbind(arg, tcg_env); 6760 register_name = "TCBind"; 6761 break; 6762 case CP0_REG02__TCRESTART: 6763 CP0_CHECK(ctx->insn_flags & ASE_MT); 6764 gen_helper_dmfc0_tcrestart(arg, tcg_env); 6765 register_name = "TCRestart"; 6766 break; 6767 case CP0_REG02__TCHALT: 6768 CP0_CHECK(ctx->insn_flags & ASE_MT); 6769 gen_helper_dmfc0_tchalt(arg, tcg_env); 6770 register_name = "TCHalt"; 6771 break; 6772 case CP0_REG02__TCCONTEXT: 6773 CP0_CHECK(ctx->insn_flags & ASE_MT); 6774 gen_helper_dmfc0_tccontext(arg, tcg_env); 6775 register_name = "TCContext"; 6776 break; 6777 case CP0_REG02__TCSCHEDULE: 6778 CP0_CHECK(ctx->insn_flags & ASE_MT); 6779 gen_helper_dmfc0_tcschedule(arg, tcg_env); 6780 register_name = "TCSchedule"; 6781 break; 6782 case CP0_REG02__TCSCHEFBACK: 6783 CP0_CHECK(ctx->insn_flags & ASE_MT); 6784 gen_helper_dmfc0_tcschefback(arg, tcg_env); 6785 register_name = "TCScheFBack"; 6786 break; 6787 default: 6788 goto cp0_unimplemented; 6789 } 6790 break; 6791 case CP0_REGISTER_03: 6792 switch (sel) { 6793 case CP0_REG03__ENTRYLO1: 6794 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 6795 register_name = "EntryLo1"; 6796 break; 6797 case CP0_REG03__GLOBALNUM: 6798 CP0_CHECK(ctx->vp); 6799 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 6800 register_name = "GlobalNumber"; 6801 break; 6802 default: 6803 goto cp0_unimplemented; 6804 } 6805 break; 6806 case CP0_REGISTER_04: 6807 switch (sel) { 6808 case CP0_REG04__CONTEXT: 6809 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context)); 6810 register_name = "Context"; 6811 break; 6812 case CP0_REG04__CONTEXTCONFIG: 6813 /* SmartMIPS ASE */ 6814 /* gen_helper_dmfc0_contextconfig(arg); */ 6815 register_name = "ContextConfig"; 6816 goto cp0_unimplemented; 6817 case CP0_REG04__USERLOCAL: 6818 CP0_CHECK(ctx->ulri); 6819 tcg_gen_ld_tl(arg, tcg_env, 6820 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6821 register_name = "UserLocal"; 6822 break; 6823 case CP0_REG04__MMID: 6824 CP0_CHECK(ctx->mi); 6825 gen_helper_mtc0_memorymapid(tcg_env, arg); 6826 register_name = "MMID"; 6827 break; 6828 default: 6829 goto cp0_unimplemented; 6830 } 6831 break; 6832 case CP0_REGISTER_05: 6833 switch (sel) { 6834 case CP0_REG05__PAGEMASK: 6835 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 6836 register_name = "PageMask"; 6837 break; 6838 case CP0_REG05__PAGEGRAIN: 6839 check_insn(ctx, ISA_MIPS_R2); 6840 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 6841 register_name = "PageGrain"; 6842 break; 6843 case CP0_REG05__SEGCTL0: 6844 CP0_CHECK(ctx->sc); 6845 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 6846 register_name = "SegCtl0"; 6847 break; 6848 case CP0_REG05__SEGCTL1: 6849 CP0_CHECK(ctx->sc); 6850 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 6851 register_name = "SegCtl1"; 6852 break; 6853 case CP0_REG05__SEGCTL2: 6854 CP0_CHECK(ctx->sc); 6855 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 6856 register_name = "SegCtl2"; 6857 break; 6858 case CP0_REG05__PWBASE: 6859 check_pw(ctx); 6860 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase)); 6861 register_name = "PWBase"; 6862 break; 6863 case CP0_REG05__PWFIELD: 6864 check_pw(ctx); 6865 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWField)); 6866 register_name = "PWField"; 6867 break; 6868 case CP0_REG05__PWSIZE: 6869 check_pw(ctx); 6870 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWSize)); 6871 register_name = "PWSize"; 6872 break; 6873 default: 6874 goto cp0_unimplemented; 6875 } 6876 break; 6877 case CP0_REGISTER_06: 6878 switch (sel) { 6879 case CP0_REG06__WIRED: 6880 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 6881 register_name = "Wired"; 6882 break; 6883 case CP0_REG06__SRSCONF0: 6884 check_insn(ctx, ISA_MIPS_R2); 6885 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 6886 register_name = "SRSConf0"; 6887 break; 6888 case CP0_REG06__SRSCONF1: 6889 check_insn(ctx, ISA_MIPS_R2); 6890 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 6891 register_name = "SRSConf1"; 6892 break; 6893 case CP0_REG06__SRSCONF2: 6894 check_insn(ctx, ISA_MIPS_R2); 6895 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 6896 register_name = "SRSConf2"; 6897 break; 6898 case CP0_REG06__SRSCONF3: 6899 check_insn(ctx, ISA_MIPS_R2); 6900 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 6901 register_name = "SRSConf3"; 6902 break; 6903 case CP0_REG06__SRSCONF4: 6904 check_insn(ctx, ISA_MIPS_R2); 6905 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 6906 register_name = "SRSConf4"; 6907 break; 6908 case CP0_REG06__PWCTL: 6909 check_pw(ctx); 6910 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 6911 register_name = "PWCtl"; 6912 break; 6913 default: 6914 goto cp0_unimplemented; 6915 } 6916 break; 6917 case CP0_REGISTER_07: 6918 switch (sel) { 6919 case CP0_REG07__HWRENA: 6920 check_insn(ctx, ISA_MIPS_R2); 6921 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 6922 register_name = "HWREna"; 6923 break; 6924 default: 6925 goto cp0_unimplemented; 6926 } 6927 break; 6928 case CP0_REGISTER_08: 6929 switch (sel) { 6930 case CP0_REG08__BADVADDR: 6931 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 6932 register_name = "BadVAddr"; 6933 break; 6934 case CP0_REG08__BADINSTR: 6935 CP0_CHECK(ctx->bi); 6936 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 6937 register_name = "BadInstr"; 6938 break; 6939 case CP0_REG08__BADINSTRP: 6940 CP0_CHECK(ctx->bp); 6941 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 6942 register_name = "BadInstrP"; 6943 break; 6944 case CP0_REG08__BADINSTRX: 6945 CP0_CHECK(ctx->bi); 6946 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 6947 tcg_gen_andi_tl(arg, arg, ~0xffff); 6948 register_name = "BadInstrX"; 6949 break; 6950 default: 6951 goto cp0_unimplemented; 6952 } 6953 break; 6954 case CP0_REGISTER_09: 6955 switch (sel) { 6956 case CP0_REG09__COUNT: 6957 /* Mark as an IO operation because we read the time. */ 6958 translator_io_start(&ctx->base); 6959 gen_helper_mfc0_count(arg, tcg_env); 6960 /* 6961 * Break the TB to be able to take timer interrupts immediately 6962 * after reading count. DISAS_STOP isn't sufficient, we need to 6963 * ensure we break completely out of translated code. 6964 */ 6965 gen_save_pc(ctx->base.pc_next + 4); 6966 ctx->base.is_jmp = DISAS_EXIT; 6967 register_name = "Count"; 6968 break; 6969 default: 6970 goto cp0_unimplemented; 6971 } 6972 break; 6973 case CP0_REGISTER_10: 6974 switch (sel) { 6975 case CP0_REG10__ENTRYHI: 6976 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi)); 6977 register_name = "EntryHi"; 6978 break; 6979 default: 6980 goto cp0_unimplemented; 6981 } 6982 break; 6983 case CP0_REGISTER_11: 6984 switch (sel) { 6985 case CP0_REG11__COMPARE: 6986 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 6987 register_name = "Compare"; 6988 break; 6989 /* 6,7 are implementation dependent */ 6990 default: 6991 goto cp0_unimplemented; 6992 } 6993 break; 6994 case CP0_REGISTER_12: 6995 switch (sel) { 6996 case CP0_REG12__STATUS: 6997 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 6998 register_name = "Status"; 6999 break; 7000 case CP0_REG12__INTCTL: 7001 check_insn(ctx, ISA_MIPS_R2); 7002 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 7003 register_name = "IntCtl"; 7004 break; 7005 case CP0_REG12__SRSCTL: 7006 check_insn(ctx, ISA_MIPS_R2); 7007 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 7008 register_name = "SRSCtl"; 7009 break; 7010 case CP0_REG12__SRSMAP: 7011 check_insn(ctx, ISA_MIPS_R2); 7012 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7013 register_name = "SRSMap"; 7014 break; 7015 default: 7016 goto cp0_unimplemented; 7017 } 7018 break; 7019 case CP0_REGISTER_13: 7020 switch (sel) { 7021 case CP0_REG13__CAUSE: 7022 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 7023 register_name = "Cause"; 7024 break; 7025 default: 7026 goto cp0_unimplemented; 7027 } 7028 break; 7029 case CP0_REGISTER_14: 7030 switch (sel) { 7031 case CP0_REG14__EPC: 7032 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 7033 register_name = "EPC"; 7034 break; 7035 default: 7036 goto cp0_unimplemented; 7037 } 7038 break; 7039 case CP0_REGISTER_15: 7040 switch (sel) { 7041 case CP0_REG15__PRID: 7042 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 7043 register_name = "PRid"; 7044 break; 7045 case CP0_REG15__EBASE: 7046 check_insn(ctx, ISA_MIPS_R2); 7047 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase)); 7048 register_name = "EBase"; 7049 break; 7050 case CP0_REG15__CMGCRBASE: 7051 check_insn(ctx, ISA_MIPS_R2); 7052 CP0_CHECK(ctx->cmgcr); 7053 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 7054 register_name = "CMGCRBase"; 7055 break; 7056 default: 7057 goto cp0_unimplemented; 7058 } 7059 break; 7060 case CP0_REGISTER_16: 7061 switch (sel) { 7062 case CP0_REG16__CONFIG: 7063 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 7064 register_name = "Config"; 7065 break; 7066 case CP0_REG16__CONFIG1: 7067 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 7068 register_name = "Config1"; 7069 break; 7070 case CP0_REG16__CONFIG2: 7071 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 7072 register_name = "Config2"; 7073 break; 7074 case CP0_REG16__CONFIG3: 7075 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 7076 register_name = "Config3"; 7077 break; 7078 case CP0_REG16__CONFIG4: 7079 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 7080 register_name = "Config4"; 7081 break; 7082 case CP0_REG16__CONFIG5: 7083 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 7084 register_name = "Config5"; 7085 break; 7086 /* 6,7 are implementation dependent */ 7087 case CP0_REG16__CONFIG6: 7088 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 7089 register_name = "Config6"; 7090 break; 7091 case CP0_REG16__CONFIG7: 7092 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 7093 register_name = "Config7"; 7094 break; 7095 default: 7096 goto cp0_unimplemented; 7097 } 7098 break; 7099 case CP0_REGISTER_17: 7100 switch (sel) { 7101 case CP0_REG17__LLADDR: 7102 gen_helper_dmfc0_lladdr(arg, tcg_env); 7103 register_name = "LLAddr"; 7104 break; 7105 case CP0_REG17__MAAR: 7106 CP0_CHECK(ctx->mrp); 7107 gen_helper_dmfc0_maar(arg, tcg_env); 7108 register_name = "MAAR"; 7109 break; 7110 case CP0_REG17__MAARI: 7111 CP0_CHECK(ctx->mrp); 7112 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 7113 register_name = "MAARI"; 7114 break; 7115 default: 7116 goto cp0_unimplemented; 7117 } 7118 break; 7119 case CP0_REGISTER_18: 7120 switch (sel) { 7121 case CP0_REG18__WATCHLO0: 7122 case CP0_REG18__WATCHLO1: 7123 case CP0_REG18__WATCHLO2: 7124 case CP0_REG18__WATCHLO3: 7125 case CP0_REG18__WATCHLO4: 7126 case CP0_REG18__WATCHLO5: 7127 case CP0_REG18__WATCHLO6: 7128 case CP0_REG18__WATCHLO7: 7129 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7130 gen_helper_1e0i(dmfc0_watchlo, arg, sel); 7131 register_name = "WatchLo"; 7132 break; 7133 default: 7134 goto cp0_unimplemented; 7135 } 7136 break; 7137 case CP0_REGISTER_19: 7138 switch (sel) { 7139 case CP0_REG19__WATCHHI0: 7140 case CP0_REG19__WATCHHI1: 7141 case CP0_REG19__WATCHHI2: 7142 case CP0_REG19__WATCHHI3: 7143 case CP0_REG19__WATCHHI4: 7144 case CP0_REG19__WATCHHI5: 7145 case CP0_REG19__WATCHHI6: 7146 case CP0_REG19__WATCHHI7: 7147 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7148 gen_helper_1e0i(dmfc0_watchhi, arg, sel); 7149 register_name = "WatchHi"; 7150 break; 7151 default: 7152 goto cp0_unimplemented; 7153 } 7154 break; 7155 case CP0_REGISTER_20: 7156 switch (sel) { 7157 case CP0_REG20__XCONTEXT: 7158 check_insn(ctx, ISA_MIPS3); 7159 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext)); 7160 register_name = "XContext"; 7161 break; 7162 default: 7163 goto cp0_unimplemented; 7164 } 7165 break; 7166 case CP0_REGISTER_21: 7167 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7168 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7169 switch (sel) { 7170 case 0: 7171 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 7172 register_name = "Framemask"; 7173 break; 7174 default: 7175 goto cp0_unimplemented; 7176 } 7177 break; 7178 case CP0_REGISTER_22: 7179 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7180 register_name = "'Diagnostic"; /* implementation dependent */ 7181 break; 7182 case CP0_REGISTER_23: 7183 switch (sel) { 7184 case CP0_REG23__DEBUG: 7185 gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */ 7186 register_name = "Debug"; 7187 break; 7188 case CP0_REG23__TRACECONTROL: 7189 /* PDtrace support */ 7190 /* gen_helper_dmfc0_tracecontrol(arg, tcg_env); */ 7191 register_name = "TraceControl"; 7192 goto cp0_unimplemented; 7193 case CP0_REG23__TRACECONTROL2: 7194 /* PDtrace support */ 7195 /* gen_helper_dmfc0_tracecontrol2(arg, tcg_env); */ 7196 register_name = "TraceControl2"; 7197 goto cp0_unimplemented; 7198 case CP0_REG23__USERTRACEDATA1: 7199 /* PDtrace support */ 7200 /* gen_helper_dmfc0_usertracedata1(arg, tcg_env);*/ 7201 register_name = "UserTraceData1"; 7202 goto cp0_unimplemented; 7203 case CP0_REG23__TRACEIBPC: 7204 /* PDtrace support */ 7205 /* gen_helper_dmfc0_traceibpc(arg, tcg_env); */ 7206 register_name = "TraceIBPC"; 7207 goto cp0_unimplemented; 7208 case CP0_REG23__TRACEDBPC: 7209 /* PDtrace support */ 7210 /* gen_helper_dmfc0_tracedbpc(arg, tcg_env); */ 7211 register_name = "TraceDBPC"; 7212 goto cp0_unimplemented; 7213 default: 7214 goto cp0_unimplemented; 7215 } 7216 break; 7217 case CP0_REGISTER_24: 7218 switch (sel) { 7219 case CP0_REG24__DEPC: 7220 /* EJTAG support */ 7221 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 7222 register_name = "DEPC"; 7223 break; 7224 default: 7225 goto cp0_unimplemented; 7226 } 7227 break; 7228 case CP0_REGISTER_25: 7229 switch (sel) { 7230 case CP0_REG25__PERFCTL0: 7231 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 7232 register_name = "Performance0"; 7233 break; 7234 case CP0_REG25__PERFCNT0: 7235 /* gen_helper_dmfc0_performance1(arg); */ 7236 register_name = "Performance1"; 7237 goto cp0_unimplemented; 7238 case CP0_REG25__PERFCTL1: 7239 /* gen_helper_dmfc0_performance2(arg); */ 7240 register_name = "Performance2"; 7241 goto cp0_unimplemented; 7242 case CP0_REG25__PERFCNT1: 7243 /* gen_helper_dmfc0_performance3(arg); */ 7244 register_name = "Performance3"; 7245 goto cp0_unimplemented; 7246 case CP0_REG25__PERFCTL2: 7247 /* gen_helper_dmfc0_performance4(arg); */ 7248 register_name = "Performance4"; 7249 goto cp0_unimplemented; 7250 case CP0_REG25__PERFCNT2: 7251 /* gen_helper_dmfc0_performance5(arg); */ 7252 register_name = "Performance5"; 7253 goto cp0_unimplemented; 7254 case CP0_REG25__PERFCTL3: 7255 /* gen_helper_dmfc0_performance6(arg); */ 7256 register_name = "Performance6"; 7257 goto cp0_unimplemented; 7258 case CP0_REG25__PERFCNT3: 7259 /* gen_helper_dmfc0_performance7(arg); */ 7260 register_name = "Performance7"; 7261 goto cp0_unimplemented; 7262 default: 7263 goto cp0_unimplemented; 7264 } 7265 break; 7266 case CP0_REGISTER_26: 7267 switch (sel) { 7268 case CP0_REG26__ERRCTL: 7269 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 7270 register_name = "ErrCtl"; 7271 break; 7272 default: 7273 goto cp0_unimplemented; 7274 } 7275 break; 7276 case CP0_REGISTER_27: 7277 switch (sel) { 7278 /* ignored */ 7279 case CP0_REG27__CACHERR: 7280 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7281 register_name = "CacheErr"; 7282 break; 7283 default: 7284 goto cp0_unimplemented; 7285 } 7286 break; 7287 case CP0_REGISTER_28: 7288 switch (sel) { 7289 case CP0_REG28__TAGLO: 7290 case CP0_REG28__TAGLO1: 7291 case CP0_REG28__TAGLO2: 7292 case CP0_REG28__TAGLO3: 7293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 7294 register_name = "TagLo"; 7295 break; 7296 case CP0_REG28__DATALO: 7297 case CP0_REG28__DATALO1: 7298 case CP0_REG28__DATALO2: 7299 case CP0_REG28__DATALO3: 7300 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 7301 register_name = "DataLo"; 7302 break; 7303 default: 7304 goto cp0_unimplemented; 7305 } 7306 break; 7307 case CP0_REGISTER_29: 7308 switch (sel) { 7309 case CP0_REG29__TAGHI: 7310 case CP0_REG29__TAGHI1: 7311 case CP0_REG29__TAGHI2: 7312 case CP0_REG29__TAGHI3: 7313 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 7314 register_name = "TagHi"; 7315 break; 7316 case CP0_REG29__DATAHI: 7317 case CP0_REG29__DATAHI1: 7318 case CP0_REG29__DATAHI2: 7319 case CP0_REG29__DATAHI3: 7320 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 7321 register_name = "DataHi"; 7322 break; 7323 default: 7324 goto cp0_unimplemented; 7325 } 7326 break; 7327 case CP0_REGISTER_30: 7328 switch (sel) { 7329 case CP0_REG30__ERROREPC: 7330 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7331 register_name = "ErrorEPC"; 7332 break; 7333 default: 7334 goto cp0_unimplemented; 7335 } 7336 break; 7337 case CP0_REGISTER_31: 7338 switch (sel) { 7339 case CP0_REG31__DESAVE: 7340 /* EJTAG support */ 7341 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7342 register_name = "DESAVE"; 7343 break; 7344 case CP0_REG31__KSCRATCH1: 7345 case CP0_REG31__KSCRATCH2: 7346 case CP0_REG31__KSCRATCH3: 7347 case CP0_REG31__KSCRATCH4: 7348 case CP0_REG31__KSCRATCH5: 7349 case CP0_REG31__KSCRATCH6: 7350 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7351 tcg_gen_ld_tl(arg, tcg_env, 7352 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7353 register_name = "KScratch"; 7354 break; 7355 default: 7356 goto cp0_unimplemented; 7357 } 7358 break; 7359 default: 7360 goto cp0_unimplemented; 7361 } 7362 trace_mips_translate_c0("dmfc0", register_name, reg, sel); 7363 return; 7364 7365 cp0_unimplemented: 7366 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", 7367 register_name, reg, sel); 7368 gen_mfc0_unimplemented(ctx, arg); 7369 } 7370 7371 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7372 { 7373 const char *register_name = "invalid"; 7374 bool icount; 7375 7376 if (sel != 0) { 7377 check_insn(ctx, ISA_MIPS_R1); 7378 } 7379 7380 icount = translator_io_start(&ctx->base); 7381 7382 switch (reg) { 7383 case CP0_REGISTER_00: 7384 switch (sel) { 7385 case CP0_REG00__INDEX: 7386 gen_helper_mtc0_index(tcg_env, arg); 7387 register_name = "Index"; 7388 break; 7389 case CP0_REG00__MVPCONTROL: 7390 CP0_CHECK(ctx->insn_flags & ASE_MT); 7391 gen_helper_mtc0_mvpcontrol(tcg_env, arg); 7392 register_name = "MVPControl"; 7393 break; 7394 case CP0_REG00__MVPCONF0: 7395 CP0_CHECK(ctx->insn_flags & ASE_MT); 7396 /* ignored */ 7397 register_name = "MVPConf0"; 7398 break; 7399 case CP0_REG00__MVPCONF1: 7400 CP0_CHECK(ctx->insn_flags & ASE_MT); 7401 /* ignored */ 7402 register_name = "MVPConf1"; 7403 break; 7404 case CP0_REG00__VPCONTROL: 7405 CP0_CHECK(ctx->vp); 7406 /* ignored */ 7407 register_name = "VPControl"; 7408 break; 7409 default: 7410 goto cp0_unimplemented; 7411 } 7412 break; 7413 case CP0_REGISTER_01: 7414 switch (sel) { 7415 case CP0_REG01__RANDOM: 7416 /* ignored */ 7417 register_name = "Random"; 7418 break; 7419 case CP0_REG01__VPECONTROL: 7420 CP0_CHECK(ctx->insn_flags & ASE_MT); 7421 gen_helper_mtc0_vpecontrol(tcg_env, arg); 7422 register_name = "VPEControl"; 7423 break; 7424 case CP0_REG01__VPECONF0: 7425 CP0_CHECK(ctx->insn_flags & ASE_MT); 7426 gen_helper_mtc0_vpeconf0(tcg_env, arg); 7427 register_name = "VPEConf0"; 7428 break; 7429 case CP0_REG01__VPECONF1: 7430 CP0_CHECK(ctx->insn_flags & ASE_MT); 7431 gen_helper_mtc0_vpeconf1(tcg_env, arg); 7432 register_name = "VPEConf1"; 7433 break; 7434 case CP0_REG01__YQMASK: 7435 CP0_CHECK(ctx->insn_flags & ASE_MT); 7436 gen_helper_mtc0_yqmask(tcg_env, arg); 7437 register_name = "YQMask"; 7438 break; 7439 case CP0_REG01__VPESCHEDULE: 7440 CP0_CHECK(ctx->insn_flags & ASE_MT); 7441 tcg_gen_st_tl(arg, tcg_env, 7442 offsetof(CPUMIPSState, CP0_VPESchedule)); 7443 register_name = "VPESchedule"; 7444 break; 7445 case CP0_REG01__VPESCHEFBACK: 7446 CP0_CHECK(ctx->insn_flags & ASE_MT); 7447 tcg_gen_st_tl(arg, tcg_env, 7448 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7449 register_name = "VPEScheFBack"; 7450 break; 7451 case CP0_REG01__VPEOPT: 7452 CP0_CHECK(ctx->insn_flags & ASE_MT); 7453 gen_helper_mtc0_vpeopt(tcg_env, arg); 7454 register_name = "VPEOpt"; 7455 break; 7456 default: 7457 goto cp0_unimplemented; 7458 } 7459 break; 7460 case CP0_REGISTER_02: 7461 switch (sel) { 7462 case CP0_REG02__ENTRYLO0: 7463 gen_helper_dmtc0_entrylo0(tcg_env, arg); 7464 register_name = "EntryLo0"; 7465 break; 7466 case CP0_REG02__TCSTATUS: 7467 CP0_CHECK(ctx->insn_flags & ASE_MT); 7468 gen_helper_mtc0_tcstatus(tcg_env, arg); 7469 register_name = "TCStatus"; 7470 break; 7471 case CP0_REG02__TCBIND: 7472 CP0_CHECK(ctx->insn_flags & ASE_MT); 7473 gen_helper_mtc0_tcbind(tcg_env, arg); 7474 register_name = "TCBind"; 7475 break; 7476 case CP0_REG02__TCRESTART: 7477 CP0_CHECK(ctx->insn_flags & ASE_MT); 7478 gen_helper_mtc0_tcrestart(tcg_env, arg); 7479 register_name = "TCRestart"; 7480 break; 7481 case CP0_REG02__TCHALT: 7482 CP0_CHECK(ctx->insn_flags & ASE_MT); 7483 gen_helper_mtc0_tchalt(tcg_env, arg); 7484 register_name = "TCHalt"; 7485 break; 7486 case CP0_REG02__TCCONTEXT: 7487 CP0_CHECK(ctx->insn_flags & ASE_MT); 7488 gen_helper_mtc0_tccontext(tcg_env, arg); 7489 register_name = "TCContext"; 7490 break; 7491 case CP0_REG02__TCSCHEDULE: 7492 CP0_CHECK(ctx->insn_flags & ASE_MT); 7493 gen_helper_mtc0_tcschedule(tcg_env, arg); 7494 register_name = "TCSchedule"; 7495 break; 7496 case CP0_REG02__TCSCHEFBACK: 7497 CP0_CHECK(ctx->insn_flags & ASE_MT); 7498 gen_helper_mtc0_tcschefback(tcg_env, arg); 7499 register_name = "TCScheFBack"; 7500 break; 7501 default: 7502 goto cp0_unimplemented; 7503 } 7504 break; 7505 case CP0_REGISTER_03: 7506 switch (sel) { 7507 case CP0_REG03__ENTRYLO1: 7508 gen_helper_dmtc0_entrylo1(tcg_env, arg); 7509 register_name = "EntryLo1"; 7510 break; 7511 case CP0_REG03__GLOBALNUM: 7512 CP0_CHECK(ctx->vp); 7513 /* ignored */ 7514 register_name = "GlobalNumber"; 7515 break; 7516 default: 7517 goto cp0_unimplemented; 7518 } 7519 break; 7520 case CP0_REGISTER_04: 7521 switch (sel) { 7522 case CP0_REG04__CONTEXT: 7523 gen_helper_mtc0_context(tcg_env, arg); 7524 register_name = "Context"; 7525 break; 7526 case CP0_REG04__CONTEXTCONFIG: 7527 /* SmartMIPS ASE */ 7528 /* gen_helper_dmtc0_contextconfig(arg); */ 7529 register_name = "ContextConfig"; 7530 goto cp0_unimplemented; 7531 case CP0_REG04__USERLOCAL: 7532 CP0_CHECK(ctx->ulri); 7533 tcg_gen_st_tl(arg, tcg_env, 7534 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 7535 register_name = "UserLocal"; 7536 break; 7537 case CP0_REG04__MMID: 7538 CP0_CHECK(ctx->mi); 7539 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 7540 register_name = "MMID"; 7541 break; 7542 default: 7543 goto cp0_unimplemented; 7544 } 7545 break; 7546 case CP0_REGISTER_05: 7547 switch (sel) { 7548 case CP0_REG05__PAGEMASK: 7549 gen_helper_mtc0_pagemask(tcg_env, arg); 7550 register_name = "PageMask"; 7551 break; 7552 case CP0_REG05__PAGEGRAIN: 7553 check_insn(ctx, ISA_MIPS_R2); 7554 gen_helper_mtc0_pagegrain(tcg_env, arg); 7555 register_name = "PageGrain"; 7556 break; 7557 case CP0_REG05__SEGCTL0: 7558 CP0_CHECK(ctx->sc); 7559 gen_helper_mtc0_segctl0(tcg_env, arg); 7560 register_name = "SegCtl0"; 7561 break; 7562 case CP0_REG05__SEGCTL1: 7563 CP0_CHECK(ctx->sc); 7564 gen_helper_mtc0_segctl1(tcg_env, arg); 7565 register_name = "SegCtl1"; 7566 break; 7567 case CP0_REG05__SEGCTL2: 7568 CP0_CHECK(ctx->sc); 7569 gen_helper_mtc0_segctl2(tcg_env, arg); 7570 register_name = "SegCtl2"; 7571 break; 7572 case CP0_REG05__PWBASE: 7573 check_pw(ctx); 7574 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase)); 7575 register_name = "PWBase"; 7576 break; 7577 case CP0_REG05__PWFIELD: 7578 check_pw(ctx); 7579 gen_helper_mtc0_pwfield(tcg_env, arg); 7580 register_name = "PWField"; 7581 break; 7582 case CP0_REG05__PWSIZE: 7583 check_pw(ctx); 7584 gen_helper_mtc0_pwsize(tcg_env, arg); 7585 register_name = "PWSize"; 7586 break; 7587 default: 7588 goto cp0_unimplemented; 7589 } 7590 break; 7591 case CP0_REGISTER_06: 7592 switch (sel) { 7593 case CP0_REG06__WIRED: 7594 gen_helper_mtc0_wired(tcg_env, arg); 7595 register_name = "Wired"; 7596 break; 7597 case CP0_REG06__SRSCONF0: 7598 check_insn(ctx, ISA_MIPS_R2); 7599 gen_helper_mtc0_srsconf0(tcg_env, arg); 7600 register_name = "SRSConf0"; 7601 break; 7602 case CP0_REG06__SRSCONF1: 7603 check_insn(ctx, ISA_MIPS_R2); 7604 gen_helper_mtc0_srsconf1(tcg_env, arg); 7605 register_name = "SRSConf1"; 7606 break; 7607 case CP0_REG06__SRSCONF2: 7608 check_insn(ctx, ISA_MIPS_R2); 7609 gen_helper_mtc0_srsconf2(tcg_env, arg); 7610 register_name = "SRSConf2"; 7611 break; 7612 case CP0_REG06__SRSCONF3: 7613 check_insn(ctx, ISA_MIPS_R2); 7614 gen_helper_mtc0_srsconf3(tcg_env, arg); 7615 register_name = "SRSConf3"; 7616 break; 7617 case CP0_REG06__SRSCONF4: 7618 check_insn(ctx, ISA_MIPS_R2); 7619 gen_helper_mtc0_srsconf4(tcg_env, arg); 7620 register_name = "SRSConf4"; 7621 break; 7622 case CP0_REG06__PWCTL: 7623 check_pw(ctx); 7624 gen_helper_mtc0_pwctl(tcg_env, arg); 7625 register_name = "PWCtl"; 7626 break; 7627 default: 7628 goto cp0_unimplemented; 7629 } 7630 break; 7631 case CP0_REGISTER_07: 7632 switch (sel) { 7633 case CP0_REG07__HWRENA: 7634 check_insn(ctx, ISA_MIPS_R2); 7635 gen_helper_mtc0_hwrena(tcg_env, arg); 7636 ctx->base.is_jmp = DISAS_STOP; 7637 register_name = "HWREna"; 7638 break; 7639 default: 7640 goto cp0_unimplemented; 7641 } 7642 break; 7643 case CP0_REGISTER_08: 7644 switch (sel) { 7645 case CP0_REG08__BADVADDR: 7646 /* ignored */ 7647 register_name = "BadVAddr"; 7648 break; 7649 case CP0_REG08__BADINSTR: 7650 /* ignored */ 7651 register_name = "BadInstr"; 7652 break; 7653 case CP0_REG08__BADINSTRP: 7654 /* ignored */ 7655 register_name = "BadInstrP"; 7656 break; 7657 case CP0_REG08__BADINSTRX: 7658 /* ignored */ 7659 register_name = "BadInstrX"; 7660 break; 7661 default: 7662 goto cp0_unimplemented; 7663 } 7664 break; 7665 case CP0_REGISTER_09: 7666 switch (sel) { 7667 case CP0_REG09__COUNT: 7668 gen_helper_mtc0_count(tcg_env, arg); 7669 register_name = "Count"; 7670 break; 7671 default: 7672 goto cp0_unimplemented; 7673 } 7674 /* Stop translation as we may have switched the execution mode */ 7675 ctx->base.is_jmp = DISAS_STOP; 7676 break; 7677 case CP0_REGISTER_10: 7678 switch (sel) { 7679 case CP0_REG10__ENTRYHI: 7680 gen_helper_mtc0_entryhi(tcg_env, arg); 7681 register_name = "EntryHi"; 7682 break; 7683 default: 7684 goto cp0_unimplemented; 7685 } 7686 break; 7687 case CP0_REGISTER_11: 7688 switch (sel) { 7689 case CP0_REG11__COMPARE: 7690 gen_helper_mtc0_compare(tcg_env, arg); 7691 register_name = "Compare"; 7692 break; 7693 /* 6,7 are implementation dependent */ 7694 default: 7695 goto cp0_unimplemented; 7696 } 7697 /* Stop translation as we may have switched the execution mode */ 7698 ctx->base.is_jmp = DISAS_STOP; 7699 break; 7700 case CP0_REGISTER_12: 7701 switch (sel) { 7702 case CP0_REG12__STATUS: 7703 save_cpu_state(ctx, 1); 7704 gen_helper_mtc0_status(tcg_env, arg); 7705 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7706 gen_save_pc(ctx->base.pc_next + 4); 7707 ctx->base.is_jmp = DISAS_EXIT; 7708 register_name = "Status"; 7709 break; 7710 case CP0_REG12__INTCTL: 7711 check_insn(ctx, ISA_MIPS_R2); 7712 gen_helper_mtc0_intctl(tcg_env, arg); 7713 /* Stop translation as we may have switched the execution mode */ 7714 ctx->base.is_jmp = DISAS_STOP; 7715 register_name = "IntCtl"; 7716 break; 7717 case CP0_REG12__SRSCTL: 7718 check_insn(ctx, ISA_MIPS_R2); 7719 gen_helper_mtc0_srsctl(tcg_env, arg); 7720 /* Stop translation as we may have switched the execution mode */ 7721 ctx->base.is_jmp = DISAS_STOP; 7722 register_name = "SRSCtl"; 7723 break; 7724 case CP0_REG12__SRSMAP: 7725 check_insn(ctx, ISA_MIPS_R2); 7726 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7727 /* Stop translation as we may have switched the execution mode */ 7728 ctx->base.is_jmp = DISAS_STOP; 7729 register_name = "SRSMap"; 7730 break; 7731 default: 7732 goto cp0_unimplemented; 7733 } 7734 break; 7735 case CP0_REGISTER_13: 7736 switch (sel) { 7737 case CP0_REG13__CAUSE: 7738 save_cpu_state(ctx, 1); 7739 gen_helper_mtc0_cause(tcg_env, arg); 7740 /* 7741 * Stop translation as we may have triggered an interrupt. 7742 * DISAS_STOP isn't sufficient, we need to ensure we break out of 7743 * translated code to check for pending interrupts. 7744 */ 7745 gen_save_pc(ctx->base.pc_next + 4); 7746 ctx->base.is_jmp = DISAS_EXIT; 7747 register_name = "Cause"; 7748 break; 7749 default: 7750 goto cp0_unimplemented; 7751 } 7752 break; 7753 case CP0_REGISTER_14: 7754 switch (sel) { 7755 case CP0_REG14__EPC: 7756 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC)); 7757 register_name = "EPC"; 7758 break; 7759 default: 7760 goto cp0_unimplemented; 7761 } 7762 break; 7763 case CP0_REGISTER_15: 7764 switch (sel) { 7765 case CP0_REG15__PRID: 7766 /* ignored */ 7767 register_name = "PRid"; 7768 break; 7769 case CP0_REG15__EBASE: 7770 check_insn(ctx, ISA_MIPS_R2); 7771 gen_helper_mtc0_ebase(tcg_env, arg); 7772 register_name = "EBase"; 7773 break; 7774 default: 7775 goto cp0_unimplemented; 7776 } 7777 break; 7778 case CP0_REGISTER_16: 7779 switch (sel) { 7780 case CP0_REG16__CONFIG: 7781 gen_helper_mtc0_config0(tcg_env, arg); 7782 register_name = "Config"; 7783 /* Stop translation as we may have switched the execution mode */ 7784 ctx->base.is_jmp = DISAS_STOP; 7785 break; 7786 case CP0_REG16__CONFIG1: 7787 /* ignored, read only */ 7788 register_name = "Config1"; 7789 break; 7790 case CP0_REG16__CONFIG2: 7791 gen_helper_mtc0_config2(tcg_env, arg); 7792 register_name = "Config2"; 7793 /* Stop translation as we may have switched the execution mode */ 7794 ctx->base.is_jmp = DISAS_STOP; 7795 break; 7796 case CP0_REG16__CONFIG3: 7797 gen_helper_mtc0_config3(tcg_env, arg); 7798 register_name = "Config3"; 7799 /* Stop translation as we may have switched the execution mode */ 7800 ctx->base.is_jmp = DISAS_STOP; 7801 break; 7802 case CP0_REG16__CONFIG4: 7803 /* currently ignored */ 7804 register_name = "Config4"; 7805 break; 7806 case CP0_REG16__CONFIG5: 7807 gen_helper_mtc0_config5(tcg_env, arg); 7808 register_name = "Config5"; 7809 /* Stop translation as we may have switched the execution mode */ 7810 ctx->base.is_jmp = DISAS_STOP; 7811 break; 7812 /* 6,7 are implementation dependent */ 7813 default: 7814 register_name = "Invalid config selector"; 7815 goto cp0_unimplemented; 7816 } 7817 break; 7818 case CP0_REGISTER_17: 7819 switch (sel) { 7820 case CP0_REG17__LLADDR: 7821 gen_helper_mtc0_lladdr(tcg_env, arg); 7822 register_name = "LLAddr"; 7823 break; 7824 case CP0_REG17__MAAR: 7825 CP0_CHECK(ctx->mrp); 7826 gen_helper_mtc0_maar(tcg_env, arg); 7827 register_name = "MAAR"; 7828 break; 7829 case CP0_REG17__MAARI: 7830 CP0_CHECK(ctx->mrp); 7831 gen_helper_mtc0_maari(tcg_env, arg); 7832 register_name = "MAARI"; 7833 break; 7834 default: 7835 goto cp0_unimplemented; 7836 } 7837 break; 7838 case CP0_REGISTER_18: 7839 switch (sel) { 7840 case CP0_REG18__WATCHLO0: 7841 case CP0_REG18__WATCHLO1: 7842 case CP0_REG18__WATCHLO2: 7843 case CP0_REG18__WATCHLO3: 7844 case CP0_REG18__WATCHLO4: 7845 case CP0_REG18__WATCHLO5: 7846 case CP0_REG18__WATCHLO6: 7847 case CP0_REG18__WATCHLO7: 7848 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7849 gen_helper_0e1i(mtc0_watchlo, arg, sel); 7850 register_name = "WatchLo"; 7851 break; 7852 default: 7853 goto cp0_unimplemented; 7854 } 7855 break; 7856 case CP0_REGISTER_19: 7857 switch (sel) { 7858 case CP0_REG19__WATCHHI0: 7859 case CP0_REG19__WATCHHI1: 7860 case CP0_REG19__WATCHHI2: 7861 case CP0_REG19__WATCHHI3: 7862 case CP0_REG19__WATCHHI4: 7863 case CP0_REG19__WATCHHI5: 7864 case CP0_REG19__WATCHHI6: 7865 case CP0_REG19__WATCHHI7: 7866 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7867 gen_helper_0e1i(mtc0_watchhi, arg, sel); 7868 register_name = "WatchHi"; 7869 break; 7870 default: 7871 goto cp0_unimplemented; 7872 } 7873 break; 7874 case CP0_REGISTER_20: 7875 switch (sel) { 7876 case CP0_REG20__XCONTEXT: 7877 check_insn(ctx, ISA_MIPS3); 7878 gen_helper_mtc0_xcontext(tcg_env, arg); 7879 register_name = "XContext"; 7880 break; 7881 default: 7882 goto cp0_unimplemented; 7883 } 7884 break; 7885 case CP0_REGISTER_21: 7886 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7887 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7888 switch (sel) { 7889 case 0: 7890 gen_helper_mtc0_framemask(tcg_env, arg); 7891 register_name = "Framemask"; 7892 break; 7893 default: 7894 goto cp0_unimplemented; 7895 } 7896 break; 7897 case CP0_REGISTER_22: 7898 /* ignored */ 7899 register_name = "Diagnostic"; /* implementation dependent */ 7900 break; 7901 case CP0_REGISTER_23: 7902 switch (sel) { 7903 case CP0_REG23__DEBUG: 7904 gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */ 7905 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7906 gen_save_pc(ctx->base.pc_next + 4); 7907 ctx->base.is_jmp = DISAS_EXIT; 7908 register_name = "Debug"; 7909 break; 7910 case CP0_REG23__TRACECONTROL: 7911 /* PDtrace support */ 7912 /* gen_helper_mtc0_tracecontrol(tcg_env, arg); */ 7913 /* Stop translation as we may have switched the execution mode */ 7914 ctx->base.is_jmp = DISAS_STOP; 7915 register_name = "TraceControl"; 7916 goto cp0_unimplemented; 7917 case CP0_REG23__TRACECONTROL2: 7918 /* PDtrace support */ 7919 /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */ 7920 /* Stop translation as we may have switched the execution mode */ 7921 ctx->base.is_jmp = DISAS_STOP; 7922 register_name = "TraceControl2"; 7923 goto cp0_unimplemented; 7924 case CP0_REG23__USERTRACEDATA1: 7925 /* PDtrace support */ 7926 /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/ 7927 /* Stop translation as we may have switched the execution mode */ 7928 ctx->base.is_jmp = DISAS_STOP; 7929 register_name = "UserTraceData1"; 7930 goto cp0_unimplemented; 7931 case CP0_REG23__TRACEIBPC: 7932 /* PDtrace support */ 7933 /* gen_helper_mtc0_traceibpc(tcg_env, arg); */ 7934 /* Stop translation as we may have switched the execution mode */ 7935 ctx->base.is_jmp = DISAS_STOP; 7936 register_name = "TraceIBPC"; 7937 goto cp0_unimplemented; 7938 case CP0_REG23__TRACEDBPC: 7939 /* PDtrace support */ 7940 /* gen_helper_mtc0_tracedbpc(tcg_env, arg); */ 7941 /* Stop translation as we may have switched the execution mode */ 7942 ctx->base.is_jmp = DISAS_STOP; 7943 register_name = "TraceDBPC"; 7944 goto cp0_unimplemented; 7945 default: 7946 goto cp0_unimplemented; 7947 } 7948 break; 7949 case CP0_REGISTER_24: 7950 switch (sel) { 7951 case CP0_REG24__DEPC: 7952 /* EJTAG support */ 7953 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC)); 7954 register_name = "DEPC"; 7955 break; 7956 default: 7957 goto cp0_unimplemented; 7958 } 7959 break; 7960 case CP0_REGISTER_25: 7961 switch (sel) { 7962 case CP0_REG25__PERFCTL0: 7963 gen_helper_mtc0_performance0(tcg_env, arg); 7964 register_name = "Performance0"; 7965 break; 7966 case CP0_REG25__PERFCNT0: 7967 /* gen_helper_mtc0_performance1(tcg_env, arg); */ 7968 register_name = "Performance1"; 7969 goto cp0_unimplemented; 7970 case CP0_REG25__PERFCTL1: 7971 /* gen_helper_mtc0_performance2(tcg_env, arg); */ 7972 register_name = "Performance2"; 7973 goto cp0_unimplemented; 7974 case CP0_REG25__PERFCNT1: 7975 /* gen_helper_mtc0_performance3(tcg_env, arg); */ 7976 register_name = "Performance3"; 7977 goto cp0_unimplemented; 7978 case CP0_REG25__PERFCTL2: 7979 /* gen_helper_mtc0_performance4(tcg_env, arg); */ 7980 register_name = "Performance4"; 7981 goto cp0_unimplemented; 7982 case CP0_REG25__PERFCNT2: 7983 /* gen_helper_mtc0_performance5(tcg_env, arg); */ 7984 register_name = "Performance5"; 7985 goto cp0_unimplemented; 7986 case CP0_REG25__PERFCTL3: 7987 /* gen_helper_mtc0_performance6(tcg_env, arg); */ 7988 register_name = "Performance6"; 7989 goto cp0_unimplemented; 7990 case CP0_REG25__PERFCNT3: 7991 /* gen_helper_mtc0_performance7(tcg_env, arg); */ 7992 register_name = "Performance7"; 7993 goto cp0_unimplemented; 7994 default: 7995 goto cp0_unimplemented; 7996 } 7997 break; 7998 case CP0_REGISTER_26: 7999 switch (sel) { 8000 case CP0_REG26__ERRCTL: 8001 gen_helper_mtc0_errctl(tcg_env, arg); 8002 ctx->base.is_jmp = DISAS_STOP; 8003 register_name = "ErrCtl"; 8004 break; 8005 default: 8006 goto cp0_unimplemented; 8007 } 8008 break; 8009 case CP0_REGISTER_27: 8010 switch (sel) { 8011 case CP0_REG27__CACHERR: 8012 /* ignored */ 8013 register_name = "CacheErr"; 8014 break; 8015 default: 8016 goto cp0_unimplemented; 8017 } 8018 break; 8019 case CP0_REGISTER_28: 8020 switch (sel) { 8021 case CP0_REG28__TAGLO: 8022 case CP0_REG28__TAGLO1: 8023 case CP0_REG28__TAGLO2: 8024 case CP0_REG28__TAGLO3: 8025 gen_helper_mtc0_taglo(tcg_env, arg); 8026 register_name = "TagLo"; 8027 break; 8028 case CP0_REG28__DATALO: 8029 case CP0_REG28__DATALO1: 8030 case CP0_REG28__DATALO2: 8031 case CP0_REG28__DATALO3: 8032 gen_helper_mtc0_datalo(tcg_env, arg); 8033 register_name = "DataLo"; 8034 break; 8035 default: 8036 goto cp0_unimplemented; 8037 } 8038 break; 8039 case CP0_REGISTER_29: 8040 switch (sel) { 8041 case CP0_REG29__TAGHI: 8042 case CP0_REG29__TAGHI1: 8043 case CP0_REG29__TAGHI2: 8044 case CP0_REG29__TAGHI3: 8045 gen_helper_mtc0_taghi(tcg_env, arg); 8046 register_name = "TagHi"; 8047 break; 8048 case CP0_REG29__DATAHI: 8049 case CP0_REG29__DATAHI1: 8050 case CP0_REG29__DATAHI2: 8051 case CP0_REG29__DATAHI3: 8052 gen_helper_mtc0_datahi(tcg_env, arg); 8053 register_name = "DataHi"; 8054 break; 8055 default: 8056 register_name = "invalid sel"; 8057 goto cp0_unimplemented; 8058 } 8059 break; 8060 case CP0_REGISTER_30: 8061 switch (sel) { 8062 case CP0_REG30__ERROREPC: 8063 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 8064 register_name = "ErrorEPC"; 8065 break; 8066 default: 8067 goto cp0_unimplemented; 8068 } 8069 break; 8070 case CP0_REGISTER_31: 8071 switch (sel) { 8072 case CP0_REG31__DESAVE: 8073 /* EJTAG support */ 8074 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 8075 register_name = "DESAVE"; 8076 break; 8077 case CP0_REG31__KSCRATCH1: 8078 case CP0_REG31__KSCRATCH2: 8079 case CP0_REG31__KSCRATCH3: 8080 case CP0_REG31__KSCRATCH4: 8081 case CP0_REG31__KSCRATCH5: 8082 case CP0_REG31__KSCRATCH6: 8083 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8084 tcg_gen_st_tl(arg, tcg_env, 8085 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8086 register_name = "KScratch"; 8087 break; 8088 default: 8089 goto cp0_unimplemented; 8090 } 8091 break; 8092 default: 8093 goto cp0_unimplemented; 8094 } 8095 trace_mips_translate_c0("dmtc0", register_name, reg, sel); 8096 8097 /* For simplicity assume that all writes can cause interrupts. */ 8098 if (icount) { 8099 /* 8100 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8101 * translated code to check for pending interrupts. 8102 */ 8103 gen_save_pc(ctx->base.pc_next + 4); 8104 ctx->base.is_jmp = DISAS_EXIT; 8105 } 8106 return; 8107 8108 cp0_unimplemented: 8109 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", 8110 register_name, reg, sel); 8111 } 8112 #endif /* TARGET_MIPS64 */ 8113 8114 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 8115 int u, int sel, int h) 8116 { 8117 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8118 TCGv t0 = tcg_temp_new(); 8119 8120 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8121 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8122 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8123 tcg_gen_movi_tl(t0, -1); 8124 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8125 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8126 tcg_gen_movi_tl(t0, -1); 8127 } else if (u == 0) { 8128 switch (rt) { 8129 case 1: 8130 switch (sel) { 8131 case 1: 8132 gen_helper_mftc0_vpecontrol(t0, tcg_env); 8133 break; 8134 case 2: 8135 gen_helper_mftc0_vpeconf0(t0, tcg_env); 8136 break; 8137 default: 8138 goto die; 8139 break; 8140 } 8141 break; 8142 case 2: 8143 switch (sel) { 8144 case 1: 8145 gen_helper_mftc0_tcstatus(t0, tcg_env); 8146 break; 8147 case 2: 8148 gen_helper_mftc0_tcbind(t0, tcg_env); 8149 break; 8150 case 3: 8151 gen_helper_mftc0_tcrestart(t0, tcg_env); 8152 break; 8153 case 4: 8154 gen_helper_mftc0_tchalt(t0, tcg_env); 8155 break; 8156 case 5: 8157 gen_helper_mftc0_tccontext(t0, tcg_env); 8158 break; 8159 case 6: 8160 gen_helper_mftc0_tcschedule(t0, tcg_env); 8161 break; 8162 case 7: 8163 gen_helper_mftc0_tcschefback(t0, tcg_env); 8164 break; 8165 default: 8166 gen_mfc0(ctx, t0, rt, sel); 8167 break; 8168 } 8169 break; 8170 case 10: 8171 switch (sel) { 8172 case 0: 8173 gen_helper_mftc0_entryhi(t0, tcg_env); 8174 break; 8175 default: 8176 gen_mfc0(ctx, t0, rt, sel); 8177 break; 8178 } 8179 break; 8180 case 12: 8181 switch (sel) { 8182 case 0: 8183 gen_helper_mftc0_status(t0, tcg_env); 8184 break; 8185 default: 8186 gen_mfc0(ctx, t0, rt, sel); 8187 break; 8188 } 8189 break; 8190 case 13: 8191 switch (sel) { 8192 case 0: 8193 gen_helper_mftc0_cause(t0, tcg_env); 8194 break; 8195 default: 8196 goto die; 8197 break; 8198 } 8199 break; 8200 case 14: 8201 switch (sel) { 8202 case 0: 8203 gen_helper_mftc0_epc(t0, tcg_env); 8204 break; 8205 default: 8206 goto die; 8207 break; 8208 } 8209 break; 8210 case 15: 8211 switch (sel) { 8212 case 1: 8213 gen_helper_mftc0_ebase(t0, tcg_env); 8214 break; 8215 default: 8216 goto die; 8217 break; 8218 } 8219 break; 8220 case 16: 8221 switch (sel) { 8222 case 0: 8223 case 1: 8224 case 2: 8225 case 3: 8226 case 4: 8227 case 5: 8228 case 6: 8229 case 7: 8230 gen_helper_mftc0_configx(t0, tcg_env, tcg_constant_tl(sel)); 8231 break; 8232 default: 8233 goto die; 8234 break; 8235 } 8236 break; 8237 case 23: 8238 switch (sel) { 8239 case 0: 8240 gen_helper_mftc0_debug(t0, tcg_env); 8241 break; 8242 default: 8243 gen_mfc0(ctx, t0, rt, sel); 8244 break; 8245 } 8246 break; 8247 default: 8248 gen_mfc0(ctx, t0, rt, sel); 8249 } 8250 } else { 8251 switch (sel) { 8252 /* GPR registers. */ 8253 case 0: 8254 gen_helper_1e0i(mftgpr, t0, rt); 8255 break; 8256 /* Auxiliary CPU registers */ 8257 case 1: 8258 switch (rt) { 8259 case 0: 8260 gen_helper_1e0i(mftlo, t0, 0); 8261 break; 8262 case 1: 8263 gen_helper_1e0i(mfthi, t0, 0); 8264 break; 8265 case 2: 8266 gen_helper_1e0i(mftacx, t0, 0); 8267 break; 8268 case 4: 8269 gen_helper_1e0i(mftlo, t0, 1); 8270 break; 8271 case 5: 8272 gen_helper_1e0i(mfthi, t0, 1); 8273 break; 8274 case 6: 8275 gen_helper_1e0i(mftacx, t0, 1); 8276 break; 8277 case 8: 8278 gen_helper_1e0i(mftlo, t0, 2); 8279 break; 8280 case 9: 8281 gen_helper_1e0i(mfthi, t0, 2); 8282 break; 8283 case 10: 8284 gen_helper_1e0i(mftacx, t0, 2); 8285 break; 8286 case 12: 8287 gen_helper_1e0i(mftlo, t0, 3); 8288 break; 8289 case 13: 8290 gen_helper_1e0i(mfthi, t0, 3); 8291 break; 8292 case 14: 8293 gen_helper_1e0i(mftacx, t0, 3); 8294 break; 8295 case 16: 8296 gen_helper_mftdsp(t0, tcg_env); 8297 break; 8298 default: 8299 goto die; 8300 } 8301 break; 8302 /* Floating point (COP1). */ 8303 case 2: 8304 /* XXX: For now we support only a single FPU context. */ 8305 if (h == 0) { 8306 TCGv_i32 fp0 = tcg_temp_new_i32(); 8307 8308 gen_load_fpr32(ctx, fp0, rt); 8309 tcg_gen_ext_i32_tl(t0, fp0); 8310 } else { 8311 TCGv_i32 fp0 = tcg_temp_new_i32(); 8312 8313 gen_load_fpr32h(ctx, fp0, rt); 8314 tcg_gen_ext_i32_tl(t0, fp0); 8315 } 8316 break; 8317 case 3: 8318 /* XXX: For now we support only a single FPU context. */ 8319 gen_helper_1e0i(cfc1, t0, rt); 8320 break; 8321 /* COP2: Not implemented. */ 8322 case 4: 8323 case 5: 8324 /* fall through */ 8325 default: 8326 goto die; 8327 } 8328 } 8329 trace_mips_translate_tr("mftr", rt, u, sel, h); 8330 gen_store_gpr(t0, rd); 8331 return; 8332 8333 die: 8334 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 8335 gen_reserved_instruction(ctx); 8336 } 8337 8338 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 8339 int u, int sel, int h) 8340 { 8341 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8342 TCGv t0 = tcg_temp_new(); 8343 8344 gen_load_gpr(t0, rt); 8345 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8346 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8347 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8348 /* NOP */ 8349 ; 8350 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8351 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8352 /* NOP */ 8353 ; 8354 } else if (u == 0) { 8355 switch (rd) { 8356 case 1: 8357 switch (sel) { 8358 case 1: 8359 gen_helper_mttc0_vpecontrol(tcg_env, t0); 8360 break; 8361 case 2: 8362 gen_helper_mttc0_vpeconf0(tcg_env, t0); 8363 break; 8364 default: 8365 goto die; 8366 break; 8367 } 8368 break; 8369 case 2: 8370 switch (sel) { 8371 case 1: 8372 gen_helper_mttc0_tcstatus(tcg_env, t0); 8373 break; 8374 case 2: 8375 gen_helper_mttc0_tcbind(tcg_env, t0); 8376 break; 8377 case 3: 8378 gen_helper_mttc0_tcrestart(tcg_env, t0); 8379 break; 8380 case 4: 8381 gen_helper_mttc0_tchalt(tcg_env, t0); 8382 break; 8383 case 5: 8384 gen_helper_mttc0_tccontext(tcg_env, t0); 8385 break; 8386 case 6: 8387 gen_helper_mttc0_tcschedule(tcg_env, t0); 8388 break; 8389 case 7: 8390 gen_helper_mttc0_tcschefback(tcg_env, t0); 8391 break; 8392 default: 8393 gen_mtc0(ctx, t0, rd, sel); 8394 break; 8395 } 8396 break; 8397 case 10: 8398 switch (sel) { 8399 case 0: 8400 gen_helper_mttc0_entryhi(tcg_env, t0); 8401 break; 8402 default: 8403 gen_mtc0(ctx, t0, rd, sel); 8404 break; 8405 } 8406 break; 8407 case 12: 8408 switch (sel) { 8409 case 0: 8410 gen_helper_mttc0_status(tcg_env, t0); 8411 break; 8412 default: 8413 gen_mtc0(ctx, t0, rd, sel); 8414 break; 8415 } 8416 break; 8417 case 13: 8418 switch (sel) { 8419 case 0: 8420 gen_helper_mttc0_cause(tcg_env, t0); 8421 break; 8422 default: 8423 goto die; 8424 break; 8425 } 8426 break; 8427 case 15: 8428 switch (sel) { 8429 case 1: 8430 gen_helper_mttc0_ebase(tcg_env, t0); 8431 break; 8432 default: 8433 goto die; 8434 break; 8435 } 8436 break; 8437 case 23: 8438 switch (sel) { 8439 case 0: 8440 gen_helper_mttc0_debug(tcg_env, t0); 8441 break; 8442 default: 8443 gen_mtc0(ctx, t0, rd, sel); 8444 break; 8445 } 8446 break; 8447 default: 8448 gen_mtc0(ctx, t0, rd, sel); 8449 } 8450 } else { 8451 switch (sel) { 8452 /* GPR registers. */ 8453 case 0: 8454 gen_helper_0e1i(mttgpr, t0, rd); 8455 break; 8456 /* Auxiliary CPU registers */ 8457 case 1: 8458 switch (rd) { 8459 case 0: 8460 gen_helper_0e1i(mttlo, t0, 0); 8461 break; 8462 case 1: 8463 gen_helper_0e1i(mtthi, t0, 0); 8464 break; 8465 case 2: 8466 gen_helper_0e1i(mttacx, t0, 0); 8467 break; 8468 case 4: 8469 gen_helper_0e1i(mttlo, t0, 1); 8470 break; 8471 case 5: 8472 gen_helper_0e1i(mtthi, t0, 1); 8473 break; 8474 case 6: 8475 gen_helper_0e1i(mttacx, t0, 1); 8476 break; 8477 case 8: 8478 gen_helper_0e1i(mttlo, t0, 2); 8479 break; 8480 case 9: 8481 gen_helper_0e1i(mtthi, t0, 2); 8482 break; 8483 case 10: 8484 gen_helper_0e1i(mttacx, t0, 2); 8485 break; 8486 case 12: 8487 gen_helper_0e1i(mttlo, t0, 3); 8488 break; 8489 case 13: 8490 gen_helper_0e1i(mtthi, t0, 3); 8491 break; 8492 case 14: 8493 gen_helper_0e1i(mttacx, t0, 3); 8494 break; 8495 case 16: 8496 gen_helper_mttdsp(tcg_env, t0); 8497 break; 8498 default: 8499 goto die; 8500 } 8501 break; 8502 /* Floating point (COP1). */ 8503 case 2: 8504 /* XXX: For now we support only a single FPU context. */ 8505 if (h == 0) { 8506 TCGv_i32 fp0 = tcg_temp_new_i32(); 8507 8508 tcg_gen_trunc_tl_i32(fp0, t0); 8509 gen_store_fpr32(ctx, fp0, rd); 8510 } else { 8511 TCGv_i32 fp0 = tcg_temp_new_i32(); 8512 8513 tcg_gen_trunc_tl_i32(fp0, t0); 8514 gen_store_fpr32h(ctx, fp0, rd); 8515 } 8516 break; 8517 case 3: 8518 /* XXX: For now we support only a single FPU context. */ 8519 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt); 8520 /* Stop translation as we may have changed hflags */ 8521 ctx->base.is_jmp = DISAS_STOP; 8522 break; 8523 /* COP2: Not implemented. */ 8524 case 4: 8525 case 5: 8526 /* fall through */ 8527 default: 8528 goto die; 8529 } 8530 } 8531 trace_mips_translate_tr("mttr", rd, u, sel, h); 8532 return; 8533 8534 die: 8535 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 8536 gen_reserved_instruction(ctx); 8537 } 8538 8539 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 8540 int rt, int rd) 8541 { 8542 const char *opn = "ldst"; 8543 8544 check_cp0_enabled(ctx); 8545 switch (opc) { 8546 case OPC_MFC0: 8547 if (rt == 0) { 8548 /* Treat as NOP. */ 8549 return; 8550 } 8551 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8552 opn = "mfc0"; 8553 break; 8554 case OPC_MTC0: 8555 { 8556 TCGv t0 = tcg_temp_new(); 8557 8558 gen_load_gpr(t0, rt); 8559 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7); 8560 } 8561 opn = "mtc0"; 8562 break; 8563 #if defined(TARGET_MIPS64) 8564 case OPC_DMFC0: 8565 check_insn(ctx, ISA_MIPS3); 8566 if (rt == 0) { 8567 /* Treat as NOP. */ 8568 return; 8569 } 8570 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8571 opn = "dmfc0"; 8572 break; 8573 case OPC_DMTC0: 8574 check_insn(ctx, ISA_MIPS3); 8575 { 8576 TCGv t0 = tcg_temp_new(); 8577 8578 gen_load_gpr(t0, rt); 8579 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7); 8580 } 8581 opn = "dmtc0"; 8582 break; 8583 #endif 8584 case OPC_MFHC0: 8585 check_mvh(ctx); 8586 if (rt == 0) { 8587 /* Treat as NOP. */ 8588 return; 8589 } 8590 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 8591 opn = "mfhc0"; 8592 break; 8593 case OPC_MTHC0: 8594 check_mvh(ctx); 8595 { 8596 TCGv t0 = tcg_temp_new(); 8597 gen_load_gpr(t0, rt); 8598 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7); 8599 } 8600 opn = "mthc0"; 8601 break; 8602 case OPC_MFTR: 8603 check_cp0_enabled(ctx); 8604 if (rd == 0) { 8605 /* Treat as NOP. */ 8606 return; 8607 } 8608 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 8609 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 8610 opn = "mftr"; 8611 break; 8612 case OPC_MTTR: 8613 check_cp0_enabled(ctx); 8614 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 8615 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 8616 opn = "mttr"; 8617 break; 8618 case OPC_TLBWI: 8619 opn = "tlbwi"; 8620 if (!env->tlb->helper_tlbwi) { 8621 goto die; 8622 } 8623 gen_helper_tlbwi(tcg_env); 8624 break; 8625 case OPC_TLBINV: 8626 opn = "tlbinv"; 8627 if (ctx->ie >= 2) { 8628 if (!env->tlb->helper_tlbinv) { 8629 goto die; 8630 } 8631 gen_helper_tlbinv(tcg_env); 8632 } /* treat as nop if TLBINV not supported */ 8633 break; 8634 case OPC_TLBINVF: 8635 opn = "tlbinvf"; 8636 if (ctx->ie >= 2) { 8637 if (!env->tlb->helper_tlbinvf) { 8638 goto die; 8639 } 8640 gen_helper_tlbinvf(tcg_env); 8641 } /* treat as nop if TLBINV not supported */ 8642 break; 8643 case OPC_TLBWR: 8644 opn = "tlbwr"; 8645 if (!env->tlb->helper_tlbwr) { 8646 goto die; 8647 } 8648 gen_helper_tlbwr(tcg_env); 8649 break; 8650 case OPC_TLBP: 8651 opn = "tlbp"; 8652 if (!env->tlb->helper_tlbp) { 8653 goto die; 8654 } 8655 gen_helper_tlbp(tcg_env); 8656 break; 8657 case OPC_TLBR: 8658 opn = "tlbr"; 8659 if (!env->tlb->helper_tlbr) { 8660 goto die; 8661 } 8662 gen_helper_tlbr(tcg_env); 8663 break; 8664 case OPC_ERET: /* OPC_ERETNC */ 8665 if ((ctx->insn_flags & ISA_MIPS_R6) && 8666 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8667 goto die; 8668 } else { 8669 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6; 8670 if (ctx->opcode & (1 << bit_shift)) { 8671 /* OPC_ERETNC */ 8672 opn = "eretnc"; 8673 check_insn(ctx, ISA_MIPS_R5); 8674 gen_helper_eretnc(tcg_env); 8675 } else { 8676 /* OPC_ERET */ 8677 opn = "eret"; 8678 check_insn(ctx, ISA_MIPS2); 8679 gen_helper_eret(tcg_env); 8680 } 8681 ctx->base.is_jmp = DISAS_EXIT; 8682 } 8683 break; 8684 case OPC_DERET: 8685 opn = "deret"; 8686 check_insn(ctx, ISA_MIPS_R1); 8687 if ((ctx->insn_flags & ISA_MIPS_R6) && 8688 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8689 goto die; 8690 } 8691 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 8692 MIPS_INVAL(opn); 8693 gen_reserved_instruction(ctx); 8694 } else { 8695 gen_helper_deret(tcg_env); 8696 ctx->base.is_jmp = DISAS_EXIT; 8697 } 8698 break; 8699 case OPC_WAIT: 8700 opn = "wait"; 8701 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 8702 if ((ctx->insn_flags & ISA_MIPS_R6) && 8703 (ctx->hflags & MIPS_HFLAG_BMASK)) { 8704 goto die; 8705 } 8706 /* If we get an exception, we want to restart at next instruction */ 8707 ctx->base.pc_next += 4; 8708 save_cpu_state(ctx, 1); 8709 ctx->base.pc_next -= 4; 8710 gen_helper_wait(tcg_env); 8711 ctx->base.is_jmp = DISAS_NORETURN; 8712 break; 8713 default: 8714 die: 8715 MIPS_INVAL(opn); 8716 gen_reserved_instruction(ctx); 8717 return; 8718 } 8719 (void)opn; /* avoid a compiler warning */ 8720 } 8721 #endif /* !CONFIG_USER_ONLY */ 8722 8723 /* CP1 Branches (before delay slot) */ 8724 static void gen_compute_branch1(DisasContext *ctx, uint32_t op, 8725 int32_t cc, int32_t offset) 8726 { 8727 target_ulong btarget; 8728 TCGv_i32 t0 = tcg_temp_new_i32(); 8729 8730 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { 8731 gen_reserved_instruction(ctx); 8732 return; 8733 } 8734 8735 if (cc != 0) { 8736 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 8737 } 8738 8739 btarget = ctx->base.pc_next + 4 + offset; 8740 8741 switch (op) { 8742 case OPC_BC1F: 8743 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8744 tcg_gen_not_i32(t0, t0); 8745 tcg_gen_andi_i32(t0, t0, 1); 8746 tcg_gen_extu_i32_tl(bcond, t0); 8747 goto not_likely; 8748 case OPC_BC1FL: 8749 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8750 tcg_gen_not_i32(t0, t0); 8751 tcg_gen_andi_i32(t0, t0, 1); 8752 tcg_gen_extu_i32_tl(bcond, t0); 8753 goto likely; 8754 case OPC_BC1T: 8755 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8756 tcg_gen_andi_i32(t0, t0, 1); 8757 tcg_gen_extu_i32_tl(bcond, t0); 8758 goto not_likely; 8759 case OPC_BC1TL: 8760 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8761 tcg_gen_andi_i32(t0, t0, 1); 8762 tcg_gen_extu_i32_tl(bcond, t0); 8763 likely: 8764 ctx->hflags |= MIPS_HFLAG_BL; 8765 break; 8766 case OPC_BC1FANY2: 8767 { 8768 TCGv_i32 t1 = tcg_temp_new_i32(); 8769 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8770 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8771 tcg_gen_nand_i32(t0, t0, t1); 8772 tcg_gen_andi_i32(t0, t0, 1); 8773 tcg_gen_extu_i32_tl(bcond, t0); 8774 } 8775 goto not_likely; 8776 case OPC_BC1TANY2: 8777 { 8778 TCGv_i32 t1 = tcg_temp_new_i32(); 8779 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8780 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8781 tcg_gen_or_i32(t0, t0, t1); 8782 tcg_gen_andi_i32(t0, t0, 1); 8783 tcg_gen_extu_i32_tl(bcond, t0); 8784 } 8785 goto not_likely; 8786 case OPC_BC1FANY4: 8787 { 8788 TCGv_i32 t1 = tcg_temp_new_i32(); 8789 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8790 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8791 tcg_gen_and_i32(t0, t0, t1); 8792 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 8793 tcg_gen_and_i32(t0, t0, t1); 8794 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 8795 tcg_gen_nand_i32(t0, t0, t1); 8796 tcg_gen_andi_i32(t0, t0, 1); 8797 tcg_gen_extu_i32_tl(bcond, t0); 8798 } 8799 goto not_likely; 8800 case OPC_BC1TANY4: 8801 { 8802 TCGv_i32 t1 = tcg_temp_new_i32(); 8803 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 8804 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 8805 tcg_gen_or_i32(t0, t0, t1); 8806 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 8807 tcg_gen_or_i32(t0, t0, t1); 8808 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 8809 tcg_gen_or_i32(t0, t0, t1); 8810 tcg_gen_andi_i32(t0, t0, 1); 8811 tcg_gen_extu_i32_tl(bcond, t0); 8812 } 8813 not_likely: 8814 ctx->hflags |= MIPS_HFLAG_BC; 8815 break; 8816 default: 8817 MIPS_INVAL("cp1 cond branch"); 8818 gen_reserved_instruction(ctx); 8819 return; 8820 } 8821 ctx->btarget = btarget; 8822 ctx->hflags |= MIPS_HFLAG_BDS32; 8823 } 8824 8825 /* R6 CP1 Branches */ 8826 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, 8827 int32_t ft, int32_t offset, 8828 int delayslot_size) 8829 { 8830 target_ulong btarget; 8831 TCGv_i64 t0 = tcg_temp_new_i64(); 8832 8833 if (ctx->hflags & MIPS_HFLAG_BMASK) { 8834 #ifdef MIPS_DEBUG_DISAS 8835 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 8836 VADDR_PRIx "\n", ctx->base.pc_next); 8837 #endif 8838 gen_reserved_instruction(ctx); 8839 return; 8840 } 8841 8842 gen_load_fpr64(ctx, t0, ft); 8843 tcg_gen_andi_i64(t0, t0, 1); 8844 8845 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 8846 8847 switch (op) { 8848 case OPC_BC1EQZ: 8849 tcg_gen_xori_i64(t0, t0, 1); 8850 ctx->hflags |= MIPS_HFLAG_BC; 8851 break; 8852 case OPC_BC1NEZ: 8853 /* t0 already set */ 8854 ctx->hflags |= MIPS_HFLAG_BC; 8855 break; 8856 default: 8857 MIPS_INVAL("cp1 cond branch"); 8858 gen_reserved_instruction(ctx); 8859 return; 8860 } 8861 8862 tcg_gen_trunc_i64_tl(bcond, t0); 8863 8864 ctx->btarget = btarget; 8865 8866 switch (delayslot_size) { 8867 case 2: 8868 ctx->hflags |= MIPS_HFLAG_BDS16; 8869 break; 8870 case 4: 8871 ctx->hflags |= MIPS_HFLAG_BDS32; 8872 break; 8873 } 8874 } 8875 8876 /* Coprocessor 1 (FPU) */ 8877 8878 #define FOP(func, fmt) (((fmt) << 21) | (func)) 8879 8880 enum fopcode { 8881 OPC_ADD_S = FOP(0, FMT_S), 8882 OPC_SUB_S = FOP(1, FMT_S), 8883 OPC_MUL_S = FOP(2, FMT_S), 8884 OPC_DIV_S = FOP(3, FMT_S), 8885 OPC_SQRT_S = FOP(4, FMT_S), 8886 OPC_ABS_S = FOP(5, FMT_S), 8887 OPC_MOV_S = FOP(6, FMT_S), 8888 OPC_NEG_S = FOP(7, FMT_S), 8889 OPC_ROUND_L_S = FOP(8, FMT_S), 8890 OPC_TRUNC_L_S = FOP(9, FMT_S), 8891 OPC_CEIL_L_S = FOP(10, FMT_S), 8892 OPC_FLOOR_L_S = FOP(11, FMT_S), 8893 OPC_ROUND_W_S = FOP(12, FMT_S), 8894 OPC_TRUNC_W_S = FOP(13, FMT_S), 8895 OPC_CEIL_W_S = FOP(14, FMT_S), 8896 OPC_FLOOR_W_S = FOP(15, FMT_S), 8897 OPC_SEL_S = FOP(16, FMT_S), 8898 OPC_MOVCF_S = FOP(17, FMT_S), 8899 OPC_MOVZ_S = FOP(18, FMT_S), 8900 OPC_MOVN_S = FOP(19, FMT_S), 8901 OPC_SELEQZ_S = FOP(20, FMT_S), 8902 OPC_RECIP_S = FOP(21, FMT_S), 8903 OPC_RSQRT_S = FOP(22, FMT_S), 8904 OPC_SELNEZ_S = FOP(23, FMT_S), 8905 OPC_MADDF_S = FOP(24, FMT_S), 8906 OPC_MSUBF_S = FOP(25, FMT_S), 8907 OPC_RINT_S = FOP(26, FMT_S), 8908 OPC_CLASS_S = FOP(27, FMT_S), 8909 OPC_MIN_S = FOP(28, FMT_S), 8910 OPC_RECIP2_S = FOP(28, FMT_S), 8911 OPC_MINA_S = FOP(29, FMT_S), 8912 OPC_RECIP1_S = FOP(29, FMT_S), 8913 OPC_MAX_S = FOP(30, FMT_S), 8914 OPC_RSQRT1_S = FOP(30, FMT_S), 8915 OPC_MAXA_S = FOP(31, FMT_S), 8916 OPC_RSQRT2_S = FOP(31, FMT_S), 8917 OPC_CVT_D_S = FOP(33, FMT_S), 8918 OPC_CVT_W_S = FOP(36, FMT_S), 8919 OPC_CVT_L_S = FOP(37, FMT_S), 8920 OPC_CVT_PS_S = FOP(38, FMT_S), 8921 OPC_CMP_F_S = FOP(48, FMT_S), 8922 OPC_CMP_UN_S = FOP(49, FMT_S), 8923 OPC_CMP_EQ_S = FOP(50, FMT_S), 8924 OPC_CMP_UEQ_S = FOP(51, FMT_S), 8925 OPC_CMP_OLT_S = FOP(52, FMT_S), 8926 OPC_CMP_ULT_S = FOP(53, FMT_S), 8927 OPC_CMP_OLE_S = FOP(54, FMT_S), 8928 OPC_CMP_ULE_S = FOP(55, FMT_S), 8929 OPC_CMP_SF_S = FOP(56, FMT_S), 8930 OPC_CMP_NGLE_S = FOP(57, FMT_S), 8931 OPC_CMP_SEQ_S = FOP(58, FMT_S), 8932 OPC_CMP_NGL_S = FOP(59, FMT_S), 8933 OPC_CMP_LT_S = FOP(60, FMT_S), 8934 OPC_CMP_NGE_S = FOP(61, FMT_S), 8935 OPC_CMP_LE_S = FOP(62, FMT_S), 8936 OPC_CMP_NGT_S = FOP(63, FMT_S), 8937 8938 OPC_ADD_D = FOP(0, FMT_D), 8939 OPC_SUB_D = FOP(1, FMT_D), 8940 OPC_MUL_D = FOP(2, FMT_D), 8941 OPC_DIV_D = FOP(3, FMT_D), 8942 OPC_SQRT_D = FOP(4, FMT_D), 8943 OPC_ABS_D = FOP(5, FMT_D), 8944 OPC_MOV_D = FOP(6, FMT_D), 8945 OPC_NEG_D = FOP(7, FMT_D), 8946 OPC_ROUND_L_D = FOP(8, FMT_D), 8947 OPC_TRUNC_L_D = FOP(9, FMT_D), 8948 OPC_CEIL_L_D = FOP(10, FMT_D), 8949 OPC_FLOOR_L_D = FOP(11, FMT_D), 8950 OPC_ROUND_W_D = FOP(12, FMT_D), 8951 OPC_TRUNC_W_D = FOP(13, FMT_D), 8952 OPC_CEIL_W_D = FOP(14, FMT_D), 8953 OPC_FLOOR_W_D = FOP(15, FMT_D), 8954 OPC_SEL_D = FOP(16, FMT_D), 8955 OPC_MOVCF_D = FOP(17, FMT_D), 8956 OPC_MOVZ_D = FOP(18, FMT_D), 8957 OPC_MOVN_D = FOP(19, FMT_D), 8958 OPC_SELEQZ_D = FOP(20, FMT_D), 8959 OPC_RECIP_D = FOP(21, FMT_D), 8960 OPC_RSQRT_D = FOP(22, FMT_D), 8961 OPC_SELNEZ_D = FOP(23, FMT_D), 8962 OPC_MADDF_D = FOP(24, FMT_D), 8963 OPC_MSUBF_D = FOP(25, FMT_D), 8964 OPC_RINT_D = FOP(26, FMT_D), 8965 OPC_CLASS_D = FOP(27, FMT_D), 8966 OPC_MIN_D = FOP(28, FMT_D), 8967 OPC_RECIP2_D = FOP(28, FMT_D), 8968 OPC_MINA_D = FOP(29, FMT_D), 8969 OPC_RECIP1_D = FOP(29, FMT_D), 8970 OPC_MAX_D = FOP(30, FMT_D), 8971 OPC_RSQRT1_D = FOP(30, FMT_D), 8972 OPC_MAXA_D = FOP(31, FMT_D), 8973 OPC_RSQRT2_D = FOP(31, FMT_D), 8974 OPC_CVT_S_D = FOP(32, FMT_D), 8975 OPC_CVT_W_D = FOP(36, FMT_D), 8976 OPC_CVT_L_D = FOP(37, FMT_D), 8977 OPC_CMP_F_D = FOP(48, FMT_D), 8978 OPC_CMP_UN_D = FOP(49, FMT_D), 8979 OPC_CMP_EQ_D = FOP(50, FMT_D), 8980 OPC_CMP_UEQ_D = FOP(51, FMT_D), 8981 OPC_CMP_OLT_D = FOP(52, FMT_D), 8982 OPC_CMP_ULT_D = FOP(53, FMT_D), 8983 OPC_CMP_OLE_D = FOP(54, FMT_D), 8984 OPC_CMP_ULE_D = FOP(55, FMT_D), 8985 OPC_CMP_SF_D = FOP(56, FMT_D), 8986 OPC_CMP_NGLE_D = FOP(57, FMT_D), 8987 OPC_CMP_SEQ_D = FOP(58, FMT_D), 8988 OPC_CMP_NGL_D = FOP(59, FMT_D), 8989 OPC_CMP_LT_D = FOP(60, FMT_D), 8990 OPC_CMP_NGE_D = FOP(61, FMT_D), 8991 OPC_CMP_LE_D = FOP(62, FMT_D), 8992 OPC_CMP_NGT_D = FOP(63, FMT_D), 8993 8994 OPC_CVT_S_W = FOP(32, FMT_W), 8995 OPC_CVT_D_W = FOP(33, FMT_W), 8996 OPC_CVT_S_L = FOP(32, FMT_L), 8997 OPC_CVT_D_L = FOP(33, FMT_L), 8998 OPC_CVT_PS_PW = FOP(38, FMT_W), 8999 9000 OPC_ADD_PS = FOP(0, FMT_PS), 9001 OPC_SUB_PS = FOP(1, FMT_PS), 9002 OPC_MUL_PS = FOP(2, FMT_PS), 9003 OPC_DIV_PS = FOP(3, FMT_PS), 9004 OPC_ABS_PS = FOP(5, FMT_PS), 9005 OPC_MOV_PS = FOP(6, FMT_PS), 9006 OPC_NEG_PS = FOP(7, FMT_PS), 9007 OPC_MOVCF_PS = FOP(17, FMT_PS), 9008 OPC_MOVZ_PS = FOP(18, FMT_PS), 9009 OPC_MOVN_PS = FOP(19, FMT_PS), 9010 OPC_ADDR_PS = FOP(24, FMT_PS), 9011 OPC_MULR_PS = FOP(26, FMT_PS), 9012 OPC_RECIP2_PS = FOP(28, FMT_PS), 9013 OPC_RECIP1_PS = FOP(29, FMT_PS), 9014 OPC_RSQRT1_PS = FOP(30, FMT_PS), 9015 OPC_RSQRT2_PS = FOP(31, FMT_PS), 9016 9017 OPC_CVT_S_PU = FOP(32, FMT_PS), 9018 OPC_CVT_PW_PS = FOP(36, FMT_PS), 9019 OPC_CVT_S_PL = FOP(40, FMT_PS), 9020 OPC_PLL_PS = FOP(44, FMT_PS), 9021 OPC_PLU_PS = FOP(45, FMT_PS), 9022 OPC_PUL_PS = FOP(46, FMT_PS), 9023 OPC_PUU_PS = FOP(47, FMT_PS), 9024 OPC_CMP_F_PS = FOP(48, FMT_PS), 9025 OPC_CMP_UN_PS = FOP(49, FMT_PS), 9026 OPC_CMP_EQ_PS = FOP(50, FMT_PS), 9027 OPC_CMP_UEQ_PS = FOP(51, FMT_PS), 9028 OPC_CMP_OLT_PS = FOP(52, FMT_PS), 9029 OPC_CMP_ULT_PS = FOP(53, FMT_PS), 9030 OPC_CMP_OLE_PS = FOP(54, FMT_PS), 9031 OPC_CMP_ULE_PS = FOP(55, FMT_PS), 9032 OPC_CMP_SF_PS = FOP(56, FMT_PS), 9033 OPC_CMP_NGLE_PS = FOP(57, FMT_PS), 9034 OPC_CMP_SEQ_PS = FOP(58, FMT_PS), 9035 OPC_CMP_NGL_PS = FOP(59, FMT_PS), 9036 OPC_CMP_LT_PS = FOP(60, FMT_PS), 9037 OPC_CMP_NGE_PS = FOP(61, FMT_PS), 9038 OPC_CMP_LE_PS = FOP(62, FMT_PS), 9039 OPC_CMP_NGT_PS = FOP(63, FMT_PS), 9040 }; 9041 9042 enum r6_f_cmp_op { 9043 R6_OPC_CMP_AF_S = FOP(0, FMT_W), 9044 R6_OPC_CMP_UN_S = FOP(1, FMT_W), 9045 R6_OPC_CMP_EQ_S = FOP(2, FMT_W), 9046 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W), 9047 R6_OPC_CMP_LT_S = FOP(4, FMT_W), 9048 R6_OPC_CMP_ULT_S = FOP(5, FMT_W), 9049 R6_OPC_CMP_LE_S = FOP(6, FMT_W), 9050 R6_OPC_CMP_ULE_S = FOP(7, FMT_W), 9051 R6_OPC_CMP_SAF_S = FOP(8, FMT_W), 9052 R6_OPC_CMP_SUN_S = FOP(9, FMT_W), 9053 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W), 9054 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W), 9055 R6_OPC_CMP_SLT_S = FOP(12, FMT_W), 9056 R6_OPC_CMP_SULT_S = FOP(13, FMT_W), 9057 R6_OPC_CMP_SLE_S = FOP(14, FMT_W), 9058 R6_OPC_CMP_SULE_S = FOP(15, FMT_W), 9059 R6_OPC_CMP_OR_S = FOP(17, FMT_W), 9060 R6_OPC_CMP_UNE_S = FOP(18, FMT_W), 9061 R6_OPC_CMP_NE_S = FOP(19, FMT_W), 9062 R6_OPC_CMP_SOR_S = FOP(25, FMT_W), 9063 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W), 9064 R6_OPC_CMP_SNE_S = FOP(27, FMT_W), 9065 9066 R6_OPC_CMP_AF_D = FOP(0, FMT_L), 9067 R6_OPC_CMP_UN_D = FOP(1, FMT_L), 9068 R6_OPC_CMP_EQ_D = FOP(2, FMT_L), 9069 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L), 9070 R6_OPC_CMP_LT_D = FOP(4, FMT_L), 9071 R6_OPC_CMP_ULT_D = FOP(5, FMT_L), 9072 R6_OPC_CMP_LE_D = FOP(6, FMT_L), 9073 R6_OPC_CMP_ULE_D = FOP(7, FMT_L), 9074 R6_OPC_CMP_SAF_D = FOP(8, FMT_L), 9075 R6_OPC_CMP_SUN_D = FOP(9, FMT_L), 9076 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L), 9077 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L), 9078 R6_OPC_CMP_SLT_D = FOP(12, FMT_L), 9079 R6_OPC_CMP_SULT_D = FOP(13, FMT_L), 9080 R6_OPC_CMP_SLE_D = FOP(14, FMT_L), 9081 R6_OPC_CMP_SULE_D = FOP(15, FMT_L), 9082 R6_OPC_CMP_OR_D = FOP(17, FMT_L), 9083 R6_OPC_CMP_UNE_D = FOP(18, FMT_L), 9084 R6_OPC_CMP_NE_D = FOP(19, FMT_L), 9085 R6_OPC_CMP_SOR_D = FOP(25, FMT_L), 9086 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L), 9087 R6_OPC_CMP_SNE_D = FOP(27, FMT_L), 9088 }; 9089 9090 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) 9091 { 9092 TCGv t0 = tcg_temp_new(); 9093 9094 switch (opc) { 9095 case OPC_MFC1: 9096 { 9097 TCGv_i32 fp0 = tcg_temp_new_i32(); 9098 9099 gen_load_fpr32(ctx, fp0, fs); 9100 tcg_gen_ext_i32_tl(t0, fp0); 9101 } 9102 gen_store_gpr(t0, rt); 9103 break; 9104 case OPC_MTC1: 9105 gen_load_gpr(t0, rt); 9106 { 9107 TCGv_i32 fp0 = tcg_temp_new_i32(); 9108 9109 tcg_gen_trunc_tl_i32(fp0, t0); 9110 gen_store_fpr32(ctx, fp0, fs); 9111 } 9112 break; 9113 case OPC_CFC1: 9114 gen_helper_1e0i(cfc1, t0, fs); 9115 gen_store_gpr(t0, rt); 9116 break; 9117 case OPC_CTC1: 9118 gen_load_gpr(t0, rt); 9119 save_cpu_state(ctx, 0); 9120 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt); 9121 /* Stop translation as we may have changed hflags */ 9122 ctx->base.is_jmp = DISAS_STOP; 9123 break; 9124 #if defined(TARGET_MIPS64) 9125 case OPC_DMFC1: 9126 gen_load_fpr64(ctx, t0, fs); 9127 gen_store_gpr(t0, rt); 9128 break; 9129 case OPC_DMTC1: 9130 gen_load_gpr(t0, rt); 9131 gen_store_fpr64(ctx, t0, fs); 9132 break; 9133 #endif 9134 case OPC_MFHC1: 9135 { 9136 TCGv_i32 fp0 = tcg_temp_new_i32(); 9137 9138 gen_load_fpr32h(ctx, fp0, fs); 9139 tcg_gen_ext_i32_tl(t0, fp0); 9140 } 9141 gen_store_gpr(t0, rt); 9142 break; 9143 case OPC_MTHC1: 9144 gen_load_gpr(t0, rt); 9145 { 9146 TCGv_i32 fp0 = tcg_temp_new_i32(); 9147 9148 tcg_gen_trunc_tl_i32(fp0, t0); 9149 gen_store_fpr32h(ctx, fp0, fs); 9150 } 9151 break; 9152 default: 9153 MIPS_INVAL("cp1 move"); 9154 gen_reserved_instruction(ctx); 9155 return; 9156 } 9157 } 9158 9159 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf) 9160 { 9161 TCGLabel *l1; 9162 TCGCond cond; 9163 TCGv_i32 t0; 9164 9165 if (rd == 0) { 9166 /* Treat as NOP. */ 9167 return; 9168 } 9169 9170 if (tf) { 9171 cond = TCG_COND_EQ; 9172 } else { 9173 cond = TCG_COND_NE; 9174 } 9175 9176 l1 = gen_new_label(); 9177 t0 = tcg_temp_new_i32(); 9178 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9179 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9180 gen_load_gpr(cpu_gpr[rd], rs); 9181 gen_set_label(l1); 9182 } 9183 9184 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, 9185 int tf) 9186 { 9187 int cond; 9188 TCGv_i32 t0 = tcg_temp_new_i32(); 9189 TCGLabel *l1 = gen_new_label(); 9190 9191 if (tf) { 9192 cond = TCG_COND_EQ; 9193 } else { 9194 cond = TCG_COND_NE; 9195 } 9196 9197 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9198 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9199 gen_load_fpr32(ctx, t0, fs); 9200 gen_store_fpr32(ctx, t0, fd); 9201 gen_set_label(l1); 9202 } 9203 9204 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, 9205 int tf) 9206 { 9207 int cond; 9208 TCGv_i32 t0 = tcg_temp_new_i32(); 9209 TCGv_i64 fp0; 9210 TCGLabel *l1 = gen_new_label(); 9211 9212 if (tf) { 9213 cond = TCG_COND_EQ; 9214 } else { 9215 cond = TCG_COND_NE; 9216 } 9217 9218 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9219 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9220 fp0 = tcg_temp_new_i64(); 9221 gen_load_fpr64(ctx, fp0, fs); 9222 gen_store_fpr64(ctx, fp0, fd); 9223 gen_set_label(l1); 9224 } 9225 9226 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, 9227 int cc, int tf) 9228 { 9229 int cond; 9230 TCGv_i32 t0 = tcg_temp_new_i32(); 9231 TCGLabel *l1 = gen_new_label(); 9232 TCGLabel *l2 = gen_new_label(); 9233 9234 if (tf) { 9235 cond = TCG_COND_EQ; 9236 } else { 9237 cond = TCG_COND_NE; 9238 } 9239 9240 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9241 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9242 gen_load_fpr32(ctx, t0, fs); 9243 gen_store_fpr32(ctx, t0, fd); 9244 gen_set_label(l1); 9245 9246 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1)); 9247 tcg_gen_brcondi_i32(cond, t0, 0, l2); 9248 gen_load_fpr32h(ctx, t0, fs); 9249 gen_store_fpr32h(ctx, t0, fd); 9250 gen_set_label(l2); 9251 } 9252 9253 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9254 int fs) 9255 { 9256 TCGv_i32 t1 = tcg_constant_i32(0); 9257 TCGv_i32 fp0 = tcg_temp_new_i32(); 9258 TCGv_i32 fp1 = tcg_temp_new_i32(); 9259 TCGv_i32 fp2 = tcg_temp_new_i32(); 9260 gen_load_fpr32(ctx, fp0, fd); 9261 gen_load_fpr32(ctx, fp1, ft); 9262 gen_load_fpr32(ctx, fp2, fs); 9263 9264 switch (op1) { 9265 case OPC_SEL_S: 9266 tcg_gen_andi_i32(fp0, fp0, 1); 9267 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9268 break; 9269 case OPC_SELEQZ_S: 9270 tcg_gen_andi_i32(fp1, fp1, 1); 9271 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9272 break; 9273 case OPC_SELNEZ_S: 9274 tcg_gen_andi_i32(fp1, fp1, 1); 9275 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9276 break; 9277 default: 9278 MIPS_INVAL("gen_sel_s"); 9279 gen_reserved_instruction(ctx); 9280 break; 9281 } 9282 9283 gen_store_fpr32(ctx, fp0, fd); 9284 } 9285 9286 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9287 int fs) 9288 { 9289 TCGv_i64 t1 = tcg_constant_i64(0); 9290 TCGv_i64 fp0 = tcg_temp_new_i64(); 9291 TCGv_i64 fp1 = tcg_temp_new_i64(); 9292 TCGv_i64 fp2 = tcg_temp_new_i64(); 9293 gen_load_fpr64(ctx, fp0, fd); 9294 gen_load_fpr64(ctx, fp1, ft); 9295 gen_load_fpr64(ctx, fp2, fs); 9296 9297 switch (op1) { 9298 case OPC_SEL_D: 9299 tcg_gen_andi_i64(fp0, fp0, 1); 9300 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9301 break; 9302 case OPC_SELEQZ_D: 9303 tcg_gen_andi_i64(fp1, fp1, 1); 9304 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9305 break; 9306 case OPC_SELNEZ_D: 9307 tcg_gen_andi_i64(fp1, fp1, 1); 9308 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9309 break; 9310 default: 9311 MIPS_INVAL("gen_sel_d"); 9312 gen_reserved_instruction(ctx); 9313 break; 9314 } 9315 9316 gen_store_fpr64(ctx, fp0, fd); 9317 } 9318 9319 static void gen_farith(DisasContext *ctx, enum fopcode op1, 9320 int ft, int fs, int fd, int cc) 9321 { 9322 uint32_t func = ctx->opcode & 0x3f; 9323 switch (op1) { 9324 case OPC_ADD_S: 9325 { 9326 TCGv_i32 fp0 = tcg_temp_new_i32(); 9327 TCGv_i32 fp1 = tcg_temp_new_i32(); 9328 9329 gen_load_fpr32(ctx, fp0, fs); 9330 gen_load_fpr32(ctx, fp1, ft); 9331 gen_helper_float_add_s(fp0, tcg_env, fp0, fp1); 9332 gen_store_fpr32(ctx, fp0, fd); 9333 } 9334 break; 9335 case OPC_SUB_S: 9336 { 9337 TCGv_i32 fp0 = tcg_temp_new_i32(); 9338 TCGv_i32 fp1 = tcg_temp_new_i32(); 9339 9340 gen_load_fpr32(ctx, fp0, fs); 9341 gen_load_fpr32(ctx, fp1, ft); 9342 gen_helper_float_sub_s(fp0, tcg_env, fp0, fp1); 9343 gen_store_fpr32(ctx, fp0, fd); 9344 } 9345 break; 9346 case OPC_MUL_S: 9347 { 9348 TCGv_i32 fp0 = tcg_temp_new_i32(); 9349 TCGv_i32 fp1 = tcg_temp_new_i32(); 9350 9351 gen_load_fpr32(ctx, fp0, fs); 9352 gen_load_fpr32(ctx, fp1, ft); 9353 gen_helper_float_mul_s(fp0, tcg_env, fp0, fp1); 9354 gen_store_fpr32(ctx, fp0, fd); 9355 } 9356 break; 9357 case OPC_DIV_S: 9358 { 9359 TCGv_i32 fp0 = tcg_temp_new_i32(); 9360 TCGv_i32 fp1 = tcg_temp_new_i32(); 9361 9362 gen_load_fpr32(ctx, fp0, fs); 9363 gen_load_fpr32(ctx, fp1, ft); 9364 gen_helper_float_div_s(fp0, tcg_env, fp0, fp1); 9365 gen_store_fpr32(ctx, fp0, fd); 9366 } 9367 break; 9368 case OPC_SQRT_S: 9369 { 9370 TCGv_i32 fp0 = tcg_temp_new_i32(); 9371 9372 gen_load_fpr32(ctx, fp0, fs); 9373 gen_helper_float_sqrt_s(fp0, tcg_env, fp0); 9374 gen_store_fpr32(ctx, fp0, fd); 9375 } 9376 break; 9377 case OPC_ABS_S: 9378 { 9379 TCGv_i32 fp0 = tcg_temp_new_i32(); 9380 9381 gen_load_fpr32(ctx, fp0, fs); 9382 if (ctx->abs2008) { 9383 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL); 9384 } else { 9385 gen_helper_float_abs_s(fp0, fp0); 9386 } 9387 gen_store_fpr32(ctx, fp0, fd); 9388 } 9389 break; 9390 case OPC_MOV_S: 9391 { 9392 TCGv_i32 fp0 = tcg_temp_new_i32(); 9393 9394 gen_load_fpr32(ctx, fp0, fs); 9395 gen_store_fpr32(ctx, fp0, fd); 9396 } 9397 break; 9398 case OPC_NEG_S: 9399 { 9400 TCGv_i32 fp0 = tcg_temp_new_i32(); 9401 9402 gen_load_fpr32(ctx, fp0, fs); 9403 if (ctx->abs2008) { 9404 tcg_gen_xori_i32(fp0, fp0, 1UL << 31); 9405 } else { 9406 gen_helper_float_chs_s(fp0, fp0); 9407 } 9408 gen_store_fpr32(ctx, fp0, fd); 9409 } 9410 break; 9411 case OPC_ROUND_L_S: 9412 check_cp1_64bitmode(ctx); 9413 { 9414 TCGv_i32 fp32 = tcg_temp_new_i32(); 9415 TCGv_i64 fp64 = tcg_temp_new_i64(); 9416 9417 gen_load_fpr32(ctx, fp32, fs); 9418 if (ctx->nan2008) { 9419 gen_helper_float_round_2008_l_s(fp64, tcg_env, fp32); 9420 } else { 9421 gen_helper_float_round_l_s(fp64, tcg_env, fp32); 9422 } 9423 gen_store_fpr64(ctx, fp64, fd); 9424 } 9425 break; 9426 case OPC_TRUNC_L_S: 9427 check_cp1_64bitmode(ctx); 9428 { 9429 TCGv_i32 fp32 = tcg_temp_new_i32(); 9430 TCGv_i64 fp64 = tcg_temp_new_i64(); 9431 9432 gen_load_fpr32(ctx, fp32, fs); 9433 if (ctx->nan2008) { 9434 gen_helper_float_trunc_2008_l_s(fp64, tcg_env, fp32); 9435 } else { 9436 gen_helper_float_trunc_l_s(fp64, tcg_env, fp32); 9437 } 9438 gen_store_fpr64(ctx, fp64, fd); 9439 } 9440 break; 9441 case OPC_CEIL_L_S: 9442 check_cp1_64bitmode(ctx); 9443 { 9444 TCGv_i32 fp32 = tcg_temp_new_i32(); 9445 TCGv_i64 fp64 = tcg_temp_new_i64(); 9446 9447 gen_load_fpr32(ctx, fp32, fs); 9448 if (ctx->nan2008) { 9449 gen_helper_float_ceil_2008_l_s(fp64, tcg_env, fp32); 9450 } else { 9451 gen_helper_float_ceil_l_s(fp64, tcg_env, fp32); 9452 } 9453 gen_store_fpr64(ctx, fp64, fd); 9454 } 9455 break; 9456 case OPC_FLOOR_L_S: 9457 check_cp1_64bitmode(ctx); 9458 { 9459 TCGv_i32 fp32 = tcg_temp_new_i32(); 9460 TCGv_i64 fp64 = tcg_temp_new_i64(); 9461 9462 gen_load_fpr32(ctx, fp32, fs); 9463 if (ctx->nan2008) { 9464 gen_helper_float_floor_2008_l_s(fp64, tcg_env, fp32); 9465 } else { 9466 gen_helper_float_floor_l_s(fp64, tcg_env, fp32); 9467 } 9468 gen_store_fpr64(ctx, fp64, fd); 9469 } 9470 break; 9471 case OPC_ROUND_W_S: 9472 { 9473 TCGv_i32 fp0 = tcg_temp_new_i32(); 9474 9475 gen_load_fpr32(ctx, fp0, fs); 9476 if (ctx->nan2008) { 9477 gen_helper_float_round_2008_w_s(fp0, tcg_env, fp0); 9478 } else { 9479 gen_helper_float_round_w_s(fp0, tcg_env, fp0); 9480 } 9481 gen_store_fpr32(ctx, fp0, fd); 9482 } 9483 break; 9484 case OPC_TRUNC_W_S: 9485 { 9486 TCGv_i32 fp0 = tcg_temp_new_i32(); 9487 9488 gen_load_fpr32(ctx, fp0, fs); 9489 if (ctx->nan2008) { 9490 gen_helper_float_trunc_2008_w_s(fp0, tcg_env, fp0); 9491 } else { 9492 gen_helper_float_trunc_w_s(fp0, tcg_env, fp0); 9493 } 9494 gen_store_fpr32(ctx, fp0, fd); 9495 } 9496 break; 9497 case OPC_CEIL_W_S: 9498 { 9499 TCGv_i32 fp0 = tcg_temp_new_i32(); 9500 9501 gen_load_fpr32(ctx, fp0, fs); 9502 if (ctx->nan2008) { 9503 gen_helper_float_ceil_2008_w_s(fp0, tcg_env, fp0); 9504 } else { 9505 gen_helper_float_ceil_w_s(fp0, tcg_env, fp0); 9506 } 9507 gen_store_fpr32(ctx, fp0, fd); 9508 } 9509 break; 9510 case OPC_FLOOR_W_S: 9511 { 9512 TCGv_i32 fp0 = tcg_temp_new_i32(); 9513 9514 gen_load_fpr32(ctx, fp0, fs); 9515 if (ctx->nan2008) { 9516 gen_helper_float_floor_2008_w_s(fp0, tcg_env, fp0); 9517 } else { 9518 gen_helper_float_floor_w_s(fp0, tcg_env, fp0); 9519 } 9520 gen_store_fpr32(ctx, fp0, fd); 9521 } 9522 break; 9523 case OPC_SEL_S: 9524 check_insn(ctx, ISA_MIPS_R6); 9525 gen_sel_s(ctx, op1, fd, ft, fs); 9526 break; 9527 case OPC_SELEQZ_S: 9528 check_insn(ctx, ISA_MIPS_R6); 9529 gen_sel_s(ctx, op1, fd, ft, fs); 9530 break; 9531 case OPC_SELNEZ_S: 9532 check_insn(ctx, ISA_MIPS_R6); 9533 gen_sel_s(ctx, op1, fd, ft, fs); 9534 break; 9535 case OPC_MOVCF_S: 9536 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9537 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 9538 break; 9539 case OPC_MOVZ_S: 9540 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9541 { 9542 TCGLabel *l1 = gen_new_label(); 9543 TCGv_i32 fp0; 9544 9545 if (ft != 0) { 9546 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 9547 } 9548 fp0 = tcg_temp_new_i32(); 9549 gen_load_fpr32(ctx, fp0, fs); 9550 gen_store_fpr32(ctx, fp0, fd); 9551 gen_set_label(l1); 9552 } 9553 break; 9554 case OPC_MOVN_S: 9555 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9556 { 9557 TCGLabel *l1 = gen_new_label(); 9558 TCGv_i32 fp0; 9559 9560 if (ft != 0) { 9561 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 9562 fp0 = tcg_temp_new_i32(); 9563 gen_load_fpr32(ctx, fp0, fs); 9564 gen_store_fpr32(ctx, fp0, fd); 9565 gen_set_label(l1); 9566 } 9567 } 9568 break; 9569 case OPC_RECIP_S: 9570 { 9571 TCGv_i32 fp0 = tcg_temp_new_i32(); 9572 9573 gen_load_fpr32(ctx, fp0, fs); 9574 gen_helper_float_recip_s(fp0, tcg_env, fp0); 9575 gen_store_fpr32(ctx, fp0, fd); 9576 } 9577 break; 9578 case OPC_RSQRT_S: 9579 { 9580 TCGv_i32 fp0 = tcg_temp_new_i32(); 9581 9582 gen_load_fpr32(ctx, fp0, fs); 9583 gen_helper_float_rsqrt_s(fp0, tcg_env, fp0); 9584 gen_store_fpr32(ctx, fp0, fd); 9585 } 9586 break; 9587 case OPC_MADDF_S: 9588 check_insn(ctx, ISA_MIPS_R6); 9589 { 9590 TCGv_i32 fp0 = tcg_temp_new_i32(); 9591 TCGv_i32 fp1 = tcg_temp_new_i32(); 9592 TCGv_i32 fp2 = tcg_temp_new_i32(); 9593 gen_load_fpr32(ctx, fp0, fs); 9594 gen_load_fpr32(ctx, fp1, ft); 9595 gen_load_fpr32(ctx, fp2, fd); 9596 gen_helper_float_maddf_s(fp2, tcg_env, fp0, fp1, fp2); 9597 gen_store_fpr32(ctx, fp2, fd); 9598 } 9599 break; 9600 case OPC_MSUBF_S: 9601 check_insn(ctx, ISA_MIPS_R6); 9602 { 9603 TCGv_i32 fp0 = tcg_temp_new_i32(); 9604 TCGv_i32 fp1 = tcg_temp_new_i32(); 9605 TCGv_i32 fp2 = tcg_temp_new_i32(); 9606 gen_load_fpr32(ctx, fp0, fs); 9607 gen_load_fpr32(ctx, fp1, ft); 9608 gen_load_fpr32(ctx, fp2, fd); 9609 gen_helper_float_msubf_s(fp2, tcg_env, fp0, fp1, fp2); 9610 gen_store_fpr32(ctx, fp2, fd); 9611 } 9612 break; 9613 case OPC_RINT_S: 9614 check_insn(ctx, ISA_MIPS_R6); 9615 { 9616 TCGv_i32 fp0 = tcg_temp_new_i32(); 9617 gen_load_fpr32(ctx, fp0, fs); 9618 gen_helper_float_rint_s(fp0, tcg_env, fp0); 9619 gen_store_fpr32(ctx, fp0, fd); 9620 } 9621 break; 9622 case OPC_CLASS_S: 9623 check_insn(ctx, ISA_MIPS_R6); 9624 { 9625 TCGv_i32 fp0 = tcg_temp_new_i32(); 9626 gen_load_fpr32(ctx, fp0, fs); 9627 gen_helper_float_class_s(fp0, tcg_env, fp0); 9628 gen_store_fpr32(ctx, fp0, fd); 9629 } 9630 break; 9631 case OPC_MIN_S: /* OPC_RECIP2_S */ 9632 if (ctx->insn_flags & ISA_MIPS_R6) { 9633 /* OPC_MIN_S */ 9634 TCGv_i32 fp0 = tcg_temp_new_i32(); 9635 TCGv_i32 fp1 = tcg_temp_new_i32(); 9636 TCGv_i32 fp2 = tcg_temp_new_i32(); 9637 gen_load_fpr32(ctx, fp0, fs); 9638 gen_load_fpr32(ctx, fp1, ft); 9639 gen_helper_float_min_s(fp2, tcg_env, fp0, fp1); 9640 gen_store_fpr32(ctx, fp2, fd); 9641 } else { 9642 /* OPC_RECIP2_S */ 9643 check_cp1_64bitmode(ctx); 9644 { 9645 TCGv_i32 fp0 = tcg_temp_new_i32(); 9646 TCGv_i32 fp1 = tcg_temp_new_i32(); 9647 9648 gen_load_fpr32(ctx, fp0, fs); 9649 gen_load_fpr32(ctx, fp1, ft); 9650 gen_helper_float_recip2_s(fp0, tcg_env, fp0, fp1); 9651 gen_store_fpr32(ctx, fp0, fd); 9652 } 9653 } 9654 break; 9655 case OPC_MINA_S: /* OPC_RECIP1_S */ 9656 if (ctx->insn_flags & ISA_MIPS_R6) { 9657 /* OPC_MINA_S */ 9658 TCGv_i32 fp0 = tcg_temp_new_i32(); 9659 TCGv_i32 fp1 = tcg_temp_new_i32(); 9660 TCGv_i32 fp2 = tcg_temp_new_i32(); 9661 gen_load_fpr32(ctx, fp0, fs); 9662 gen_load_fpr32(ctx, fp1, ft); 9663 gen_helper_float_mina_s(fp2, tcg_env, fp0, fp1); 9664 gen_store_fpr32(ctx, fp2, fd); 9665 } else { 9666 /* OPC_RECIP1_S */ 9667 check_cp1_64bitmode(ctx); 9668 { 9669 TCGv_i32 fp0 = tcg_temp_new_i32(); 9670 9671 gen_load_fpr32(ctx, fp0, fs); 9672 gen_helper_float_recip1_s(fp0, tcg_env, fp0); 9673 gen_store_fpr32(ctx, fp0, fd); 9674 } 9675 } 9676 break; 9677 case OPC_MAX_S: /* OPC_RSQRT1_S */ 9678 if (ctx->insn_flags & ISA_MIPS_R6) { 9679 /* OPC_MAX_S */ 9680 TCGv_i32 fp0 = tcg_temp_new_i32(); 9681 TCGv_i32 fp1 = tcg_temp_new_i32(); 9682 gen_load_fpr32(ctx, fp0, fs); 9683 gen_load_fpr32(ctx, fp1, ft); 9684 gen_helper_float_max_s(fp1, tcg_env, fp0, fp1); 9685 gen_store_fpr32(ctx, fp1, fd); 9686 } else { 9687 /* OPC_RSQRT1_S */ 9688 check_cp1_64bitmode(ctx); 9689 { 9690 TCGv_i32 fp0 = tcg_temp_new_i32(); 9691 9692 gen_load_fpr32(ctx, fp0, fs); 9693 gen_helper_float_rsqrt1_s(fp0, tcg_env, fp0); 9694 gen_store_fpr32(ctx, fp0, fd); 9695 } 9696 } 9697 break; 9698 case OPC_MAXA_S: /* OPC_RSQRT2_S */ 9699 if (ctx->insn_flags & ISA_MIPS_R6) { 9700 /* OPC_MAXA_S */ 9701 TCGv_i32 fp0 = tcg_temp_new_i32(); 9702 TCGv_i32 fp1 = tcg_temp_new_i32(); 9703 gen_load_fpr32(ctx, fp0, fs); 9704 gen_load_fpr32(ctx, fp1, ft); 9705 gen_helper_float_maxa_s(fp1, tcg_env, fp0, fp1); 9706 gen_store_fpr32(ctx, fp1, fd); 9707 } else { 9708 /* OPC_RSQRT2_S */ 9709 check_cp1_64bitmode(ctx); 9710 { 9711 TCGv_i32 fp0 = tcg_temp_new_i32(); 9712 TCGv_i32 fp1 = tcg_temp_new_i32(); 9713 9714 gen_load_fpr32(ctx, fp0, fs); 9715 gen_load_fpr32(ctx, fp1, ft); 9716 gen_helper_float_rsqrt2_s(fp0, tcg_env, fp0, fp1); 9717 gen_store_fpr32(ctx, fp0, fd); 9718 } 9719 } 9720 break; 9721 case OPC_CVT_D_S: 9722 check_cp1_registers(ctx, fd); 9723 { 9724 TCGv_i32 fp32 = tcg_temp_new_i32(); 9725 TCGv_i64 fp64 = tcg_temp_new_i64(); 9726 9727 gen_load_fpr32(ctx, fp32, fs); 9728 gen_helper_float_cvtd_s(fp64, tcg_env, fp32); 9729 gen_store_fpr64(ctx, fp64, fd); 9730 } 9731 break; 9732 case OPC_CVT_W_S: 9733 { 9734 TCGv_i32 fp0 = tcg_temp_new_i32(); 9735 9736 gen_load_fpr32(ctx, fp0, fs); 9737 if (ctx->nan2008) { 9738 gen_helper_float_cvt_2008_w_s(fp0, tcg_env, fp0); 9739 } else { 9740 gen_helper_float_cvt_w_s(fp0, tcg_env, fp0); 9741 } 9742 gen_store_fpr32(ctx, fp0, fd); 9743 } 9744 break; 9745 case OPC_CVT_L_S: 9746 check_cp1_64bitmode(ctx); 9747 { 9748 TCGv_i32 fp32 = tcg_temp_new_i32(); 9749 TCGv_i64 fp64 = tcg_temp_new_i64(); 9750 9751 gen_load_fpr32(ctx, fp32, fs); 9752 if (ctx->nan2008) { 9753 gen_helper_float_cvt_2008_l_s(fp64, tcg_env, fp32); 9754 } else { 9755 gen_helper_float_cvt_l_s(fp64, tcg_env, fp32); 9756 } 9757 gen_store_fpr64(ctx, fp64, fd); 9758 } 9759 break; 9760 case OPC_CVT_PS_S: 9761 check_ps(ctx); 9762 { 9763 TCGv_i64 fp64 = tcg_temp_new_i64(); 9764 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 9765 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 9766 9767 gen_load_fpr32(ctx, fp32_0, fs); 9768 gen_load_fpr32(ctx, fp32_1, ft); 9769 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); 9770 gen_store_fpr64(ctx, fp64, fd); 9771 } 9772 break; 9773 case OPC_CMP_F_S: 9774 case OPC_CMP_UN_S: 9775 case OPC_CMP_EQ_S: 9776 case OPC_CMP_UEQ_S: 9777 case OPC_CMP_OLT_S: 9778 case OPC_CMP_ULT_S: 9779 case OPC_CMP_OLE_S: 9780 case OPC_CMP_ULE_S: 9781 case OPC_CMP_SF_S: 9782 case OPC_CMP_NGLE_S: 9783 case OPC_CMP_SEQ_S: 9784 case OPC_CMP_NGL_S: 9785 case OPC_CMP_LT_S: 9786 case OPC_CMP_NGE_S: 9787 case OPC_CMP_LE_S: 9788 case OPC_CMP_NGT_S: 9789 check_insn_opc_removed(ctx, ISA_MIPS_R6); 9790 if (ctx->opcode & (1 << 6)) { 9791 gen_cmpabs_s(ctx, func - 48, ft, fs, cc); 9792 } else { 9793 gen_cmp_s(ctx, func - 48, ft, fs, cc); 9794 } 9795 break; 9796 case OPC_ADD_D: 9797 check_cp1_registers(ctx, fs | ft | fd); 9798 { 9799 TCGv_i64 fp0 = tcg_temp_new_i64(); 9800 TCGv_i64 fp1 = tcg_temp_new_i64(); 9801 9802 gen_load_fpr64(ctx, fp0, fs); 9803 gen_load_fpr64(ctx, fp1, ft); 9804 gen_helper_float_add_d(fp0, tcg_env, fp0, fp1); 9805 gen_store_fpr64(ctx, fp0, fd); 9806 } 9807 break; 9808 case OPC_SUB_D: 9809 check_cp1_registers(ctx, fs | ft | fd); 9810 { 9811 TCGv_i64 fp0 = tcg_temp_new_i64(); 9812 TCGv_i64 fp1 = tcg_temp_new_i64(); 9813 9814 gen_load_fpr64(ctx, fp0, fs); 9815 gen_load_fpr64(ctx, fp1, ft); 9816 gen_helper_float_sub_d(fp0, tcg_env, fp0, fp1); 9817 gen_store_fpr64(ctx, fp0, fd); 9818 } 9819 break; 9820 case OPC_MUL_D: 9821 check_cp1_registers(ctx, fs | ft | fd); 9822 { 9823 TCGv_i64 fp0 = tcg_temp_new_i64(); 9824 TCGv_i64 fp1 = tcg_temp_new_i64(); 9825 9826 gen_load_fpr64(ctx, fp0, fs); 9827 gen_load_fpr64(ctx, fp1, ft); 9828 gen_helper_float_mul_d(fp0, tcg_env, fp0, fp1); 9829 gen_store_fpr64(ctx, fp0, fd); 9830 } 9831 break; 9832 case OPC_DIV_D: 9833 check_cp1_registers(ctx, fs | ft | fd); 9834 { 9835 TCGv_i64 fp0 = tcg_temp_new_i64(); 9836 TCGv_i64 fp1 = tcg_temp_new_i64(); 9837 9838 gen_load_fpr64(ctx, fp0, fs); 9839 gen_load_fpr64(ctx, fp1, ft); 9840 gen_helper_float_div_d(fp0, tcg_env, fp0, fp1); 9841 gen_store_fpr64(ctx, fp0, fd); 9842 } 9843 break; 9844 case OPC_SQRT_D: 9845 check_cp1_registers(ctx, fs | fd); 9846 { 9847 TCGv_i64 fp0 = tcg_temp_new_i64(); 9848 9849 gen_load_fpr64(ctx, fp0, fs); 9850 gen_helper_float_sqrt_d(fp0, tcg_env, fp0); 9851 gen_store_fpr64(ctx, fp0, fd); 9852 } 9853 break; 9854 case OPC_ABS_D: 9855 check_cp1_registers(ctx, fs | fd); 9856 { 9857 TCGv_i64 fp0 = tcg_temp_new_i64(); 9858 9859 gen_load_fpr64(ctx, fp0, fs); 9860 if (ctx->abs2008) { 9861 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL); 9862 } else { 9863 gen_helper_float_abs_d(fp0, fp0); 9864 } 9865 gen_store_fpr64(ctx, fp0, fd); 9866 } 9867 break; 9868 case OPC_MOV_D: 9869 check_cp1_registers(ctx, fs | fd); 9870 { 9871 TCGv_i64 fp0 = tcg_temp_new_i64(); 9872 9873 gen_load_fpr64(ctx, fp0, fs); 9874 gen_store_fpr64(ctx, fp0, fd); 9875 } 9876 break; 9877 case OPC_NEG_D: 9878 check_cp1_registers(ctx, fs | fd); 9879 { 9880 TCGv_i64 fp0 = tcg_temp_new_i64(); 9881 9882 gen_load_fpr64(ctx, fp0, fs); 9883 if (ctx->abs2008) { 9884 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63); 9885 } else { 9886 gen_helper_float_chs_d(fp0, fp0); 9887 } 9888 gen_store_fpr64(ctx, fp0, fd); 9889 } 9890 break; 9891 case OPC_ROUND_L_D: 9892 check_cp1_64bitmode(ctx); 9893 { 9894 TCGv_i64 fp0 = tcg_temp_new_i64(); 9895 9896 gen_load_fpr64(ctx, fp0, fs); 9897 if (ctx->nan2008) { 9898 gen_helper_float_round_2008_l_d(fp0, tcg_env, fp0); 9899 } else { 9900 gen_helper_float_round_l_d(fp0, tcg_env, fp0); 9901 } 9902 gen_store_fpr64(ctx, fp0, fd); 9903 } 9904 break; 9905 case OPC_TRUNC_L_D: 9906 check_cp1_64bitmode(ctx); 9907 { 9908 TCGv_i64 fp0 = tcg_temp_new_i64(); 9909 9910 gen_load_fpr64(ctx, fp0, fs); 9911 if (ctx->nan2008) { 9912 gen_helper_float_trunc_2008_l_d(fp0, tcg_env, fp0); 9913 } else { 9914 gen_helper_float_trunc_l_d(fp0, tcg_env, fp0); 9915 } 9916 gen_store_fpr64(ctx, fp0, fd); 9917 } 9918 break; 9919 case OPC_CEIL_L_D: 9920 check_cp1_64bitmode(ctx); 9921 { 9922 TCGv_i64 fp0 = tcg_temp_new_i64(); 9923 9924 gen_load_fpr64(ctx, fp0, fs); 9925 if (ctx->nan2008) { 9926 gen_helper_float_ceil_2008_l_d(fp0, tcg_env, fp0); 9927 } else { 9928 gen_helper_float_ceil_l_d(fp0, tcg_env, fp0); 9929 } 9930 gen_store_fpr64(ctx, fp0, fd); 9931 } 9932 break; 9933 case OPC_FLOOR_L_D: 9934 check_cp1_64bitmode(ctx); 9935 { 9936 TCGv_i64 fp0 = tcg_temp_new_i64(); 9937 9938 gen_load_fpr64(ctx, fp0, fs); 9939 if (ctx->nan2008) { 9940 gen_helper_float_floor_2008_l_d(fp0, tcg_env, fp0); 9941 } else { 9942 gen_helper_float_floor_l_d(fp0, tcg_env, fp0); 9943 } 9944 gen_store_fpr64(ctx, fp0, fd); 9945 } 9946 break; 9947 case OPC_ROUND_W_D: 9948 check_cp1_registers(ctx, fs); 9949 { 9950 TCGv_i32 fp32 = tcg_temp_new_i32(); 9951 TCGv_i64 fp64 = tcg_temp_new_i64(); 9952 9953 gen_load_fpr64(ctx, fp64, fs); 9954 if (ctx->nan2008) { 9955 gen_helper_float_round_2008_w_d(fp32, tcg_env, fp64); 9956 } else { 9957 gen_helper_float_round_w_d(fp32, tcg_env, fp64); 9958 } 9959 gen_store_fpr32(ctx, fp32, fd); 9960 } 9961 break; 9962 case OPC_TRUNC_W_D: 9963 check_cp1_registers(ctx, fs); 9964 { 9965 TCGv_i32 fp32 = tcg_temp_new_i32(); 9966 TCGv_i64 fp64 = tcg_temp_new_i64(); 9967 9968 gen_load_fpr64(ctx, fp64, fs); 9969 if (ctx->nan2008) { 9970 gen_helper_float_trunc_2008_w_d(fp32, tcg_env, fp64); 9971 } else { 9972 gen_helper_float_trunc_w_d(fp32, tcg_env, fp64); 9973 } 9974 gen_store_fpr32(ctx, fp32, fd); 9975 } 9976 break; 9977 case OPC_CEIL_W_D: 9978 check_cp1_registers(ctx, fs); 9979 { 9980 TCGv_i32 fp32 = tcg_temp_new_i32(); 9981 TCGv_i64 fp64 = tcg_temp_new_i64(); 9982 9983 gen_load_fpr64(ctx, fp64, fs); 9984 if (ctx->nan2008) { 9985 gen_helper_float_ceil_2008_w_d(fp32, tcg_env, fp64); 9986 } else { 9987 gen_helper_float_ceil_w_d(fp32, tcg_env, fp64); 9988 } 9989 gen_store_fpr32(ctx, fp32, fd); 9990 } 9991 break; 9992 case OPC_FLOOR_W_D: 9993 check_cp1_registers(ctx, fs); 9994 { 9995 TCGv_i32 fp32 = tcg_temp_new_i32(); 9996 TCGv_i64 fp64 = tcg_temp_new_i64(); 9997 9998 gen_load_fpr64(ctx, fp64, fs); 9999 if (ctx->nan2008) { 10000 gen_helper_float_floor_2008_w_d(fp32, tcg_env, fp64); 10001 } else { 10002 gen_helper_float_floor_w_d(fp32, tcg_env, fp64); 10003 } 10004 gen_store_fpr32(ctx, fp32, fd); 10005 } 10006 break; 10007 case OPC_SEL_D: 10008 check_insn(ctx, ISA_MIPS_R6); 10009 gen_sel_d(ctx, op1, fd, ft, fs); 10010 break; 10011 case OPC_SELEQZ_D: 10012 check_insn(ctx, ISA_MIPS_R6); 10013 gen_sel_d(ctx, op1, fd, ft, fs); 10014 break; 10015 case OPC_SELNEZ_D: 10016 check_insn(ctx, ISA_MIPS_R6); 10017 gen_sel_d(ctx, op1, fd, ft, fs); 10018 break; 10019 case OPC_MOVCF_D: 10020 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10021 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10022 break; 10023 case OPC_MOVZ_D: 10024 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10025 { 10026 TCGLabel *l1 = gen_new_label(); 10027 TCGv_i64 fp0; 10028 10029 if (ft != 0) { 10030 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10031 } 10032 fp0 = tcg_temp_new_i64(); 10033 gen_load_fpr64(ctx, fp0, fs); 10034 gen_store_fpr64(ctx, fp0, fd); 10035 gen_set_label(l1); 10036 } 10037 break; 10038 case OPC_MOVN_D: 10039 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10040 { 10041 TCGLabel *l1 = gen_new_label(); 10042 TCGv_i64 fp0; 10043 10044 if (ft != 0) { 10045 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10046 fp0 = tcg_temp_new_i64(); 10047 gen_load_fpr64(ctx, fp0, fs); 10048 gen_store_fpr64(ctx, fp0, fd); 10049 gen_set_label(l1); 10050 } 10051 } 10052 break; 10053 case OPC_RECIP_D: 10054 check_cp1_registers(ctx, fs | fd); 10055 { 10056 TCGv_i64 fp0 = tcg_temp_new_i64(); 10057 10058 gen_load_fpr64(ctx, fp0, fs); 10059 gen_helper_float_recip_d(fp0, tcg_env, fp0); 10060 gen_store_fpr64(ctx, fp0, fd); 10061 } 10062 break; 10063 case OPC_RSQRT_D: 10064 check_cp1_registers(ctx, fs | fd); 10065 { 10066 TCGv_i64 fp0 = tcg_temp_new_i64(); 10067 10068 gen_load_fpr64(ctx, fp0, fs); 10069 gen_helper_float_rsqrt_d(fp0, tcg_env, fp0); 10070 gen_store_fpr64(ctx, fp0, fd); 10071 } 10072 break; 10073 case OPC_MADDF_D: 10074 check_insn(ctx, ISA_MIPS_R6); 10075 { 10076 TCGv_i64 fp0 = tcg_temp_new_i64(); 10077 TCGv_i64 fp1 = tcg_temp_new_i64(); 10078 TCGv_i64 fp2 = tcg_temp_new_i64(); 10079 gen_load_fpr64(ctx, fp0, fs); 10080 gen_load_fpr64(ctx, fp1, ft); 10081 gen_load_fpr64(ctx, fp2, fd); 10082 gen_helper_float_maddf_d(fp2, tcg_env, fp0, fp1, fp2); 10083 gen_store_fpr64(ctx, fp2, fd); 10084 } 10085 break; 10086 case OPC_MSUBF_D: 10087 check_insn(ctx, ISA_MIPS_R6); 10088 { 10089 TCGv_i64 fp0 = tcg_temp_new_i64(); 10090 TCGv_i64 fp1 = tcg_temp_new_i64(); 10091 TCGv_i64 fp2 = tcg_temp_new_i64(); 10092 gen_load_fpr64(ctx, fp0, fs); 10093 gen_load_fpr64(ctx, fp1, ft); 10094 gen_load_fpr64(ctx, fp2, fd); 10095 gen_helper_float_msubf_d(fp2, tcg_env, fp0, fp1, fp2); 10096 gen_store_fpr64(ctx, fp2, fd); 10097 } 10098 break; 10099 case OPC_RINT_D: 10100 check_insn(ctx, ISA_MIPS_R6); 10101 { 10102 TCGv_i64 fp0 = tcg_temp_new_i64(); 10103 gen_load_fpr64(ctx, fp0, fs); 10104 gen_helper_float_rint_d(fp0, tcg_env, fp0); 10105 gen_store_fpr64(ctx, fp0, fd); 10106 } 10107 break; 10108 case OPC_CLASS_D: 10109 check_insn(ctx, ISA_MIPS_R6); 10110 { 10111 TCGv_i64 fp0 = tcg_temp_new_i64(); 10112 gen_load_fpr64(ctx, fp0, fs); 10113 gen_helper_float_class_d(fp0, tcg_env, fp0); 10114 gen_store_fpr64(ctx, fp0, fd); 10115 } 10116 break; 10117 case OPC_MIN_D: /* OPC_RECIP2_D */ 10118 if (ctx->insn_flags & ISA_MIPS_R6) { 10119 /* OPC_MIN_D */ 10120 TCGv_i64 fp0 = tcg_temp_new_i64(); 10121 TCGv_i64 fp1 = tcg_temp_new_i64(); 10122 gen_load_fpr64(ctx, fp0, fs); 10123 gen_load_fpr64(ctx, fp1, ft); 10124 gen_helper_float_min_d(fp1, tcg_env, fp0, fp1); 10125 gen_store_fpr64(ctx, fp1, fd); 10126 } else { 10127 /* OPC_RECIP2_D */ 10128 check_cp1_64bitmode(ctx); 10129 { 10130 TCGv_i64 fp0 = tcg_temp_new_i64(); 10131 TCGv_i64 fp1 = tcg_temp_new_i64(); 10132 10133 gen_load_fpr64(ctx, fp0, fs); 10134 gen_load_fpr64(ctx, fp1, ft); 10135 gen_helper_float_recip2_d(fp0, tcg_env, fp0, fp1); 10136 gen_store_fpr64(ctx, fp0, fd); 10137 } 10138 } 10139 break; 10140 case OPC_MINA_D: /* OPC_RECIP1_D */ 10141 if (ctx->insn_flags & ISA_MIPS_R6) { 10142 /* OPC_MINA_D */ 10143 TCGv_i64 fp0 = tcg_temp_new_i64(); 10144 TCGv_i64 fp1 = tcg_temp_new_i64(); 10145 gen_load_fpr64(ctx, fp0, fs); 10146 gen_load_fpr64(ctx, fp1, ft); 10147 gen_helper_float_mina_d(fp1, tcg_env, fp0, fp1); 10148 gen_store_fpr64(ctx, fp1, fd); 10149 } else { 10150 /* OPC_RECIP1_D */ 10151 check_cp1_64bitmode(ctx); 10152 { 10153 TCGv_i64 fp0 = tcg_temp_new_i64(); 10154 10155 gen_load_fpr64(ctx, fp0, fs); 10156 gen_helper_float_recip1_d(fp0, tcg_env, fp0); 10157 gen_store_fpr64(ctx, fp0, fd); 10158 } 10159 } 10160 break; 10161 case OPC_MAX_D: /* OPC_RSQRT1_D */ 10162 if (ctx->insn_flags & ISA_MIPS_R6) { 10163 /* OPC_MAX_D */ 10164 TCGv_i64 fp0 = tcg_temp_new_i64(); 10165 TCGv_i64 fp1 = tcg_temp_new_i64(); 10166 gen_load_fpr64(ctx, fp0, fs); 10167 gen_load_fpr64(ctx, fp1, ft); 10168 gen_helper_float_max_d(fp1, tcg_env, fp0, fp1); 10169 gen_store_fpr64(ctx, fp1, fd); 10170 } else { 10171 /* OPC_RSQRT1_D */ 10172 check_cp1_64bitmode(ctx); 10173 { 10174 TCGv_i64 fp0 = tcg_temp_new_i64(); 10175 10176 gen_load_fpr64(ctx, fp0, fs); 10177 gen_helper_float_rsqrt1_d(fp0, tcg_env, fp0); 10178 gen_store_fpr64(ctx, fp0, fd); 10179 } 10180 } 10181 break; 10182 case OPC_MAXA_D: /* OPC_RSQRT2_D */ 10183 if (ctx->insn_flags & ISA_MIPS_R6) { 10184 /* OPC_MAXA_D */ 10185 TCGv_i64 fp0 = tcg_temp_new_i64(); 10186 TCGv_i64 fp1 = tcg_temp_new_i64(); 10187 gen_load_fpr64(ctx, fp0, fs); 10188 gen_load_fpr64(ctx, fp1, ft); 10189 gen_helper_float_maxa_d(fp1, tcg_env, fp0, fp1); 10190 gen_store_fpr64(ctx, fp1, fd); 10191 } else { 10192 /* OPC_RSQRT2_D */ 10193 check_cp1_64bitmode(ctx); 10194 { 10195 TCGv_i64 fp0 = tcg_temp_new_i64(); 10196 TCGv_i64 fp1 = tcg_temp_new_i64(); 10197 10198 gen_load_fpr64(ctx, fp0, fs); 10199 gen_load_fpr64(ctx, fp1, ft); 10200 gen_helper_float_rsqrt2_d(fp0, tcg_env, fp0, fp1); 10201 gen_store_fpr64(ctx, fp0, fd); 10202 } 10203 } 10204 break; 10205 case OPC_CMP_F_D: 10206 case OPC_CMP_UN_D: 10207 case OPC_CMP_EQ_D: 10208 case OPC_CMP_UEQ_D: 10209 case OPC_CMP_OLT_D: 10210 case OPC_CMP_ULT_D: 10211 case OPC_CMP_OLE_D: 10212 case OPC_CMP_ULE_D: 10213 case OPC_CMP_SF_D: 10214 case OPC_CMP_NGLE_D: 10215 case OPC_CMP_SEQ_D: 10216 case OPC_CMP_NGL_D: 10217 case OPC_CMP_LT_D: 10218 case OPC_CMP_NGE_D: 10219 case OPC_CMP_LE_D: 10220 case OPC_CMP_NGT_D: 10221 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10222 if (ctx->opcode & (1 << 6)) { 10223 gen_cmpabs_d(ctx, func - 48, ft, fs, cc); 10224 } else { 10225 gen_cmp_d(ctx, func - 48, ft, fs, cc); 10226 } 10227 break; 10228 case OPC_CVT_S_D: 10229 check_cp1_registers(ctx, fs); 10230 { 10231 TCGv_i32 fp32 = tcg_temp_new_i32(); 10232 TCGv_i64 fp64 = tcg_temp_new_i64(); 10233 10234 gen_load_fpr64(ctx, fp64, fs); 10235 gen_helper_float_cvts_d(fp32, tcg_env, fp64); 10236 gen_store_fpr32(ctx, fp32, fd); 10237 } 10238 break; 10239 case OPC_CVT_W_D: 10240 check_cp1_registers(ctx, fs); 10241 { 10242 TCGv_i32 fp32 = tcg_temp_new_i32(); 10243 TCGv_i64 fp64 = tcg_temp_new_i64(); 10244 10245 gen_load_fpr64(ctx, fp64, fs); 10246 if (ctx->nan2008) { 10247 gen_helper_float_cvt_2008_w_d(fp32, tcg_env, fp64); 10248 } else { 10249 gen_helper_float_cvt_w_d(fp32, tcg_env, fp64); 10250 } 10251 gen_store_fpr32(ctx, fp32, fd); 10252 } 10253 break; 10254 case OPC_CVT_L_D: 10255 check_cp1_64bitmode(ctx); 10256 { 10257 TCGv_i64 fp0 = tcg_temp_new_i64(); 10258 10259 gen_load_fpr64(ctx, fp0, fs); 10260 if (ctx->nan2008) { 10261 gen_helper_float_cvt_2008_l_d(fp0, tcg_env, fp0); 10262 } else { 10263 gen_helper_float_cvt_l_d(fp0, tcg_env, fp0); 10264 } 10265 gen_store_fpr64(ctx, fp0, fd); 10266 } 10267 break; 10268 case OPC_CVT_S_W: 10269 { 10270 TCGv_i32 fp0 = tcg_temp_new_i32(); 10271 10272 gen_load_fpr32(ctx, fp0, fs); 10273 gen_helper_float_cvts_w(fp0, tcg_env, fp0); 10274 gen_store_fpr32(ctx, fp0, fd); 10275 } 10276 break; 10277 case OPC_CVT_D_W: 10278 check_cp1_registers(ctx, fd); 10279 { 10280 TCGv_i32 fp32 = tcg_temp_new_i32(); 10281 TCGv_i64 fp64 = tcg_temp_new_i64(); 10282 10283 gen_load_fpr32(ctx, fp32, fs); 10284 gen_helper_float_cvtd_w(fp64, tcg_env, fp32); 10285 gen_store_fpr64(ctx, fp64, fd); 10286 } 10287 break; 10288 case OPC_CVT_S_L: 10289 check_cp1_64bitmode(ctx); 10290 { 10291 TCGv_i32 fp32 = tcg_temp_new_i32(); 10292 TCGv_i64 fp64 = tcg_temp_new_i64(); 10293 10294 gen_load_fpr64(ctx, fp64, fs); 10295 gen_helper_float_cvts_l(fp32, tcg_env, fp64); 10296 gen_store_fpr32(ctx, fp32, fd); 10297 } 10298 break; 10299 case OPC_CVT_D_L: 10300 check_cp1_64bitmode(ctx); 10301 { 10302 TCGv_i64 fp0 = tcg_temp_new_i64(); 10303 10304 gen_load_fpr64(ctx, fp0, fs); 10305 gen_helper_float_cvtd_l(fp0, tcg_env, fp0); 10306 gen_store_fpr64(ctx, fp0, fd); 10307 } 10308 break; 10309 case OPC_CVT_PS_PW: 10310 check_ps(ctx); 10311 { 10312 TCGv_i64 fp0 = tcg_temp_new_i64(); 10313 10314 gen_load_fpr64(ctx, fp0, fs); 10315 gen_helper_float_cvtps_pw(fp0, tcg_env, fp0); 10316 gen_store_fpr64(ctx, fp0, fd); 10317 } 10318 break; 10319 case OPC_ADD_PS: 10320 check_ps(ctx); 10321 { 10322 TCGv_i64 fp0 = tcg_temp_new_i64(); 10323 TCGv_i64 fp1 = tcg_temp_new_i64(); 10324 10325 gen_load_fpr64(ctx, fp0, fs); 10326 gen_load_fpr64(ctx, fp1, ft); 10327 gen_helper_float_add_ps(fp0, tcg_env, fp0, fp1); 10328 gen_store_fpr64(ctx, fp0, fd); 10329 } 10330 break; 10331 case OPC_SUB_PS: 10332 check_ps(ctx); 10333 { 10334 TCGv_i64 fp0 = tcg_temp_new_i64(); 10335 TCGv_i64 fp1 = tcg_temp_new_i64(); 10336 10337 gen_load_fpr64(ctx, fp0, fs); 10338 gen_load_fpr64(ctx, fp1, ft); 10339 gen_helper_float_sub_ps(fp0, tcg_env, fp0, fp1); 10340 gen_store_fpr64(ctx, fp0, fd); 10341 } 10342 break; 10343 case OPC_MUL_PS: 10344 check_ps(ctx); 10345 { 10346 TCGv_i64 fp0 = tcg_temp_new_i64(); 10347 TCGv_i64 fp1 = tcg_temp_new_i64(); 10348 10349 gen_load_fpr64(ctx, fp0, fs); 10350 gen_load_fpr64(ctx, fp1, ft); 10351 gen_helper_float_mul_ps(fp0, tcg_env, fp0, fp1); 10352 gen_store_fpr64(ctx, fp0, fd); 10353 } 10354 break; 10355 case OPC_ABS_PS: 10356 check_ps(ctx); 10357 { 10358 TCGv_i64 fp0 = tcg_temp_new_i64(); 10359 10360 gen_load_fpr64(ctx, fp0, fs); 10361 gen_helper_float_abs_ps(fp0, fp0); 10362 gen_store_fpr64(ctx, fp0, fd); 10363 } 10364 break; 10365 case OPC_MOV_PS: 10366 check_ps(ctx); 10367 { 10368 TCGv_i64 fp0 = tcg_temp_new_i64(); 10369 10370 gen_load_fpr64(ctx, fp0, fs); 10371 gen_store_fpr64(ctx, fp0, fd); 10372 } 10373 break; 10374 case OPC_NEG_PS: 10375 check_ps(ctx); 10376 { 10377 TCGv_i64 fp0 = tcg_temp_new_i64(); 10378 10379 gen_load_fpr64(ctx, fp0, fs); 10380 gen_helper_float_chs_ps(fp0, fp0); 10381 gen_store_fpr64(ctx, fp0, fd); 10382 } 10383 break; 10384 case OPC_MOVCF_PS: 10385 check_ps(ctx); 10386 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10387 break; 10388 case OPC_MOVZ_PS: 10389 check_ps(ctx); 10390 { 10391 TCGLabel *l1 = gen_new_label(); 10392 TCGv_i64 fp0; 10393 10394 if (ft != 0) { 10395 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10396 } 10397 fp0 = tcg_temp_new_i64(); 10398 gen_load_fpr64(ctx, fp0, fs); 10399 gen_store_fpr64(ctx, fp0, fd); 10400 gen_set_label(l1); 10401 } 10402 break; 10403 case OPC_MOVN_PS: 10404 check_ps(ctx); 10405 { 10406 TCGLabel *l1 = gen_new_label(); 10407 TCGv_i64 fp0; 10408 10409 if (ft != 0) { 10410 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10411 fp0 = tcg_temp_new_i64(); 10412 gen_load_fpr64(ctx, fp0, fs); 10413 gen_store_fpr64(ctx, fp0, fd); 10414 gen_set_label(l1); 10415 } 10416 } 10417 break; 10418 case OPC_ADDR_PS: 10419 check_ps(ctx); 10420 { 10421 TCGv_i64 fp0 = tcg_temp_new_i64(); 10422 TCGv_i64 fp1 = tcg_temp_new_i64(); 10423 10424 gen_load_fpr64(ctx, fp0, ft); 10425 gen_load_fpr64(ctx, fp1, fs); 10426 gen_helper_float_addr_ps(fp0, tcg_env, fp0, fp1); 10427 gen_store_fpr64(ctx, fp0, fd); 10428 } 10429 break; 10430 case OPC_MULR_PS: 10431 check_ps(ctx); 10432 { 10433 TCGv_i64 fp0 = tcg_temp_new_i64(); 10434 TCGv_i64 fp1 = tcg_temp_new_i64(); 10435 10436 gen_load_fpr64(ctx, fp0, ft); 10437 gen_load_fpr64(ctx, fp1, fs); 10438 gen_helper_float_mulr_ps(fp0, tcg_env, fp0, fp1); 10439 gen_store_fpr64(ctx, fp0, fd); 10440 } 10441 break; 10442 case OPC_RECIP2_PS: 10443 check_ps(ctx); 10444 { 10445 TCGv_i64 fp0 = tcg_temp_new_i64(); 10446 TCGv_i64 fp1 = tcg_temp_new_i64(); 10447 10448 gen_load_fpr64(ctx, fp0, fs); 10449 gen_load_fpr64(ctx, fp1, ft); 10450 gen_helper_float_recip2_ps(fp0, tcg_env, fp0, fp1); 10451 gen_store_fpr64(ctx, fp0, fd); 10452 } 10453 break; 10454 case OPC_RECIP1_PS: 10455 check_ps(ctx); 10456 { 10457 TCGv_i64 fp0 = tcg_temp_new_i64(); 10458 10459 gen_load_fpr64(ctx, fp0, fs); 10460 gen_helper_float_recip1_ps(fp0, tcg_env, fp0); 10461 gen_store_fpr64(ctx, fp0, fd); 10462 } 10463 break; 10464 case OPC_RSQRT1_PS: 10465 check_ps(ctx); 10466 { 10467 TCGv_i64 fp0 = tcg_temp_new_i64(); 10468 10469 gen_load_fpr64(ctx, fp0, fs); 10470 gen_helper_float_rsqrt1_ps(fp0, tcg_env, fp0); 10471 gen_store_fpr64(ctx, fp0, fd); 10472 } 10473 break; 10474 case OPC_RSQRT2_PS: 10475 check_ps(ctx); 10476 { 10477 TCGv_i64 fp0 = tcg_temp_new_i64(); 10478 TCGv_i64 fp1 = tcg_temp_new_i64(); 10479 10480 gen_load_fpr64(ctx, fp0, fs); 10481 gen_load_fpr64(ctx, fp1, ft); 10482 gen_helper_float_rsqrt2_ps(fp0, tcg_env, fp0, fp1); 10483 gen_store_fpr64(ctx, fp0, fd); 10484 } 10485 break; 10486 case OPC_CVT_S_PU: 10487 check_cp1_64bitmode(ctx); 10488 { 10489 TCGv_i32 fp0 = tcg_temp_new_i32(); 10490 10491 gen_load_fpr32h(ctx, fp0, fs); 10492 gen_helper_float_cvts_pu(fp0, tcg_env, fp0); 10493 gen_store_fpr32(ctx, fp0, fd); 10494 } 10495 break; 10496 case OPC_CVT_PW_PS: 10497 check_ps(ctx); 10498 { 10499 TCGv_i64 fp0 = tcg_temp_new_i64(); 10500 10501 gen_load_fpr64(ctx, fp0, fs); 10502 gen_helper_float_cvtpw_ps(fp0, tcg_env, fp0); 10503 gen_store_fpr64(ctx, fp0, fd); 10504 } 10505 break; 10506 case OPC_CVT_S_PL: 10507 check_cp1_64bitmode(ctx); 10508 { 10509 TCGv_i32 fp0 = tcg_temp_new_i32(); 10510 10511 gen_load_fpr32(ctx, fp0, fs); 10512 gen_helper_float_cvts_pl(fp0, tcg_env, fp0); 10513 gen_store_fpr32(ctx, fp0, fd); 10514 } 10515 break; 10516 case OPC_PLL_PS: 10517 check_ps(ctx); 10518 { 10519 TCGv_i32 fp0 = tcg_temp_new_i32(); 10520 TCGv_i32 fp1 = tcg_temp_new_i32(); 10521 10522 gen_load_fpr32(ctx, fp0, fs); 10523 gen_load_fpr32(ctx, fp1, ft); 10524 gen_store_fpr32h(ctx, fp0, fd); 10525 gen_store_fpr32(ctx, fp1, fd); 10526 } 10527 break; 10528 case OPC_PLU_PS: 10529 check_ps(ctx); 10530 { 10531 TCGv_i32 fp0 = tcg_temp_new_i32(); 10532 TCGv_i32 fp1 = tcg_temp_new_i32(); 10533 10534 gen_load_fpr32(ctx, fp0, fs); 10535 gen_load_fpr32h(ctx, fp1, ft); 10536 gen_store_fpr32(ctx, fp1, fd); 10537 gen_store_fpr32h(ctx, fp0, fd); 10538 } 10539 break; 10540 case OPC_PUL_PS: 10541 check_ps(ctx); 10542 { 10543 TCGv_i32 fp0 = tcg_temp_new_i32(); 10544 TCGv_i32 fp1 = tcg_temp_new_i32(); 10545 10546 gen_load_fpr32h(ctx, fp0, fs); 10547 gen_load_fpr32(ctx, fp1, ft); 10548 gen_store_fpr32(ctx, fp1, fd); 10549 gen_store_fpr32h(ctx, fp0, fd); 10550 } 10551 break; 10552 case OPC_PUU_PS: 10553 check_ps(ctx); 10554 { 10555 TCGv_i32 fp0 = tcg_temp_new_i32(); 10556 TCGv_i32 fp1 = tcg_temp_new_i32(); 10557 10558 gen_load_fpr32h(ctx, fp0, fs); 10559 gen_load_fpr32h(ctx, fp1, ft); 10560 gen_store_fpr32(ctx, fp1, fd); 10561 gen_store_fpr32h(ctx, fp0, fd); 10562 } 10563 break; 10564 case OPC_CMP_F_PS: 10565 case OPC_CMP_UN_PS: 10566 case OPC_CMP_EQ_PS: 10567 case OPC_CMP_UEQ_PS: 10568 case OPC_CMP_OLT_PS: 10569 case OPC_CMP_ULT_PS: 10570 case OPC_CMP_OLE_PS: 10571 case OPC_CMP_ULE_PS: 10572 case OPC_CMP_SF_PS: 10573 case OPC_CMP_NGLE_PS: 10574 case OPC_CMP_SEQ_PS: 10575 case OPC_CMP_NGL_PS: 10576 case OPC_CMP_LT_PS: 10577 case OPC_CMP_NGE_PS: 10578 case OPC_CMP_LE_PS: 10579 case OPC_CMP_NGT_PS: 10580 if (ctx->opcode & (1 << 6)) { 10581 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc); 10582 } else { 10583 gen_cmp_ps(ctx, func - 48, ft, fs, cc); 10584 } 10585 break; 10586 default: 10587 MIPS_INVAL("farith"); 10588 gen_reserved_instruction(ctx); 10589 return; 10590 } 10591 } 10592 10593 /* Coprocessor 3 (FPU) */ 10594 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, 10595 int fd, int fs, int base, int index) 10596 { 10597 TCGv t0 = tcg_temp_new(); 10598 10599 if (base == 0) { 10600 gen_load_gpr(t0, index); 10601 } else if (index == 0) { 10602 gen_load_gpr(t0, base); 10603 } else { 10604 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); 10605 } 10606 /* 10607 * Don't do NOP if destination is zero: we must perform the actual 10608 * memory access. 10609 */ 10610 switch (opc) { 10611 case OPC_LWXC1: 10612 check_cop1x(ctx); 10613 { 10614 TCGv_i32 fp0 = tcg_temp_new_i32(); 10615 10616 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 10617 tcg_gen_trunc_tl_i32(fp0, t0); 10618 gen_store_fpr32(ctx, fp0, fd); 10619 } 10620 break; 10621 case OPC_LDXC1: 10622 check_cop1x(ctx); 10623 check_cp1_registers(ctx, fd); 10624 { 10625 TCGv_i64 fp0 = tcg_temp_new_i64(); 10626 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10627 gen_store_fpr64(ctx, fp0, fd); 10628 } 10629 break; 10630 case OPC_LUXC1: 10631 check_cp1_64bitmode(ctx); 10632 tcg_gen_andi_tl(t0, t0, ~0x7); 10633 { 10634 TCGv_i64 fp0 = tcg_temp_new_i64(); 10635 10636 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10637 gen_store_fpr64(ctx, fp0, fd); 10638 } 10639 break; 10640 case OPC_SWXC1: 10641 check_cop1x(ctx); 10642 { 10643 TCGv_i32 fp0 = tcg_temp_new_i32(); 10644 gen_load_fpr32(ctx, fp0, fs); 10645 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL); 10646 } 10647 break; 10648 case OPC_SDXC1: 10649 check_cop1x(ctx); 10650 check_cp1_registers(ctx, fs); 10651 { 10652 TCGv_i64 fp0 = tcg_temp_new_i64(); 10653 gen_load_fpr64(ctx, fp0, fs); 10654 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10655 } 10656 break; 10657 case OPC_SUXC1: 10658 check_cp1_64bitmode(ctx); 10659 tcg_gen_andi_tl(t0, t0, ~0x7); 10660 { 10661 TCGv_i64 fp0 = tcg_temp_new_i64(); 10662 gen_load_fpr64(ctx, fp0, fs); 10663 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 10664 } 10665 break; 10666 } 10667 } 10668 10669 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, 10670 int fd, int fr, int fs, int ft) 10671 { 10672 switch (opc) { 10673 case OPC_ALNV_PS: 10674 check_ps(ctx); 10675 { 10676 TCGv t0 = tcg_temp_new(); 10677 TCGv_i32 fp = tcg_temp_new_i32(); 10678 TCGv_i32 fph = tcg_temp_new_i32(); 10679 TCGLabel *l1 = gen_new_label(); 10680 TCGLabel *l2 = gen_new_label(); 10681 10682 gen_load_gpr(t0, fr); 10683 tcg_gen_andi_tl(t0, t0, 0x7); 10684 10685 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 10686 gen_load_fpr32(ctx, fp, fs); 10687 gen_load_fpr32h(ctx, fph, fs); 10688 gen_store_fpr32(ctx, fp, fd); 10689 gen_store_fpr32h(ctx, fph, fd); 10690 tcg_gen_br(l2); 10691 gen_set_label(l1); 10692 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 10693 if (disas_is_bigendian(ctx)) { 10694 gen_load_fpr32(ctx, fp, fs); 10695 gen_load_fpr32h(ctx, fph, ft); 10696 gen_store_fpr32h(ctx, fp, fd); 10697 gen_store_fpr32(ctx, fph, fd); 10698 } else { 10699 gen_load_fpr32h(ctx, fph, fs); 10700 gen_load_fpr32(ctx, fp, ft); 10701 gen_store_fpr32(ctx, fph, fd); 10702 gen_store_fpr32h(ctx, fp, fd); 10703 } 10704 gen_set_label(l2); 10705 } 10706 break; 10707 case OPC_MADD_S: 10708 check_cop1x(ctx); 10709 { 10710 TCGv_i32 fp0 = tcg_temp_new_i32(); 10711 TCGv_i32 fp1 = tcg_temp_new_i32(); 10712 TCGv_i32 fp2 = tcg_temp_new_i32(); 10713 10714 gen_load_fpr32(ctx, fp0, fs); 10715 gen_load_fpr32(ctx, fp1, ft); 10716 gen_load_fpr32(ctx, fp2, fr); 10717 gen_helper_float_madd_s(fp2, tcg_env, fp0, fp1, fp2); 10718 gen_store_fpr32(ctx, fp2, fd); 10719 } 10720 break; 10721 case OPC_MADD_D: 10722 check_cop1x(ctx); 10723 check_cp1_registers(ctx, fd | fs | ft | fr); 10724 { 10725 TCGv_i64 fp0 = tcg_temp_new_i64(); 10726 TCGv_i64 fp1 = tcg_temp_new_i64(); 10727 TCGv_i64 fp2 = tcg_temp_new_i64(); 10728 10729 gen_load_fpr64(ctx, fp0, fs); 10730 gen_load_fpr64(ctx, fp1, ft); 10731 gen_load_fpr64(ctx, fp2, fr); 10732 gen_helper_float_madd_d(fp2, tcg_env, fp0, fp1, fp2); 10733 gen_store_fpr64(ctx, fp2, fd); 10734 } 10735 break; 10736 case OPC_MADD_PS: 10737 check_ps(ctx); 10738 { 10739 TCGv_i64 fp0 = tcg_temp_new_i64(); 10740 TCGv_i64 fp1 = tcg_temp_new_i64(); 10741 TCGv_i64 fp2 = tcg_temp_new_i64(); 10742 10743 gen_load_fpr64(ctx, fp0, fs); 10744 gen_load_fpr64(ctx, fp1, ft); 10745 gen_load_fpr64(ctx, fp2, fr); 10746 gen_helper_float_madd_ps(fp2, tcg_env, fp0, fp1, fp2); 10747 gen_store_fpr64(ctx, fp2, fd); 10748 } 10749 break; 10750 case OPC_MSUB_S: 10751 check_cop1x(ctx); 10752 { 10753 TCGv_i32 fp0 = tcg_temp_new_i32(); 10754 TCGv_i32 fp1 = tcg_temp_new_i32(); 10755 TCGv_i32 fp2 = tcg_temp_new_i32(); 10756 10757 gen_load_fpr32(ctx, fp0, fs); 10758 gen_load_fpr32(ctx, fp1, ft); 10759 gen_load_fpr32(ctx, fp2, fr); 10760 gen_helper_float_msub_s(fp2, tcg_env, fp0, fp1, fp2); 10761 gen_store_fpr32(ctx, fp2, fd); 10762 } 10763 break; 10764 case OPC_MSUB_D: 10765 check_cop1x(ctx); 10766 check_cp1_registers(ctx, fd | fs | ft | fr); 10767 { 10768 TCGv_i64 fp0 = tcg_temp_new_i64(); 10769 TCGv_i64 fp1 = tcg_temp_new_i64(); 10770 TCGv_i64 fp2 = tcg_temp_new_i64(); 10771 10772 gen_load_fpr64(ctx, fp0, fs); 10773 gen_load_fpr64(ctx, fp1, ft); 10774 gen_load_fpr64(ctx, fp2, fr); 10775 gen_helper_float_msub_d(fp2, tcg_env, fp0, fp1, fp2); 10776 gen_store_fpr64(ctx, fp2, fd); 10777 } 10778 break; 10779 case OPC_MSUB_PS: 10780 check_ps(ctx); 10781 { 10782 TCGv_i64 fp0 = tcg_temp_new_i64(); 10783 TCGv_i64 fp1 = tcg_temp_new_i64(); 10784 TCGv_i64 fp2 = tcg_temp_new_i64(); 10785 10786 gen_load_fpr64(ctx, fp0, fs); 10787 gen_load_fpr64(ctx, fp1, ft); 10788 gen_load_fpr64(ctx, fp2, fr); 10789 gen_helper_float_msub_ps(fp2, tcg_env, fp0, fp1, fp2); 10790 gen_store_fpr64(ctx, fp2, fd); 10791 } 10792 break; 10793 case OPC_NMADD_S: 10794 check_cop1x(ctx); 10795 { 10796 TCGv_i32 fp0 = tcg_temp_new_i32(); 10797 TCGv_i32 fp1 = tcg_temp_new_i32(); 10798 TCGv_i32 fp2 = tcg_temp_new_i32(); 10799 10800 gen_load_fpr32(ctx, fp0, fs); 10801 gen_load_fpr32(ctx, fp1, ft); 10802 gen_load_fpr32(ctx, fp2, fr); 10803 gen_helper_float_nmadd_s(fp2, tcg_env, fp0, fp1, fp2); 10804 gen_store_fpr32(ctx, fp2, fd); 10805 } 10806 break; 10807 case OPC_NMADD_D: 10808 check_cop1x(ctx); 10809 check_cp1_registers(ctx, fd | fs | ft | fr); 10810 { 10811 TCGv_i64 fp0 = tcg_temp_new_i64(); 10812 TCGv_i64 fp1 = tcg_temp_new_i64(); 10813 TCGv_i64 fp2 = tcg_temp_new_i64(); 10814 10815 gen_load_fpr64(ctx, fp0, fs); 10816 gen_load_fpr64(ctx, fp1, ft); 10817 gen_load_fpr64(ctx, fp2, fr); 10818 gen_helper_float_nmadd_d(fp2, tcg_env, fp0, fp1, fp2); 10819 gen_store_fpr64(ctx, fp2, fd); 10820 } 10821 break; 10822 case OPC_NMADD_PS: 10823 check_ps(ctx); 10824 { 10825 TCGv_i64 fp0 = tcg_temp_new_i64(); 10826 TCGv_i64 fp1 = tcg_temp_new_i64(); 10827 TCGv_i64 fp2 = tcg_temp_new_i64(); 10828 10829 gen_load_fpr64(ctx, fp0, fs); 10830 gen_load_fpr64(ctx, fp1, ft); 10831 gen_load_fpr64(ctx, fp2, fr); 10832 gen_helper_float_nmadd_ps(fp2, tcg_env, fp0, fp1, fp2); 10833 gen_store_fpr64(ctx, fp2, fd); 10834 } 10835 break; 10836 case OPC_NMSUB_S: 10837 check_cop1x(ctx); 10838 { 10839 TCGv_i32 fp0 = tcg_temp_new_i32(); 10840 TCGv_i32 fp1 = tcg_temp_new_i32(); 10841 TCGv_i32 fp2 = tcg_temp_new_i32(); 10842 10843 gen_load_fpr32(ctx, fp0, fs); 10844 gen_load_fpr32(ctx, fp1, ft); 10845 gen_load_fpr32(ctx, fp2, fr); 10846 gen_helper_float_nmsub_s(fp2, tcg_env, fp0, fp1, fp2); 10847 gen_store_fpr32(ctx, fp2, fd); 10848 } 10849 break; 10850 case OPC_NMSUB_D: 10851 check_cop1x(ctx); 10852 check_cp1_registers(ctx, fd | fs | ft | fr); 10853 { 10854 TCGv_i64 fp0 = tcg_temp_new_i64(); 10855 TCGv_i64 fp1 = tcg_temp_new_i64(); 10856 TCGv_i64 fp2 = tcg_temp_new_i64(); 10857 10858 gen_load_fpr64(ctx, fp0, fs); 10859 gen_load_fpr64(ctx, fp1, ft); 10860 gen_load_fpr64(ctx, fp2, fr); 10861 gen_helper_float_nmsub_d(fp2, tcg_env, fp0, fp1, fp2); 10862 gen_store_fpr64(ctx, fp2, fd); 10863 } 10864 break; 10865 case OPC_NMSUB_PS: 10866 check_ps(ctx); 10867 { 10868 TCGv_i64 fp0 = tcg_temp_new_i64(); 10869 TCGv_i64 fp1 = tcg_temp_new_i64(); 10870 TCGv_i64 fp2 = tcg_temp_new_i64(); 10871 10872 gen_load_fpr64(ctx, fp0, fs); 10873 gen_load_fpr64(ctx, fp1, ft); 10874 gen_load_fpr64(ctx, fp2, fr); 10875 gen_helper_float_nmsub_ps(fp2, tcg_env, fp0, fp1, fp2); 10876 gen_store_fpr64(ctx, fp2, fd); 10877 } 10878 break; 10879 default: 10880 MIPS_INVAL("flt3_arith"); 10881 gen_reserved_instruction(ctx); 10882 return; 10883 } 10884 } 10885 10886 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) 10887 { 10888 TCGv t0; 10889 10890 #if !defined(CONFIG_USER_ONLY) 10891 /* 10892 * The Linux kernel will emulate rdhwr if it's not supported natively. 10893 * Therefore only check the ISA in system mode. 10894 */ 10895 check_insn(ctx, ISA_MIPS_R2); 10896 #endif 10897 t0 = tcg_temp_new(); 10898 10899 switch (rd) { 10900 case 0: 10901 gen_helper_rdhwr_cpunum(t0, tcg_env); 10902 gen_store_gpr(t0, rt); 10903 break; 10904 case 1: 10905 gen_helper_rdhwr_synci_step(t0, tcg_env); 10906 gen_store_gpr(t0, rt); 10907 break; 10908 case 2: 10909 translator_io_start(&ctx->base); 10910 gen_helper_rdhwr_cc(t0, tcg_env); 10911 gen_store_gpr(t0, rt); 10912 /* 10913 * Break the TB to be able to take timer interrupts immediately 10914 * after reading count. DISAS_STOP isn't sufficient, we need to ensure 10915 * we break completely out of translated code. 10916 */ 10917 gen_save_pc(ctx->base.pc_next + 4); 10918 ctx->base.is_jmp = DISAS_EXIT; 10919 break; 10920 case 3: 10921 gen_helper_rdhwr_ccres(t0, tcg_env); 10922 gen_store_gpr(t0, rt); 10923 break; 10924 case 4: 10925 check_insn(ctx, ISA_MIPS_R6); 10926 if (sel != 0) { 10927 /* 10928 * Performance counter registers are not implemented other than 10929 * control register 0. 10930 */ 10931 generate_exception(ctx, EXCP_RI); 10932 } 10933 gen_helper_rdhwr_performance(t0, tcg_env); 10934 gen_store_gpr(t0, rt); 10935 break; 10936 case 5: 10937 check_insn(ctx, ISA_MIPS_R6); 10938 gen_helper_rdhwr_xnp(t0, tcg_env); 10939 gen_store_gpr(t0, rt); 10940 break; 10941 case 29: 10942 #if defined(CONFIG_USER_ONLY) 10943 tcg_gen_ld_tl(t0, tcg_env, 10944 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 10945 gen_store_gpr(t0, rt); 10946 break; 10947 #else 10948 if ((ctx->hflags & MIPS_HFLAG_CP0) || 10949 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) { 10950 tcg_gen_ld_tl(t0, tcg_env, 10951 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 10952 gen_store_gpr(t0, rt); 10953 } else { 10954 gen_reserved_instruction(ctx); 10955 } 10956 break; 10957 #endif 10958 default: /* Invalid */ 10959 MIPS_INVAL("rdhwr"); 10960 gen_reserved_instruction(ctx); 10961 break; 10962 } 10963 } 10964 10965 static inline void clear_branch_hflags(DisasContext *ctx) 10966 { 10967 ctx->hflags &= ~MIPS_HFLAG_BMASK; 10968 if (ctx->base.is_jmp == DISAS_NEXT) { 10969 save_cpu_state(ctx, 0); 10970 } else { 10971 /* 10972 * It is not safe to save ctx->hflags as hflags may be changed 10973 * in execution time by the instruction in delay / forbidden slot. 10974 */ 10975 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK); 10976 } 10977 } 10978 10979 static void gen_branch(DisasContext *ctx, int insn_bytes) 10980 { 10981 if (ctx->hflags & MIPS_HFLAG_BMASK) { 10982 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK; 10983 /* Branches completion */ 10984 clear_branch_hflags(ctx); 10985 ctx->base.is_jmp = DISAS_NORETURN; 10986 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) { 10987 case MIPS_HFLAG_FBNSLOT: 10988 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes); 10989 break; 10990 case MIPS_HFLAG_B: 10991 /* unconditional branch */ 10992 if (proc_hflags & MIPS_HFLAG_BX) { 10993 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16); 10994 } 10995 gen_goto_tb(ctx, 0, ctx->btarget); 10996 break; 10997 case MIPS_HFLAG_BL: 10998 /* blikely taken case */ 10999 gen_goto_tb(ctx, 0, ctx->btarget); 11000 break; 11001 case MIPS_HFLAG_BC: 11002 /* Conditional branch */ 11003 { 11004 TCGLabel *l1 = gen_new_label(); 11005 11006 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 11007 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); 11008 gen_set_label(l1); 11009 gen_goto_tb(ctx, 0, ctx->btarget); 11010 } 11011 break; 11012 case MIPS_HFLAG_BR: 11013 /* unconditional branch to register */ 11014 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) { 11015 TCGv t0 = tcg_temp_new(); 11016 TCGv_i32 t1 = tcg_temp_new_i32(); 11017 11018 tcg_gen_andi_tl(t0, btarget, 0x1); 11019 tcg_gen_trunc_tl_i32(t1, t0); 11020 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16); 11021 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT); 11022 tcg_gen_or_i32(hflags, hflags, t1); 11023 11024 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1); 11025 } else { 11026 tcg_gen_mov_tl(cpu_PC, btarget); 11027 } 11028 tcg_gen_lookup_and_goto_ptr(); 11029 break; 11030 default: 11031 LOG_DISAS("unknown branch 0x%x\n", proc_hflags); 11032 gen_reserved_instruction(ctx); 11033 } 11034 } 11035 } 11036 11037 /* Compact Branches */ 11038 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, 11039 int rs, int rt, int32_t offset) 11040 { 11041 int bcond_compute = 0; 11042 TCGv t0 = tcg_temp_new(); 11043 TCGv t1 = tcg_temp_new(); 11044 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; 11045 11046 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11047 #ifdef MIPS_DEBUG_DISAS 11048 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016" 11049 VADDR_PRIx "\n", ctx->base.pc_next); 11050 #endif 11051 gen_reserved_instruction(ctx); 11052 return; 11053 } 11054 11055 /* Load needed operands and calculate btarget */ 11056 switch (opc) { 11057 /* compact branch */ 11058 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11059 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11060 gen_load_gpr(t0, rs); 11061 gen_load_gpr(t1, rt); 11062 bcond_compute = 1; 11063 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11064 if (rs <= rt && rs == 0) { 11065 /* OPC_BEQZALC, OPC_BNEZALC */ 11066 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11067 } 11068 break; 11069 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11070 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11071 gen_load_gpr(t0, rs); 11072 gen_load_gpr(t1, rt); 11073 bcond_compute = 1; 11074 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11075 break; 11076 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11077 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11078 if (rs == 0 || rs == rt) { 11079 /* OPC_BLEZALC, OPC_BGEZALC */ 11080 /* OPC_BGTZALC, OPC_BLTZALC */ 11081 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11082 } 11083 gen_load_gpr(t0, rs); 11084 gen_load_gpr(t1, rt); 11085 bcond_compute = 1; 11086 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11087 break; 11088 case OPC_BC: 11089 case OPC_BALC: 11090 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11091 break; 11092 case OPC_BEQZC: 11093 case OPC_BNEZC: 11094 if (rs != 0) { 11095 /* OPC_BEQZC, OPC_BNEZC */ 11096 gen_load_gpr(t0, rs); 11097 bcond_compute = 1; 11098 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11099 } else { 11100 /* OPC_JIC, OPC_JIALC */ 11101 TCGv tbase = tcg_temp_new(); 11102 11103 gen_load_gpr(tbase, rt); 11104 gen_op_addr_addi(ctx, btarget, tbase, offset); 11105 } 11106 break; 11107 default: 11108 MIPS_INVAL("Compact branch/jump"); 11109 gen_reserved_instruction(ctx); 11110 return; 11111 } 11112 11113 if (bcond_compute == 0) { 11114 /* Unconditional compact branch */ 11115 switch (opc) { 11116 case OPC_JIALC: 11117 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11118 /* Fallthrough */ 11119 case OPC_JIC: 11120 ctx->hflags |= MIPS_HFLAG_BR; 11121 break; 11122 case OPC_BALC: 11123 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11124 /* Fallthrough */ 11125 case OPC_BC: 11126 ctx->hflags |= MIPS_HFLAG_B; 11127 break; 11128 default: 11129 MIPS_INVAL("Compact branch/jump"); 11130 gen_reserved_instruction(ctx); 11131 return; 11132 } 11133 11134 /* Generating branch here as compact branches don't have delay slot */ 11135 gen_branch(ctx, 4); 11136 } else { 11137 /* Conditional compact branch */ 11138 TCGLabel *fs = gen_new_label(); 11139 save_cpu_state(ctx, 0); 11140 11141 switch (opc) { 11142 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11143 if (rs == 0 && rt != 0) { 11144 /* OPC_BLEZALC */ 11145 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11146 } else if (rs != 0 && rt != 0 && rs == rt) { 11147 /* OPC_BGEZALC */ 11148 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11149 } else { 11150 /* OPC_BGEUC */ 11151 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 11152 } 11153 break; 11154 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11155 if (rs == 0 && rt != 0) { 11156 /* OPC_BGTZALC */ 11157 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11158 } else if (rs != 0 && rt != 0 && rs == rt) { 11159 /* OPC_BLTZALC */ 11160 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11161 } else { 11162 /* OPC_BLTUC */ 11163 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 11164 } 11165 break; 11166 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11167 if (rs == 0 && rt != 0) { 11168 /* OPC_BLEZC */ 11169 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 11170 } else if (rs != 0 && rt != 0 && rs == rt) { 11171 /* OPC_BGEZC */ 11172 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 11173 } else { 11174 /* OPC_BGEC */ 11175 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 11176 } 11177 break; 11178 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11179 if (rs == 0 && rt != 0) { 11180 /* OPC_BGTZC */ 11181 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 11182 } else if (rs != 0 && rt != 0 && rs == rt) { 11183 /* OPC_BLTZC */ 11184 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 11185 } else { 11186 /* OPC_BLTC */ 11187 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 11188 } 11189 break; 11190 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11191 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11192 if (rs >= rt) { 11193 /* OPC_BOVC, OPC_BNVC */ 11194 TCGv t2 = tcg_temp_new(); 11195 TCGv t3 = tcg_temp_new(); 11196 TCGv t4 = tcg_temp_new(); 11197 TCGv input_overflow = tcg_temp_new(); 11198 11199 gen_load_gpr(t0, rs); 11200 gen_load_gpr(t1, rt); 11201 tcg_gen_ext32s_tl(t2, t0); 11202 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0); 11203 tcg_gen_ext32s_tl(t3, t1); 11204 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1); 11205 tcg_gen_or_tl(input_overflow, input_overflow, t4); 11206 11207 tcg_gen_add_tl(t4, t2, t3); 11208 tcg_gen_ext32s_tl(t4, t4); 11209 tcg_gen_xor_tl(t2, t2, t3); 11210 tcg_gen_xor_tl(t3, t4, t3); 11211 tcg_gen_andc_tl(t2, t3, t2); 11212 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0); 11213 tcg_gen_or_tl(t4, t4, input_overflow); 11214 if (opc == OPC_BOVC) { 11215 /* OPC_BOVC */ 11216 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs); 11217 } else { 11218 /* OPC_BNVC */ 11219 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs); 11220 } 11221 } else if (rs < rt && rs == 0) { 11222 /* OPC_BEQZALC, OPC_BNEZALC */ 11223 if (opc == OPC_BEQZALC) { 11224 /* OPC_BEQZALC */ 11225 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs); 11226 } else { 11227 /* OPC_BNEZALC */ 11228 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs); 11229 } 11230 } else { 11231 /* OPC_BEQC, OPC_BNEC */ 11232 if (opc == OPC_BEQC) { 11233 /* OPC_BEQC */ 11234 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); 11235 } else { 11236 /* OPC_BNEC */ 11237 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); 11238 } 11239 } 11240 break; 11241 case OPC_BEQZC: 11242 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 11243 break; 11244 case OPC_BNEZC: 11245 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs); 11246 break; 11247 default: 11248 MIPS_INVAL("Compact conditional branch/jump"); 11249 gen_reserved_instruction(ctx); 11250 return; 11251 } 11252 11253 /* Generating branch here as compact branches don't have delay slot */ 11254 gen_goto_tb(ctx, 1, ctx->btarget); 11255 gen_set_label(fs); 11256 11257 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 11258 } 11259 } 11260 11261 void gen_addiupc(DisasContext *ctx, int rx, int imm, 11262 int is_64_bit, int extended) 11263 { 11264 target_ulong npc; 11265 11266 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { 11267 gen_reserved_instruction(ctx); 11268 return; 11269 } 11270 11271 npc = pc_relative_pc(ctx) + imm; 11272 if (!is_64_bit) { 11273 npc = (int32_t)npc; 11274 } 11275 tcg_gen_movi_tl(cpu_gpr[rx], npc); 11276 } 11277 11278 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, 11279 int16_t offset) 11280 { 11281 TCGv_i32 t0 = tcg_constant_i32(op); 11282 TCGv t1 = tcg_temp_new(); 11283 gen_base_offset_addr(ctx, t1, base, offset); 11284 gen_helper_cache(tcg_env, t1, t0); 11285 } 11286 11287 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code) 11288 { 11289 #ifdef CONFIG_USER_ONLY 11290 return false; 11291 #else 11292 bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM; 11293 return semihosting_enabled(is_user) && sdbbp_code == 1; 11294 #endif 11295 } 11296 11297 void gen_ldxs(DisasContext *ctx, int base, int index, int rd) 11298 { 11299 TCGv t0 = tcg_temp_new(); 11300 TCGv t1 = tcg_temp_new(); 11301 11302 gen_load_gpr(t0, base); 11303 11304 if (index != 0) { 11305 gen_load_gpr(t1, index); 11306 tcg_gen_shli_tl(t1, t1, 2); 11307 gen_op_addr_add(ctx, t0, t1, t0); 11308 } 11309 11310 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 11311 gen_store_gpr(t1, rd); 11312 } 11313 11314 static void gen_sync(int stype) 11315 { 11316 TCGBar tcg_mo = TCG_BAR_SC; 11317 11318 switch (stype) { 11319 case 0x4: /* SYNC_WMB */ 11320 tcg_mo |= TCG_MO_ST_ST; 11321 break; 11322 case 0x10: /* SYNC_MB */ 11323 tcg_mo |= TCG_MO_ALL; 11324 break; 11325 case 0x11: /* SYNC_ACQUIRE */ 11326 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; 11327 break; 11328 case 0x12: /* SYNC_RELEASE */ 11329 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; 11330 break; 11331 case 0x13: /* SYNC_RMB */ 11332 tcg_mo |= TCG_MO_LD_LD; 11333 break; 11334 default: 11335 tcg_mo |= TCG_MO_ALL; 11336 break; 11337 } 11338 11339 tcg_gen_mb(tcg_mo); 11340 } 11341 11342 /* ISA extensions (ASEs) */ 11343 11344 /* MIPS16 extension to MIPS32 */ 11345 #include "mips16e_translate.c.inc" 11346 11347 /* microMIPS extension to MIPS32/MIPS64 */ 11348 11349 /* 11350 * Values for microMIPS fmt field. Variable-width, depending on which 11351 * formats the instruction supports. 11352 */ 11353 enum { 11354 FMT_SD_S = 0, 11355 FMT_SD_D = 1, 11356 11357 FMT_SDPS_S = 0, 11358 FMT_SDPS_D = 1, 11359 FMT_SDPS_PS = 2, 11360 11361 FMT_SWL_S = 0, 11362 FMT_SWL_W = 1, 11363 FMT_SWL_L = 2, 11364 11365 FMT_DWL_D = 0, 11366 FMT_DWL_W = 1, 11367 FMT_DWL_L = 2 11368 }; 11369 11370 #include "micromips_translate.c.inc" 11371 11372 #include "nanomips_translate.c.inc" 11373 11374 /* MIPSDSP functions. */ 11375 11376 /* Indexed load is not for DSP only */ 11377 static void gen_mips_lx(DisasContext *ctx, uint32_t opc, 11378 int rd, int base, int offset) 11379 { 11380 TCGv t0; 11381 11382 if (!(ctx->insn_flags & INSN_OCTEON)) { 11383 check_dsp(ctx); 11384 } 11385 t0 = tcg_temp_new(); 11386 11387 if (base == 0) { 11388 gen_load_gpr(t0, offset); 11389 } else if (offset == 0) { 11390 gen_load_gpr(t0, base); 11391 } else { 11392 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]); 11393 } 11394 11395 switch (opc) { 11396 case OPC_LBUX: 11397 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB); 11398 gen_store_gpr(t0, rd); 11399 break; 11400 case OPC_LHX: 11401 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW); 11402 gen_store_gpr(t0, rd); 11403 break; 11404 case OPC_LWX: 11405 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL); 11406 gen_store_gpr(t0, rd); 11407 break; 11408 #if defined(TARGET_MIPS64) 11409 case OPC_LDX: 11410 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ); 11411 gen_store_gpr(t0, rd); 11412 break; 11413 #endif 11414 } 11415 } 11416 11417 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2, 11418 int ret, int v1, int v2) 11419 { 11420 TCGv v1_t; 11421 TCGv v2_t; 11422 11423 if (ret == 0) { 11424 /* Treat as NOP. */ 11425 return; 11426 } 11427 11428 v1_t = tcg_temp_new(); 11429 v2_t = tcg_temp_new(); 11430 11431 gen_load_gpr(v1_t, v1); 11432 gen_load_gpr(v2_t, v2); 11433 11434 switch (op1) { 11435 case OPC_ADDUH_QB_DSP: 11436 check_dsp_r2(ctx); 11437 switch (op2) { 11438 case OPC_ADDUH_QB: 11439 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); 11440 break; 11441 case OPC_ADDUH_R_QB: 11442 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); 11443 break; 11444 case OPC_ADDQH_PH: 11445 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); 11446 break; 11447 case OPC_ADDQH_R_PH: 11448 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 11449 break; 11450 case OPC_ADDQH_W: 11451 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); 11452 break; 11453 case OPC_ADDQH_R_W: 11454 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); 11455 break; 11456 case OPC_SUBUH_QB: 11457 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); 11458 break; 11459 case OPC_SUBUH_R_QB: 11460 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); 11461 break; 11462 case OPC_SUBQH_PH: 11463 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); 11464 break; 11465 case OPC_SUBQH_R_PH: 11466 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 11467 break; 11468 case OPC_SUBQH_W: 11469 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); 11470 break; 11471 case OPC_SUBQH_R_W: 11472 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); 11473 break; 11474 } 11475 break; 11476 case OPC_ABSQ_S_PH_DSP: 11477 switch (op2) { 11478 case OPC_ABSQ_S_QB: 11479 check_dsp_r2(ctx); 11480 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, tcg_env); 11481 break; 11482 case OPC_ABSQ_S_PH: 11483 check_dsp(ctx); 11484 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, tcg_env); 11485 break; 11486 case OPC_ABSQ_S_W: 11487 check_dsp(ctx); 11488 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, tcg_env); 11489 break; 11490 case OPC_PRECEQ_W_PHL: 11491 check_dsp(ctx); 11492 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); 11493 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 11494 break; 11495 case OPC_PRECEQ_W_PHR: 11496 check_dsp(ctx); 11497 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); 11498 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); 11499 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 11500 break; 11501 case OPC_PRECEQU_PH_QBL: 11502 check_dsp(ctx); 11503 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); 11504 break; 11505 case OPC_PRECEQU_PH_QBR: 11506 check_dsp(ctx); 11507 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); 11508 break; 11509 case OPC_PRECEQU_PH_QBLA: 11510 check_dsp(ctx); 11511 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); 11512 break; 11513 case OPC_PRECEQU_PH_QBRA: 11514 check_dsp(ctx); 11515 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); 11516 break; 11517 case OPC_PRECEU_PH_QBL: 11518 check_dsp(ctx); 11519 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); 11520 break; 11521 case OPC_PRECEU_PH_QBR: 11522 check_dsp(ctx); 11523 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); 11524 break; 11525 case OPC_PRECEU_PH_QBLA: 11526 check_dsp(ctx); 11527 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); 11528 break; 11529 case OPC_PRECEU_PH_QBRA: 11530 check_dsp(ctx); 11531 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); 11532 break; 11533 } 11534 break; 11535 case OPC_ADDU_QB_DSP: 11536 switch (op2) { 11537 case OPC_ADDQ_PH: 11538 check_dsp(ctx); 11539 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11540 break; 11541 case OPC_ADDQ_S_PH: 11542 check_dsp(ctx); 11543 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11544 break; 11545 case OPC_ADDQ_S_W: 11546 check_dsp(ctx); 11547 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11548 break; 11549 case OPC_ADDU_QB: 11550 check_dsp(ctx); 11551 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11552 break; 11553 case OPC_ADDU_S_QB: 11554 check_dsp(ctx); 11555 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11556 break; 11557 case OPC_ADDU_PH: 11558 check_dsp_r2(ctx); 11559 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11560 break; 11561 case OPC_ADDU_S_PH: 11562 check_dsp_r2(ctx); 11563 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11564 break; 11565 case OPC_SUBQ_PH: 11566 check_dsp(ctx); 11567 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11568 break; 11569 case OPC_SUBQ_S_PH: 11570 check_dsp(ctx); 11571 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11572 break; 11573 case OPC_SUBQ_S_W: 11574 check_dsp(ctx); 11575 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11576 break; 11577 case OPC_SUBU_QB: 11578 check_dsp(ctx); 11579 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11580 break; 11581 case OPC_SUBU_S_QB: 11582 check_dsp(ctx); 11583 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11584 break; 11585 case OPC_SUBU_PH: 11586 check_dsp_r2(ctx); 11587 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11588 break; 11589 case OPC_SUBU_S_PH: 11590 check_dsp_r2(ctx); 11591 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11592 break; 11593 case OPC_ADDSC: 11594 check_dsp(ctx); 11595 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11596 break; 11597 case OPC_ADDWC: 11598 check_dsp(ctx); 11599 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11600 break; 11601 case OPC_MODSUB: 11602 check_dsp(ctx); 11603 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); 11604 break; 11605 case OPC_RADDU_W_QB: 11606 check_dsp(ctx); 11607 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); 11608 break; 11609 } 11610 break; 11611 case OPC_CMPU_EQ_QB_DSP: 11612 switch (op2) { 11613 case OPC_PRECR_QB_PH: 11614 check_dsp_r2(ctx); 11615 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); 11616 break; 11617 case OPC_PRECRQ_QB_PH: 11618 check_dsp(ctx); 11619 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); 11620 break; 11621 case OPC_PRECR_SRA_PH_W: 11622 check_dsp_r2(ctx); 11623 { 11624 TCGv_i32 sa_t = tcg_constant_i32(v2); 11625 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, 11626 cpu_gpr[ret]); 11627 break; 11628 } 11629 case OPC_PRECR_SRA_R_PH_W: 11630 check_dsp_r2(ctx); 11631 { 11632 TCGv_i32 sa_t = tcg_constant_i32(v2); 11633 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, 11634 cpu_gpr[ret]); 11635 break; 11636 } 11637 case OPC_PRECRQ_PH_W: 11638 check_dsp(ctx); 11639 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); 11640 break; 11641 case OPC_PRECRQ_RS_PH_W: 11642 check_dsp(ctx); 11643 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11644 break; 11645 case OPC_PRECRQU_S_QB_PH: 11646 check_dsp(ctx); 11647 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11648 break; 11649 } 11650 break; 11651 #ifdef TARGET_MIPS64 11652 case OPC_ABSQ_S_QH_DSP: 11653 switch (op2) { 11654 case OPC_PRECEQ_L_PWL: 11655 check_dsp(ctx); 11656 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); 11657 break; 11658 case OPC_PRECEQ_L_PWR: 11659 check_dsp(ctx); 11660 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); 11661 break; 11662 case OPC_PRECEQ_PW_QHL: 11663 check_dsp(ctx); 11664 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); 11665 break; 11666 case OPC_PRECEQ_PW_QHR: 11667 check_dsp(ctx); 11668 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); 11669 break; 11670 case OPC_PRECEQ_PW_QHLA: 11671 check_dsp(ctx); 11672 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); 11673 break; 11674 case OPC_PRECEQ_PW_QHRA: 11675 check_dsp(ctx); 11676 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); 11677 break; 11678 case OPC_PRECEQU_QH_OBL: 11679 check_dsp(ctx); 11680 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); 11681 break; 11682 case OPC_PRECEQU_QH_OBR: 11683 check_dsp(ctx); 11684 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); 11685 break; 11686 case OPC_PRECEQU_QH_OBLA: 11687 check_dsp(ctx); 11688 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); 11689 break; 11690 case OPC_PRECEQU_QH_OBRA: 11691 check_dsp(ctx); 11692 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); 11693 break; 11694 case OPC_PRECEU_QH_OBL: 11695 check_dsp(ctx); 11696 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); 11697 break; 11698 case OPC_PRECEU_QH_OBR: 11699 check_dsp(ctx); 11700 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); 11701 break; 11702 case OPC_PRECEU_QH_OBLA: 11703 check_dsp(ctx); 11704 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); 11705 break; 11706 case OPC_PRECEU_QH_OBRA: 11707 check_dsp(ctx); 11708 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); 11709 break; 11710 case OPC_ABSQ_S_OB: 11711 check_dsp_r2(ctx); 11712 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, tcg_env); 11713 break; 11714 case OPC_ABSQ_S_PW: 11715 check_dsp(ctx); 11716 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, tcg_env); 11717 break; 11718 case OPC_ABSQ_S_QH: 11719 check_dsp(ctx); 11720 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, tcg_env); 11721 break; 11722 } 11723 break; 11724 case OPC_ADDU_OB_DSP: 11725 switch (op2) { 11726 case OPC_RADDU_L_OB: 11727 check_dsp(ctx); 11728 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); 11729 break; 11730 case OPC_SUBQ_PW: 11731 check_dsp(ctx); 11732 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11733 break; 11734 case OPC_SUBQ_S_PW: 11735 check_dsp(ctx); 11736 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11737 break; 11738 case OPC_SUBQ_QH: 11739 check_dsp(ctx); 11740 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11741 break; 11742 case OPC_SUBQ_S_QH: 11743 check_dsp(ctx); 11744 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11745 break; 11746 case OPC_SUBU_OB: 11747 check_dsp(ctx); 11748 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11749 break; 11750 case OPC_SUBU_S_OB: 11751 check_dsp(ctx); 11752 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11753 break; 11754 case OPC_SUBU_QH: 11755 check_dsp_r2(ctx); 11756 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11757 break; 11758 case OPC_SUBU_S_QH: 11759 check_dsp_r2(ctx); 11760 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11761 break; 11762 case OPC_SUBUH_OB: 11763 check_dsp_r2(ctx); 11764 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); 11765 break; 11766 case OPC_SUBUH_R_OB: 11767 check_dsp_r2(ctx); 11768 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); 11769 break; 11770 case OPC_ADDQ_PW: 11771 check_dsp(ctx); 11772 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11773 break; 11774 case OPC_ADDQ_S_PW: 11775 check_dsp(ctx); 11776 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11777 break; 11778 case OPC_ADDQ_QH: 11779 check_dsp(ctx); 11780 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11781 break; 11782 case OPC_ADDQ_S_QH: 11783 check_dsp(ctx); 11784 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11785 break; 11786 case OPC_ADDU_OB: 11787 check_dsp(ctx); 11788 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11789 break; 11790 case OPC_ADDU_S_OB: 11791 check_dsp(ctx); 11792 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11793 break; 11794 case OPC_ADDU_QH: 11795 check_dsp_r2(ctx); 11796 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11797 break; 11798 case OPC_ADDU_S_QH: 11799 check_dsp_r2(ctx); 11800 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11801 break; 11802 case OPC_ADDUH_OB: 11803 check_dsp_r2(ctx); 11804 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); 11805 break; 11806 case OPC_ADDUH_R_OB: 11807 check_dsp_r2(ctx); 11808 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); 11809 break; 11810 } 11811 break; 11812 case OPC_CMPU_EQ_OB_DSP: 11813 switch (op2) { 11814 case OPC_PRECR_OB_QH: 11815 check_dsp_r2(ctx); 11816 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); 11817 break; 11818 case OPC_PRECR_SRA_QH_PW: 11819 check_dsp_r2(ctx); 11820 { 11821 TCGv_i32 ret_t = tcg_constant_i32(ret); 11822 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); 11823 break; 11824 } 11825 case OPC_PRECR_SRA_R_QH_PW: 11826 check_dsp_r2(ctx); 11827 { 11828 TCGv_i32 sa_v = tcg_constant_i32(ret); 11829 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); 11830 break; 11831 } 11832 case OPC_PRECRQ_OB_QH: 11833 check_dsp(ctx); 11834 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); 11835 break; 11836 case OPC_PRECRQ_PW_L: 11837 check_dsp(ctx); 11838 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); 11839 break; 11840 case OPC_PRECRQ_QH_PW: 11841 check_dsp(ctx); 11842 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); 11843 break; 11844 case OPC_PRECRQ_RS_QH_PW: 11845 check_dsp(ctx); 11846 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11847 break; 11848 case OPC_PRECRQU_S_OB_QH: 11849 check_dsp(ctx); 11850 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11851 break; 11852 } 11853 break; 11854 #endif 11855 } 11856 } 11857 11858 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, 11859 int ret, int v1, int v2) 11860 { 11861 uint32_t op2; 11862 TCGv t0; 11863 TCGv v1_t; 11864 TCGv v2_t; 11865 11866 if (ret == 0) { 11867 /* Treat as NOP. */ 11868 return; 11869 } 11870 11871 t0 = tcg_temp_new(); 11872 v1_t = tcg_temp_new(); 11873 v2_t = tcg_temp_new(); 11874 11875 tcg_gen_movi_tl(t0, v1); 11876 gen_load_gpr(v1_t, v1); 11877 gen_load_gpr(v2_t, v2); 11878 11879 switch (opc) { 11880 case OPC_SHLL_QB_DSP: 11881 { 11882 op2 = MASK_SHLL_QB(ctx->opcode); 11883 switch (op2) { 11884 case OPC_SHLL_QB: 11885 check_dsp(ctx); 11886 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, tcg_env); 11887 break; 11888 case OPC_SHLLV_QB: 11889 check_dsp(ctx); 11890 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11891 break; 11892 case OPC_SHLL_PH: 11893 check_dsp(ctx); 11894 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, tcg_env); 11895 break; 11896 case OPC_SHLLV_PH: 11897 check_dsp(ctx); 11898 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11899 break; 11900 case OPC_SHLL_S_PH: 11901 check_dsp(ctx); 11902 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, tcg_env); 11903 break; 11904 case OPC_SHLLV_S_PH: 11905 check_dsp(ctx); 11906 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11907 break; 11908 case OPC_SHLL_S_W: 11909 check_dsp(ctx); 11910 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, tcg_env); 11911 break; 11912 case OPC_SHLLV_S_W: 11913 check_dsp(ctx); 11914 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 11915 break; 11916 case OPC_SHRL_QB: 11917 check_dsp(ctx); 11918 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); 11919 break; 11920 case OPC_SHRLV_QB: 11921 check_dsp(ctx); 11922 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); 11923 break; 11924 case OPC_SHRL_PH: 11925 check_dsp_r2(ctx); 11926 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); 11927 break; 11928 case OPC_SHRLV_PH: 11929 check_dsp_r2(ctx); 11930 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); 11931 break; 11932 case OPC_SHRA_QB: 11933 check_dsp_r2(ctx); 11934 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); 11935 break; 11936 case OPC_SHRA_R_QB: 11937 check_dsp_r2(ctx); 11938 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); 11939 break; 11940 case OPC_SHRAV_QB: 11941 check_dsp_r2(ctx); 11942 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); 11943 break; 11944 case OPC_SHRAV_R_QB: 11945 check_dsp_r2(ctx); 11946 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); 11947 break; 11948 case OPC_SHRA_PH: 11949 check_dsp(ctx); 11950 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); 11951 break; 11952 case OPC_SHRA_R_PH: 11953 check_dsp(ctx); 11954 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); 11955 break; 11956 case OPC_SHRAV_PH: 11957 check_dsp(ctx); 11958 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); 11959 break; 11960 case OPC_SHRAV_R_PH: 11961 check_dsp(ctx); 11962 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); 11963 break; 11964 case OPC_SHRA_R_W: 11965 check_dsp(ctx); 11966 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); 11967 break; 11968 case OPC_SHRAV_R_W: 11969 check_dsp(ctx); 11970 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); 11971 break; 11972 default: /* Invalid */ 11973 MIPS_INVAL("MASK SHLL.QB"); 11974 gen_reserved_instruction(ctx); 11975 break; 11976 } 11977 break; 11978 } 11979 #ifdef TARGET_MIPS64 11980 case OPC_SHLL_OB_DSP: 11981 op2 = MASK_SHLL_OB(ctx->opcode); 11982 switch (op2) { 11983 case OPC_SHLL_PW: 11984 check_dsp(ctx); 11985 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, tcg_env); 11986 break; 11987 case OPC_SHLLV_PW: 11988 check_dsp(ctx); 11989 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11990 break; 11991 case OPC_SHLL_S_PW: 11992 check_dsp(ctx); 11993 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, tcg_env); 11994 break; 11995 case OPC_SHLLV_S_PW: 11996 check_dsp(ctx); 11997 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env); 11998 break; 11999 case OPC_SHLL_OB: 12000 check_dsp(ctx); 12001 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, tcg_env); 12002 break; 12003 case OPC_SHLLV_OB: 12004 check_dsp(ctx); 12005 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, tcg_env); 12006 break; 12007 case OPC_SHLL_QH: 12008 check_dsp(ctx); 12009 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, tcg_env); 12010 break; 12011 case OPC_SHLLV_QH: 12012 check_dsp(ctx); 12013 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env); 12014 break; 12015 case OPC_SHLL_S_QH: 12016 check_dsp(ctx); 12017 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, tcg_env); 12018 break; 12019 case OPC_SHLLV_S_QH: 12020 check_dsp(ctx); 12021 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env); 12022 break; 12023 case OPC_SHRA_OB: 12024 check_dsp_r2(ctx); 12025 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); 12026 break; 12027 case OPC_SHRAV_OB: 12028 check_dsp_r2(ctx); 12029 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); 12030 break; 12031 case OPC_SHRA_R_OB: 12032 check_dsp_r2(ctx); 12033 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); 12034 break; 12035 case OPC_SHRAV_R_OB: 12036 check_dsp_r2(ctx); 12037 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); 12038 break; 12039 case OPC_SHRA_PW: 12040 check_dsp(ctx); 12041 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); 12042 break; 12043 case OPC_SHRAV_PW: 12044 check_dsp(ctx); 12045 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); 12046 break; 12047 case OPC_SHRA_R_PW: 12048 check_dsp(ctx); 12049 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); 12050 break; 12051 case OPC_SHRAV_R_PW: 12052 check_dsp(ctx); 12053 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); 12054 break; 12055 case OPC_SHRA_QH: 12056 check_dsp(ctx); 12057 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); 12058 break; 12059 case OPC_SHRAV_QH: 12060 check_dsp(ctx); 12061 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); 12062 break; 12063 case OPC_SHRA_R_QH: 12064 check_dsp(ctx); 12065 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); 12066 break; 12067 case OPC_SHRAV_R_QH: 12068 check_dsp(ctx); 12069 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); 12070 break; 12071 case OPC_SHRL_OB: 12072 check_dsp(ctx); 12073 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); 12074 break; 12075 case OPC_SHRLV_OB: 12076 check_dsp(ctx); 12077 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); 12078 break; 12079 case OPC_SHRL_QH: 12080 check_dsp_r2(ctx); 12081 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); 12082 break; 12083 case OPC_SHRLV_QH: 12084 check_dsp_r2(ctx); 12085 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); 12086 break; 12087 default: /* Invalid */ 12088 MIPS_INVAL("MASK SHLL.OB"); 12089 gen_reserved_instruction(ctx); 12090 break; 12091 } 12092 break; 12093 #endif 12094 } 12095 } 12096 12097 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2, 12098 int ret, int v1, int v2, int check_ret) 12099 { 12100 TCGv_i32 t0; 12101 TCGv v1_t; 12102 TCGv v2_t; 12103 12104 if ((ret == 0) && (check_ret == 1)) { 12105 /* Treat as NOP. */ 12106 return; 12107 } 12108 12109 t0 = tcg_temp_new_i32(); 12110 v1_t = tcg_temp_new(); 12111 v2_t = tcg_temp_new(); 12112 12113 tcg_gen_movi_i32(t0, ret); 12114 gen_load_gpr(v1_t, v1); 12115 gen_load_gpr(v2_t, v2); 12116 12117 switch (op1) { 12118 case OPC_MUL_PH_DSP: 12119 check_dsp_r2(ctx); 12120 switch (op2) { 12121 case OPC_MUL_PH: 12122 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12123 break; 12124 case OPC_MUL_S_PH: 12125 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12126 break; 12127 case OPC_MULQ_S_W: 12128 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12129 break; 12130 case OPC_MULQ_RS_W: 12131 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12132 break; 12133 } 12134 break; 12135 case OPC_DPA_W_PH_DSP: 12136 switch (op2) { 12137 case OPC_DPAU_H_QBL: 12138 check_dsp(ctx); 12139 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, tcg_env); 12140 break; 12141 case OPC_DPAU_H_QBR: 12142 check_dsp(ctx); 12143 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, tcg_env); 12144 break; 12145 case OPC_DPSU_H_QBL: 12146 check_dsp(ctx); 12147 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, tcg_env); 12148 break; 12149 case OPC_DPSU_H_QBR: 12150 check_dsp(ctx); 12151 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, tcg_env); 12152 break; 12153 case OPC_DPA_W_PH: 12154 check_dsp_r2(ctx); 12155 gen_helper_dpa_w_ph(t0, v1_t, v2_t, tcg_env); 12156 break; 12157 case OPC_DPAX_W_PH: 12158 check_dsp_r2(ctx); 12159 gen_helper_dpax_w_ph(t0, v1_t, v2_t, tcg_env); 12160 break; 12161 case OPC_DPAQ_S_W_PH: 12162 check_dsp(ctx); 12163 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12164 break; 12165 case OPC_DPAQX_S_W_PH: 12166 check_dsp_r2(ctx); 12167 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, tcg_env); 12168 break; 12169 case OPC_DPAQX_SA_W_PH: 12170 check_dsp_r2(ctx); 12171 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, tcg_env); 12172 break; 12173 case OPC_DPS_W_PH: 12174 check_dsp_r2(ctx); 12175 gen_helper_dps_w_ph(t0, v1_t, v2_t, tcg_env); 12176 break; 12177 case OPC_DPSX_W_PH: 12178 check_dsp_r2(ctx); 12179 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, tcg_env); 12180 break; 12181 case OPC_DPSQ_S_W_PH: 12182 check_dsp(ctx); 12183 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12184 break; 12185 case OPC_DPSQX_S_W_PH: 12186 check_dsp_r2(ctx); 12187 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, tcg_env); 12188 break; 12189 case OPC_DPSQX_SA_W_PH: 12190 check_dsp_r2(ctx); 12191 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, tcg_env); 12192 break; 12193 case OPC_MULSAQ_S_W_PH: 12194 check_dsp(ctx); 12195 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, tcg_env); 12196 break; 12197 case OPC_DPAQ_SA_L_W: 12198 check_dsp(ctx); 12199 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, tcg_env); 12200 break; 12201 case OPC_DPSQ_SA_L_W: 12202 check_dsp(ctx); 12203 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, tcg_env); 12204 break; 12205 case OPC_MAQ_S_W_PHL: 12206 check_dsp(ctx); 12207 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, tcg_env); 12208 break; 12209 case OPC_MAQ_S_W_PHR: 12210 check_dsp(ctx); 12211 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, tcg_env); 12212 break; 12213 case OPC_MAQ_SA_W_PHL: 12214 check_dsp(ctx); 12215 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, tcg_env); 12216 break; 12217 case OPC_MAQ_SA_W_PHR: 12218 check_dsp(ctx); 12219 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, tcg_env); 12220 break; 12221 case OPC_MULSA_W_PH: 12222 check_dsp_r2(ctx); 12223 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, tcg_env); 12224 break; 12225 } 12226 break; 12227 #ifdef TARGET_MIPS64 12228 case OPC_DPAQ_W_QH_DSP: 12229 { 12230 int ac = ret & 0x03; 12231 tcg_gen_movi_i32(t0, ac); 12232 12233 switch (op2) { 12234 case OPC_DMADD: 12235 check_dsp(ctx); 12236 gen_helper_dmadd(v1_t, v2_t, t0, tcg_env); 12237 break; 12238 case OPC_DMADDU: 12239 check_dsp(ctx); 12240 gen_helper_dmaddu(v1_t, v2_t, t0, tcg_env); 12241 break; 12242 case OPC_DMSUB: 12243 check_dsp(ctx); 12244 gen_helper_dmsub(v1_t, v2_t, t0, tcg_env); 12245 break; 12246 case OPC_DMSUBU: 12247 check_dsp(ctx); 12248 gen_helper_dmsubu(v1_t, v2_t, t0, tcg_env); 12249 break; 12250 case OPC_DPA_W_QH: 12251 check_dsp_r2(ctx); 12252 gen_helper_dpa_w_qh(v1_t, v2_t, t0, tcg_env); 12253 break; 12254 case OPC_DPAQ_S_W_QH: 12255 check_dsp(ctx); 12256 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12257 break; 12258 case OPC_DPAQ_SA_L_PW: 12259 check_dsp(ctx); 12260 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, tcg_env); 12261 break; 12262 case OPC_DPAU_H_OBL: 12263 check_dsp(ctx); 12264 gen_helper_dpau_h_obl(v1_t, v2_t, t0, tcg_env); 12265 break; 12266 case OPC_DPAU_H_OBR: 12267 check_dsp(ctx); 12268 gen_helper_dpau_h_obr(v1_t, v2_t, t0, tcg_env); 12269 break; 12270 case OPC_DPS_W_QH: 12271 check_dsp_r2(ctx); 12272 gen_helper_dps_w_qh(v1_t, v2_t, t0, tcg_env); 12273 break; 12274 case OPC_DPSQ_S_W_QH: 12275 check_dsp(ctx); 12276 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12277 break; 12278 case OPC_DPSQ_SA_L_PW: 12279 check_dsp(ctx); 12280 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, tcg_env); 12281 break; 12282 case OPC_DPSU_H_OBL: 12283 check_dsp(ctx); 12284 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, tcg_env); 12285 break; 12286 case OPC_DPSU_H_OBR: 12287 check_dsp(ctx); 12288 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, tcg_env); 12289 break; 12290 case OPC_MAQ_S_L_PWL: 12291 check_dsp(ctx); 12292 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, tcg_env); 12293 break; 12294 case OPC_MAQ_S_L_PWR: 12295 check_dsp(ctx); 12296 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, tcg_env); 12297 break; 12298 case OPC_MAQ_S_W_QHLL: 12299 check_dsp(ctx); 12300 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, tcg_env); 12301 break; 12302 case OPC_MAQ_SA_W_QHLL: 12303 check_dsp(ctx); 12304 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, tcg_env); 12305 break; 12306 case OPC_MAQ_S_W_QHLR: 12307 check_dsp(ctx); 12308 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, tcg_env); 12309 break; 12310 case OPC_MAQ_SA_W_QHLR: 12311 check_dsp(ctx); 12312 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, tcg_env); 12313 break; 12314 case OPC_MAQ_S_W_QHRL: 12315 check_dsp(ctx); 12316 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, tcg_env); 12317 break; 12318 case OPC_MAQ_SA_W_QHRL: 12319 check_dsp(ctx); 12320 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, tcg_env); 12321 break; 12322 case OPC_MAQ_S_W_QHRR: 12323 check_dsp(ctx); 12324 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, tcg_env); 12325 break; 12326 case OPC_MAQ_SA_W_QHRR: 12327 check_dsp(ctx); 12328 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, tcg_env); 12329 break; 12330 case OPC_MULSAQ_S_L_PW: 12331 check_dsp(ctx); 12332 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, tcg_env); 12333 break; 12334 case OPC_MULSAQ_S_W_QH: 12335 check_dsp(ctx); 12336 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, tcg_env); 12337 break; 12338 } 12339 } 12340 break; 12341 #endif 12342 case OPC_ADDU_QB_DSP: 12343 switch (op2) { 12344 case OPC_MULEU_S_PH_QBL: 12345 check_dsp(ctx); 12346 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12347 break; 12348 case OPC_MULEU_S_PH_QBR: 12349 check_dsp(ctx); 12350 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12351 break; 12352 case OPC_MULQ_RS_PH: 12353 check_dsp(ctx); 12354 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12355 break; 12356 case OPC_MULEQ_S_W_PHL: 12357 check_dsp(ctx); 12358 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12359 break; 12360 case OPC_MULEQ_S_W_PHR: 12361 check_dsp(ctx); 12362 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12363 break; 12364 case OPC_MULQ_S_PH: 12365 check_dsp_r2(ctx); 12366 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12367 break; 12368 } 12369 break; 12370 #ifdef TARGET_MIPS64 12371 case OPC_ADDU_OB_DSP: 12372 switch (op2) { 12373 case OPC_MULEQ_S_PW_QHL: 12374 check_dsp(ctx); 12375 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12376 break; 12377 case OPC_MULEQ_S_PW_QHR: 12378 check_dsp(ctx); 12379 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12380 break; 12381 case OPC_MULEU_S_QH_OBL: 12382 check_dsp(ctx); 12383 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12384 break; 12385 case OPC_MULEU_S_QH_OBR: 12386 check_dsp(ctx); 12387 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12388 break; 12389 case OPC_MULQ_RS_QH: 12390 check_dsp(ctx); 12391 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12392 break; 12393 } 12394 break; 12395 #endif 12396 } 12397 } 12398 12399 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 12400 int ret, int val) 12401 { 12402 int16_t imm; 12403 TCGv t0; 12404 TCGv val_t; 12405 12406 if (ret == 0) { 12407 /* Treat as NOP. */ 12408 return; 12409 } 12410 12411 t0 = tcg_temp_new(); 12412 val_t = tcg_temp_new(); 12413 gen_load_gpr(val_t, val); 12414 12415 switch (op1) { 12416 case OPC_ABSQ_S_PH_DSP: 12417 switch (op2) { 12418 case OPC_BITREV: 12419 check_dsp(ctx); 12420 gen_helper_bitrev(cpu_gpr[ret], val_t); 12421 break; 12422 case OPC_REPL_QB: 12423 check_dsp(ctx); 12424 { 12425 target_long result; 12426 imm = (ctx->opcode >> 16) & 0xFF; 12427 result = (uint32_t)imm << 24 | 12428 (uint32_t)imm << 16 | 12429 (uint32_t)imm << 8 | 12430 (uint32_t)imm; 12431 result = (int32_t)result; 12432 tcg_gen_movi_tl(cpu_gpr[ret], result); 12433 } 12434 break; 12435 case OPC_REPLV_QB: 12436 check_dsp(ctx); 12437 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 12438 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 12439 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12440 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12441 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12442 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12443 break; 12444 case OPC_REPL_PH: 12445 check_dsp(ctx); 12446 { 12447 imm = (ctx->opcode >> 16) & 0x03FF; 12448 imm = (int16_t)(imm << 6) >> 6; 12449 tcg_gen_movi_tl(cpu_gpr[ret], \ 12450 (target_long)((int32_t)imm << 16 | \ 12451 (uint16_t)imm)); 12452 } 12453 break; 12454 case OPC_REPLV_PH: 12455 check_dsp(ctx); 12456 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 12457 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12458 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12459 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12460 break; 12461 } 12462 break; 12463 #ifdef TARGET_MIPS64 12464 case OPC_ABSQ_S_QH_DSP: 12465 switch (op2) { 12466 case OPC_REPL_OB: 12467 check_dsp(ctx); 12468 { 12469 target_long temp; 12470 12471 imm = (ctx->opcode >> 16) & 0xFF; 12472 temp = ((uint64_t)imm << 8) | (uint64_t)imm; 12473 temp = (temp << 16) | temp; 12474 temp = (temp << 32) | temp; 12475 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12476 break; 12477 } 12478 case OPC_REPL_PW: 12479 check_dsp(ctx); 12480 { 12481 target_long temp; 12482 12483 imm = (ctx->opcode >> 16) & 0x03FF; 12484 imm = (int16_t)(imm << 6) >> 6; 12485 temp = ((target_long)imm << 32) \ 12486 | ((target_long)imm & 0xFFFFFFFF); 12487 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12488 break; 12489 } 12490 case OPC_REPL_QH: 12491 check_dsp(ctx); 12492 { 12493 target_long temp; 12494 12495 imm = (ctx->opcode >> 16) & 0x03FF; 12496 imm = (int16_t)(imm << 6) >> 6; 12497 12498 temp = ((uint64_t)(uint16_t)imm << 48) | 12499 ((uint64_t)(uint16_t)imm << 32) | 12500 ((uint64_t)(uint16_t)imm << 16) | 12501 (uint64_t)(uint16_t)imm; 12502 tcg_gen_movi_tl(cpu_gpr[ret], temp); 12503 break; 12504 } 12505 case OPC_REPLV_OB: 12506 check_dsp(ctx); 12507 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 12508 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 12509 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12510 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12511 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12512 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12513 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12514 break; 12515 case OPC_REPLV_PW: 12516 check_dsp(ctx); 12517 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); 12518 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12519 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12520 break; 12521 case OPC_REPLV_QH: 12522 check_dsp(ctx); 12523 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 12524 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 12525 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12526 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 12527 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 12528 break; 12529 } 12530 break; 12531 #endif 12532 } 12533 } 12534 12535 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, 12536 uint32_t op1, uint32_t op2, 12537 int ret, int v1, int v2, int check_ret) 12538 { 12539 TCGv t1; 12540 TCGv v1_t; 12541 TCGv v2_t; 12542 12543 if ((ret == 0) && (check_ret == 1)) { 12544 /* Treat as NOP. */ 12545 return; 12546 } 12547 12548 t1 = tcg_temp_new(); 12549 v1_t = tcg_temp_new(); 12550 v2_t = tcg_temp_new(); 12551 12552 gen_load_gpr(v1_t, v1); 12553 gen_load_gpr(v2_t, v2); 12554 12555 switch (op1) { 12556 case OPC_CMPU_EQ_QB_DSP: 12557 switch (op2) { 12558 case OPC_CMPU_EQ_QB: 12559 check_dsp(ctx); 12560 gen_helper_cmpu_eq_qb(v1_t, v2_t, tcg_env); 12561 break; 12562 case OPC_CMPU_LT_QB: 12563 check_dsp(ctx); 12564 gen_helper_cmpu_lt_qb(v1_t, v2_t, tcg_env); 12565 break; 12566 case OPC_CMPU_LE_QB: 12567 check_dsp(ctx); 12568 gen_helper_cmpu_le_qb(v1_t, v2_t, tcg_env); 12569 break; 12570 case OPC_CMPGU_EQ_QB: 12571 check_dsp(ctx); 12572 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); 12573 break; 12574 case OPC_CMPGU_LT_QB: 12575 check_dsp(ctx); 12576 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); 12577 break; 12578 case OPC_CMPGU_LE_QB: 12579 check_dsp(ctx); 12580 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); 12581 break; 12582 case OPC_CMPGDU_EQ_QB: 12583 check_dsp_r2(ctx); 12584 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); 12585 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12586 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12587 tcg_gen_shli_tl(t1, t1, 24); 12588 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12589 break; 12590 case OPC_CMPGDU_LT_QB: 12591 check_dsp_r2(ctx); 12592 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); 12593 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12594 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12595 tcg_gen_shli_tl(t1, t1, 24); 12596 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12597 break; 12598 case OPC_CMPGDU_LE_QB: 12599 check_dsp_r2(ctx); 12600 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); 12601 tcg_gen_mov_tl(cpu_gpr[ret], t1); 12602 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 12603 tcg_gen_shli_tl(t1, t1, 24); 12604 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 12605 break; 12606 case OPC_CMP_EQ_PH: 12607 check_dsp(ctx); 12608 gen_helper_cmp_eq_ph(v1_t, v2_t, tcg_env); 12609 break; 12610 case OPC_CMP_LT_PH: 12611 check_dsp(ctx); 12612 gen_helper_cmp_lt_ph(v1_t, v2_t, tcg_env); 12613 break; 12614 case OPC_CMP_LE_PH: 12615 check_dsp(ctx); 12616 gen_helper_cmp_le_ph(v1_t, v2_t, tcg_env); 12617 break; 12618 case OPC_PICK_QB: 12619 check_dsp(ctx); 12620 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12621 break; 12622 case OPC_PICK_PH: 12623 check_dsp(ctx); 12624 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12625 break; 12626 case OPC_PACKRL_PH: 12627 check_dsp(ctx); 12628 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); 12629 break; 12630 } 12631 break; 12632 #ifdef TARGET_MIPS64 12633 case OPC_CMPU_EQ_OB_DSP: 12634 switch (op2) { 12635 case OPC_CMP_EQ_PW: 12636 check_dsp(ctx); 12637 gen_helper_cmp_eq_pw(v1_t, v2_t, tcg_env); 12638 break; 12639 case OPC_CMP_LT_PW: 12640 check_dsp(ctx); 12641 gen_helper_cmp_lt_pw(v1_t, v2_t, tcg_env); 12642 break; 12643 case OPC_CMP_LE_PW: 12644 check_dsp(ctx); 12645 gen_helper_cmp_le_pw(v1_t, v2_t, tcg_env); 12646 break; 12647 case OPC_CMP_EQ_QH: 12648 check_dsp(ctx); 12649 gen_helper_cmp_eq_qh(v1_t, v2_t, tcg_env); 12650 break; 12651 case OPC_CMP_LT_QH: 12652 check_dsp(ctx); 12653 gen_helper_cmp_lt_qh(v1_t, v2_t, tcg_env); 12654 break; 12655 case OPC_CMP_LE_QH: 12656 check_dsp(ctx); 12657 gen_helper_cmp_le_qh(v1_t, v2_t, tcg_env); 12658 break; 12659 case OPC_CMPGDU_EQ_OB: 12660 check_dsp_r2(ctx); 12661 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12662 break; 12663 case OPC_CMPGDU_LT_OB: 12664 check_dsp_r2(ctx); 12665 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12666 break; 12667 case OPC_CMPGDU_LE_OB: 12668 check_dsp_r2(ctx); 12669 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12670 break; 12671 case OPC_CMPGU_EQ_OB: 12672 check_dsp(ctx); 12673 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); 12674 break; 12675 case OPC_CMPGU_LT_OB: 12676 check_dsp(ctx); 12677 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); 12678 break; 12679 case OPC_CMPGU_LE_OB: 12680 check_dsp(ctx); 12681 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); 12682 break; 12683 case OPC_CMPU_EQ_OB: 12684 check_dsp(ctx); 12685 gen_helper_cmpu_eq_ob(v1_t, v2_t, tcg_env); 12686 break; 12687 case OPC_CMPU_LT_OB: 12688 check_dsp(ctx); 12689 gen_helper_cmpu_lt_ob(v1_t, v2_t, tcg_env); 12690 break; 12691 case OPC_CMPU_LE_OB: 12692 check_dsp(ctx); 12693 gen_helper_cmpu_le_ob(v1_t, v2_t, tcg_env); 12694 break; 12695 case OPC_PACKRL_PW: 12696 check_dsp(ctx); 12697 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); 12698 break; 12699 case OPC_PICK_OB: 12700 check_dsp(ctx); 12701 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12702 break; 12703 case OPC_PICK_PW: 12704 check_dsp(ctx); 12705 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12706 break; 12707 case OPC_PICK_QH: 12708 check_dsp(ctx); 12709 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env); 12710 break; 12711 } 12712 break; 12713 #endif 12714 } 12715 } 12716 12717 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, 12718 uint32_t op1, int rt, int rs, int sa) 12719 { 12720 TCGv t0; 12721 12722 check_dsp_r2(ctx); 12723 12724 if (rt == 0) { 12725 /* Treat as NOP. */ 12726 return; 12727 } 12728 12729 t0 = tcg_temp_new(); 12730 gen_load_gpr(t0, rs); 12731 12732 switch (op1) { 12733 case OPC_APPEND_DSP: 12734 switch (MASK_APPEND(ctx->opcode)) { 12735 case OPC_APPEND: 12736 if (sa != 0) { 12737 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa); 12738 } 12739 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12740 break; 12741 case OPC_PREPEND: 12742 if (sa != 0) { 12743 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); 12744 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 12745 tcg_gen_shli_tl(t0, t0, 32 - sa); 12746 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12747 } 12748 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12749 break; 12750 case OPC_BALIGN: 12751 sa &= 3; 12752 if (sa != 0 && sa != 2) { 12753 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 12754 tcg_gen_ext32u_tl(t0, t0); 12755 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); 12756 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12757 } 12758 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 12759 break; 12760 default: /* Invalid */ 12761 MIPS_INVAL("MASK APPEND"); 12762 gen_reserved_instruction(ctx); 12763 break; 12764 } 12765 break; 12766 #ifdef TARGET_MIPS64 12767 case OPC_DAPPEND_DSP: 12768 switch (MASK_DAPPEND(ctx->opcode)) { 12769 case OPC_DAPPEND: 12770 if (sa != 0) { 12771 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa); 12772 } 12773 break; 12774 case OPC_PREPENDD: 12775 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); 12776 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); 12777 tcg_gen_or_tl(cpu_gpr[rt], t0, t0); 12778 break; 12779 case OPC_PREPENDW: 12780 if (sa != 0) { 12781 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 12782 tcg_gen_shli_tl(t0, t0, 64 - sa); 12783 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12784 } 12785 break; 12786 case OPC_DBALIGN: 12787 sa &= 7; 12788 if (sa != 0 && sa != 2 && sa != 4) { 12789 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 12790 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); 12791 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 12792 } 12793 break; 12794 default: /* Invalid */ 12795 MIPS_INVAL("MASK DAPPEND"); 12796 gen_reserved_instruction(ctx); 12797 break; 12798 } 12799 break; 12800 #endif 12801 } 12802 } 12803 12804 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 12805 int ret, int v1, int v2, int check_ret) 12806 12807 { 12808 TCGv t0; 12809 TCGv t1; 12810 TCGv v1_t; 12811 int16_t imm; 12812 12813 if ((ret == 0) && (check_ret == 1)) { 12814 /* Treat as NOP. */ 12815 return; 12816 } 12817 12818 t0 = tcg_temp_new(); 12819 t1 = tcg_temp_new(); 12820 v1_t = tcg_temp_new(); 12821 12822 gen_load_gpr(v1_t, v1); 12823 12824 switch (op1) { 12825 case OPC_EXTR_W_DSP: 12826 check_dsp(ctx); 12827 switch (op2) { 12828 case OPC_EXTR_W: 12829 tcg_gen_movi_tl(t0, v2); 12830 tcg_gen_movi_tl(t1, v1); 12831 gen_helper_extr_w(cpu_gpr[ret], t0, t1, tcg_env); 12832 break; 12833 case OPC_EXTR_R_W: 12834 tcg_gen_movi_tl(t0, v2); 12835 tcg_gen_movi_tl(t1, v1); 12836 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, tcg_env); 12837 break; 12838 case OPC_EXTR_RS_W: 12839 tcg_gen_movi_tl(t0, v2); 12840 tcg_gen_movi_tl(t1, v1); 12841 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, tcg_env); 12842 break; 12843 case OPC_EXTR_S_H: 12844 tcg_gen_movi_tl(t0, v2); 12845 tcg_gen_movi_tl(t1, v1); 12846 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, tcg_env); 12847 break; 12848 case OPC_EXTRV_S_H: 12849 tcg_gen_movi_tl(t0, v2); 12850 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env); 12851 break; 12852 case OPC_EXTRV_W: 12853 tcg_gen_movi_tl(t0, v2); 12854 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12855 break; 12856 case OPC_EXTRV_R_W: 12857 tcg_gen_movi_tl(t0, v2); 12858 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12859 break; 12860 case OPC_EXTRV_RS_W: 12861 tcg_gen_movi_tl(t0, v2); 12862 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env); 12863 break; 12864 case OPC_EXTP: 12865 tcg_gen_movi_tl(t0, v2); 12866 tcg_gen_movi_tl(t1, v1); 12867 gen_helper_extp(cpu_gpr[ret], t0, t1, tcg_env); 12868 break; 12869 case OPC_EXTPV: 12870 tcg_gen_movi_tl(t0, v2); 12871 gen_helper_extp(cpu_gpr[ret], t0, v1_t, tcg_env); 12872 break; 12873 case OPC_EXTPDP: 12874 tcg_gen_movi_tl(t0, v2); 12875 tcg_gen_movi_tl(t1, v1); 12876 gen_helper_extpdp(cpu_gpr[ret], t0, t1, tcg_env); 12877 break; 12878 case OPC_EXTPDPV: 12879 tcg_gen_movi_tl(t0, v2); 12880 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, tcg_env); 12881 break; 12882 case OPC_SHILO: 12883 imm = (ctx->opcode >> 20) & 0x3F; 12884 tcg_gen_movi_tl(t0, ret); 12885 tcg_gen_movi_tl(t1, imm); 12886 gen_helper_shilo(t0, t1, tcg_env); 12887 break; 12888 case OPC_SHILOV: 12889 tcg_gen_movi_tl(t0, ret); 12890 gen_helper_shilo(t0, v1_t, tcg_env); 12891 break; 12892 case OPC_MTHLIP: 12893 tcg_gen_movi_tl(t0, ret); 12894 gen_helper_mthlip(t0, v1_t, tcg_env); 12895 break; 12896 case OPC_WRDSP: 12897 imm = (ctx->opcode >> 11) & 0x3FF; 12898 tcg_gen_movi_tl(t0, imm); 12899 gen_helper_wrdsp(v1_t, t0, tcg_env); 12900 break; 12901 case OPC_RDDSP: 12902 imm = (ctx->opcode >> 16) & 0x03FF; 12903 tcg_gen_movi_tl(t0, imm); 12904 gen_helper_rddsp(cpu_gpr[ret], t0, tcg_env); 12905 break; 12906 } 12907 break; 12908 #ifdef TARGET_MIPS64 12909 case OPC_DEXTR_W_DSP: 12910 check_dsp(ctx); 12911 switch (op2) { 12912 case OPC_DMTHLIP: 12913 tcg_gen_movi_tl(t0, ret); 12914 gen_helper_dmthlip(v1_t, t0, tcg_env); 12915 break; 12916 case OPC_DSHILO: 12917 { 12918 int shift = (ctx->opcode >> 19) & 0x7F; 12919 int ac = (ctx->opcode >> 11) & 0x03; 12920 tcg_gen_movi_tl(t0, shift); 12921 tcg_gen_movi_tl(t1, ac); 12922 gen_helper_dshilo(t0, t1, tcg_env); 12923 break; 12924 } 12925 case OPC_DSHILOV: 12926 { 12927 int ac = (ctx->opcode >> 11) & 0x03; 12928 tcg_gen_movi_tl(t0, ac); 12929 gen_helper_dshilo(v1_t, t0, tcg_env); 12930 break; 12931 } 12932 case OPC_DEXTP: 12933 tcg_gen_movi_tl(t0, v2); 12934 tcg_gen_movi_tl(t1, v1); 12935 12936 gen_helper_dextp(cpu_gpr[ret], t0, t1, tcg_env); 12937 break; 12938 case OPC_DEXTPV: 12939 tcg_gen_movi_tl(t0, v2); 12940 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, tcg_env); 12941 break; 12942 case OPC_DEXTPDP: 12943 tcg_gen_movi_tl(t0, v2); 12944 tcg_gen_movi_tl(t1, v1); 12945 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, tcg_env); 12946 break; 12947 case OPC_DEXTPDPV: 12948 tcg_gen_movi_tl(t0, v2); 12949 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, tcg_env); 12950 break; 12951 case OPC_DEXTR_L: 12952 tcg_gen_movi_tl(t0, v2); 12953 tcg_gen_movi_tl(t1, v1); 12954 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, tcg_env); 12955 break; 12956 case OPC_DEXTR_R_L: 12957 tcg_gen_movi_tl(t0, v2); 12958 tcg_gen_movi_tl(t1, v1); 12959 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, tcg_env); 12960 break; 12961 case OPC_DEXTR_RS_L: 12962 tcg_gen_movi_tl(t0, v2); 12963 tcg_gen_movi_tl(t1, v1); 12964 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, tcg_env); 12965 break; 12966 case OPC_DEXTR_W: 12967 tcg_gen_movi_tl(t0, v2); 12968 tcg_gen_movi_tl(t1, v1); 12969 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, tcg_env); 12970 break; 12971 case OPC_DEXTR_R_W: 12972 tcg_gen_movi_tl(t0, v2); 12973 tcg_gen_movi_tl(t1, v1); 12974 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, tcg_env); 12975 break; 12976 case OPC_DEXTR_RS_W: 12977 tcg_gen_movi_tl(t0, v2); 12978 tcg_gen_movi_tl(t1, v1); 12979 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, tcg_env); 12980 break; 12981 case OPC_DEXTR_S_H: 12982 tcg_gen_movi_tl(t0, v2); 12983 tcg_gen_movi_tl(t1, v1); 12984 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, tcg_env); 12985 break; 12986 case OPC_DEXTRV_S_H: 12987 tcg_gen_movi_tl(t0, v2); 12988 gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env); 12989 break; 12990 case OPC_DEXTRV_L: 12991 tcg_gen_movi_tl(t0, v2); 12992 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, tcg_env); 12993 break; 12994 case OPC_DEXTRV_R_L: 12995 tcg_gen_movi_tl(t0, v2); 12996 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, tcg_env); 12997 break; 12998 case OPC_DEXTRV_RS_L: 12999 tcg_gen_movi_tl(t0, v2); 13000 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, tcg_env); 13001 break; 13002 case OPC_DEXTRV_W: 13003 tcg_gen_movi_tl(t0, v2); 13004 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, tcg_env); 13005 break; 13006 case OPC_DEXTRV_R_W: 13007 tcg_gen_movi_tl(t0, v2); 13008 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env); 13009 break; 13010 case OPC_DEXTRV_RS_W: 13011 tcg_gen_movi_tl(t0, v2); 13012 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env); 13013 break; 13014 } 13015 break; 13016 #endif 13017 } 13018 } 13019 13020 /* End MIPSDSP functions. */ 13021 13022 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) 13023 { 13024 int rs, rt, rd, sa; 13025 uint32_t op1, op2; 13026 13027 rs = (ctx->opcode >> 21) & 0x1f; 13028 rt = (ctx->opcode >> 16) & 0x1f; 13029 rd = (ctx->opcode >> 11) & 0x1f; 13030 sa = (ctx->opcode >> 6) & 0x1f; 13031 13032 op1 = MASK_SPECIAL(ctx->opcode); 13033 switch (op1) { 13034 case OPC_MULT: 13035 case OPC_MULTU: 13036 case OPC_DIV: 13037 case OPC_DIVU: 13038 op2 = MASK_R6_MULDIV(ctx->opcode); 13039 switch (op2) { 13040 case R6_OPC_MUL: 13041 case R6_OPC_MUH: 13042 case R6_OPC_MULU: 13043 case R6_OPC_MUHU: 13044 case R6_OPC_DIV: 13045 case R6_OPC_MOD: 13046 case R6_OPC_DIVU: 13047 case R6_OPC_MODU: 13048 gen_r6_muldiv(ctx, op2, rd, rs, rt); 13049 break; 13050 default: 13051 MIPS_INVAL("special_r6 muldiv"); 13052 gen_reserved_instruction(ctx); 13053 break; 13054 } 13055 break; 13056 case OPC_SELEQZ: 13057 case OPC_SELNEZ: 13058 gen_cond_move(ctx, op1, rd, rs, rt); 13059 break; 13060 case R6_OPC_CLO: 13061 case R6_OPC_CLZ: 13062 if (rt == 0 && sa == 1) { 13063 /* 13064 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13065 * We need additionally to check other fields. 13066 */ 13067 gen_cl(ctx, op1, rd, rs); 13068 } else { 13069 gen_reserved_instruction(ctx); 13070 } 13071 break; 13072 case R6_OPC_SDBBP: 13073 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 13074 ctx->base.is_jmp = DISAS_SEMIHOST; 13075 } else { 13076 if (ctx->hflags & MIPS_HFLAG_SBRI) { 13077 gen_reserved_instruction(ctx); 13078 } else { 13079 generate_exception_end(ctx, EXCP_DBp); 13080 } 13081 } 13082 break; 13083 #if defined(TARGET_MIPS64) 13084 case R6_OPC_DCLO: 13085 case R6_OPC_DCLZ: 13086 if (rt == 0 && sa == 1) { 13087 /* 13088 * Major opcode and function field is shared with preR6 MFHI/MTHI. 13089 * We need additionally to check other fields. 13090 */ 13091 check_mips_64(ctx); 13092 gen_cl(ctx, op1, rd, rs); 13093 } else { 13094 gen_reserved_instruction(ctx); 13095 } 13096 break; 13097 case OPC_DMULT: 13098 case OPC_DMULTU: 13099 case OPC_DDIV: 13100 case OPC_DDIVU: 13101 13102 op2 = MASK_R6_MULDIV(ctx->opcode); 13103 switch (op2) { 13104 case R6_OPC_DMUL: 13105 case R6_OPC_DMUH: 13106 case R6_OPC_DMULU: 13107 case R6_OPC_DMUHU: 13108 case R6_OPC_DDIV: 13109 case R6_OPC_DMOD: 13110 case R6_OPC_DDIVU: 13111 case R6_OPC_DMODU: 13112 check_mips_64(ctx); 13113 gen_r6_muldiv(ctx, op2, rd, rs, rt); 13114 break; 13115 default: 13116 MIPS_INVAL("special_r6 muldiv"); 13117 gen_reserved_instruction(ctx); 13118 break; 13119 } 13120 break; 13121 #endif 13122 default: /* Invalid */ 13123 MIPS_INVAL("special_r6"); 13124 gen_reserved_instruction(ctx); 13125 break; 13126 } 13127 } 13128 13129 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) 13130 { 13131 int rs = extract32(ctx->opcode, 21, 5); 13132 int rt = extract32(ctx->opcode, 16, 5); 13133 int rd = extract32(ctx->opcode, 11, 5); 13134 uint32_t op1 = MASK_SPECIAL(ctx->opcode); 13135 13136 switch (op1) { 13137 case OPC_MOVN: /* Conditional move */ 13138 case OPC_MOVZ: 13139 gen_cond_move(ctx, op1, rd, rs, rt); 13140 break; 13141 case OPC_MFHI: /* Move from HI/LO */ 13142 case OPC_MFLO: 13143 gen_HILO(ctx, op1, 0, rd); 13144 break; 13145 case OPC_MTHI: 13146 case OPC_MTLO: /* Move to HI/LO */ 13147 gen_HILO(ctx, op1, 0, rs); 13148 break; 13149 case OPC_MULT: 13150 case OPC_MULTU: 13151 gen_mul_txx9(ctx, op1, rd, rs, rt); 13152 break; 13153 case OPC_DIV: 13154 case OPC_DIVU: 13155 gen_muldiv(ctx, op1, 0, rs, rt); 13156 break; 13157 #if defined(TARGET_MIPS64) 13158 case OPC_DMULT: 13159 case OPC_DMULTU: 13160 case OPC_DDIV: 13161 case OPC_DDIVU: 13162 check_insn_opc_user_only(ctx, INSN_R5900); 13163 gen_muldiv(ctx, op1, 0, rs, rt); 13164 break; 13165 #endif 13166 case OPC_JR: 13167 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13168 break; 13169 default: /* Invalid */ 13170 MIPS_INVAL("special_tx79"); 13171 gen_reserved_instruction(ctx); 13172 break; 13173 } 13174 } 13175 13176 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) 13177 { 13178 int rs, rt, rd; 13179 uint32_t op1; 13180 13181 rs = (ctx->opcode >> 21) & 0x1f; 13182 rt = (ctx->opcode >> 16) & 0x1f; 13183 rd = (ctx->opcode >> 11) & 0x1f; 13184 13185 op1 = MASK_SPECIAL(ctx->opcode); 13186 switch (op1) { 13187 case OPC_MOVN: /* Conditional move */ 13188 case OPC_MOVZ: 13189 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | 13190 INSN_LOONGSON2E | INSN_LOONGSON2F); 13191 gen_cond_move(ctx, op1, rd, rs, rt); 13192 break; 13193 case OPC_MFHI: /* Move from HI/LO */ 13194 case OPC_MFLO: 13195 gen_HILO(ctx, op1, rs & 3, rd); 13196 break; 13197 case OPC_MTHI: 13198 case OPC_MTLO: /* Move to HI/LO */ 13199 gen_HILO(ctx, op1, rd & 3, rs); 13200 break; 13201 case OPC_MOVCI: 13202 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 13203 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 13204 check_cp1_enabled(ctx); 13205 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 13206 (ctx->opcode >> 16) & 1); 13207 } else { 13208 generate_exception_err(ctx, EXCP_CpU, 1); 13209 } 13210 break; 13211 case OPC_MULT: 13212 case OPC_MULTU: 13213 gen_muldiv(ctx, op1, rd & 3, rs, rt); 13214 break; 13215 case OPC_DIV: 13216 case OPC_DIVU: 13217 gen_muldiv(ctx, op1, 0, rs, rt); 13218 break; 13219 #if defined(TARGET_MIPS64) 13220 case OPC_DMULT: 13221 case OPC_DMULTU: 13222 case OPC_DDIV: 13223 case OPC_DDIVU: 13224 check_insn(ctx, ISA_MIPS3); 13225 check_mips_64(ctx); 13226 gen_muldiv(ctx, op1, 0, rs, rt); 13227 break; 13228 #endif 13229 case OPC_JR: 13230 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 13231 break; 13232 case OPC_SPIM: 13233 #ifdef MIPS_STRICT_STANDARD 13234 MIPS_INVAL("SPIM"); 13235 gen_reserved_instruction(ctx); 13236 #else 13237 /* Implemented as RI exception for now. */ 13238 MIPS_INVAL("spim (unofficial)"); 13239 gen_reserved_instruction(ctx); 13240 #endif 13241 break; 13242 default: /* Invalid */ 13243 MIPS_INVAL("special_legacy"); 13244 gen_reserved_instruction(ctx); 13245 break; 13246 } 13247 } 13248 13249 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) 13250 { 13251 int rs, rt, rd, sa; 13252 uint32_t op1; 13253 13254 rs = (ctx->opcode >> 21) & 0x1f; 13255 rt = (ctx->opcode >> 16) & 0x1f; 13256 rd = (ctx->opcode >> 11) & 0x1f; 13257 sa = (ctx->opcode >> 6) & 0x1f; 13258 13259 op1 = MASK_SPECIAL(ctx->opcode); 13260 switch (op1) { 13261 case OPC_SLL: /* Shift with immediate */ 13262 if (sa == 5 && rd == 0 && 13263 rs == 0 && rt == 0) { /* PAUSE */ 13264 if ((ctx->insn_flags & ISA_MIPS_R6) && 13265 (ctx->hflags & MIPS_HFLAG_BMASK)) { 13266 gen_reserved_instruction(ctx); 13267 break; 13268 } 13269 } 13270 /* Fallthrough */ 13271 case OPC_SRA: 13272 gen_shift_imm(ctx, op1, rd, rt, sa); 13273 break; 13274 case OPC_SRL: 13275 switch ((ctx->opcode >> 21) & 0x1f) { 13276 case 1: 13277 /* rotr is decoded as srl on non-R2 CPUs */ 13278 if (ctx->insn_flags & ISA_MIPS_R2) { 13279 op1 = OPC_ROTR; 13280 } 13281 /* Fallthrough */ 13282 case 0: 13283 gen_shift_imm(ctx, op1, rd, rt, sa); 13284 break; 13285 default: 13286 gen_reserved_instruction(ctx); 13287 break; 13288 } 13289 break; 13290 case OPC_ADD: 13291 case OPC_ADDU: 13292 case OPC_SUB: 13293 case OPC_SUBU: 13294 gen_arith(ctx, op1, rd, rs, rt); 13295 break; 13296 case OPC_SLLV: /* Shifts */ 13297 case OPC_SRAV: 13298 gen_shift(ctx, op1, rd, rs, rt); 13299 break; 13300 case OPC_SRLV: 13301 switch ((ctx->opcode >> 6) & 0x1f) { 13302 case 1: 13303 /* rotrv is decoded as srlv on non-R2 CPUs */ 13304 if (ctx->insn_flags & ISA_MIPS_R2) { 13305 op1 = OPC_ROTRV; 13306 } 13307 /* Fallthrough */ 13308 case 0: 13309 gen_shift(ctx, op1, rd, rs, rt); 13310 break; 13311 default: 13312 gen_reserved_instruction(ctx); 13313 break; 13314 } 13315 break; 13316 case OPC_SLT: /* Set on less than */ 13317 case OPC_SLTU: 13318 gen_slt(ctx, op1, rd, rs, rt); 13319 break; 13320 case OPC_AND: /* Logic*/ 13321 case OPC_OR: 13322 case OPC_NOR: 13323 case OPC_XOR: 13324 gen_logic(ctx, op1, rd, rs, rt); 13325 break; 13326 case OPC_JALR: 13327 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 13328 break; 13329 case OPC_TGE: /* Traps */ 13330 case OPC_TGEU: 13331 case OPC_TLT: 13332 case OPC_TLTU: 13333 case OPC_TEQ: 13334 case OPC_TNE: 13335 check_insn(ctx, ISA_MIPS2); 13336 gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10)); 13337 break; 13338 case OPC_PMON: 13339 /* Pmon entry point, also R4010 selsl */ 13340 #ifdef MIPS_STRICT_STANDARD 13341 MIPS_INVAL("PMON / selsl"); 13342 gen_reserved_instruction(ctx); 13343 #else 13344 gen_helper_pmon(tcg_env, tcg_constant_i32(sa)); 13345 #endif 13346 break; 13347 case OPC_SYSCALL: 13348 generate_exception_end(ctx, EXCP_SYSCALL); 13349 break; 13350 case OPC_BREAK: 13351 generate_exception_break(ctx, extract32(ctx->opcode, 6, 20)); 13352 break; 13353 case OPC_SYNC: 13354 check_insn(ctx, ISA_MIPS2); 13355 gen_sync(extract32(ctx->opcode, 6, 5)); 13356 break; 13357 13358 #if defined(TARGET_MIPS64) 13359 /* MIPS64 specific opcodes */ 13360 case OPC_DSLL: 13361 case OPC_DSRA: 13362 case OPC_DSLL32: 13363 case OPC_DSRA32: 13364 check_insn(ctx, ISA_MIPS3); 13365 check_mips_64(ctx); 13366 gen_shift_imm(ctx, op1, rd, rt, sa); 13367 break; 13368 case OPC_DSRL: 13369 switch ((ctx->opcode >> 21) & 0x1f) { 13370 case 1: 13371 /* drotr is decoded as dsrl on non-R2 CPUs */ 13372 if (ctx->insn_flags & ISA_MIPS_R2) { 13373 op1 = OPC_DROTR; 13374 } 13375 /* Fallthrough */ 13376 case 0: 13377 check_insn(ctx, ISA_MIPS3); 13378 check_mips_64(ctx); 13379 gen_shift_imm(ctx, op1, rd, rt, sa); 13380 break; 13381 default: 13382 gen_reserved_instruction(ctx); 13383 break; 13384 } 13385 break; 13386 case OPC_DSRL32: 13387 switch ((ctx->opcode >> 21) & 0x1f) { 13388 case 1: 13389 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 13390 if (ctx->insn_flags & ISA_MIPS_R2) { 13391 op1 = OPC_DROTR32; 13392 } 13393 /* Fallthrough */ 13394 case 0: 13395 check_insn(ctx, ISA_MIPS3); 13396 check_mips_64(ctx); 13397 gen_shift_imm(ctx, op1, rd, rt, sa); 13398 break; 13399 default: 13400 gen_reserved_instruction(ctx); 13401 break; 13402 } 13403 break; 13404 case OPC_DADD: 13405 case OPC_DADDU: 13406 case OPC_DSUB: 13407 case OPC_DSUBU: 13408 check_insn(ctx, ISA_MIPS3); 13409 check_mips_64(ctx); 13410 gen_arith(ctx, op1, rd, rs, rt); 13411 break; 13412 case OPC_DSLLV: 13413 case OPC_DSRAV: 13414 check_insn(ctx, ISA_MIPS3); 13415 check_mips_64(ctx); 13416 gen_shift(ctx, op1, rd, rs, rt); 13417 break; 13418 case OPC_DSRLV: 13419 switch ((ctx->opcode >> 6) & 0x1f) { 13420 case 1: 13421 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 13422 if (ctx->insn_flags & ISA_MIPS_R2) { 13423 op1 = OPC_DROTRV; 13424 } 13425 /* Fallthrough */ 13426 case 0: 13427 check_insn(ctx, ISA_MIPS3); 13428 check_mips_64(ctx); 13429 gen_shift(ctx, op1, rd, rs, rt); 13430 break; 13431 default: 13432 gen_reserved_instruction(ctx); 13433 break; 13434 } 13435 break; 13436 #endif 13437 default: 13438 if (ctx->insn_flags & ISA_MIPS_R6) { 13439 decode_opc_special_r6(env, ctx); 13440 } else if (ctx->insn_flags & INSN_R5900) { 13441 decode_opc_special_tx79(env, ctx); 13442 } else { 13443 decode_opc_special_legacy(env, ctx); 13444 } 13445 } 13446 } 13447 13448 13449 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) 13450 { 13451 int rs, rt, rd; 13452 uint32_t op1; 13453 13454 rs = (ctx->opcode >> 21) & 0x1f; 13455 rt = (ctx->opcode >> 16) & 0x1f; 13456 rd = (ctx->opcode >> 11) & 0x1f; 13457 13458 op1 = MASK_SPECIAL2(ctx->opcode); 13459 switch (op1) { 13460 case OPC_MADD: /* Multiply and add/sub */ 13461 case OPC_MADDU: 13462 case OPC_MSUB: 13463 case OPC_MSUBU: 13464 check_insn(ctx, ISA_MIPS_R1); 13465 gen_muldiv(ctx, op1, rd & 3, rs, rt); 13466 break; 13467 case OPC_MUL: 13468 gen_arith(ctx, op1, rd, rs, rt); 13469 break; 13470 case OPC_MULT_G_2F: 13471 case OPC_MULTU_G_2F: 13472 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 13473 gen_loongson_integer(ctx, op1, rd, rs, rt); 13474 break; 13475 case OPC_CLO: 13476 case OPC_CLZ: 13477 check_insn(ctx, ISA_MIPS_R1); 13478 gen_cl(ctx, op1, rd, rs); 13479 break; 13480 case OPC_SDBBP: 13481 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) { 13482 ctx->base.is_jmp = DISAS_SEMIHOST; 13483 } else { 13484 /* 13485 * XXX: not clear which exception should be raised 13486 * when in debug mode... 13487 */ 13488 check_insn(ctx, ISA_MIPS_R1); 13489 generate_exception_end(ctx, EXCP_DBp); 13490 } 13491 break; 13492 #if defined(TARGET_MIPS64) 13493 case OPC_DCLO: 13494 case OPC_DCLZ: 13495 check_insn(ctx, ISA_MIPS_R1); 13496 check_mips_64(ctx); 13497 gen_cl(ctx, op1, rd, rs); 13498 break; 13499 case OPC_DMULT_G_2F: 13500 case OPC_DMULTU_G_2F: 13501 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 13502 gen_loongson_integer(ctx, op1, rd, rs, rt); 13503 break; 13504 #endif 13505 default: /* Invalid */ 13506 MIPS_INVAL("special2_legacy"); 13507 gen_reserved_instruction(ctx); 13508 break; 13509 } 13510 } 13511 13512 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) 13513 { 13514 int rs, rt, rd, sa; 13515 uint32_t op1, op2; 13516 int16_t imm; 13517 13518 rs = (ctx->opcode >> 21) & 0x1f; 13519 rt = (ctx->opcode >> 16) & 0x1f; 13520 rd = (ctx->opcode >> 11) & 0x1f; 13521 sa = (ctx->opcode >> 6) & 0x1f; 13522 imm = (int16_t)ctx->opcode >> 7; 13523 13524 op1 = MASK_SPECIAL3(ctx->opcode); 13525 switch (op1) { 13526 case R6_OPC_PREF: 13527 if (rt >= 24) { 13528 /* hint codes 24-31 are reserved and signal RI */ 13529 gen_reserved_instruction(ctx); 13530 } 13531 /* Treat as NOP. */ 13532 break; 13533 case R6_OPC_CACHE: 13534 check_cp0_enabled(ctx); 13535 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 13536 gen_cache_operation(ctx, rt, rs, imm); 13537 } 13538 break; 13539 case R6_OPC_SC: 13540 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false); 13541 break; 13542 case R6_OPC_LL: 13543 gen_ld(ctx, op1, rt, rs, imm); 13544 break; 13545 case OPC_BSHFL: 13546 { 13547 if (rd == 0) { 13548 /* Treat as NOP. */ 13549 break; 13550 } 13551 op2 = MASK_BSHFL(ctx->opcode); 13552 switch (op2) { 13553 case OPC_ALIGN: 13554 case OPC_ALIGN_1: 13555 case OPC_ALIGN_2: 13556 case OPC_ALIGN_3: 13557 gen_align(ctx, 32, rd, rs, rt, sa & 3); 13558 break; 13559 case OPC_BITSWAP: 13560 gen_bitswap(ctx, op2, rd, rt); 13561 break; 13562 } 13563 } 13564 break; 13565 #ifndef CONFIG_USER_ONLY 13566 case OPC_GINV: 13567 if (unlikely(ctx->gi <= 1)) { 13568 gen_reserved_instruction(ctx); 13569 } 13570 check_cp0_enabled(ctx); 13571 switch ((ctx->opcode >> 6) & 3) { 13572 case 0: /* GINVI */ 13573 /* Treat as NOP. */ 13574 break; 13575 case 2: /* GINVT */ 13576 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); 13577 break; 13578 default: 13579 gen_reserved_instruction(ctx); 13580 break; 13581 } 13582 break; 13583 #endif 13584 #if defined(TARGET_MIPS64) 13585 case R6_OPC_SCD: 13586 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false); 13587 break; 13588 case R6_OPC_LLD: 13589 gen_ld(ctx, op1, rt, rs, imm); 13590 break; 13591 case OPC_DBSHFL: 13592 check_mips_64(ctx); 13593 { 13594 if (rd == 0) { 13595 /* Treat as NOP. */ 13596 break; 13597 } 13598 op2 = MASK_DBSHFL(ctx->opcode); 13599 switch (op2) { 13600 case OPC_DALIGN: 13601 case OPC_DALIGN_1: 13602 case OPC_DALIGN_2: 13603 case OPC_DALIGN_3: 13604 case OPC_DALIGN_4: 13605 case OPC_DALIGN_5: 13606 case OPC_DALIGN_6: 13607 case OPC_DALIGN_7: 13608 gen_align(ctx, 64, rd, rs, rt, sa & 7); 13609 break; 13610 case OPC_DBITSWAP: 13611 gen_bitswap(ctx, op2, rd, rt); 13612 break; 13613 } 13614 13615 } 13616 break; 13617 #endif 13618 default: /* Invalid */ 13619 MIPS_INVAL("special3_r6"); 13620 gen_reserved_instruction(ctx); 13621 break; 13622 } 13623 } 13624 13625 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) 13626 { 13627 int rs, rt, rd; 13628 uint32_t op1, op2; 13629 13630 rs = (ctx->opcode >> 21) & 0x1f; 13631 rt = (ctx->opcode >> 16) & 0x1f; 13632 rd = (ctx->opcode >> 11) & 0x1f; 13633 13634 op1 = MASK_SPECIAL3(ctx->opcode); 13635 switch (op1) { 13636 case OPC_MULT_G_2E: 13637 case OPC_MULTU_G_2E: 13638 /* 13639 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 13640 * the same mask and op1. 13641 */ 13642 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MUL_PH_DSP)) { 13643 op2 = MASK_ADDUH_QB(ctx->opcode); 13644 switch (op2) { 13645 case OPC_ADDUH_QB: 13646 case OPC_ADDUH_R_QB: 13647 case OPC_ADDQH_PH: 13648 case OPC_ADDQH_R_PH: 13649 case OPC_ADDQH_W: 13650 case OPC_ADDQH_R_W: 13651 case OPC_SUBUH_QB: 13652 case OPC_SUBUH_R_QB: 13653 case OPC_SUBQH_PH: 13654 case OPC_SUBQH_R_PH: 13655 case OPC_SUBQH_W: 13656 case OPC_SUBQH_R_W: 13657 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13658 break; 13659 case OPC_MUL_PH: 13660 case OPC_MUL_S_PH: 13661 case OPC_MULQ_S_W: 13662 case OPC_MULQ_RS_W: 13663 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13664 break; 13665 default: 13666 MIPS_INVAL("MASK ADDUH.QB"); 13667 gen_reserved_instruction(ctx); 13668 break; 13669 } 13670 } else if (ctx->insn_flags & INSN_LOONGSON2E) { 13671 gen_loongson_integer(ctx, op1, rd, rs, rt); 13672 } else { 13673 gen_reserved_instruction(ctx); 13674 } 13675 break; 13676 case OPC_LX_DSP: 13677 op2 = MASK_LX(ctx->opcode); 13678 switch (op2) { 13679 #if defined(TARGET_MIPS64) 13680 case OPC_LDX: 13681 #endif 13682 case OPC_LBUX: 13683 case OPC_LHX: 13684 case OPC_LWX: 13685 gen_mips_lx(ctx, op2, rd, rs, rt); 13686 break; 13687 default: /* Invalid */ 13688 MIPS_INVAL("MASK LX"); 13689 gen_reserved_instruction(ctx); 13690 break; 13691 } 13692 break; 13693 case OPC_ABSQ_S_PH_DSP: 13694 op2 = MASK_ABSQ_S_PH(ctx->opcode); 13695 switch (op2) { 13696 case OPC_ABSQ_S_QB: 13697 case OPC_ABSQ_S_PH: 13698 case OPC_ABSQ_S_W: 13699 case OPC_PRECEQ_W_PHL: 13700 case OPC_PRECEQ_W_PHR: 13701 case OPC_PRECEQU_PH_QBL: 13702 case OPC_PRECEQU_PH_QBR: 13703 case OPC_PRECEQU_PH_QBLA: 13704 case OPC_PRECEQU_PH_QBRA: 13705 case OPC_PRECEU_PH_QBL: 13706 case OPC_PRECEU_PH_QBR: 13707 case OPC_PRECEU_PH_QBLA: 13708 case OPC_PRECEU_PH_QBRA: 13709 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13710 break; 13711 case OPC_BITREV: 13712 case OPC_REPL_QB: 13713 case OPC_REPLV_QB: 13714 case OPC_REPL_PH: 13715 case OPC_REPLV_PH: 13716 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 13717 break; 13718 default: 13719 MIPS_INVAL("MASK ABSQ_S.PH"); 13720 gen_reserved_instruction(ctx); 13721 break; 13722 } 13723 break; 13724 case OPC_ADDU_QB_DSP: 13725 op2 = MASK_ADDU_QB(ctx->opcode); 13726 switch (op2) { 13727 case OPC_ADDQ_PH: 13728 case OPC_ADDQ_S_PH: 13729 case OPC_ADDQ_S_W: 13730 case OPC_ADDU_QB: 13731 case OPC_ADDU_S_QB: 13732 case OPC_ADDU_PH: 13733 case OPC_ADDU_S_PH: 13734 case OPC_SUBQ_PH: 13735 case OPC_SUBQ_S_PH: 13736 case OPC_SUBQ_S_W: 13737 case OPC_SUBU_QB: 13738 case OPC_SUBU_S_QB: 13739 case OPC_SUBU_PH: 13740 case OPC_SUBU_S_PH: 13741 case OPC_ADDSC: 13742 case OPC_ADDWC: 13743 case OPC_MODSUB: 13744 case OPC_RADDU_W_QB: 13745 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13746 break; 13747 case OPC_MULEU_S_PH_QBL: 13748 case OPC_MULEU_S_PH_QBR: 13749 case OPC_MULQ_RS_PH: 13750 case OPC_MULEQ_S_W_PHL: 13751 case OPC_MULEQ_S_W_PHR: 13752 case OPC_MULQ_S_PH: 13753 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13754 break; 13755 default: /* Invalid */ 13756 MIPS_INVAL("MASK ADDU.QB"); 13757 gen_reserved_instruction(ctx); 13758 break; 13759 13760 } 13761 break; 13762 case OPC_CMPU_EQ_QB_DSP: 13763 op2 = MASK_CMPU_EQ_QB(ctx->opcode); 13764 switch (op2) { 13765 case OPC_PRECR_SRA_PH_W: 13766 case OPC_PRECR_SRA_R_PH_W: 13767 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 13768 break; 13769 case OPC_PRECR_QB_PH: 13770 case OPC_PRECRQ_QB_PH: 13771 case OPC_PRECRQ_PH_W: 13772 case OPC_PRECRQ_RS_PH_W: 13773 case OPC_PRECRQU_S_QB_PH: 13774 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13775 break; 13776 case OPC_CMPU_EQ_QB: 13777 case OPC_CMPU_LT_QB: 13778 case OPC_CMPU_LE_QB: 13779 case OPC_CMP_EQ_PH: 13780 case OPC_CMP_LT_PH: 13781 case OPC_CMP_LE_PH: 13782 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 13783 break; 13784 case OPC_CMPGU_EQ_QB: 13785 case OPC_CMPGU_LT_QB: 13786 case OPC_CMPGU_LE_QB: 13787 case OPC_CMPGDU_EQ_QB: 13788 case OPC_CMPGDU_LT_QB: 13789 case OPC_CMPGDU_LE_QB: 13790 case OPC_PICK_QB: 13791 case OPC_PICK_PH: 13792 case OPC_PACKRL_PH: 13793 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 13794 break; 13795 default: /* Invalid */ 13796 MIPS_INVAL("MASK CMPU.EQ.QB"); 13797 gen_reserved_instruction(ctx); 13798 break; 13799 } 13800 break; 13801 case OPC_SHLL_QB_DSP: 13802 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 13803 break; 13804 case OPC_DPA_W_PH_DSP: 13805 op2 = MASK_DPA_W_PH(ctx->opcode); 13806 switch (op2) { 13807 case OPC_DPAU_H_QBL: 13808 case OPC_DPAU_H_QBR: 13809 case OPC_DPSU_H_QBL: 13810 case OPC_DPSU_H_QBR: 13811 case OPC_DPA_W_PH: 13812 case OPC_DPAX_W_PH: 13813 case OPC_DPAQ_S_W_PH: 13814 case OPC_DPAQX_S_W_PH: 13815 case OPC_DPAQX_SA_W_PH: 13816 case OPC_DPS_W_PH: 13817 case OPC_DPSX_W_PH: 13818 case OPC_DPSQ_S_W_PH: 13819 case OPC_DPSQX_S_W_PH: 13820 case OPC_DPSQX_SA_W_PH: 13821 case OPC_MULSAQ_S_W_PH: 13822 case OPC_DPAQ_SA_L_W: 13823 case OPC_DPSQ_SA_L_W: 13824 case OPC_MAQ_S_W_PHL: 13825 case OPC_MAQ_S_W_PHR: 13826 case OPC_MAQ_SA_W_PHL: 13827 case OPC_MAQ_SA_W_PHR: 13828 case OPC_MULSA_W_PH: 13829 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 13830 break; 13831 default: /* Invalid */ 13832 MIPS_INVAL("MASK DPAW.PH"); 13833 gen_reserved_instruction(ctx); 13834 break; 13835 } 13836 break; 13837 case OPC_INSV_DSP: 13838 op2 = MASK_INSV(ctx->opcode); 13839 switch (op2) { 13840 case OPC_INSV: 13841 check_dsp(ctx); 13842 { 13843 TCGv t0, t1; 13844 13845 if (rt == 0) { 13846 break; 13847 } 13848 13849 t0 = tcg_temp_new(); 13850 t1 = tcg_temp_new(); 13851 13852 gen_load_gpr(t0, rt); 13853 gen_load_gpr(t1, rs); 13854 13855 gen_helper_insv(cpu_gpr[rt], tcg_env, t1, t0); 13856 break; 13857 } 13858 default: /* Invalid */ 13859 MIPS_INVAL("MASK INSV"); 13860 gen_reserved_instruction(ctx); 13861 break; 13862 } 13863 break; 13864 case OPC_APPEND_DSP: 13865 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 13866 break; 13867 case OPC_EXTR_W_DSP: 13868 op2 = MASK_EXTR_W(ctx->opcode); 13869 switch (op2) { 13870 case OPC_EXTR_W: 13871 case OPC_EXTR_R_W: 13872 case OPC_EXTR_RS_W: 13873 case OPC_EXTR_S_H: 13874 case OPC_EXTRV_S_H: 13875 case OPC_EXTRV_W: 13876 case OPC_EXTRV_R_W: 13877 case OPC_EXTRV_RS_W: 13878 case OPC_EXTP: 13879 case OPC_EXTPV: 13880 case OPC_EXTPDP: 13881 case OPC_EXTPDPV: 13882 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 13883 break; 13884 case OPC_RDDSP: 13885 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1); 13886 break; 13887 case OPC_SHILO: 13888 case OPC_SHILOV: 13889 case OPC_MTHLIP: 13890 case OPC_WRDSP: 13891 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 13892 break; 13893 default: /* Invalid */ 13894 MIPS_INVAL("MASK EXTR.W"); 13895 gen_reserved_instruction(ctx); 13896 break; 13897 } 13898 break; 13899 #if defined(TARGET_MIPS64) 13900 case OPC_DMULT_G_2E: 13901 case OPC_DMULTU_G_2E: 13902 check_insn(ctx, INSN_LOONGSON2E); 13903 gen_loongson_integer(ctx, op1, rd, rs, rt); 13904 break; 13905 case OPC_ABSQ_S_QH_DSP: 13906 op2 = MASK_ABSQ_S_QH(ctx->opcode); 13907 switch (op2) { 13908 case OPC_PRECEQ_L_PWL: 13909 case OPC_PRECEQ_L_PWR: 13910 case OPC_PRECEQ_PW_QHL: 13911 case OPC_PRECEQ_PW_QHR: 13912 case OPC_PRECEQ_PW_QHLA: 13913 case OPC_PRECEQ_PW_QHRA: 13914 case OPC_PRECEQU_QH_OBL: 13915 case OPC_PRECEQU_QH_OBR: 13916 case OPC_PRECEQU_QH_OBLA: 13917 case OPC_PRECEQU_QH_OBRA: 13918 case OPC_PRECEU_QH_OBL: 13919 case OPC_PRECEU_QH_OBR: 13920 case OPC_PRECEU_QH_OBLA: 13921 case OPC_PRECEU_QH_OBRA: 13922 case OPC_ABSQ_S_OB: 13923 case OPC_ABSQ_S_PW: 13924 case OPC_ABSQ_S_QH: 13925 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13926 break; 13927 case OPC_REPL_OB: 13928 case OPC_REPL_PW: 13929 case OPC_REPL_QH: 13930 case OPC_REPLV_OB: 13931 case OPC_REPLV_PW: 13932 case OPC_REPLV_QH: 13933 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 13934 break; 13935 default: /* Invalid */ 13936 MIPS_INVAL("MASK ABSQ_S.QH"); 13937 gen_reserved_instruction(ctx); 13938 break; 13939 } 13940 break; 13941 case OPC_ADDU_OB_DSP: 13942 op2 = MASK_ADDU_OB(ctx->opcode); 13943 switch (op2) { 13944 case OPC_RADDU_L_OB: 13945 case OPC_SUBQ_PW: 13946 case OPC_SUBQ_S_PW: 13947 case OPC_SUBQ_QH: 13948 case OPC_SUBQ_S_QH: 13949 case OPC_SUBU_OB: 13950 case OPC_SUBU_S_OB: 13951 case OPC_SUBU_QH: 13952 case OPC_SUBU_S_QH: 13953 case OPC_SUBUH_OB: 13954 case OPC_SUBUH_R_OB: 13955 case OPC_ADDQ_PW: 13956 case OPC_ADDQ_S_PW: 13957 case OPC_ADDQ_QH: 13958 case OPC_ADDQ_S_QH: 13959 case OPC_ADDU_OB: 13960 case OPC_ADDU_S_OB: 13961 case OPC_ADDU_QH: 13962 case OPC_ADDU_S_QH: 13963 case OPC_ADDUH_OB: 13964 case OPC_ADDUH_R_OB: 13965 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13966 break; 13967 case OPC_MULEQ_S_PW_QHL: 13968 case OPC_MULEQ_S_PW_QHR: 13969 case OPC_MULEU_S_QH_OBL: 13970 case OPC_MULEU_S_QH_OBR: 13971 case OPC_MULQ_RS_QH: 13972 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 13973 break; 13974 default: /* Invalid */ 13975 MIPS_INVAL("MASK ADDU.OB"); 13976 gen_reserved_instruction(ctx); 13977 break; 13978 } 13979 break; 13980 case OPC_CMPU_EQ_OB_DSP: 13981 op2 = MASK_CMPU_EQ_OB(ctx->opcode); 13982 switch (op2) { 13983 case OPC_PRECR_SRA_QH_PW: 13984 case OPC_PRECR_SRA_R_QH_PW: 13985 /* Return value is rt. */ 13986 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 13987 break; 13988 case OPC_PRECR_OB_QH: 13989 case OPC_PRECRQ_OB_QH: 13990 case OPC_PRECRQ_PW_L: 13991 case OPC_PRECRQ_QH_PW: 13992 case OPC_PRECRQ_RS_QH_PW: 13993 case OPC_PRECRQU_S_OB_QH: 13994 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 13995 break; 13996 case OPC_CMPU_EQ_OB: 13997 case OPC_CMPU_LT_OB: 13998 case OPC_CMPU_LE_OB: 13999 case OPC_CMP_EQ_QH: 14000 case OPC_CMP_LT_QH: 14001 case OPC_CMP_LE_QH: 14002 case OPC_CMP_EQ_PW: 14003 case OPC_CMP_LT_PW: 14004 case OPC_CMP_LE_PW: 14005 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 14006 break; 14007 case OPC_CMPGDU_EQ_OB: 14008 case OPC_CMPGDU_LT_OB: 14009 case OPC_CMPGDU_LE_OB: 14010 case OPC_CMPGU_EQ_OB: 14011 case OPC_CMPGU_LT_OB: 14012 case OPC_CMPGU_LE_OB: 14013 case OPC_PACKRL_PW: 14014 case OPC_PICK_OB: 14015 case OPC_PICK_PW: 14016 case OPC_PICK_QH: 14017 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 14018 break; 14019 default: /* Invalid */ 14020 MIPS_INVAL("MASK CMPU_EQ.OB"); 14021 gen_reserved_instruction(ctx); 14022 break; 14023 } 14024 break; 14025 case OPC_DAPPEND_DSP: 14026 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 14027 break; 14028 case OPC_DEXTR_W_DSP: 14029 op2 = MASK_DEXTR_W(ctx->opcode); 14030 switch (op2) { 14031 case OPC_DEXTP: 14032 case OPC_DEXTPDP: 14033 case OPC_DEXTPDPV: 14034 case OPC_DEXTPV: 14035 case OPC_DEXTR_L: 14036 case OPC_DEXTR_R_L: 14037 case OPC_DEXTR_RS_L: 14038 case OPC_DEXTR_W: 14039 case OPC_DEXTR_R_W: 14040 case OPC_DEXTR_RS_W: 14041 case OPC_DEXTR_S_H: 14042 case OPC_DEXTRV_L: 14043 case OPC_DEXTRV_R_L: 14044 case OPC_DEXTRV_RS_L: 14045 case OPC_DEXTRV_S_H: 14046 case OPC_DEXTRV_W: 14047 case OPC_DEXTRV_R_W: 14048 case OPC_DEXTRV_RS_W: 14049 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 14050 break; 14051 case OPC_DMTHLIP: 14052 case OPC_DSHILO: 14053 case OPC_DSHILOV: 14054 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 14055 break; 14056 default: /* Invalid */ 14057 MIPS_INVAL("MASK EXTR.W"); 14058 gen_reserved_instruction(ctx); 14059 break; 14060 } 14061 break; 14062 case OPC_DPAQ_W_QH_DSP: 14063 op2 = MASK_DPAQ_W_QH(ctx->opcode); 14064 switch (op2) { 14065 case OPC_DPAU_H_OBL: 14066 case OPC_DPAU_H_OBR: 14067 case OPC_DPSU_H_OBL: 14068 case OPC_DPSU_H_OBR: 14069 case OPC_DPA_W_QH: 14070 case OPC_DPAQ_S_W_QH: 14071 case OPC_DPS_W_QH: 14072 case OPC_DPSQ_S_W_QH: 14073 case OPC_MULSAQ_S_W_QH: 14074 case OPC_DPAQ_SA_L_PW: 14075 case OPC_DPSQ_SA_L_PW: 14076 case OPC_MULSAQ_S_L_PW: 14077 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14078 break; 14079 case OPC_MAQ_S_W_QHLL: 14080 case OPC_MAQ_S_W_QHLR: 14081 case OPC_MAQ_S_W_QHRL: 14082 case OPC_MAQ_S_W_QHRR: 14083 case OPC_MAQ_SA_W_QHLL: 14084 case OPC_MAQ_SA_W_QHLR: 14085 case OPC_MAQ_SA_W_QHRL: 14086 case OPC_MAQ_SA_W_QHRR: 14087 case OPC_MAQ_S_L_PWL: 14088 case OPC_MAQ_S_L_PWR: 14089 case OPC_DMADD: 14090 case OPC_DMADDU: 14091 case OPC_DMSUB: 14092 case OPC_DMSUBU: 14093 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14094 break; 14095 default: /* Invalid */ 14096 MIPS_INVAL("MASK DPAQ.W.QH"); 14097 gen_reserved_instruction(ctx); 14098 break; 14099 } 14100 break; 14101 case OPC_DINSV_DSP: 14102 op2 = MASK_INSV(ctx->opcode); 14103 switch (op2) { 14104 case OPC_DINSV: 14105 { 14106 TCGv t0, t1; 14107 14108 check_dsp(ctx); 14109 14110 if (rt == 0) { 14111 break; 14112 } 14113 14114 t0 = tcg_temp_new(); 14115 t1 = tcg_temp_new(); 14116 14117 gen_load_gpr(t0, rt); 14118 gen_load_gpr(t1, rs); 14119 14120 gen_helper_dinsv(cpu_gpr[rt], tcg_env, t1, t0); 14121 break; 14122 } 14123 default: /* Invalid */ 14124 MIPS_INVAL("MASK DINSV"); 14125 gen_reserved_instruction(ctx); 14126 break; 14127 } 14128 break; 14129 case OPC_SHLL_OB_DSP: 14130 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14131 break; 14132 #endif 14133 default: /* Invalid */ 14134 MIPS_INVAL("special3_legacy"); 14135 gen_reserved_instruction(ctx); 14136 break; 14137 } 14138 } 14139 14140 14141 #if defined(TARGET_MIPS64) 14142 14143 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) 14144 { 14145 uint32_t opc = MASK_MMI(ctx->opcode); 14146 int rs = extract32(ctx->opcode, 21, 5); 14147 int rt = extract32(ctx->opcode, 16, 5); 14148 int rd = extract32(ctx->opcode, 11, 5); 14149 14150 switch (opc) { 14151 case MMI_OPC_MULT1: 14152 case MMI_OPC_MULTU1: 14153 case MMI_OPC_MADD: 14154 case MMI_OPC_MADDU: 14155 case MMI_OPC_MADD1: 14156 case MMI_OPC_MADDU1: 14157 gen_mul_txx9(ctx, opc, rd, rs, rt); 14158 break; 14159 case MMI_OPC_DIV1: 14160 case MMI_OPC_DIVU1: 14161 gen_div1_tx79(ctx, opc, rs, rt); 14162 break; 14163 default: 14164 MIPS_INVAL("TX79 MMI class"); 14165 gen_reserved_instruction(ctx); 14166 break; 14167 } 14168 } 14169 14170 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset) 14171 { 14172 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */ 14173 } 14174 14175 /* 14176 * The TX79-specific instruction Store Quadword 14177 * 14178 * +--------+-------+-------+------------------------+ 14179 * | 011111 | base | rt | offset | SQ 14180 * +--------+-------+-------+------------------------+ 14181 * 6 5 5 16 14182 * 14183 * has the same opcode as the Read Hardware Register instruction 14184 * 14185 * +--------+-------+-------+-------+-------+--------+ 14186 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR 14187 * +--------+-------+-------+-------+-------+--------+ 14188 * 6 5 5 5 5 6 14189 * 14190 * that is required, trapped and emulated by the Linux kernel. However, all 14191 * RDHWR encodings yield address error exceptions on the TX79 since the SQ 14192 * offset is odd. Therefore all valid SQ instructions can execute normally. 14193 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish 14194 * between SQ and RDHWR, as the Linux kernel does. 14195 */ 14196 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx) 14197 { 14198 int base = extract32(ctx->opcode, 21, 5); 14199 int rt = extract32(ctx->opcode, 16, 5); 14200 int offset = extract32(ctx->opcode, 0, 16); 14201 14202 #ifdef CONFIG_USER_ONLY 14203 uint32_t op1 = MASK_SPECIAL3(ctx->opcode); 14204 uint32_t op2 = extract32(ctx->opcode, 6, 5); 14205 14206 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) { 14207 int rd = extract32(ctx->opcode, 11, 5); 14208 14209 gen_rdhwr(ctx, rt, rd, 0); 14210 return; 14211 } 14212 #endif 14213 14214 gen_mmi_sq(ctx, base, rt, offset); 14215 } 14216 14217 #endif 14218 14219 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) 14220 { 14221 int rs, rt, rd, sa; 14222 uint32_t op1, op2; 14223 int16_t imm; 14224 14225 rs = (ctx->opcode >> 21) & 0x1f; 14226 rt = (ctx->opcode >> 16) & 0x1f; 14227 rd = (ctx->opcode >> 11) & 0x1f; 14228 sa = (ctx->opcode >> 6) & 0x1f; 14229 imm = sextract32(ctx->opcode, 7, 9); 14230 14231 op1 = MASK_SPECIAL3(ctx->opcode); 14232 14233 /* 14234 * EVA loads and stores overlap Loongson 2E instructions decoded by 14235 * decode_opc_special3_legacy(), so be careful to allow their decoding when 14236 * EVA is absent. 14237 */ 14238 if (ctx->eva) { 14239 switch (op1) { 14240 case OPC_LWLE: 14241 case OPC_LWRE: 14242 case OPC_LBUE: 14243 case OPC_LHUE: 14244 case OPC_LBE: 14245 case OPC_LHE: 14246 case OPC_LLE: 14247 case OPC_LWE: 14248 check_cp0_enabled(ctx); 14249 gen_ld(ctx, op1, rt, rs, imm); 14250 return; 14251 case OPC_SWLE: 14252 case OPC_SWRE: 14253 case OPC_SBE: 14254 case OPC_SHE: 14255 case OPC_SWE: 14256 check_cp0_enabled(ctx); 14257 gen_st(ctx, op1, rt, rs, imm); 14258 return; 14259 case OPC_SCE: 14260 check_cp0_enabled(ctx); 14261 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, true); 14262 return; 14263 case OPC_CACHEE: 14264 check_eva(ctx); 14265 check_cp0_enabled(ctx); 14266 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14267 gen_cache_operation(ctx, rt, rs, imm); 14268 } 14269 return; 14270 case OPC_PREFE: 14271 check_cp0_enabled(ctx); 14272 /* Treat as NOP. */ 14273 return; 14274 } 14275 } 14276 14277 switch (op1) { 14278 case OPC_EXT: 14279 case OPC_INS: 14280 check_insn(ctx, ISA_MIPS_R2); 14281 gen_bitops(ctx, op1, rt, rs, sa, rd); 14282 break; 14283 case OPC_BSHFL: 14284 op2 = MASK_BSHFL(ctx->opcode); 14285 switch (op2) { 14286 case OPC_ALIGN: 14287 case OPC_ALIGN_1: 14288 case OPC_ALIGN_2: 14289 case OPC_ALIGN_3: 14290 case OPC_BITSWAP: 14291 check_insn(ctx, ISA_MIPS_R6); 14292 decode_opc_special3_r6(env, ctx); 14293 break; 14294 default: 14295 check_insn(ctx, ISA_MIPS_R2); 14296 gen_bshfl(ctx, op2, rt, rd); 14297 break; 14298 } 14299 break; 14300 #if defined(TARGET_MIPS64) 14301 case OPC_DEXTM: 14302 case OPC_DEXTU: 14303 case OPC_DEXT: 14304 case OPC_DINSM: 14305 case OPC_DINSU: 14306 case OPC_DINS: 14307 check_insn(ctx, ISA_MIPS_R2); 14308 check_mips_64(ctx); 14309 gen_bitops(ctx, op1, rt, rs, sa, rd); 14310 break; 14311 case OPC_DBSHFL: 14312 op2 = MASK_DBSHFL(ctx->opcode); 14313 switch (op2) { 14314 case OPC_DALIGN: 14315 case OPC_DALIGN_1: 14316 case OPC_DALIGN_2: 14317 case OPC_DALIGN_3: 14318 case OPC_DALIGN_4: 14319 case OPC_DALIGN_5: 14320 case OPC_DALIGN_6: 14321 case OPC_DALIGN_7: 14322 case OPC_DBITSWAP: 14323 check_insn(ctx, ISA_MIPS_R6); 14324 decode_opc_special3_r6(env, ctx); 14325 break; 14326 default: 14327 check_insn(ctx, ISA_MIPS_R2); 14328 check_mips_64(ctx); 14329 op2 = MASK_DBSHFL(ctx->opcode); 14330 gen_bshfl(ctx, op2, rt, rd); 14331 break; 14332 } 14333 break; 14334 #endif 14335 case OPC_RDHWR: 14336 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3)); 14337 break; 14338 case OPC_FORK: 14339 check_mt(ctx); 14340 { 14341 TCGv t0 = tcg_temp_new(); 14342 TCGv t1 = tcg_temp_new(); 14343 14344 gen_load_gpr(t0, rt); 14345 gen_load_gpr(t1, rs); 14346 gen_helper_fork(t0, t1); 14347 } 14348 break; 14349 case OPC_YIELD: 14350 check_mt(ctx); 14351 { 14352 TCGv t0 = tcg_temp_new(); 14353 14354 gen_load_gpr(t0, rs); 14355 gen_helper_yield(t0, tcg_env, t0); 14356 gen_store_gpr(t0, rd); 14357 } 14358 break; 14359 default: 14360 if (ctx->insn_flags & ISA_MIPS_R6) { 14361 decode_opc_special3_r6(env, ctx); 14362 } else { 14363 decode_opc_special3_legacy(env, ctx); 14364 } 14365 } 14366 } 14367 14368 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) 14369 { 14370 int32_t offset; 14371 int rs, rt, rd, sa; 14372 uint32_t op, op1; 14373 int16_t imm; 14374 14375 op = MASK_OP_MAJOR(ctx->opcode); 14376 rs = (ctx->opcode >> 21) & 0x1f; 14377 rt = (ctx->opcode >> 16) & 0x1f; 14378 rd = (ctx->opcode >> 11) & 0x1f; 14379 sa = (ctx->opcode >> 6) & 0x1f; 14380 imm = (int16_t)ctx->opcode; 14381 switch (op) { 14382 case OPC_SPECIAL: 14383 decode_opc_special(env, ctx); 14384 break; 14385 case OPC_SPECIAL2: 14386 #if defined(TARGET_MIPS64) 14387 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { 14388 decode_mmi(env, ctx); 14389 break; 14390 } 14391 #endif 14392 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) { 14393 if (decode_ase_mxu(ctx, ctx->opcode)) { 14394 break; 14395 } 14396 } 14397 decode_opc_special2_legacy(env, ctx); 14398 break; 14399 case OPC_SPECIAL3: 14400 #if defined(TARGET_MIPS64) 14401 if (ctx->insn_flags & INSN_R5900) { 14402 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ 14403 } else { 14404 decode_opc_special3(env, ctx); 14405 } 14406 #else 14407 decode_opc_special3(env, ctx); 14408 #endif 14409 break; 14410 case OPC_REGIMM: 14411 op1 = MASK_REGIMM(ctx->opcode); 14412 switch (op1) { 14413 case OPC_BLTZL: /* REGIMM branches */ 14414 case OPC_BGEZL: 14415 case OPC_BLTZALL: 14416 case OPC_BGEZALL: 14417 check_insn(ctx, ISA_MIPS2); 14418 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14419 /* Fallthrough */ 14420 case OPC_BLTZ: 14421 case OPC_BGEZ: 14422 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 14423 break; 14424 case OPC_BLTZAL: 14425 case OPC_BGEZAL: 14426 if (ctx->insn_flags & ISA_MIPS_R6) { 14427 if (rs == 0) { 14428 /* OPC_NAL, OPC_BAL */ 14429 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); 14430 } else { 14431 gen_reserved_instruction(ctx); 14432 } 14433 } else { 14434 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 14435 } 14436 break; 14437 case OPC_TGEI: /* REGIMM traps */ 14438 case OPC_TGEIU: 14439 case OPC_TLTI: 14440 case OPC_TLTIU: 14441 case OPC_TEQI: 14442 case OPC_TNEI: 14443 check_insn(ctx, ISA_MIPS2); 14444 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14445 gen_trap(ctx, op1, rs, -1, imm, 0); 14446 break; 14447 case OPC_SIGRIE: 14448 check_insn(ctx, ISA_MIPS_R6); 14449 gen_reserved_instruction(ctx); 14450 break; 14451 case OPC_SYNCI: 14452 check_insn(ctx, ISA_MIPS_R2); 14453 /* 14454 * Break the TB to be able to sync copied instructions 14455 * immediately. 14456 */ 14457 ctx->base.is_jmp = DISAS_STOP; 14458 break; 14459 case OPC_BPOSGE32: /* MIPS DSP branch */ 14460 #if defined(TARGET_MIPS64) 14461 case OPC_BPOSGE64: 14462 #endif 14463 check_dsp(ctx); 14464 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); 14465 break; 14466 #if defined(TARGET_MIPS64) 14467 case OPC_DAHI: 14468 check_insn(ctx, ISA_MIPS_R6); 14469 check_mips_64(ctx); 14470 if (rs != 0) { 14471 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); 14472 } 14473 break; 14474 case OPC_DATI: 14475 check_insn(ctx, ISA_MIPS_R6); 14476 check_mips_64(ctx); 14477 if (rs != 0) { 14478 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); 14479 } 14480 break; 14481 #endif 14482 default: /* Invalid */ 14483 MIPS_INVAL("regimm"); 14484 gen_reserved_instruction(ctx); 14485 break; 14486 } 14487 break; 14488 case OPC_CP0: 14489 check_cp0_enabled(ctx); 14490 op1 = MASK_CP0(ctx->opcode); 14491 switch (op1) { 14492 case OPC_MFC0: 14493 case OPC_MTC0: 14494 case OPC_MFTR: 14495 case OPC_MTTR: 14496 case OPC_MFHC0: 14497 case OPC_MTHC0: 14498 #if defined(TARGET_MIPS64) 14499 case OPC_DMFC0: 14500 case OPC_DMTC0: 14501 #endif 14502 #ifndef CONFIG_USER_ONLY 14503 gen_cp0(env, ctx, op1, rt, rd); 14504 #endif /* !CONFIG_USER_ONLY */ 14505 break; 14506 case OPC_C0: 14507 case OPC_C0_1: 14508 case OPC_C0_2: 14509 case OPC_C0_3: 14510 case OPC_C0_4: 14511 case OPC_C0_5: 14512 case OPC_C0_6: 14513 case OPC_C0_7: 14514 case OPC_C0_8: 14515 case OPC_C0_9: 14516 case OPC_C0_A: 14517 case OPC_C0_B: 14518 case OPC_C0_C: 14519 case OPC_C0_D: 14520 case OPC_C0_E: 14521 case OPC_C0_F: 14522 #ifndef CONFIG_USER_ONLY 14523 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 14524 #endif /* !CONFIG_USER_ONLY */ 14525 break; 14526 case OPC_MFMC0: 14527 #ifndef CONFIG_USER_ONLY 14528 { 14529 uint32_t op2; 14530 TCGv t0 = tcg_temp_new(); 14531 14532 op2 = MASK_MFMC0(ctx->opcode); 14533 switch (op2) { 14534 case OPC_DMT: 14535 check_cp0_mt(ctx); 14536 gen_helper_dmt(t0); 14537 gen_store_gpr(t0, rt); 14538 break; 14539 case OPC_EMT: 14540 check_cp0_mt(ctx); 14541 gen_helper_emt(t0); 14542 gen_store_gpr(t0, rt); 14543 break; 14544 case OPC_DVPE: 14545 check_cp0_mt(ctx); 14546 gen_helper_dvpe(t0, tcg_env); 14547 gen_store_gpr(t0, rt); 14548 break; 14549 case OPC_EVPE: 14550 check_cp0_mt(ctx); 14551 gen_helper_evpe(t0, tcg_env); 14552 gen_store_gpr(t0, rt); 14553 break; 14554 case OPC_DVP: 14555 check_insn(ctx, ISA_MIPS_R6); 14556 if (ctx->vp) { 14557 gen_helper_dvp(t0, tcg_env); 14558 gen_store_gpr(t0, rt); 14559 } 14560 break; 14561 case OPC_EVP: 14562 check_insn(ctx, ISA_MIPS_R6); 14563 if (ctx->vp) { 14564 gen_helper_evp(t0, tcg_env); 14565 gen_store_gpr(t0, rt); 14566 } 14567 break; 14568 case OPC_DI: 14569 check_insn(ctx, ISA_MIPS_R2); 14570 save_cpu_state(ctx, 1); 14571 gen_helper_di(t0, tcg_env); 14572 gen_store_gpr(t0, rt); 14573 /* 14574 * Stop translation as we may have switched 14575 * the execution mode. 14576 */ 14577 ctx->base.is_jmp = DISAS_STOP; 14578 break; 14579 case OPC_EI: 14580 check_insn(ctx, ISA_MIPS_R2); 14581 save_cpu_state(ctx, 1); 14582 gen_helper_ei(t0, tcg_env); 14583 gen_store_gpr(t0, rt); 14584 /* 14585 * DISAS_STOP isn't sufficient, we need to ensure we break 14586 * out of translated code to check for pending interrupts. 14587 */ 14588 gen_save_pc(ctx->base.pc_next + 4); 14589 ctx->base.is_jmp = DISAS_EXIT; 14590 break; 14591 default: /* Invalid */ 14592 MIPS_INVAL("mfmc0"); 14593 gen_reserved_instruction(ctx); 14594 break; 14595 } 14596 } 14597 #endif /* !CONFIG_USER_ONLY */ 14598 break; 14599 case OPC_RDPGPR: 14600 check_insn(ctx, ISA_MIPS_R2); 14601 gen_load_srsgpr(rt, rd); 14602 break; 14603 case OPC_WRPGPR: 14604 check_insn(ctx, ISA_MIPS_R2); 14605 gen_store_srsgpr(rt, rd); 14606 break; 14607 default: 14608 MIPS_INVAL("cp0"); 14609 gen_reserved_instruction(ctx); 14610 break; 14611 } 14612 break; 14613 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */ 14614 if (ctx->insn_flags & ISA_MIPS_R6) { 14615 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */ 14616 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14617 } else { 14618 /* OPC_ADDI */ 14619 /* Arithmetic with immediate opcode */ 14620 gen_arith_imm(ctx, op, rt, rs, imm); 14621 } 14622 break; 14623 case OPC_ADDIU: 14624 gen_arith_imm(ctx, op, rt, rs, imm); 14625 break; 14626 case OPC_SLTI: /* Set on less than with immediate opcode */ 14627 case OPC_SLTIU: 14628 gen_slt_imm(ctx, op, rt, rs, imm); 14629 break; 14630 case OPC_ANDI: /* Arithmetic with immediate opcode */ 14631 case OPC_LUI: /* OPC_AUI */ 14632 case OPC_ORI: 14633 case OPC_XORI: 14634 gen_logic_imm(ctx, op, rt, rs, imm); 14635 break; 14636 case OPC_J: /* Jump */ 14637 case OPC_JAL: 14638 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 14639 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 14640 break; 14641 /* Branch */ 14642 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ 14643 if (ctx->insn_flags & ISA_MIPS_R6) { 14644 if (rt == 0) { 14645 gen_reserved_instruction(ctx); 14646 break; 14647 } 14648 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */ 14649 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14650 } else { 14651 /* OPC_BLEZL */ 14652 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14653 } 14654 break; 14655 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ 14656 if (ctx->insn_flags & ISA_MIPS_R6) { 14657 if (rt == 0) { 14658 gen_reserved_instruction(ctx); 14659 break; 14660 } 14661 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */ 14662 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14663 } else { 14664 /* OPC_BGTZL */ 14665 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14666 } 14667 break; 14668 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */ 14669 if (rt == 0) { 14670 /* OPC_BLEZ */ 14671 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14672 } else { 14673 check_insn(ctx, ISA_MIPS_R6); 14674 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */ 14675 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14676 } 14677 break; 14678 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */ 14679 if (rt == 0) { 14680 /* OPC_BGTZ */ 14681 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14682 } else { 14683 check_insn(ctx, ISA_MIPS_R6); 14684 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */ 14685 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 14686 } 14687 break; 14688 case OPC_BEQL: 14689 case OPC_BNEL: 14690 check_insn(ctx, ISA_MIPS2); 14691 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14692 /* Fallthrough */ 14693 case OPC_BEQ: 14694 case OPC_BNE: 14695 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 14696 break; 14697 case OPC_LL: /* Load and stores */ 14698 check_insn(ctx, ISA_MIPS2); 14699 if (ctx->insn_flags & INSN_R5900) { 14700 check_insn_opc_user_only(ctx, INSN_R5900); 14701 } 14702 /* Fallthrough */ 14703 case OPC_LWL: 14704 case OPC_LWR: 14705 case OPC_LB: 14706 case OPC_LH: 14707 case OPC_LW: 14708 case OPC_LWPC: 14709 case OPC_LBU: 14710 case OPC_LHU: 14711 gen_ld(ctx, op, rt, rs, imm); 14712 break; 14713 case OPC_SWL: 14714 case OPC_SWR: 14715 case OPC_SB: 14716 case OPC_SH: 14717 case OPC_SW: 14718 gen_st(ctx, op, rt, rs, imm); 14719 break; 14720 case OPC_SC: 14721 check_insn(ctx, ISA_MIPS2); 14722 if (ctx->insn_flags & INSN_R5900) { 14723 check_insn_opc_user_only(ctx, INSN_R5900); 14724 } 14725 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false); 14726 break; 14727 case OPC_CACHE: 14728 check_cp0_enabled(ctx); 14729 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 14730 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14731 gen_cache_operation(ctx, rt, rs, imm); 14732 } 14733 /* Treat as NOP. */ 14734 break; 14735 case OPC_PREF: 14736 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900); 14737 /* Treat as NOP. */ 14738 break; 14739 14740 /* Floating point (COP1). */ 14741 case OPC_LWC1: 14742 case OPC_LDC1: 14743 case OPC_SWC1: 14744 case OPC_SDC1: 14745 gen_cop1_ldst(ctx, op, rt, rs, imm); 14746 break; 14747 14748 case OPC_CP1: 14749 op1 = MASK_CP1(ctx->opcode); 14750 14751 switch (op1) { 14752 case OPC_MFHC1: 14753 case OPC_MTHC1: 14754 check_cp1_enabled(ctx); 14755 check_insn(ctx, ISA_MIPS_R2); 14756 /* fall through */ 14757 case OPC_MFC1: 14758 case OPC_CFC1: 14759 case OPC_MTC1: 14760 case OPC_CTC1: 14761 check_cp1_enabled(ctx); 14762 gen_cp1(ctx, op1, rt, rd); 14763 break; 14764 #if defined(TARGET_MIPS64) 14765 case OPC_DMFC1: 14766 case OPC_DMTC1: 14767 check_cp1_enabled(ctx); 14768 check_insn(ctx, ISA_MIPS3); 14769 check_mips_64(ctx); 14770 gen_cp1(ctx, op1, rt, rd); 14771 break; 14772 #endif 14773 case OPC_BC1EQZ: /* OPC_BC1ANY2 */ 14774 check_cp1_enabled(ctx); 14775 if (ctx->insn_flags & ISA_MIPS_R6) { 14776 /* OPC_BC1EQZ */ 14777 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 14778 rt, imm << 2, 4); 14779 } else { 14780 /* OPC_BC1ANY2 */ 14781 check_cop1x(ctx); 14782 check_insn(ctx, ASE_MIPS3D); 14783 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 14784 (rt >> 2) & 0x7, imm << 2); 14785 } 14786 break; 14787 case OPC_BC1NEZ: 14788 check_cp1_enabled(ctx); 14789 check_insn(ctx, ISA_MIPS_R6); 14790 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 14791 rt, imm << 2, 4); 14792 break; 14793 case OPC_BC1ANY4: 14794 check_cp1_enabled(ctx); 14795 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14796 check_cop1x(ctx); 14797 check_insn(ctx, ASE_MIPS3D); 14798 /* fall through */ 14799 case OPC_BC1: 14800 check_cp1_enabled(ctx); 14801 check_insn_opc_removed(ctx, ISA_MIPS_R6); 14802 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 14803 (rt >> 2) & 0x7, imm << 2); 14804 break; 14805 case OPC_PS_FMT: 14806 check_ps(ctx); 14807 /* fall through */ 14808 case OPC_S_FMT: 14809 case OPC_D_FMT: 14810 check_cp1_enabled(ctx); 14811 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 14812 (imm >> 8) & 0x7); 14813 break; 14814 case OPC_W_FMT: 14815 case OPC_L_FMT: 14816 { 14817 int r6_op = ctx->opcode & FOP(0x3f, 0x1f); 14818 check_cp1_enabled(ctx); 14819 if (ctx->insn_flags & ISA_MIPS_R6) { 14820 switch (r6_op) { 14821 case R6_OPC_CMP_AF_S: 14822 case R6_OPC_CMP_UN_S: 14823 case R6_OPC_CMP_EQ_S: 14824 case R6_OPC_CMP_UEQ_S: 14825 case R6_OPC_CMP_LT_S: 14826 case R6_OPC_CMP_ULT_S: 14827 case R6_OPC_CMP_LE_S: 14828 case R6_OPC_CMP_ULE_S: 14829 case R6_OPC_CMP_SAF_S: 14830 case R6_OPC_CMP_SUN_S: 14831 case R6_OPC_CMP_SEQ_S: 14832 case R6_OPC_CMP_SEUQ_S: 14833 case R6_OPC_CMP_SLT_S: 14834 case R6_OPC_CMP_SULT_S: 14835 case R6_OPC_CMP_SLE_S: 14836 case R6_OPC_CMP_SULE_S: 14837 case R6_OPC_CMP_OR_S: 14838 case R6_OPC_CMP_UNE_S: 14839 case R6_OPC_CMP_NE_S: 14840 case R6_OPC_CMP_SOR_S: 14841 case R6_OPC_CMP_SUNE_S: 14842 case R6_OPC_CMP_SNE_S: 14843 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa); 14844 break; 14845 case R6_OPC_CMP_AF_D: 14846 case R6_OPC_CMP_UN_D: 14847 case R6_OPC_CMP_EQ_D: 14848 case R6_OPC_CMP_UEQ_D: 14849 case R6_OPC_CMP_LT_D: 14850 case R6_OPC_CMP_ULT_D: 14851 case R6_OPC_CMP_LE_D: 14852 case R6_OPC_CMP_ULE_D: 14853 case R6_OPC_CMP_SAF_D: 14854 case R6_OPC_CMP_SUN_D: 14855 case R6_OPC_CMP_SEQ_D: 14856 case R6_OPC_CMP_SEUQ_D: 14857 case R6_OPC_CMP_SLT_D: 14858 case R6_OPC_CMP_SULT_D: 14859 case R6_OPC_CMP_SLE_D: 14860 case R6_OPC_CMP_SULE_D: 14861 case R6_OPC_CMP_OR_D: 14862 case R6_OPC_CMP_UNE_D: 14863 case R6_OPC_CMP_NE_D: 14864 case R6_OPC_CMP_SOR_D: 14865 case R6_OPC_CMP_SUNE_D: 14866 case R6_OPC_CMP_SNE_D: 14867 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa); 14868 break; 14869 default: 14870 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), 14871 rt, rd, sa, (imm >> 8) & 0x7); 14872 14873 break; 14874 } 14875 } else { 14876 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 14877 (imm >> 8) & 0x7); 14878 } 14879 break; 14880 } 14881 default: 14882 MIPS_INVAL("cp1"); 14883 gen_reserved_instruction(ctx); 14884 break; 14885 } 14886 break; 14887 14888 /* Compact branches [R6] and COP2 [non-R6] */ 14889 case OPC_BC: /* OPC_LWC2 */ 14890 case OPC_BALC: /* OPC_SWC2 */ 14891 if (ctx->insn_flags & ISA_MIPS_R6) { 14892 /* OPC_BC, OPC_BALC */ 14893 gen_compute_compact_branch(ctx, op, 0, 0, 14894 sextract32(ctx->opcode << 2, 0, 28)); 14895 } else if (ctx->insn_flags & ASE_LEXT) { 14896 gen_loongson_lswc2(ctx, rt, rs, rd); 14897 } else { 14898 /* OPC_LWC2, OPC_SWC2 */ 14899 /* COP2: Not implemented. */ 14900 generate_exception_err(ctx, EXCP_CpU, 2); 14901 } 14902 break; 14903 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */ 14904 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */ 14905 if (ctx->insn_flags & ISA_MIPS_R6) { 14906 if (rs != 0) { 14907 /* OPC_BEQZC, OPC_BNEZC */ 14908 gen_compute_compact_branch(ctx, op, rs, 0, 14909 sextract32(ctx->opcode << 2, 0, 23)); 14910 } else { 14911 /* OPC_JIC, OPC_JIALC */ 14912 gen_compute_compact_branch(ctx, op, 0, rt, imm); 14913 } 14914 } else if (ctx->insn_flags & ASE_LEXT) { 14915 gen_loongson_lsdc2(ctx, rt, rs, rd); 14916 } else { 14917 /* OPC_LWC2, OPC_SWC2 */ 14918 /* COP2: Not implemented. */ 14919 generate_exception_err(ctx, EXCP_CpU, 2); 14920 } 14921 break; 14922 case OPC_CP2: 14923 check_insn(ctx, ASE_LMMI); 14924 /* Note that these instructions use different fields. */ 14925 gen_loongson_multimedia(ctx, sa, rd, rt); 14926 break; 14927 14928 case OPC_CP3: 14929 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 14930 check_cp1_enabled(ctx); 14931 op1 = MASK_CP3(ctx->opcode); 14932 switch (op1) { 14933 case OPC_LUXC1: 14934 case OPC_SUXC1: 14935 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 14936 /* Fallthrough */ 14937 case OPC_LWXC1: 14938 case OPC_LDXC1: 14939 case OPC_SWXC1: 14940 case OPC_SDXC1: 14941 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14942 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 14943 break; 14944 case OPC_PREFX: 14945 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14946 /* Treat as NOP. */ 14947 break; 14948 case OPC_ALNV_PS: 14949 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 14950 /* Fallthrough */ 14951 case OPC_MADD_S: 14952 case OPC_MADD_D: 14953 case OPC_MADD_PS: 14954 case OPC_MSUB_S: 14955 case OPC_MSUB_D: 14956 case OPC_MSUB_PS: 14957 case OPC_NMADD_S: 14958 case OPC_NMADD_D: 14959 case OPC_NMADD_PS: 14960 case OPC_NMSUB_S: 14961 case OPC_NMSUB_D: 14962 case OPC_NMSUB_PS: 14963 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 14964 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 14965 break; 14966 default: 14967 MIPS_INVAL("cp3"); 14968 gen_reserved_instruction(ctx); 14969 break; 14970 } 14971 } else { 14972 generate_exception_err(ctx, EXCP_CpU, 1); 14973 } 14974 break; 14975 14976 #if defined(TARGET_MIPS64) 14977 /* MIPS64 opcodes */ 14978 case OPC_LLD: 14979 if (ctx->insn_flags & INSN_R5900) { 14980 check_insn_opc_user_only(ctx, INSN_R5900); 14981 } 14982 /* fall through */ 14983 case OPC_LDL: 14984 case OPC_LDR: 14985 case OPC_LWU: 14986 case OPC_LD: 14987 check_insn(ctx, ISA_MIPS3); 14988 check_mips_64(ctx); 14989 gen_ld(ctx, op, rt, rs, imm); 14990 break; 14991 case OPC_SDL: 14992 case OPC_SDR: 14993 case OPC_SD: 14994 check_insn(ctx, ISA_MIPS3); 14995 check_mips_64(ctx); 14996 gen_st(ctx, op, rt, rs, imm); 14997 break; 14998 case OPC_SCD: 14999 check_insn(ctx, ISA_MIPS3); 15000 if (ctx->insn_flags & INSN_R5900) { 15001 check_insn_opc_user_only(ctx, INSN_R5900); 15002 } 15003 check_mips_64(ctx); 15004 gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false); 15005 break; 15006 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ 15007 if (ctx->insn_flags & ISA_MIPS_R6) { 15008 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */ 15009 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15010 } else { 15011 /* OPC_DADDI */ 15012 check_insn(ctx, ISA_MIPS3); 15013 check_mips_64(ctx); 15014 gen_arith_imm(ctx, op, rt, rs, imm); 15015 } 15016 break; 15017 case OPC_DADDIU: 15018 check_insn(ctx, ISA_MIPS3); 15019 check_mips_64(ctx); 15020 gen_arith_imm(ctx, op, rt, rs, imm); 15021 break; 15022 #else 15023 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 15024 if (ctx->insn_flags & ISA_MIPS_R6) { 15025 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15026 } else { 15027 MIPS_INVAL("major opcode"); 15028 gen_reserved_instruction(ctx); 15029 } 15030 break; 15031 #endif 15032 case OPC_DAUI: /* OPC_JALX */ 15033 if (ctx->insn_flags & ISA_MIPS_R6) { 15034 #if defined(TARGET_MIPS64) 15035 /* OPC_DAUI */ 15036 check_mips_64(ctx); 15037 if (rs == 0) { 15038 generate_exception(ctx, EXCP_RI); 15039 } else if (rt != 0) { 15040 TCGv t0 = tcg_temp_new(); 15041 gen_load_gpr(t0, rs); 15042 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16); 15043 } 15044 #else 15045 gen_reserved_instruction(ctx); 15046 MIPS_INVAL("major opcode"); 15047 #endif 15048 } else { 15049 /* OPC_JALX */ 15050 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS); 15051 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 15052 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 15053 } 15054 break; 15055 case OPC_MDMX: 15056 /* MDMX: Not implemented. */ 15057 break; 15058 case OPC_PCREL: 15059 check_insn(ctx, ISA_MIPS_R6); 15060 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs); 15061 break; 15062 default: /* Invalid */ 15063 MIPS_INVAL("major opcode"); 15064 return false; 15065 } 15066 return true; 15067 } 15068 15069 static void decode_opc(CPUMIPSState *env, DisasContext *ctx) 15070 { 15071 /* make sure instructions are on a word boundary */ 15072 if (ctx->base.pc_next & 0x3) { 15073 env->CP0_BadVAddr = ctx->base.pc_next; 15074 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); 15075 return; 15076 } 15077 15078 /* Handle blikely not taken case */ 15079 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { 15080 TCGLabel *l1 = gen_new_label(); 15081 15082 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 15083 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 15084 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); 15085 gen_set_label(l1); 15086 } 15087 15088 /* Transition to the auto-generated decoder. */ 15089 15090 /* Vendor specific extensions */ 15091 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { 15092 return; 15093 } 15094 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) { 15095 return; 15096 } 15097 if (TARGET_LONG_BITS == 64 && decode_ext_loongson(ctx, ctx->opcode)) { 15098 return; 15099 } 15100 #if defined(TARGET_MIPS64) 15101 if (ase_lcsr_available(env) && decode_ase_lcsr(ctx, ctx->opcode)) { 15102 return; 15103 } 15104 if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) { 15105 return; 15106 } 15107 #endif 15108 15109 /* ISA extensions */ 15110 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) { 15111 return; 15112 } 15113 15114 /* ISA (from latest to oldest) */ 15115 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) { 15116 return; 15117 } 15118 15119 if (decode_opc_legacy(env, ctx)) { 15120 return; 15121 } 15122 15123 gen_reserved_instruction(ctx); 15124 } 15125 15126 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 15127 { 15128 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15129 CPUMIPSState *env = cpu_env(cs); 15130 15131 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; 15132 ctx->saved_pc = -1; 15133 ctx->insn_flags = env->insn_flags; 15134 ctx->CP0_Config0 = env->CP0_Config0; 15135 ctx->CP0_Config1 = env->CP0_Config1; 15136 ctx->CP0_Config2 = env->CP0_Config2; 15137 ctx->CP0_Config3 = env->CP0_Config3; 15138 ctx->CP0_Config5 = env->CP0_Config5; 15139 ctx->btarget = 0; 15140 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; 15141 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; 15142 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3; 15143 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1; 15144 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1; 15145 ctx->PAMask = env->PAMask; 15146 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; 15147 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; 15148 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1; 15149 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift; 15150 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; 15151 /* Restore delay slot state from the tb context. */ 15152 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ 15153 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; 15154 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || 15155 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); 15156 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1; 15157 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; 15158 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; 15159 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; 15160 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1; 15161 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3; 15162 restore_cpu_state(env, ctx); 15163 #ifdef CONFIG_USER_ONLY 15164 ctx->mem_idx = MIPS_HFLAG_UM; 15165 #else 15166 ctx->mem_idx = hflags_mmu_index(ctx->hflags); 15167 #endif 15168 ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) && 15169 (ctx->insn_flags & (ISA_MIPS_R6 | 15170 INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN; 15171 15172 /* 15173 * Execute a branch and its delay slot as a single instruction. 15174 * This is what GDB expects and is consistent with what the 15175 * hardware does (e.g. if a delay slot instruction faults, the 15176 * reported PC is the PC of the branch). 15177 */ 15178 if ((tb_cflags(ctx->base.tb) & CF_SINGLE_STEP) && 15179 (ctx->hflags & MIPS_HFLAG_BMASK)) { 15180 ctx->base.max_insns = 2; 15181 } 15182 15183 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, 15184 ctx->hflags); 15185 } 15186 15187 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) 15188 { 15189 } 15190 15191 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 15192 { 15193 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15194 15195 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, 15196 ctx->btarget); 15197 } 15198 15199 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 15200 { 15201 CPUMIPSState *env = cpu_env(cs); 15202 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15203 int insn_bytes; 15204 int is_slot; 15205 15206 is_slot = ctx->hflags & MIPS_HFLAG_BMASK; 15207 if (ctx->insn_flags & ISA_NANOMIPS32) { 15208 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15209 insn_bytes = decode_isa_nanomips(env, ctx); 15210 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) { 15211 ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next); 15212 insn_bytes = 4; 15213 decode_opc(env, ctx); 15214 } else if (ctx->insn_flags & ASE_MICROMIPS) { 15215 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15216 insn_bytes = decode_isa_micromips(env, ctx); 15217 } else if (ctx->insn_flags & ASE_MIPS16) { 15218 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next); 15219 insn_bytes = decode_ase_mips16e(env, ctx); 15220 } else { 15221 gen_reserved_instruction(ctx); 15222 g_assert(ctx->base.is_jmp == DISAS_NORETURN); 15223 return; 15224 } 15225 15226 if (ctx->hflags & MIPS_HFLAG_BMASK) { 15227 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 | 15228 MIPS_HFLAG_FBNSLOT))) { 15229 /* 15230 * Force to generate branch as there is neither delay nor 15231 * forbidden slot. 15232 */ 15233 is_slot = 1; 15234 } 15235 if ((ctx->hflags & MIPS_HFLAG_M16) && 15236 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) { 15237 /* 15238 * Force to generate branch as microMIPS R6 doesn't restrict 15239 * branches in the forbidden slot. 15240 */ 15241 is_slot = 1; 15242 } 15243 } 15244 if (is_slot) { 15245 gen_branch(ctx, insn_bytes); 15246 } 15247 if (ctx->base.is_jmp == DISAS_SEMIHOST) { 15248 generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes); 15249 } 15250 ctx->base.pc_next += insn_bytes; 15251 15252 if (ctx->base.is_jmp != DISAS_NEXT) { 15253 return; 15254 } 15255 15256 /* 15257 * End the TB on (most) page crossings. 15258 * See mips_tr_init_disas_context about single-stepping a branch 15259 * together with its delay slot. 15260 */ 15261 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE 15262 && !(tb_cflags(ctx->base.tb) & CF_SINGLE_STEP)) { 15263 ctx->base.is_jmp = DISAS_TOO_MANY; 15264 } 15265 } 15266 15267 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 15268 { 15269 DisasContext *ctx = container_of(dcbase, DisasContext, base); 15270 15271 switch (ctx->base.is_jmp) { 15272 case DISAS_STOP: 15273 gen_save_pc(ctx->base.pc_next); 15274 tcg_gen_lookup_and_goto_ptr(); 15275 break; 15276 case DISAS_NEXT: 15277 case DISAS_TOO_MANY: 15278 save_cpu_state(ctx, 0); 15279 gen_goto_tb(ctx, 0, ctx->base.pc_next); 15280 break; 15281 case DISAS_EXIT: 15282 tcg_gen_exit_tb(NULL, 0); 15283 break; 15284 case DISAS_NORETURN: 15285 break; 15286 default: 15287 g_assert_not_reached(); 15288 } 15289 } 15290 15291 static const TranslatorOps mips_tr_ops = { 15292 .init_disas_context = mips_tr_init_disas_context, 15293 .tb_start = mips_tr_tb_start, 15294 .insn_start = mips_tr_insn_start, 15295 .translate_insn = mips_tr_translate_insn, 15296 .tb_stop = mips_tr_tb_stop, 15297 }; 15298 15299 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, 15300 vaddr pc, void *host_pc) 15301 { 15302 DisasContext ctx; 15303 15304 translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base); 15305 } 15306 15307 void mips_tcg_init(void) 15308 { 15309 cpu_gpr[0] = NULL; 15310 for (unsigned i = 1; i < 32; i++) 15311 cpu_gpr[i] = tcg_global_mem_new(tcg_env, 15312 offsetof(CPUMIPSState, 15313 active_tc.gpr[i]), 15314 regnames[i]); 15315 #if defined(TARGET_MIPS64) 15316 cpu_gpr_hi[0] = NULL; 15317 15318 for (unsigned i = 1; i < 32; i++) { 15319 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]); 15320 15321 cpu_gpr_hi[i] = tcg_global_mem_new_i64(tcg_env, 15322 offsetof(CPUMIPSState, 15323 active_tc.gpr_hi[i]), 15324 rname); 15325 } 15326 #endif /* !TARGET_MIPS64 */ 15327 for (unsigned i = 0; i < 32; i++) { 15328 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); 15329 15330 fpu_f64[i] = tcg_global_mem_new_i64(tcg_env, off, fregnames[i]); 15331 } 15332 msa_translate_init(); 15333 cpu_PC = tcg_global_mem_new(tcg_env, 15334 offsetof(CPUMIPSState, active_tc.PC), "PC"); 15335 for (unsigned i = 0; i < MIPS_DSP_ACC; i++) { 15336 cpu_HI[i] = tcg_global_mem_new(tcg_env, 15337 offsetof(CPUMIPSState, active_tc.HI[i]), 15338 regnames_HI[i]); 15339 cpu_LO[i] = tcg_global_mem_new(tcg_env, 15340 offsetof(CPUMIPSState, active_tc.LO[i]), 15341 regnames_LO[i]); 15342 } 15343 cpu_dspctrl = tcg_global_mem_new(tcg_env, 15344 offsetof(CPUMIPSState, 15345 active_tc.DSPControl), 15346 "DSPControl"); 15347 bcond = tcg_global_mem_new(tcg_env, 15348 offsetof(CPUMIPSState, bcond), "bcond"); 15349 btarget = tcg_global_mem_new(tcg_env, 15350 offsetof(CPUMIPSState, btarget), "btarget"); 15351 hflags = tcg_global_mem_new_i32(tcg_env, 15352 offsetof(CPUMIPSState, hflags), "hflags"); 15353 15354 fpu_fcr0 = tcg_global_mem_new_i32(tcg_env, 15355 offsetof(CPUMIPSState, active_fpu.fcr0), 15356 "fcr0"); 15357 fpu_fcr31 = tcg_global_mem_new_i32(tcg_env, 15358 offsetof(CPUMIPSState, active_fpu.fcr31), 15359 "fcr31"); 15360 cpu_lladdr = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, lladdr), 15361 "lladdr"); 15362 cpu_llval = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, llval), 15363 "llval"); 15364 15365 if (TARGET_LONG_BITS == 32) { 15366 mxu_translate_init(); 15367 } 15368 } 15369 15370 void mips_restore_state_to_opc(CPUState *cs, 15371 const TranslationBlock *tb, 15372 const uint64_t *data) 15373 { 15374 CPUMIPSState *env = cpu_env(cs); 15375 15376 env->active_tc.PC = data[0]; 15377 env->hflags &= ~MIPS_HFLAG_BMASK; 15378 env->hflags |= data[1]; 15379 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) { 15380 case MIPS_HFLAG_BR: 15381 break; 15382 case MIPS_HFLAG_BC: 15383 case MIPS_HFLAG_BL: 15384 case MIPS_HFLAG_B: 15385 env->btarget = data[2]; 15386 break; 15387 } 15388 } 15389