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 "cpu.h" 27 #include "internal.h" 28 #include "tcg/tcg-op.h" 29 #include "exec/translator.h" 30 #include "exec/helper-proto.h" 31 #include "exec/helper-gen.h" 32 #include "semihosting/semihost.h" 33 34 #include "trace.h" 35 #include "trace-tcg.h" 36 #include "exec/translator.h" 37 #include "exec/log.h" 38 #include "qemu/qemu-print.h" 39 #include "fpu_helper.h" 40 #include "translate.h" 41 42 /* 43 * Many sysemu-only helpers are not reachable for user-only. 44 * Define stub generators here, so that we need not either sprinkle 45 * ifdefs through the translator, nor provide the helper function. 46 */ 47 #define STUB_HELPER(NAME, ...) \ 48 static inline void gen_helper_##NAME(__VA_ARGS__) \ 49 { g_assert_not_reached(); } 50 51 #ifdef CONFIG_USER_ONLY 52 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg) 53 #endif 54 55 enum { 56 /* indirect opcode tables */ 57 OPC_SPECIAL = (0x00 << 26), 58 OPC_REGIMM = (0x01 << 26), 59 OPC_CP0 = (0x10 << 26), 60 OPC_CP2 = (0x12 << 26), 61 OPC_CP3 = (0x13 << 26), 62 OPC_SPECIAL2 = (0x1C << 26), 63 OPC_SPECIAL3 = (0x1F << 26), 64 /* arithmetic with immediate */ 65 OPC_ADDI = (0x08 << 26), 66 OPC_ADDIU = (0x09 << 26), 67 OPC_SLTI = (0x0A << 26), 68 OPC_SLTIU = (0x0B << 26), 69 /* logic with immediate */ 70 OPC_ANDI = (0x0C << 26), 71 OPC_ORI = (0x0D << 26), 72 OPC_XORI = (0x0E << 26), 73 OPC_LUI = (0x0F << 26), 74 /* arithmetic with immediate */ 75 OPC_DADDI = (0x18 << 26), 76 OPC_DADDIU = (0x19 << 26), 77 /* Jump and branches */ 78 OPC_J = (0x02 << 26), 79 OPC_JAL = (0x03 << 26), 80 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */ 81 OPC_BEQL = (0x14 << 26), 82 OPC_BNE = (0x05 << 26), 83 OPC_BNEL = (0x15 << 26), 84 OPC_BLEZ = (0x06 << 26), 85 OPC_BLEZL = (0x16 << 26), 86 OPC_BGTZ = (0x07 << 26), 87 OPC_BGTZL = (0x17 << 26), 88 OPC_JALX = (0x1D << 26), 89 OPC_DAUI = (0x1D << 26), 90 /* Load and stores */ 91 OPC_LDL = (0x1A << 26), 92 OPC_LDR = (0x1B << 26), 93 OPC_LB = (0x20 << 26), 94 OPC_LH = (0x21 << 26), 95 OPC_LWL = (0x22 << 26), 96 OPC_LW = (0x23 << 26), 97 OPC_LWPC = OPC_LW | 0x5, 98 OPC_LBU = (0x24 << 26), 99 OPC_LHU = (0x25 << 26), 100 OPC_LWR = (0x26 << 26), 101 OPC_LWU = (0x27 << 26), 102 OPC_SB = (0x28 << 26), 103 OPC_SH = (0x29 << 26), 104 OPC_SWL = (0x2A << 26), 105 OPC_SW = (0x2B << 26), 106 OPC_SDL = (0x2C << 26), 107 OPC_SDR = (0x2D << 26), 108 OPC_SWR = (0x2E << 26), 109 OPC_LL = (0x30 << 26), 110 OPC_LLD = (0x34 << 26), 111 OPC_LD = (0x37 << 26), 112 OPC_LDPC = OPC_LD | 0x5, 113 OPC_SC = (0x38 << 26), 114 OPC_SCD = (0x3C << 26), 115 OPC_SD = (0x3F << 26), 116 /* Floating point load/store */ 117 OPC_LWC1 = (0x31 << 26), 118 OPC_LWC2 = (0x32 << 26), 119 OPC_LDC1 = (0x35 << 26), 120 OPC_LDC2 = (0x36 << 26), 121 OPC_SWC1 = (0x39 << 26), 122 OPC_SWC2 = (0x3A << 26), 123 OPC_SDC1 = (0x3D << 26), 124 OPC_SDC2 = (0x3E << 26), 125 /* Compact Branches */ 126 OPC_BLEZALC = (0x06 << 26), 127 OPC_BGEZALC = (0x06 << 26), 128 OPC_BGEUC = (0x06 << 26), 129 OPC_BGTZALC = (0x07 << 26), 130 OPC_BLTZALC = (0x07 << 26), 131 OPC_BLTUC = (0x07 << 26), 132 OPC_BOVC = (0x08 << 26), 133 OPC_BEQZALC = (0x08 << 26), 134 OPC_BEQC = (0x08 << 26), 135 OPC_BLEZC = (0x16 << 26), 136 OPC_BGEZC = (0x16 << 26), 137 OPC_BGEC = (0x16 << 26), 138 OPC_BGTZC = (0x17 << 26), 139 OPC_BLTZC = (0x17 << 26), 140 OPC_BLTC = (0x17 << 26), 141 OPC_BNVC = (0x18 << 26), 142 OPC_BNEZALC = (0x18 << 26), 143 OPC_BNEC = (0x18 << 26), 144 OPC_BC = (0x32 << 26), 145 OPC_BEQZC = (0x36 << 26), 146 OPC_JIC = (0x36 << 26), 147 OPC_BALC = (0x3A << 26), 148 OPC_BNEZC = (0x3E << 26), 149 OPC_JIALC = (0x3E << 26), 150 /* MDMX ASE specific */ 151 OPC_MDMX = (0x1E << 26), 152 /* Cache and prefetch */ 153 OPC_CACHE = (0x2F << 26), 154 OPC_PREF = (0x33 << 26), 155 /* PC-relative address computation / loads */ 156 OPC_PCREL = (0x3B << 26), 157 }; 158 159 /* PC-relative address computation / loads */ 160 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19))) 161 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16))) 162 enum { 163 /* Instructions determined by bits 19 and 20 */ 164 OPC_ADDIUPC = OPC_PCREL | (0 << 19), 165 R6_OPC_LWPC = OPC_PCREL | (1 << 19), 166 OPC_LWUPC = OPC_PCREL | (2 << 19), 167 168 /* Instructions determined by bits 16 ... 20 */ 169 OPC_AUIPC = OPC_PCREL | (0x1e << 16), 170 OPC_ALUIPC = OPC_PCREL | (0x1f << 16), 171 172 /* Other */ 173 R6_OPC_LDPC = OPC_PCREL | (6 << 18), 174 }; 175 176 /* MIPS special opcodes */ 177 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 178 179 enum { 180 /* Shifts */ 181 OPC_SLL = 0x00 | OPC_SPECIAL, 182 /* NOP is SLL r0, r0, 0 */ 183 /* SSNOP is SLL r0, r0, 1 */ 184 /* EHB is SLL r0, r0, 3 */ 185 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */ 186 OPC_ROTR = OPC_SRL | (1 << 21), 187 OPC_SRA = 0x03 | OPC_SPECIAL, 188 OPC_SLLV = 0x04 | OPC_SPECIAL, 189 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */ 190 OPC_ROTRV = OPC_SRLV | (1 << 6), 191 OPC_SRAV = 0x07 | OPC_SPECIAL, 192 OPC_DSLLV = 0x14 | OPC_SPECIAL, 193 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */ 194 OPC_DROTRV = OPC_DSRLV | (1 << 6), 195 OPC_DSRAV = 0x17 | OPC_SPECIAL, 196 OPC_DSLL = 0x38 | OPC_SPECIAL, 197 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */ 198 OPC_DROTR = OPC_DSRL | (1 << 21), 199 OPC_DSRA = 0x3B | OPC_SPECIAL, 200 OPC_DSLL32 = 0x3C | OPC_SPECIAL, 201 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */ 202 OPC_DROTR32 = OPC_DSRL32 | (1 << 21), 203 OPC_DSRA32 = 0x3F | OPC_SPECIAL, 204 /* Multiplication / division */ 205 OPC_MULT = 0x18 | OPC_SPECIAL, 206 OPC_MULTU = 0x19 | OPC_SPECIAL, 207 OPC_DIV = 0x1A | OPC_SPECIAL, 208 OPC_DIVU = 0x1B | OPC_SPECIAL, 209 OPC_DMULT = 0x1C | OPC_SPECIAL, 210 OPC_DMULTU = 0x1D | OPC_SPECIAL, 211 OPC_DDIV = 0x1E | OPC_SPECIAL, 212 OPC_DDIVU = 0x1F | OPC_SPECIAL, 213 214 /* 2 registers arithmetic / logic */ 215 OPC_ADD = 0x20 | OPC_SPECIAL, 216 OPC_ADDU = 0x21 | OPC_SPECIAL, 217 OPC_SUB = 0x22 | OPC_SPECIAL, 218 OPC_SUBU = 0x23 | OPC_SPECIAL, 219 OPC_AND = 0x24 | OPC_SPECIAL, 220 OPC_OR = 0x25 | OPC_SPECIAL, 221 OPC_XOR = 0x26 | OPC_SPECIAL, 222 OPC_NOR = 0x27 | OPC_SPECIAL, 223 OPC_SLT = 0x2A | OPC_SPECIAL, 224 OPC_SLTU = 0x2B | OPC_SPECIAL, 225 OPC_DADD = 0x2C | OPC_SPECIAL, 226 OPC_DADDU = 0x2D | OPC_SPECIAL, 227 OPC_DSUB = 0x2E | OPC_SPECIAL, 228 OPC_DSUBU = 0x2F | OPC_SPECIAL, 229 /* Jumps */ 230 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ 231 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ 232 /* Traps */ 233 OPC_TGE = 0x30 | OPC_SPECIAL, 234 OPC_TGEU = 0x31 | OPC_SPECIAL, 235 OPC_TLT = 0x32 | OPC_SPECIAL, 236 OPC_TLTU = 0x33 | OPC_SPECIAL, 237 OPC_TEQ = 0x34 | OPC_SPECIAL, 238 OPC_TNE = 0x36 | OPC_SPECIAL, 239 /* HI / LO registers load & stores */ 240 OPC_MFHI = 0x10 | OPC_SPECIAL, 241 OPC_MTHI = 0x11 | OPC_SPECIAL, 242 OPC_MFLO = 0x12 | OPC_SPECIAL, 243 OPC_MTLO = 0x13 | OPC_SPECIAL, 244 /* Conditional moves */ 245 OPC_MOVZ = 0x0A | OPC_SPECIAL, 246 OPC_MOVN = 0x0B | OPC_SPECIAL, 247 248 OPC_SELEQZ = 0x35 | OPC_SPECIAL, 249 OPC_SELNEZ = 0x37 | OPC_SPECIAL, 250 251 OPC_MOVCI = 0x01 | OPC_SPECIAL, 252 253 /* Special */ 254 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */ 255 OPC_SYSCALL = 0x0C | OPC_SPECIAL, 256 OPC_BREAK = 0x0D | OPC_SPECIAL, 257 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */ 258 OPC_SYNC = 0x0F | OPC_SPECIAL, 259 260 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, 261 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, 262 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, 263 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, 264 }; 265 266 /* 267 * R6 Multiply and Divide instructions have the same opcode 268 * and function field as legacy OPC_MULT[U]/OPC_DIV[U] 269 */ 270 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff))) 271 272 enum { 273 R6_OPC_MUL = OPC_MULT | (2 << 6), 274 R6_OPC_MUH = OPC_MULT | (3 << 6), 275 R6_OPC_MULU = OPC_MULTU | (2 << 6), 276 R6_OPC_MUHU = OPC_MULTU | (3 << 6), 277 R6_OPC_DIV = OPC_DIV | (2 << 6), 278 R6_OPC_MOD = OPC_DIV | (3 << 6), 279 R6_OPC_DIVU = OPC_DIVU | (2 << 6), 280 R6_OPC_MODU = OPC_DIVU | (3 << 6), 281 282 R6_OPC_DMUL = OPC_DMULT | (2 << 6), 283 R6_OPC_DMUH = OPC_DMULT | (3 << 6), 284 R6_OPC_DMULU = OPC_DMULTU | (2 << 6), 285 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6), 286 R6_OPC_DDIV = OPC_DDIV | (2 << 6), 287 R6_OPC_DMOD = OPC_DDIV | (3 << 6), 288 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6), 289 R6_OPC_DMODU = OPC_DDIVU | (3 << 6), 290 291 R6_OPC_CLZ = 0x10 | OPC_SPECIAL, 292 R6_OPC_CLO = 0x11 | OPC_SPECIAL, 293 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL, 294 R6_OPC_DCLO = 0x13 | OPC_SPECIAL, 295 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL, 296 }; 297 298 /* Multiplication variants of the vr54xx. */ 299 #define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6))) 300 301 enum { 302 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT, 303 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU, 304 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT, 305 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU, 306 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT, 307 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU, 308 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT, 309 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU, 310 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT, 311 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU, 312 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT, 313 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU, 314 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT, 315 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU, 316 }; 317 318 /* REGIMM (rt field) opcodes */ 319 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16))) 320 321 enum { 322 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM, 323 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM, 324 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM, 325 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM, 326 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM, 327 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM, 328 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM, 329 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM, 330 OPC_TGEI = (0x08 << 16) | OPC_REGIMM, 331 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM, 332 OPC_TLTI = (0x0A << 16) | OPC_REGIMM, 333 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM, 334 OPC_TEQI = (0x0C << 16) | OPC_REGIMM, 335 OPC_TNEI = (0x0E << 16) | OPC_REGIMM, 336 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM, 337 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM, 338 339 OPC_DAHI = (0x06 << 16) | OPC_REGIMM, 340 OPC_DATI = (0x1e << 16) | OPC_REGIMM, 341 }; 342 343 /* Special2 opcodes */ 344 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 345 346 enum { 347 /* Multiply & xxx operations */ 348 OPC_MADD = 0x00 | OPC_SPECIAL2, 349 OPC_MADDU = 0x01 | OPC_SPECIAL2, 350 OPC_MUL = 0x02 | OPC_SPECIAL2, 351 OPC_MSUB = 0x04 | OPC_SPECIAL2, 352 OPC_MSUBU = 0x05 | OPC_SPECIAL2, 353 /* Loongson 2F */ 354 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2, 355 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2, 356 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2, 357 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2, 358 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2, 359 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2, 360 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2, 361 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2, 362 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2, 363 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2, 364 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2, 365 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2, 366 /* Misc */ 367 OPC_CLZ = 0x20 | OPC_SPECIAL2, 368 OPC_CLO = 0x21 | OPC_SPECIAL2, 369 OPC_DCLZ = 0x24 | OPC_SPECIAL2, 370 OPC_DCLO = 0x25 | OPC_SPECIAL2, 371 /* Special */ 372 OPC_SDBBP = 0x3F | OPC_SPECIAL2, 373 }; 374 375 /* Special3 opcodes */ 376 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 377 378 enum { 379 OPC_EXT = 0x00 | OPC_SPECIAL3, 380 OPC_DEXTM = 0x01 | OPC_SPECIAL3, 381 OPC_DEXTU = 0x02 | OPC_SPECIAL3, 382 OPC_DEXT = 0x03 | OPC_SPECIAL3, 383 OPC_INS = 0x04 | OPC_SPECIAL3, 384 OPC_DINSM = 0x05 | OPC_SPECIAL3, 385 OPC_DINSU = 0x06 | OPC_SPECIAL3, 386 OPC_DINS = 0x07 | OPC_SPECIAL3, 387 OPC_FORK = 0x08 | OPC_SPECIAL3, 388 OPC_YIELD = 0x09 | OPC_SPECIAL3, 389 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 390 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 391 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 392 OPC_GINV = 0x3D | OPC_SPECIAL3, 393 394 /* Loongson 2E */ 395 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3, 396 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3, 397 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3, 398 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3, 399 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3, 400 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3, 401 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3, 402 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3, 403 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3, 404 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3, 405 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3, 406 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3, 407 408 /* MIPS DSP Load */ 409 OPC_LX_DSP = 0x0A | OPC_SPECIAL3, 410 /* MIPS DSP Arithmetic */ 411 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3, 412 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3, 413 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3, 414 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3, 415 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */ 416 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */ 417 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3, 418 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3, 419 /* MIPS DSP GPR-Based Shift Sub-class */ 420 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3, 421 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3, 422 /* MIPS DSP Multiply Sub-class insns */ 423 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */ 424 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */ 425 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3, 426 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3, 427 /* DSP Bit/Manipulation Sub-class */ 428 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, 429 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3, 430 /* MIPS DSP Append Sub-class */ 431 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3, 432 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3, 433 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 434 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, 435 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, 436 437 /* EVA */ 438 OPC_LWLE = 0x19 | OPC_SPECIAL3, 439 OPC_LWRE = 0x1A | OPC_SPECIAL3, 440 OPC_CACHEE = 0x1B | OPC_SPECIAL3, 441 OPC_SBE = 0x1C | OPC_SPECIAL3, 442 OPC_SHE = 0x1D | OPC_SPECIAL3, 443 OPC_SCE = 0x1E | OPC_SPECIAL3, 444 OPC_SWE = 0x1F | OPC_SPECIAL3, 445 OPC_SWLE = 0x21 | OPC_SPECIAL3, 446 OPC_SWRE = 0x22 | OPC_SPECIAL3, 447 OPC_PREFE = 0x23 | OPC_SPECIAL3, 448 OPC_LBUE = 0x28 | OPC_SPECIAL3, 449 OPC_LHUE = 0x29 | OPC_SPECIAL3, 450 OPC_LBE = 0x2C | OPC_SPECIAL3, 451 OPC_LHE = 0x2D | OPC_SPECIAL3, 452 OPC_LLE = 0x2E | OPC_SPECIAL3, 453 OPC_LWE = 0x2F | OPC_SPECIAL3, 454 455 /* R6 */ 456 R6_OPC_PREF = 0x35 | OPC_SPECIAL3, 457 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, 458 R6_OPC_LL = 0x36 | OPC_SPECIAL3, 459 R6_OPC_SC = 0x26 | OPC_SPECIAL3, 460 R6_OPC_LLD = 0x37 | OPC_SPECIAL3, 461 R6_OPC_SCD = 0x27 | OPC_SPECIAL3, 462 }; 463 464 /* Loongson EXT load/store quad word opcodes */ 465 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020)) 466 enum { 467 OPC_GSLQ = 0x0020 | OPC_LWC2, 468 OPC_GSLQC1 = 0x8020 | OPC_LWC2, 469 OPC_GSSHFL = OPC_LWC2, 470 OPC_GSSQ = 0x0020 | OPC_SWC2, 471 OPC_GSSQC1 = 0x8020 | OPC_SWC2, 472 OPC_GSSHFS = OPC_SWC2, 473 }; 474 475 /* Loongson EXT shifted load/store opcodes */ 476 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f)) 477 enum { 478 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL, 479 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL, 480 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL, 481 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL, 482 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS, 483 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS, 484 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS, 485 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS, 486 }; 487 488 /* Loongson EXT LDC2/SDC2 opcodes */ 489 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7)) 490 491 enum { 492 OPC_GSLBX = 0x0 | OPC_LDC2, 493 OPC_GSLHX = 0x1 | OPC_LDC2, 494 OPC_GSLWX = 0x2 | OPC_LDC2, 495 OPC_GSLDX = 0x3 | OPC_LDC2, 496 OPC_GSLWXC1 = 0x6 | OPC_LDC2, 497 OPC_GSLDXC1 = 0x7 | OPC_LDC2, 498 OPC_GSSBX = 0x0 | OPC_SDC2, 499 OPC_GSSHX = 0x1 | OPC_SDC2, 500 OPC_GSSWX = 0x2 | OPC_SDC2, 501 OPC_GSSDX = 0x3 | OPC_SDC2, 502 OPC_GSSWXC1 = 0x6 | OPC_SDC2, 503 OPC_GSSDXC1 = 0x7 | OPC_SDC2, 504 }; 505 506 /* BSHFL opcodes */ 507 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 508 509 enum { 510 OPC_WSBH = (0x02 << 6) | OPC_BSHFL, 511 OPC_SEB = (0x10 << 6) | OPC_BSHFL, 512 OPC_SEH = (0x18 << 6) | OPC_BSHFL, 513 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */ 514 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL, 515 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL, 516 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL, 517 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */ 518 }; 519 520 /* DBSHFL opcodes */ 521 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 522 523 enum { 524 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, 525 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, 526 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */ 527 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL, 528 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL, 529 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL, 530 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL, 531 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL, 532 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL, 533 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL, 534 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */ 535 }; 536 537 /* MIPS DSP REGIMM opcodes */ 538 enum { 539 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM, 540 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM, 541 }; 542 543 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 544 /* MIPS DSP Load */ 545 enum { 546 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP, 547 OPC_LHX = (0x04 << 6) | OPC_LX_DSP, 548 OPC_LWX = (0x00 << 6) | OPC_LX_DSP, 549 OPC_LDX = (0x08 << 6) | OPC_LX_DSP, 550 }; 551 552 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 553 enum { 554 /* MIPS DSP Arithmetic Sub-class */ 555 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP, 556 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP, 557 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP, 558 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP, 559 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP, 560 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP, 561 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP, 562 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP, 563 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP, 564 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP, 565 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP, 566 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP, 567 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP, 568 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP, 569 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP, 570 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP, 571 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP, 572 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP, 573 /* MIPS DSP Multiply Sub-class insns */ 574 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP, 575 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP, 576 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP, 577 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP, 578 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP, 579 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP, 580 }; 581 582 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E 583 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 584 enum { 585 /* MIPS DSP Arithmetic Sub-class */ 586 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP, 587 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP, 588 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP, 589 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP, 590 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP, 591 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP, 592 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP, 593 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP, 594 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP, 595 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP, 596 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP, 597 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP, 598 /* MIPS DSP Multiply Sub-class insns */ 599 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP, 600 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP, 601 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP, 602 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP, 603 }; 604 605 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 606 enum { 607 /* MIPS DSP Arithmetic Sub-class */ 608 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP, 609 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP, 610 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP, 611 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP, 612 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP, 613 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP, 614 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP, 615 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP, 616 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP, 617 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP, 618 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP, 619 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP, 620 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP, 621 /* DSP Bit/Manipulation Sub-class */ 622 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP, 623 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP, 624 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP, 625 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP, 626 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP, 627 }; 628 629 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 630 enum { 631 /* MIPS DSP Arithmetic Sub-class */ 632 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP, 633 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP, 634 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP, 635 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP, 636 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP, 637 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP, 638 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP, 639 /* DSP Compare-Pick Sub-class */ 640 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP, 641 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP, 642 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP, 643 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP, 644 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP, 645 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP, 646 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP, 647 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP, 648 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP, 649 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP, 650 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP, 651 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP, 652 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, 653 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, 654 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, 655 }; 656 657 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 658 enum { 659 /* MIPS DSP GPR-Based Shift Sub-class */ 660 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP, 661 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP, 662 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP, 663 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP, 664 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP, 665 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP, 666 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP, 667 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP, 668 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP, 669 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP, 670 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP, 671 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP, 672 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP, 673 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP, 674 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP, 675 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP, 676 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP, 677 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP, 678 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP, 679 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP, 680 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP, 681 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP, 682 }; 683 684 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 685 enum { 686 /* MIPS DSP Multiply Sub-class insns */ 687 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP, 688 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP, 689 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP, 690 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP, 691 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP, 692 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP, 693 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP, 694 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP, 695 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP, 696 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP, 697 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP, 698 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP, 699 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP, 700 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP, 701 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP, 702 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP, 703 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP, 704 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP, 705 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP, 706 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP, 707 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP, 708 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP, 709 }; 710 711 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 712 enum { 713 /* DSP Bit/Manipulation Sub-class */ 714 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP, 715 }; 716 717 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 718 enum { 719 /* MIPS DSP Append Sub-class */ 720 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP, 721 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP, 722 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP, 723 }; 724 725 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 726 enum { 727 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 728 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP, 729 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP, 730 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP, 731 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP, 732 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP, 733 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP, 734 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP, 735 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP, 736 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP, 737 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP, 738 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP, 739 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP, 740 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP, 741 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP, 742 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP, 743 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP, 744 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP, 745 }; 746 747 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 748 enum { 749 /* MIPS DSP Arithmetic Sub-class */ 750 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP, 751 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP, 752 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP, 753 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP, 754 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP, 755 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP, 756 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP, 757 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP, 758 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP, 759 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP, 760 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP, 761 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP, 762 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP, 763 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP, 764 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP, 765 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP, 766 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP, 767 /* DSP Bit/Manipulation Sub-class */ 768 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP, 769 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP, 770 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP, 771 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP, 772 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP, 773 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP, 774 }; 775 776 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 777 enum { 778 /* MIPS DSP Multiply Sub-class insns */ 779 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP, 780 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP, 781 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP, 782 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP, 783 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP, 784 /* MIPS DSP Arithmetic Sub-class */ 785 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP, 786 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP, 787 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP, 788 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP, 789 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP, 790 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP, 791 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP, 792 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP, 793 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP, 794 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP, 795 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP, 796 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP, 797 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP, 798 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP, 799 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP, 800 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP, 801 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP, 802 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP, 803 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP, 804 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP, 805 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP, 806 }; 807 808 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 809 enum { 810 /* DSP Compare-Pick Sub-class */ 811 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP, 812 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP, 813 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP, 814 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP, 815 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP, 816 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP, 817 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP, 818 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP, 819 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP, 820 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP, 821 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP, 822 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP, 823 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP, 824 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP, 825 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP, 826 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP, 827 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP, 828 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP, 829 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP, 830 /* MIPS DSP Arithmetic Sub-class */ 831 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP, 832 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP, 833 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP, 834 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP, 835 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP, 836 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP, 837 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP, 838 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP, 839 }; 840 841 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 842 enum { 843 /* DSP Append Sub-class */ 844 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP, 845 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP, 846 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP, 847 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP, 848 }; 849 850 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 851 enum { 852 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 853 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP, 854 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP, 855 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP, 856 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP, 857 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP, 858 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP, 859 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP, 860 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP, 861 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP, 862 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP, 863 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP, 864 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP, 865 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP, 866 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP, 867 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP, 868 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP, 869 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP, 870 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP, 871 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP, 872 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP, 873 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP, 874 }; 875 876 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 877 enum { 878 /* DSP Bit/Manipulation Sub-class */ 879 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP, 880 }; 881 882 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 883 enum { 884 /* MIPS DSP Multiply Sub-class insns */ 885 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP, 886 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP, 887 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP, 888 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP, 889 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP, 890 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP, 891 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP, 892 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP, 893 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP, 894 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP, 895 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP, 896 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP, 897 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP, 898 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP, 899 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP, 900 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP, 901 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP, 902 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP, 903 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP, 904 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP, 905 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP, 906 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP, 907 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP, 908 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP, 909 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP, 910 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP, 911 }; 912 913 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 914 enum { 915 /* MIPS DSP GPR-Based Shift Sub-class */ 916 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP, 917 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP, 918 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP, 919 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP, 920 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP, 921 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP, 922 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP, 923 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP, 924 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP, 925 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP, 926 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP, 927 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP, 928 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP, 929 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP, 930 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP, 931 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP, 932 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP, 933 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP, 934 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP, 935 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP, 936 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP, 937 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP, 938 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP, 939 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP, 940 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP, 941 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP, 942 }; 943 944 /* Coprocessor 0 (rs field) */ 945 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 946 947 enum { 948 OPC_MFC0 = (0x00 << 21) | OPC_CP0, 949 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 950 OPC_MFHC0 = (0x02 << 21) | OPC_CP0, 951 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 952 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 953 OPC_MTHC0 = (0x06 << 21) | OPC_CP0, 954 OPC_MFTR = (0x08 << 21) | OPC_CP0, 955 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 956 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 957 OPC_MTTR = (0x0C << 21) | OPC_CP0, 958 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 959 OPC_C0 = (0x10 << 21) | OPC_CP0, 960 OPC_C0_1 = (0x11 << 21) | OPC_CP0, 961 OPC_C0_2 = (0x12 << 21) | OPC_CP0, 962 OPC_C0_3 = (0x13 << 21) | OPC_CP0, 963 OPC_C0_4 = (0x14 << 21) | OPC_CP0, 964 OPC_C0_5 = (0x15 << 21) | OPC_CP0, 965 OPC_C0_6 = (0x16 << 21) | OPC_CP0, 966 OPC_C0_7 = (0x17 << 21) | OPC_CP0, 967 OPC_C0_8 = (0x18 << 21) | OPC_CP0, 968 OPC_C0_9 = (0x19 << 21) | OPC_CP0, 969 OPC_C0_A = (0x1A << 21) | OPC_CP0, 970 OPC_C0_B = (0x1B << 21) | OPC_CP0, 971 OPC_C0_C = (0x1C << 21) | OPC_CP0, 972 OPC_C0_D = (0x1D << 21) | OPC_CP0, 973 OPC_C0_E = (0x1E << 21) | OPC_CP0, 974 OPC_C0_F = (0x1F << 21) | OPC_CP0, 975 }; 976 977 /* MFMC0 opcodes */ 978 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF)) 979 980 enum { 981 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 982 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 983 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0, 984 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0, 985 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 986 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 987 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0, 988 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0, 989 }; 990 991 /* Coprocessor 0 (with rs == C0) */ 992 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F)) 993 994 enum { 995 OPC_TLBR = 0x01 | OPC_C0, 996 OPC_TLBWI = 0x02 | OPC_C0, 997 OPC_TLBINV = 0x03 | OPC_C0, 998 OPC_TLBINVF = 0x04 | OPC_C0, 999 OPC_TLBWR = 0x06 | OPC_C0, 1000 OPC_TLBP = 0x08 | OPC_C0, 1001 OPC_RFE = 0x10 | OPC_C0, 1002 OPC_ERET = 0x18 | OPC_C0, 1003 OPC_DERET = 0x1F | OPC_C0, 1004 OPC_WAIT = 0x20 | OPC_C0, 1005 }; 1006 1007 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 1008 1009 enum { 1010 OPC_MFC2 = (0x00 << 21) | OPC_CP2, 1011 OPC_DMFC2 = (0x01 << 21) | OPC_CP2, 1012 OPC_CFC2 = (0x02 << 21) | OPC_CP2, 1013 OPC_MFHC2 = (0x03 << 21) | OPC_CP2, 1014 OPC_MTC2 = (0x04 << 21) | OPC_CP2, 1015 OPC_DMTC2 = (0x05 << 21) | OPC_CP2, 1016 OPC_CTC2 = (0x06 << 21) | OPC_CP2, 1017 OPC_MTHC2 = (0x07 << 21) | OPC_CP2, 1018 OPC_BC2 = (0x08 << 21) | OPC_CP2, 1019 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2, 1020 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2, 1021 }; 1022 1023 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F)) 1024 1025 enum { 1026 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2, 1027 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2, 1028 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2, 1029 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2, 1030 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2, 1031 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2, 1032 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2, 1033 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2, 1034 1035 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2, 1036 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2, 1037 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2, 1038 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2, 1039 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2, 1040 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2, 1041 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2, 1042 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2, 1043 1044 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2, 1045 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2, 1046 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2, 1047 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2, 1048 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2, 1049 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2, 1050 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2, 1051 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2, 1052 1053 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2, 1054 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2, 1055 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2, 1056 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2, 1057 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2, 1058 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2, 1059 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2, 1060 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2, 1061 1062 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2, 1063 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2, 1064 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2, 1065 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2, 1066 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2, 1067 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2, 1068 1069 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2, 1070 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2, 1071 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2, 1072 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2, 1073 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2, 1074 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2, 1075 1076 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2, 1077 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2, 1078 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2, 1079 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2, 1080 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2, 1081 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2, 1082 1083 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2, 1084 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2, 1085 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2, 1086 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2, 1087 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2, 1088 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2, 1089 1090 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2, 1091 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2, 1092 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2, 1093 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2, 1094 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2, 1095 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2, 1096 1097 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2, 1098 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2, 1099 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2, 1100 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2, 1101 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2, 1102 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2, 1103 1104 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2, 1105 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2, 1106 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2, 1107 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2, 1108 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2, 1109 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2, 1110 1111 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2, 1112 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2, 1113 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2, 1114 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2, 1115 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2, 1116 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2, 1117 }; 1118 1119 1120 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 1121 1122 enum { 1123 OPC_LWXC1 = 0x00 | OPC_CP3, 1124 OPC_LDXC1 = 0x01 | OPC_CP3, 1125 OPC_LUXC1 = 0x05 | OPC_CP3, 1126 OPC_SWXC1 = 0x08 | OPC_CP3, 1127 OPC_SDXC1 = 0x09 | OPC_CP3, 1128 OPC_SUXC1 = 0x0D | OPC_CP3, 1129 OPC_PREFX = 0x0F | OPC_CP3, 1130 OPC_ALNV_PS = 0x1E | OPC_CP3, 1131 OPC_MADD_S = 0x20 | OPC_CP3, 1132 OPC_MADD_D = 0x21 | OPC_CP3, 1133 OPC_MADD_PS = 0x26 | OPC_CP3, 1134 OPC_MSUB_S = 0x28 | OPC_CP3, 1135 OPC_MSUB_D = 0x29 | OPC_CP3, 1136 OPC_MSUB_PS = 0x2E | OPC_CP3, 1137 OPC_NMADD_S = 0x30 | OPC_CP3, 1138 OPC_NMADD_D = 0x31 | OPC_CP3, 1139 OPC_NMADD_PS = 0x36 | OPC_CP3, 1140 OPC_NMSUB_S = 0x38 | OPC_CP3, 1141 OPC_NMSUB_D = 0x39 | OPC_CP3, 1142 OPC_NMSUB_PS = 0x3E | OPC_CP3, 1143 }; 1144 1145 /* 1146 * MMI (MultiMedia Instruction) encodings 1147 * ====================================== 1148 * 1149 * MMI instructions encoding table keys: 1150 * 1151 * * This code is reserved for future use. An attempt to execute it 1152 * causes a Reserved Instruction exception. 1153 * % This code indicates an instruction class. The instruction word 1154 * must be further decoded by examining additional tables that show 1155 * the values for other instruction fields. 1156 * # This code is reserved for the unsupported instructions DMULT, 1157 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt 1158 * to execute it causes a Reserved Instruction exception. 1159 * 1160 * MMI instructions encoded by opcode field (MMI, LQ, SQ): 1161 * 1162 * 31 26 0 1163 * +--------+----------------------------------------+ 1164 * | opcode | | 1165 * +--------+----------------------------------------+ 1166 * 1167 * opcode bits 28..26 1168 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1169 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1170 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1171 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ 1172 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI 1173 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL 1174 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ 1175 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU 1176 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE 1177 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD 1178 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD 1179 */ 1180 1181 enum { 1182 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */ 1183 MMI_OPC_LQ = 0x1E << 26, /* Same as OPC_MSA */ 1184 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */ 1185 }; 1186 1187 /* 1188 * MMI instructions with opcode field = MMI: 1189 * 1190 * 31 26 5 0 1191 * +--------+-------------------------------+--------+ 1192 * | MMI | |function| 1193 * +--------+-------------------------------+--------+ 1194 * 1195 * function bits 2..0 1196 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1197 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1198 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1199 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * 1200 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * 1201 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * 1202 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * 1203 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * 1204 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * 1205 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH 1206 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW 1207 */ 1208 1209 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) 1210 enum { 1211 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */ 1212 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */ 1213 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */ 1214 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */ 1215 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */ 1216 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */ 1217 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI, 1218 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI, 1219 }; 1220 1221 /* global register indices */ 1222 TCGv cpu_gpr[32], cpu_PC; 1223 /* 1224 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[]) 1225 * and the upper halves in cpu_gpr_hi[]. 1226 */ 1227 TCGv_i64 cpu_gpr_hi[32]; 1228 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; 1229 static TCGv cpu_dspctrl, btarget; 1230 TCGv bcond; 1231 static TCGv cpu_lladdr, cpu_llval; 1232 static TCGv_i32 hflags; 1233 TCGv_i32 fpu_fcr0, fpu_fcr31; 1234 TCGv_i64 fpu_f64[32]; 1235 1236 #include "exec/gen-icount.h" 1237 1238 #define gen_helper_0e0i(name, arg) do { \ 1239 TCGv_i32 helper_tmp = tcg_const_i32(arg); \ 1240 gen_helper_##name(cpu_env, helper_tmp); \ 1241 tcg_temp_free_i32(helper_tmp); \ 1242 } while (0) 1243 1244 #define gen_helper_0e1i(name, arg1, arg2) do { \ 1245 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ 1246 gen_helper_##name(cpu_env, arg1, helper_tmp); \ 1247 tcg_temp_free_i32(helper_tmp); \ 1248 } while (0) 1249 1250 #define gen_helper_1e0i(name, ret, arg1) do { \ 1251 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \ 1252 gen_helper_##name(ret, cpu_env, helper_tmp); \ 1253 tcg_temp_free_i32(helper_tmp); \ 1254 } while (0) 1255 1256 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \ 1257 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ 1258 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \ 1259 tcg_temp_free_i32(helper_tmp); \ 1260 } while (0) 1261 1262 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \ 1263 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ 1264 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \ 1265 tcg_temp_free_i32(helper_tmp); \ 1266 } while (0) 1267 1268 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \ 1269 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ 1270 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \ 1271 tcg_temp_free_i32(helper_tmp); \ 1272 } while (0) 1273 1274 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \ 1275 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \ 1276 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \ 1277 tcg_temp_free_i32(helper_tmp); \ 1278 } while (0) 1279 1280 #define DISAS_STOP DISAS_TARGET_0 1281 #define DISAS_EXIT DISAS_TARGET_1 1282 1283 static const char regnames_HI[][4] = { 1284 "HI0", "HI1", "HI2", "HI3", 1285 }; 1286 1287 static const char regnames_LO[][4] = { 1288 "LO0", "LO1", "LO2", "LO3", 1289 }; 1290 1291 /* General purpose registers moves. */ 1292 void gen_load_gpr(TCGv t, int reg) 1293 { 1294 if (reg == 0) { 1295 tcg_gen_movi_tl(t, 0); 1296 } else { 1297 tcg_gen_mov_tl(t, cpu_gpr[reg]); 1298 } 1299 } 1300 1301 void gen_store_gpr(TCGv t, int reg) 1302 { 1303 if (reg != 0) { 1304 tcg_gen_mov_tl(cpu_gpr[reg], t); 1305 } 1306 } 1307 1308 #if defined(TARGET_MIPS64) 1309 void gen_load_gpr_hi(TCGv_i64 t, int reg) 1310 { 1311 if (reg == 0) { 1312 tcg_gen_movi_i64(t, 0); 1313 } else { 1314 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]); 1315 } 1316 } 1317 1318 void gen_store_gpr_hi(TCGv_i64 t, int reg) 1319 { 1320 if (reg != 0) { 1321 tcg_gen_mov_i64(cpu_gpr_hi[reg], t); 1322 } 1323 } 1324 #endif /* TARGET_MIPS64 */ 1325 1326 /* Moves to/from shadow registers. */ 1327 static inline void gen_load_srsgpr(int from, int to) 1328 { 1329 TCGv t0 = tcg_temp_new(); 1330 1331 if (from == 0) { 1332 tcg_gen_movi_tl(t0, 0); 1333 } else { 1334 TCGv_i32 t2 = tcg_temp_new_i32(); 1335 TCGv_ptr addr = tcg_temp_new_ptr(); 1336 1337 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1338 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1339 tcg_gen_andi_i32(t2, t2, 0xf); 1340 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1341 tcg_gen_ext_i32_ptr(addr, t2); 1342 tcg_gen_add_ptr(addr, cpu_env, addr); 1343 1344 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 1345 tcg_temp_free_ptr(addr); 1346 tcg_temp_free_i32(t2); 1347 } 1348 gen_store_gpr(t0, to); 1349 tcg_temp_free(t0); 1350 } 1351 1352 static inline void gen_store_srsgpr(int from, int to) 1353 { 1354 if (to != 0) { 1355 TCGv t0 = tcg_temp_new(); 1356 TCGv_i32 t2 = tcg_temp_new_i32(); 1357 TCGv_ptr addr = tcg_temp_new_ptr(); 1358 1359 gen_load_gpr(t0, from); 1360 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1361 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1362 tcg_gen_andi_i32(t2, t2, 0xf); 1363 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1364 tcg_gen_ext_i32_ptr(addr, t2); 1365 tcg_gen_add_ptr(addr, cpu_env, addr); 1366 1367 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 1368 tcg_temp_free_ptr(addr); 1369 tcg_temp_free_i32(t2); 1370 tcg_temp_free(t0); 1371 } 1372 } 1373 1374 /* Tests */ 1375 static inline void gen_save_pc(target_ulong pc) 1376 { 1377 tcg_gen_movi_tl(cpu_PC, pc); 1378 } 1379 1380 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) 1381 { 1382 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 1383 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { 1384 gen_save_pc(ctx->base.pc_next); 1385 ctx->saved_pc = ctx->base.pc_next; 1386 } 1387 if (ctx->hflags != ctx->saved_hflags) { 1388 tcg_gen_movi_i32(hflags, ctx->hflags); 1389 ctx->saved_hflags = ctx->hflags; 1390 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1391 case MIPS_HFLAG_BR: 1392 break; 1393 case MIPS_HFLAG_BC: 1394 case MIPS_HFLAG_BL: 1395 case MIPS_HFLAG_B: 1396 tcg_gen_movi_tl(btarget, ctx->btarget); 1397 break; 1398 } 1399 } 1400 } 1401 1402 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) 1403 { 1404 ctx->saved_hflags = ctx->hflags; 1405 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1406 case MIPS_HFLAG_BR: 1407 break; 1408 case MIPS_HFLAG_BC: 1409 case MIPS_HFLAG_BL: 1410 case MIPS_HFLAG_B: 1411 ctx->btarget = env->btarget; 1412 break; 1413 } 1414 } 1415 1416 void generate_exception_err(DisasContext *ctx, int excp, int err) 1417 { 1418 TCGv_i32 texcp = tcg_const_i32(excp); 1419 TCGv_i32 terr = tcg_const_i32(err); 1420 save_cpu_state(ctx, 1); 1421 gen_helper_raise_exception_err(cpu_env, texcp, terr); 1422 tcg_temp_free_i32(terr); 1423 tcg_temp_free_i32(texcp); 1424 ctx->base.is_jmp = DISAS_NORETURN; 1425 } 1426 1427 void generate_exception(DisasContext *ctx, int excp) 1428 { 1429 gen_helper_0e0i(raise_exception, excp); 1430 } 1431 1432 void generate_exception_end(DisasContext *ctx, int excp) 1433 { 1434 generate_exception_err(ctx, excp, 0); 1435 } 1436 1437 void gen_reserved_instruction(DisasContext *ctx) 1438 { 1439 generate_exception_end(ctx, EXCP_RI); 1440 } 1441 1442 /* Floating point register moves. */ 1443 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1444 { 1445 if (ctx->hflags & MIPS_HFLAG_FRE) { 1446 generate_exception(ctx, EXCP_RI); 1447 } 1448 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); 1449 } 1450 1451 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1452 { 1453 TCGv_i64 t64; 1454 if (ctx->hflags & MIPS_HFLAG_FRE) { 1455 generate_exception(ctx, EXCP_RI); 1456 } 1457 t64 = tcg_temp_new_i64(); 1458 tcg_gen_extu_i32_i64(t64, t); 1459 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); 1460 tcg_temp_free_i64(t64); 1461 } 1462 1463 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1464 { 1465 if (ctx->hflags & MIPS_HFLAG_F64) { 1466 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); 1467 } else { 1468 gen_load_fpr32(ctx, t, reg | 1); 1469 } 1470 } 1471 1472 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1473 { 1474 if (ctx->hflags & MIPS_HFLAG_F64) { 1475 TCGv_i64 t64 = tcg_temp_new_i64(); 1476 tcg_gen_extu_i32_i64(t64, t); 1477 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); 1478 tcg_temp_free_i64(t64); 1479 } else { 1480 gen_store_fpr32(ctx, t, reg | 1); 1481 } 1482 } 1483 1484 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1485 { 1486 if (ctx->hflags & MIPS_HFLAG_F64) { 1487 tcg_gen_mov_i64(t, fpu_f64[reg]); 1488 } else { 1489 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]); 1490 } 1491 } 1492 1493 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1494 { 1495 if (ctx->hflags & MIPS_HFLAG_F64) { 1496 tcg_gen_mov_i64(fpu_f64[reg], t); 1497 } else { 1498 TCGv_i64 t0; 1499 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32); 1500 t0 = tcg_temp_new_i64(); 1501 tcg_gen_shri_i64(t0, t, 32); 1502 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32); 1503 tcg_temp_free_i64(t0); 1504 } 1505 } 1506 1507 int get_fp_bit(int cc) 1508 { 1509 if (cc) { 1510 return 24 + cc; 1511 } else { 1512 return 23; 1513 } 1514 } 1515 1516 /* Addresses computation */ 1517 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 1518 { 1519 tcg_gen_add_tl(ret, arg0, arg1); 1520 1521 #if defined(TARGET_MIPS64) 1522 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1523 tcg_gen_ext32s_i64(ret, ret); 1524 } 1525 #endif 1526 } 1527 1528 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, 1529 target_long ofs) 1530 { 1531 tcg_gen_addi_tl(ret, base, ofs); 1532 1533 #if defined(TARGET_MIPS64) 1534 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1535 tcg_gen_ext32s_i64(ret, ret); 1536 } 1537 #endif 1538 } 1539 1540 /* Addresses computation (translation time) */ 1541 static target_long addr_add(DisasContext *ctx, target_long base, 1542 target_long offset) 1543 { 1544 target_long sum = base + offset; 1545 1546 #if defined(TARGET_MIPS64) 1547 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1548 sum = (int32_t)sum; 1549 } 1550 #endif 1551 return sum; 1552 } 1553 1554 /* Sign-extract the low 32-bits to a target_long. */ 1555 void gen_move_low32(TCGv ret, TCGv_i64 arg) 1556 { 1557 #if defined(TARGET_MIPS64) 1558 tcg_gen_ext32s_i64(ret, arg); 1559 #else 1560 tcg_gen_extrl_i64_i32(ret, arg); 1561 #endif 1562 } 1563 1564 /* Sign-extract the high 32-bits to a target_long. */ 1565 void gen_move_high32(TCGv ret, TCGv_i64 arg) 1566 { 1567 #if defined(TARGET_MIPS64) 1568 tcg_gen_sari_i64(ret, arg, 32); 1569 #else 1570 tcg_gen_extrh_i64_i32(ret, arg); 1571 #endif 1572 } 1573 1574 bool check_cp0_enabled(DisasContext *ctx) 1575 { 1576 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1577 generate_exception_end(ctx, EXCP_CpU); 1578 return false; 1579 } 1580 return true; 1581 } 1582 1583 void check_cp1_enabled(DisasContext *ctx) 1584 { 1585 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) { 1586 generate_exception_err(ctx, EXCP_CpU, 1); 1587 } 1588 } 1589 1590 /* 1591 * Verify that the processor is running with COP1X instructions enabled. 1592 * This is associated with the nabla symbol in the MIPS32 and MIPS64 1593 * opcode tables. 1594 */ 1595 void check_cop1x(DisasContext *ctx) 1596 { 1597 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { 1598 gen_reserved_instruction(ctx); 1599 } 1600 } 1601 1602 /* 1603 * Verify that the processor is running with 64-bit floating-point 1604 * operations enabled. 1605 */ 1606 void check_cp1_64bitmode(DisasContext *ctx) 1607 { 1608 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) { 1609 gen_reserved_instruction(ctx); 1610 } 1611 } 1612 1613 /* 1614 * Verify if floating point register is valid; an operation is not defined 1615 * if bit 0 of any register specification is set and the FR bit in the 1616 * Status register equals zero, since the register numbers specify an 1617 * even-odd pair of adjacent coprocessor general registers. When the FR bit 1618 * in the Status register equals one, both even and odd register numbers 1619 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 1620 * 1621 * Multiple 64 bit wide registers can be checked by calling 1622 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 1623 */ 1624 void check_cp1_registers(DisasContext *ctx, int regs) 1625 { 1626 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { 1627 gen_reserved_instruction(ctx); 1628 } 1629 } 1630 1631 /* 1632 * Verify that the processor is running with DSP instructions enabled. 1633 * This is enabled by CP0 Status register MX(24) bit. 1634 */ 1635 static inline void check_dsp(DisasContext *ctx) 1636 { 1637 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { 1638 if (ctx->insn_flags & ASE_DSP) { 1639 generate_exception_end(ctx, EXCP_DSPDIS); 1640 } else { 1641 gen_reserved_instruction(ctx); 1642 } 1643 } 1644 } 1645 1646 static inline void check_dsp_r2(DisasContext *ctx) 1647 { 1648 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { 1649 if (ctx->insn_flags & ASE_DSP) { 1650 generate_exception_end(ctx, EXCP_DSPDIS); 1651 } else { 1652 gen_reserved_instruction(ctx); 1653 } 1654 } 1655 } 1656 1657 static inline void check_dsp_r3(DisasContext *ctx) 1658 { 1659 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { 1660 if (ctx->insn_flags & ASE_DSP) { 1661 generate_exception_end(ctx, EXCP_DSPDIS); 1662 } else { 1663 gen_reserved_instruction(ctx); 1664 } 1665 } 1666 } 1667 1668 /* 1669 * This code generates a "reserved instruction" exception if the 1670 * CPU does not support the instruction set corresponding to flags. 1671 */ 1672 void check_insn(DisasContext *ctx, uint64_t flags) 1673 { 1674 if (unlikely(!(ctx->insn_flags & flags))) { 1675 gen_reserved_instruction(ctx); 1676 } 1677 } 1678 1679 /* 1680 * This code generates a "reserved instruction" exception if the 1681 * CPU has corresponding flag set which indicates that the instruction 1682 * has been removed. 1683 */ 1684 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) 1685 { 1686 if (unlikely(ctx->insn_flags & flags)) { 1687 gen_reserved_instruction(ctx); 1688 } 1689 } 1690 1691 /* 1692 * The Linux kernel traps certain reserved instruction exceptions to 1693 * emulate the corresponding instructions. QEMU is the kernel in user 1694 * mode, so those traps are emulated by accepting the instructions. 1695 * 1696 * A reserved instruction exception is generated for flagged CPUs if 1697 * QEMU runs in system mode. 1698 */ 1699 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) 1700 { 1701 #ifndef CONFIG_USER_ONLY 1702 check_insn_opc_removed(ctx, flags); 1703 #endif 1704 } 1705 1706 /* 1707 * This code generates a "reserved instruction" exception if the 1708 * CPU does not support 64-bit paired-single (PS) floating point data type. 1709 */ 1710 static inline void check_ps(DisasContext *ctx) 1711 { 1712 if (unlikely(!ctx->ps)) { 1713 generate_exception(ctx, EXCP_RI); 1714 } 1715 check_cp1_64bitmode(ctx); 1716 } 1717 1718 /* 1719 * This code generates a "reserved instruction" exception if cpu is not 1720 * 64-bit or 64-bit instructions are not enabled. 1721 */ 1722 void check_mips_64(DisasContext *ctx) 1723 { 1724 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) { 1725 gen_reserved_instruction(ctx); 1726 } 1727 } 1728 1729 #ifndef CONFIG_USER_ONLY 1730 static inline void check_mvh(DisasContext *ctx) 1731 { 1732 if (unlikely(!ctx->mvh)) { 1733 generate_exception(ctx, EXCP_RI); 1734 } 1735 } 1736 #endif 1737 1738 /* 1739 * This code generates a "reserved instruction" exception if the 1740 * Config5 XNP bit is set. 1741 */ 1742 static inline void check_xnp(DisasContext *ctx) 1743 { 1744 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) { 1745 gen_reserved_instruction(ctx); 1746 } 1747 } 1748 1749 #ifndef CONFIG_USER_ONLY 1750 /* 1751 * This code generates a "reserved instruction" exception if the 1752 * Config3 PW bit is NOT set. 1753 */ 1754 static inline void check_pw(DisasContext *ctx) 1755 { 1756 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) { 1757 gen_reserved_instruction(ctx); 1758 } 1759 } 1760 #endif 1761 1762 /* 1763 * This code generates a "reserved instruction" exception if the 1764 * Config3 MT bit is NOT set. 1765 */ 1766 static inline void check_mt(DisasContext *ctx) 1767 { 1768 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1769 gen_reserved_instruction(ctx); 1770 } 1771 } 1772 1773 #ifndef CONFIG_USER_ONLY 1774 /* 1775 * This code generates a "coprocessor unusable" exception if CP0 is not 1776 * available, and, if that is not the case, generates a "reserved instruction" 1777 * exception if the Config5 MT bit is NOT set. This is needed for availability 1778 * control of some of MT ASE instructions. 1779 */ 1780 static inline void check_cp0_mt(DisasContext *ctx) 1781 { 1782 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1783 generate_exception_end(ctx, EXCP_CpU); 1784 } else { 1785 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1786 gen_reserved_instruction(ctx); 1787 } 1788 } 1789 } 1790 #endif 1791 1792 /* 1793 * This code generates a "reserved instruction" exception if the 1794 * Config5 NMS bit is set. 1795 */ 1796 static inline void check_nms(DisasContext *ctx) 1797 { 1798 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) { 1799 gen_reserved_instruction(ctx); 1800 } 1801 } 1802 1803 /* 1804 * This code generates a "reserved instruction" exception if the 1805 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, 1806 * Config2 TL, and Config5 L2C are unset. 1807 */ 1808 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) 1809 { 1810 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) && 1811 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) && 1812 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) && 1813 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && 1814 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && 1815 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) { 1816 gen_reserved_instruction(ctx); 1817 } 1818 } 1819 1820 /* 1821 * This code generates a "reserved instruction" exception if the 1822 * Config5 EVA bit is NOT set. 1823 */ 1824 static inline void check_eva(DisasContext *ctx) 1825 { 1826 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) { 1827 gen_reserved_instruction(ctx); 1828 } 1829 } 1830 1831 1832 /* 1833 * Define small wrappers for gen_load_fpr* so that we have a uniform 1834 * calling interface for 32 and 64-bit FPRs. No sense in changing 1835 * all callers for gen_load_fpr32 when we need the CTX parameter for 1836 * this one use. 1837 */ 1838 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) 1839 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) 1840 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \ 1841 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ 1842 int ft, int fs, int cc) \ 1843 { \ 1844 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ 1845 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ 1846 switch (ifmt) { \ 1847 case FMT_PS: \ 1848 check_ps(ctx); \ 1849 break; \ 1850 case FMT_D: \ 1851 if (abs) { \ 1852 check_cop1x(ctx); \ 1853 } \ 1854 check_cp1_registers(ctx, fs | ft); \ 1855 break; \ 1856 case FMT_S: \ 1857 if (abs) { \ 1858 check_cop1x(ctx); \ 1859 } \ 1860 break; \ 1861 } \ 1862 gen_ldcmp_fpr##bits(ctx, fp0, fs); \ 1863 gen_ldcmp_fpr##bits(ctx, fp1, ft); \ 1864 switch (n) { \ 1865 case 0: \ 1866 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \ 1867 break; \ 1868 case 1: \ 1869 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \ 1870 break; \ 1871 case 2: \ 1872 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \ 1873 break; \ 1874 case 3: \ 1875 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \ 1876 break; \ 1877 case 4: \ 1878 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \ 1879 break; \ 1880 case 5: \ 1881 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \ 1882 break; \ 1883 case 6: \ 1884 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \ 1885 break; \ 1886 case 7: \ 1887 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \ 1888 break; \ 1889 case 8: \ 1890 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \ 1891 break; \ 1892 case 9: \ 1893 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \ 1894 break; \ 1895 case 10: \ 1896 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \ 1897 break; \ 1898 case 11: \ 1899 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \ 1900 break; \ 1901 case 12: \ 1902 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \ 1903 break; \ 1904 case 13: \ 1905 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \ 1906 break; \ 1907 case 14: \ 1908 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \ 1909 break; \ 1910 case 15: \ 1911 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \ 1912 break; \ 1913 default: \ 1914 abort(); \ 1915 } \ 1916 tcg_temp_free_i##bits(fp0); \ 1917 tcg_temp_free_i##bits(fp1); \ 1918 } 1919 1920 FOP_CONDS(, 0, d, FMT_D, 64) 1921 FOP_CONDS(abs, 1, d, FMT_D, 64) 1922 FOP_CONDS(, 0, s, FMT_S, 32) 1923 FOP_CONDS(abs, 1, s, FMT_S, 32) 1924 FOP_CONDS(, 0, ps, FMT_PS, 64) 1925 FOP_CONDS(abs, 1, ps, FMT_PS, 64) 1926 #undef FOP_CONDS 1927 1928 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \ 1929 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \ 1930 int ft, int fs, int fd) \ 1931 { \ 1932 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ 1933 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ 1934 if (ifmt == FMT_D) { \ 1935 check_cp1_registers(ctx, fs | ft | fd); \ 1936 } \ 1937 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ 1938 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ 1939 switch (n) { \ 1940 case 0: \ 1941 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \ 1942 break; \ 1943 case 1: \ 1944 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \ 1945 break; \ 1946 case 2: \ 1947 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \ 1948 break; \ 1949 case 3: \ 1950 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \ 1951 break; \ 1952 case 4: \ 1953 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \ 1954 break; \ 1955 case 5: \ 1956 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \ 1957 break; \ 1958 case 6: \ 1959 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \ 1960 break; \ 1961 case 7: \ 1962 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \ 1963 break; \ 1964 case 8: \ 1965 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \ 1966 break; \ 1967 case 9: \ 1968 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \ 1969 break; \ 1970 case 10: \ 1971 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \ 1972 break; \ 1973 case 11: \ 1974 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \ 1975 break; \ 1976 case 12: \ 1977 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \ 1978 break; \ 1979 case 13: \ 1980 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \ 1981 break; \ 1982 case 14: \ 1983 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \ 1984 break; \ 1985 case 15: \ 1986 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \ 1987 break; \ 1988 case 17: \ 1989 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \ 1990 break; \ 1991 case 18: \ 1992 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \ 1993 break; \ 1994 case 19: \ 1995 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \ 1996 break; \ 1997 case 25: \ 1998 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \ 1999 break; \ 2000 case 26: \ 2001 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \ 2002 break; \ 2003 case 27: \ 2004 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \ 2005 break; \ 2006 default: \ 2007 abort(); \ 2008 } \ 2009 STORE; \ 2010 tcg_temp_free_i ## bits(fp0); \ 2011 tcg_temp_free_i ## bits(fp1); \ 2012 } 2013 2014 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) 2015 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd)) 2016 #undef FOP_CONDNS 2017 #undef gen_ldcmp_fpr32 2018 #undef gen_ldcmp_fpr64 2019 2020 /* load/store instructions. */ 2021 #ifdef CONFIG_USER_ONLY 2022 #define OP_LD_ATOMIC(insn, fname) \ 2023 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 2024 DisasContext *ctx) \ 2025 { \ 2026 TCGv t0 = tcg_temp_new(); \ 2027 tcg_gen_mov_tl(t0, arg1); \ 2028 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ 2029 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \ 2030 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \ 2031 tcg_temp_free(t0); \ 2032 } 2033 #else 2034 #define OP_LD_ATOMIC(insn, fname) \ 2035 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 2036 DisasContext *ctx) \ 2037 { \ 2038 gen_helper_1e1i(insn, ret, arg1, mem_idx); \ 2039 } 2040 #endif 2041 OP_LD_ATOMIC(ll, ld32s); 2042 #if defined(TARGET_MIPS64) 2043 OP_LD_ATOMIC(lld, ld64); 2044 #endif 2045 #undef OP_LD_ATOMIC 2046 2047 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset) 2048 { 2049 if (base == 0) { 2050 tcg_gen_movi_tl(addr, offset); 2051 } else if (offset == 0) { 2052 gen_load_gpr(addr, base); 2053 } else { 2054 tcg_gen_movi_tl(addr, offset); 2055 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); 2056 } 2057 } 2058 2059 static target_ulong pc_relative_pc(DisasContext *ctx) 2060 { 2061 target_ulong pc = ctx->base.pc_next; 2062 2063 if (ctx->hflags & MIPS_HFLAG_BMASK) { 2064 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4; 2065 2066 pc -= branch_bytes; 2067 } 2068 2069 pc &= ~(target_ulong)3; 2070 return pc; 2071 } 2072 2073 /* Load */ 2074 static void gen_ld(DisasContext *ctx, uint32_t opc, 2075 int rt, int base, int offset) 2076 { 2077 TCGv t0, t1, t2; 2078 int mem_idx = ctx->mem_idx; 2079 2080 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F | 2081 INSN_LOONGSON3A)) { 2082 /* 2083 * Loongson CPU uses a load to zero register for prefetch. 2084 * We emulate it as a NOP. On other CPU we must perform the 2085 * actual memory access. 2086 */ 2087 return; 2088 } 2089 2090 t0 = tcg_temp_new(); 2091 gen_base_offset_addr(ctx, t0, base, offset); 2092 2093 switch (opc) { 2094 #if defined(TARGET_MIPS64) 2095 case OPC_LWU: 2096 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL | 2097 ctx->default_tcg_memop_mask); 2098 gen_store_gpr(t0, rt); 2099 break; 2100 case OPC_LD: 2101 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ | 2102 ctx->default_tcg_memop_mask); 2103 gen_store_gpr(t0, rt); 2104 break; 2105 case OPC_LLD: 2106 case R6_OPC_LLD: 2107 op_ld_lld(t0, t0, mem_idx, ctx); 2108 gen_store_gpr(t0, rt); 2109 break; 2110 case OPC_LDL: 2111 t1 = tcg_temp_new(); 2112 /* 2113 * Do a byte access to possibly trigger a page 2114 * fault with the unaligned address. 2115 */ 2116 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2117 tcg_gen_andi_tl(t1, t0, 7); 2118 #ifndef TARGET_WORDS_BIGENDIAN 2119 tcg_gen_xori_tl(t1, t1, 7); 2120 #endif 2121 tcg_gen_shli_tl(t1, t1, 3); 2122 tcg_gen_andi_tl(t0, t0, ~7); 2123 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); 2124 tcg_gen_shl_tl(t0, t0, t1); 2125 t2 = tcg_const_tl(-1); 2126 tcg_gen_shl_tl(t2, t2, t1); 2127 gen_load_gpr(t1, rt); 2128 tcg_gen_andc_tl(t1, t1, t2); 2129 tcg_temp_free(t2); 2130 tcg_gen_or_tl(t0, t0, t1); 2131 tcg_temp_free(t1); 2132 gen_store_gpr(t0, rt); 2133 break; 2134 case OPC_LDR: 2135 t1 = tcg_temp_new(); 2136 /* 2137 * Do a byte access to possibly trigger a page 2138 * fault with the unaligned address. 2139 */ 2140 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2141 tcg_gen_andi_tl(t1, t0, 7); 2142 #ifdef TARGET_WORDS_BIGENDIAN 2143 tcg_gen_xori_tl(t1, t1, 7); 2144 #endif 2145 tcg_gen_shli_tl(t1, t1, 3); 2146 tcg_gen_andi_tl(t0, t0, ~7); 2147 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); 2148 tcg_gen_shr_tl(t0, t0, t1); 2149 tcg_gen_xori_tl(t1, t1, 63); 2150 t2 = tcg_const_tl(0xfffffffffffffffeull); 2151 tcg_gen_shl_tl(t2, t2, t1); 2152 gen_load_gpr(t1, rt); 2153 tcg_gen_and_tl(t1, t1, t2); 2154 tcg_temp_free(t2); 2155 tcg_gen_or_tl(t0, t0, t1); 2156 tcg_temp_free(t1); 2157 gen_store_gpr(t0, rt); 2158 break; 2159 case OPC_LDPC: 2160 t1 = tcg_const_tl(pc_relative_pc(ctx)); 2161 gen_op_addr_add(ctx, t0, t0, t1); 2162 tcg_temp_free(t1); 2163 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); 2164 gen_store_gpr(t0, rt); 2165 break; 2166 #endif 2167 case OPC_LWPC: 2168 t1 = tcg_const_tl(pc_relative_pc(ctx)); 2169 gen_op_addr_add(ctx, t0, t0, t1); 2170 tcg_temp_free(t1); 2171 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL); 2172 gen_store_gpr(t0, rt); 2173 break; 2174 case OPC_LWE: 2175 mem_idx = MIPS_HFLAG_UM; 2176 /* fall through */ 2177 case OPC_LW: 2178 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL | 2179 ctx->default_tcg_memop_mask); 2180 gen_store_gpr(t0, rt); 2181 break; 2182 case OPC_LHE: 2183 mem_idx = MIPS_HFLAG_UM; 2184 /* fall through */ 2185 case OPC_LH: 2186 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW | 2187 ctx->default_tcg_memop_mask); 2188 gen_store_gpr(t0, rt); 2189 break; 2190 case OPC_LHUE: 2191 mem_idx = MIPS_HFLAG_UM; 2192 /* fall through */ 2193 case OPC_LHU: 2194 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW | 2195 ctx->default_tcg_memop_mask); 2196 gen_store_gpr(t0, rt); 2197 break; 2198 case OPC_LBE: 2199 mem_idx = MIPS_HFLAG_UM; 2200 /* fall through */ 2201 case OPC_LB: 2202 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); 2203 gen_store_gpr(t0, rt); 2204 break; 2205 case OPC_LBUE: 2206 mem_idx = MIPS_HFLAG_UM; 2207 /* fall through */ 2208 case OPC_LBU: 2209 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); 2210 gen_store_gpr(t0, rt); 2211 break; 2212 case OPC_LWLE: 2213 mem_idx = MIPS_HFLAG_UM; 2214 /* fall through */ 2215 case OPC_LWL: 2216 t1 = tcg_temp_new(); 2217 /* 2218 * Do a byte access to possibly trigger a page 2219 * fault with the unaligned address. 2220 */ 2221 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2222 tcg_gen_andi_tl(t1, t0, 3); 2223 #ifndef TARGET_WORDS_BIGENDIAN 2224 tcg_gen_xori_tl(t1, t1, 3); 2225 #endif 2226 tcg_gen_shli_tl(t1, t1, 3); 2227 tcg_gen_andi_tl(t0, t0, ~3); 2228 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); 2229 tcg_gen_shl_tl(t0, t0, t1); 2230 t2 = tcg_const_tl(-1); 2231 tcg_gen_shl_tl(t2, t2, t1); 2232 gen_load_gpr(t1, rt); 2233 tcg_gen_andc_tl(t1, t1, t2); 2234 tcg_temp_free(t2); 2235 tcg_gen_or_tl(t0, t0, t1); 2236 tcg_temp_free(t1); 2237 tcg_gen_ext32s_tl(t0, t0); 2238 gen_store_gpr(t0, rt); 2239 break; 2240 case OPC_LWRE: 2241 mem_idx = MIPS_HFLAG_UM; 2242 /* fall through */ 2243 case OPC_LWR: 2244 t1 = tcg_temp_new(); 2245 /* 2246 * Do a byte access to possibly trigger a page 2247 * fault with the unaligned address. 2248 */ 2249 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2250 tcg_gen_andi_tl(t1, t0, 3); 2251 #ifdef TARGET_WORDS_BIGENDIAN 2252 tcg_gen_xori_tl(t1, t1, 3); 2253 #endif 2254 tcg_gen_shli_tl(t1, t1, 3); 2255 tcg_gen_andi_tl(t0, t0, ~3); 2256 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); 2257 tcg_gen_shr_tl(t0, t0, t1); 2258 tcg_gen_xori_tl(t1, t1, 31); 2259 t2 = tcg_const_tl(0xfffffffeull); 2260 tcg_gen_shl_tl(t2, t2, t1); 2261 gen_load_gpr(t1, rt); 2262 tcg_gen_and_tl(t1, t1, t2); 2263 tcg_temp_free(t2); 2264 tcg_gen_or_tl(t0, t0, t1); 2265 tcg_temp_free(t1); 2266 tcg_gen_ext32s_tl(t0, t0); 2267 gen_store_gpr(t0, rt); 2268 break; 2269 case OPC_LLE: 2270 mem_idx = MIPS_HFLAG_UM; 2271 /* fall through */ 2272 case OPC_LL: 2273 case R6_OPC_LL: 2274 op_ld_ll(t0, t0, mem_idx, ctx); 2275 gen_store_gpr(t0, rt); 2276 break; 2277 } 2278 tcg_temp_free(t0); 2279 } 2280 2281 /* Store */ 2282 static void gen_st(DisasContext *ctx, uint32_t opc, int rt, 2283 int base, int offset) 2284 { 2285 TCGv t0 = tcg_temp_new(); 2286 TCGv t1 = tcg_temp_new(); 2287 int mem_idx = ctx->mem_idx; 2288 2289 gen_base_offset_addr(ctx, t0, base, offset); 2290 gen_load_gpr(t1, rt); 2291 switch (opc) { 2292 #if defined(TARGET_MIPS64) 2293 case OPC_SD: 2294 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ | 2295 ctx->default_tcg_memop_mask); 2296 break; 2297 case OPC_SDL: 2298 gen_helper_0e2i(sdl, t1, t0, mem_idx); 2299 break; 2300 case OPC_SDR: 2301 gen_helper_0e2i(sdr, t1, t0, mem_idx); 2302 break; 2303 #endif 2304 case OPC_SWE: 2305 mem_idx = MIPS_HFLAG_UM; 2306 /* fall through */ 2307 case OPC_SW: 2308 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | 2309 ctx->default_tcg_memop_mask); 2310 break; 2311 case OPC_SHE: 2312 mem_idx = MIPS_HFLAG_UM; 2313 /* fall through */ 2314 case OPC_SH: 2315 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | 2316 ctx->default_tcg_memop_mask); 2317 break; 2318 case OPC_SBE: 2319 mem_idx = MIPS_HFLAG_UM; 2320 /* fall through */ 2321 case OPC_SB: 2322 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); 2323 break; 2324 case OPC_SWLE: 2325 mem_idx = MIPS_HFLAG_UM; 2326 /* fall through */ 2327 case OPC_SWL: 2328 gen_helper_0e2i(swl, t1, t0, mem_idx); 2329 break; 2330 case OPC_SWRE: 2331 mem_idx = MIPS_HFLAG_UM; 2332 /* fall through */ 2333 case OPC_SWR: 2334 gen_helper_0e2i(swr, t1, t0, mem_idx); 2335 break; 2336 } 2337 tcg_temp_free(t0); 2338 tcg_temp_free(t1); 2339 } 2340 2341 2342 /* Store conditional */ 2343 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, 2344 MemOp tcg_mo, bool eva) 2345 { 2346 TCGv addr, t0, val; 2347 TCGLabel *l1 = gen_new_label(); 2348 TCGLabel *done = gen_new_label(); 2349 2350 t0 = tcg_temp_new(); 2351 addr = tcg_temp_new(); 2352 /* compare the address against that of the preceding LL */ 2353 gen_base_offset_addr(ctx, addr, base, offset); 2354 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); 2355 tcg_temp_free(addr); 2356 tcg_gen_movi_tl(t0, 0); 2357 gen_store_gpr(t0, rt); 2358 tcg_gen_br(done); 2359 2360 gen_set_label(l1); 2361 /* generate cmpxchg */ 2362 val = tcg_temp_new(); 2363 gen_load_gpr(val, rt); 2364 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, 2365 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo); 2366 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); 2367 gen_store_gpr(t0, rt); 2368 tcg_temp_free(val); 2369 2370 gen_set_label(done); 2371 tcg_temp_free(t0); 2372 } 2373 2374 /* Load and store */ 2375 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, 2376 TCGv t0) 2377 { 2378 /* 2379 * Don't do NOP if destination is zero: we must perform the actual 2380 * memory access. 2381 */ 2382 switch (opc) { 2383 case OPC_LWC1: 2384 { 2385 TCGv_i32 fp0 = tcg_temp_new_i32(); 2386 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | 2387 ctx->default_tcg_memop_mask); 2388 gen_store_fpr32(ctx, fp0, ft); 2389 tcg_temp_free_i32(fp0); 2390 } 2391 break; 2392 case OPC_SWC1: 2393 { 2394 TCGv_i32 fp0 = tcg_temp_new_i32(); 2395 gen_load_fpr32(ctx, fp0, ft); 2396 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | 2397 ctx->default_tcg_memop_mask); 2398 tcg_temp_free_i32(fp0); 2399 } 2400 break; 2401 case OPC_LDC1: 2402 { 2403 TCGv_i64 fp0 = tcg_temp_new_i64(); 2404 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ | 2405 ctx->default_tcg_memop_mask); 2406 gen_store_fpr64(ctx, fp0, ft); 2407 tcg_temp_free_i64(fp0); 2408 } 2409 break; 2410 case OPC_SDC1: 2411 { 2412 TCGv_i64 fp0 = tcg_temp_new_i64(); 2413 gen_load_fpr64(ctx, fp0, ft); 2414 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ | 2415 ctx->default_tcg_memop_mask); 2416 tcg_temp_free_i64(fp0); 2417 } 2418 break; 2419 default: 2420 MIPS_INVAL("flt_ldst"); 2421 gen_reserved_instruction(ctx); 2422 break; 2423 } 2424 } 2425 2426 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, 2427 int rs, int16_t imm) 2428 { 2429 TCGv t0 = tcg_temp_new(); 2430 2431 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2432 check_cp1_enabled(ctx); 2433 switch (op) { 2434 case OPC_LDC1: 2435 case OPC_SDC1: 2436 check_insn(ctx, ISA_MIPS2); 2437 /* Fallthrough */ 2438 default: 2439 gen_base_offset_addr(ctx, t0, rs, imm); 2440 gen_flt_ldst(ctx, op, rt, t0); 2441 } 2442 } else { 2443 generate_exception_err(ctx, EXCP_CpU, 1); 2444 } 2445 tcg_temp_free(t0); 2446 } 2447 2448 /* Arithmetic with immediate operand */ 2449 static void gen_arith_imm(DisasContext *ctx, uint32_t opc, 2450 int rt, int rs, int imm) 2451 { 2452 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2453 2454 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 2455 /* 2456 * If no destination, treat it as a NOP. 2457 * For addi, we must generate the overflow exception when needed. 2458 */ 2459 return; 2460 } 2461 switch (opc) { 2462 case OPC_ADDI: 2463 { 2464 TCGv t0 = tcg_temp_local_new(); 2465 TCGv t1 = tcg_temp_new(); 2466 TCGv t2 = tcg_temp_new(); 2467 TCGLabel *l1 = gen_new_label(); 2468 2469 gen_load_gpr(t1, rs); 2470 tcg_gen_addi_tl(t0, t1, uimm); 2471 tcg_gen_ext32s_tl(t0, t0); 2472 2473 tcg_gen_xori_tl(t1, t1, ~uimm); 2474 tcg_gen_xori_tl(t2, t0, uimm); 2475 tcg_gen_and_tl(t1, t1, t2); 2476 tcg_temp_free(t2); 2477 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2478 tcg_temp_free(t1); 2479 /* operands of same sign, result different sign */ 2480 generate_exception(ctx, EXCP_OVERFLOW); 2481 gen_set_label(l1); 2482 tcg_gen_ext32s_tl(t0, t0); 2483 gen_store_gpr(t0, rt); 2484 tcg_temp_free(t0); 2485 } 2486 break; 2487 case OPC_ADDIU: 2488 if (rs != 0) { 2489 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2490 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2491 } else { 2492 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2493 } 2494 break; 2495 #if defined(TARGET_MIPS64) 2496 case OPC_DADDI: 2497 { 2498 TCGv t0 = tcg_temp_local_new(); 2499 TCGv t1 = tcg_temp_new(); 2500 TCGv t2 = tcg_temp_new(); 2501 TCGLabel *l1 = gen_new_label(); 2502 2503 gen_load_gpr(t1, rs); 2504 tcg_gen_addi_tl(t0, t1, uimm); 2505 2506 tcg_gen_xori_tl(t1, t1, ~uimm); 2507 tcg_gen_xori_tl(t2, t0, uimm); 2508 tcg_gen_and_tl(t1, t1, t2); 2509 tcg_temp_free(t2); 2510 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2511 tcg_temp_free(t1); 2512 /* operands of same sign, result different sign */ 2513 generate_exception(ctx, EXCP_OVERFLOW); 2514 gen_set_label(l1); 2515 gen_store_gpr(t0, rt); 2516 tcg_temp_free(t0); 2517 } 2518 break; 2519 case OPC_DADDIU: 2520 if (rs != 0) { 2521 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2522 } else { 2523 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2524 } 2525 break; 2526 #endif 2527 } 2528 } 2529 2530 /* Logic with immediate operand */ 2531 static void gen_logic_imm(DisasContext *ctx, uint32_t opc, 2532 int rt, int rs, int16_t imm) 2533 { 2534 target_ulong uimm; 2535 2536 if (rt == 0) { 2537 /* If no destination, treat it as a NOP. */ 2538 return; 2539 } 2540 uimm = (uint16_t)imm; 2541 switch (opc) { 2542 case OPC_ANDI: 2543 if (likely(rs != 0)) { 2544 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2545 } else { 2546 tcg_gen_movi_tl(cpu_gpr[rt], 0); 2547 } 2548 break; 2549 case OPC_ORI: 2550 if (rs != 0) { 2551 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2552 } else { 2553 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2554 } 2555 break; 2556 case OPC_XORI: 2557 if (likely(rs != 0)) { 2558 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2559 } else { 2560 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2561 } 2562 break; 2563 case OPC_LUI: 2564 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) { 2565 /* OPC_AUI */ 2566 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16); 2567 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2568 } else { 2569 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 2570 } 2571 break; 2572 2573 default: 2574 break; 2575 } 2576 } 2577 2578 /* Set on less than with immediate operand */ 2579 static void gen_slt_imm(DisasContext *ctx, uint32_t opc, 2580 int rt, int rs, int16_t imm) 2581 { 2582 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2583 TCGv t0; 2584 2585 if (rt == 0) { 2586 /* If no destination, treat it as a NOP. */ 2587 return; 2588 } 2589 t0 = tcg_temp_new(); 2590 gen_load_gpr(t0, rs); 2591 switch (opc) { 2592 case OPC_SLTI: 2593 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); 2594 break; 2595 case OPC_SLTIU: 2596 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); 2597 break; 2598 } 2599 tcg_temp_free(t0); 2600 } 2601 2602 /* Shifts with immediate operand */ 2603 static void gen_shift_imm(DisasContext *ctx, uint32_t opc, 2604 int rt, int rs, int16_t imm) 2605 { 2606 target_ulong uimm = ((uint16_t)imm) & 0x1f; 2607 TCGv t0; 2608 2609 if (rt == 0) { 2610 /* If no destination, treat it as a NOP. */ 2611 return; 2612 } 2613 2614 t0 = tcg_temp_new(); 2615 gen_load_gpr(t0, rs); 2616 switch (opc) { 2617 case OPC_SLL: 2618 tcg_gen_shli_tl(t0, t0, uimm); 2619 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2620 break; 2621 case OPC_SRA: 2622 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2623 break; 2624 case OPC_SRL: 2625 if (uimm != 0) { 2626 tcg_gen_ext32u_tl(t0, t0); 2627 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2628 } else { 2629 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2630 } 2631 break; 2632 case OPC_ROTR: 2633 if (uimm != 0) { 2634 TCGv_i32 t1 = tcg_temp_new_i32(); 2635 2636 tcg_gen_trunc_tl_i32(t1, t0); 2637 tcg_gen_rotri_i32(t1, t1, uimm); 2638 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 2639 tcg_temp_free_i32(t1); 2640 } else { 2641 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2642 } 2643 break; 2644 #if defined(TARGET_MIPS64) 2645 case OPC_DSLL: 2646 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 2647 break; 2648 case OPC_DSRA: 2649 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2650 break; 2651 case OPC_DSRL: 2652 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2653 break; 2654 case OPC_DROTR: 2655 if (uimm != 0) { 2656 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 2657 } else { 2658 tcg_gen_mov_tl(cpu_gpr[rt], t0); 2659 } 2660 break; 2661 case OPC_DSLL32: 2662 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 2663 break; 2664 case OPC_DSRA32: 2665 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 2666 break; 2667 case OPC_DSRL32: 2668 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 2669 break; 2670 case OPC_DROTR32: 2671 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 2672 break; 2673 #endif 2674 } 2675 tcg_temp_free(t0); 2676 } 2677 2678 /* Arithmetic */ 2679 static void gen_arith(DisasContext *ctx, uint32_t opc, 2680 int rd, int rs, int rt) 2681 { 2682 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 2683 && opc != OPC_DADD && opc != OPC_DSUB) { 2684 /* 2685 * If no destination, treat it as a NOP. 2686 * For add & sub, we must generate the overflow exception when needed. 2687 */ 2688 return; 2689 } 2690 2691 switch (opc) { 2692 case OPC_ADD: 2693 { 2694 TCGv t0 = tcg_temp_local_new(); 2695 TCGv t1 = tcg_temp_new(); 2696 TCGv t2 = tcg_temp_new(); 2697 TCGLabel *l1 = gen_new_label(); 2698 2699 gen_load_gpr(t1, rs); 2700 gen_load_gpr(t2, rt); 2701 tcg_gen_add_tl(t0, t1, t2); 2702 tcg_gen_ext32s_tl(t0, t0); 2703 tcg_gen_xor_tl(t1, t1, t2); 2704 tcg_gen_xor_tl(t2, t0, t2); 2705 tcg_gen_andc_tl(t1, t2, t1); 2706 tcg_temp_free(t2); 2707 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2708 tcg_temp_free(t1); 2709 /* operands of same sign, result different sign */ 2710 generate_exception(ctx, EXCP_OVERFLOW); 2711 gen_set_label(l1); 2712 gen_store_gpr(t0, rd); 2713 tcg_temp_free(t0); 2714 } 2715 break; 2716 case OPC_ADDU: 2717 if (rs != 0 && rt != 0) { 2718 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2719 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2720 } else if (rs == 0 && rt != 0) { 2721 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2722 } else if (rs != 0 && rt == 0) { 2723 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2724 } else { 2725 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2726 } 2727 break; 2728 case OPC_SUB: 2729 { 2730 TCGv t0 = tcg_temp_local_new(); 2731 TCGv t1 = tcg_temp_new(); 2732 TCGv t2 = tcg_temp_new(); 2733 TCGLabel *l1 = gen_new_label(); 2734 2735 gen_load_gpr(t1, rs); 2736 gen_load_gpr(t2, rt); 2737 tcg_gen_sub_tl(t0, t1, t2); 2738 tcg_gen_ext32s_tl(t0, t0); 2739 tcg_gen_xor_tl(t2, t1, t2); 2740 tcg_gen_xor_tl(t1, t0, t1); 2741 tcg_gen_and_tl(t1, t1, t2); 2742 tcg_temp_free(t2); 2743 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2744 tcg_temp_free(t1); 2745 /* 2746 * operands of different sign, first operand and the result 2747 * of different sign 2748 */ 2749 generate_exception(ctx, EXCP_OVERFLOW); 2750 gen_set_label(l1); 2751 gen_store_gpr(t0, rd); 2752 tcg_temp_free(t0); 2753 } 2754 break; 2755 case OPC_SUBU: 2756 if (rs != 0 && rt != 0) { 2757 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2758 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2759 } else if (rs == 0 && rt != 0) { 2760 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2761 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2762 } else if (rs != 0 && rt == 0) { 2763 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2764 } else { 2765 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2766 } 2767 break; 2768 #if defined(TARGET_MIPS64) 2769 case OPC_DADD: 2770 { 2771 TCGv t0 = tcg_temp_local_new(); 2772 TCGv t1 = tcg_temp_new(); 2773 TCGv t2 = tcg_temp_new(); 2774 TCGLabel *l1 = gen_new_label(); 2775 2776 gen_load_gpr(t1, rs); 2777 gen_load_gpr(t2, rt); 2778 tcg_gen_add_tl(t0, t1, t2); 2779 tcg_gen_xor_tl(t1, t1, t2); 2780 tcg_gen_xor_tl(t2, t0, t2); 2781 tcg_gen_andc_tl(t1, t2, t1); 2782 tcg_temp_free(t2); 2783 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2784 tcg_temp_free(t1); 2785 /* operands of same sign, result different sign */ 2786 generate_exception(ctx, EXCP_OVERFLOW); 2787 gen_set_label(l1); 2788 gen_store_gpr(t0, rd); 2789 tcg_temp_free(t0); 2790 } 2791 break; 2792 case OPC_DADDU: 2793 if (rs != 0 && rt != 0) { 2794 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2795 } else if (rs == 0 && rt != 0) { 2796 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2797 } else if (rs != 0 && rt == 0) { 2798 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2799 } else { 2800 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2801 } 2802 break; 2803 case OPC_DSUB: 2804 { 2805 TCGv t0 = tcg_temp_local_new(); 2806 TCGv t1 = tcg_temp_new(); 2807 TCGv t2 = tcg_temp_new(); 2808 TCGLabel *l1 = gen_new_label(); 2809 2810 gen_load_gpr(t1, rs); 2811 gen_load_gpr(t2, rt); 2812 tcg_gen_sub_tl(t0, t1, t2); 2813 tcg_gen_xor_tl(t2, t1, t2); 2814 tcg_gen_xor_tl(t1, t0, t1); 2815 tcg_gen_and_tl(t1, t1, t2); 2816 tcg_temp_free(t2); 2817 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2818 tcg_temp_free(t1); 2819 /* 2820 * Operands of different sign, first operand and result different 2821 * sign. 2822 */ 2823 generate_exception(ctx, EXCP_OVERFLOW); 2824 gen_set_label(l1); 2825 gen_store_gpr(t0, rd); 2826 tcg_temp_free(t0); 2827 } 2828 break; 2829 case OPC_DSUBU: 2830 if (rs != 0 && rt != 0) { 2831 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2832 } else if (rs == 0 && rt != 0) { 2833 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2834 } else if (rs != 0 && rt == 0) { 2835 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2836 } else { 2837 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2838 } 2839 break; 2840 #endif 2841 case OPC_MUL: 2842 if (likely(rs != 0 && rt != 0)) { 2843 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2844 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2845 } else { 2846 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2847 } 2848 break; 2849 } 2850 } 2851 2852 /* Conditional move */ 2853 static void gen_cond_move(DisasContext *ctx, uint32_t opc, 2854 int rd, int rs, int rt) 2855 { 2856 TCGv t0, t1, t2; 2857 2858 if (rd == 0) { 2859 /* If no destination, treat it as a NOP. */ 2860 return; 2861 } 2862 2863 t0 = tcg_temp_new(); 2864 gen_load_gpr(t0, rt); 2865 t1 = tcg_const_tl(0); 2866 t2 = tcg_temp_new(); 2867 gen_load_gpr(t2, rs); 2868 switch (opc) { 2869 case OPC_MOVN: 2870 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2871 break; 2872 case OPC_MOVZ: 2873 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2874 break; 2875 case OPC_SELNEZ: 2876 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); 2877 break; 2878 case OPC_SELEQZ: 2879 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); 2880 break; 2881 } 2882 tcg_temp_free(t2); 2883 tcg_temp_free(t1); 2884 tcg_temp_free(t0); 2885 } 2886 2887 /* Logic */ 2888 static void gen_logic(DisasContext *ctx, uint32_t opc, 2889 int rd, int rs, int rt) 2890 { 2891 if (rd == 0) { 2892 /* If no destination, treat it as a NOP. */ 2893 return; 2894 } 2895 2896 switch (opc) { 2897 case OPC_AND: 2898 if (likely(rs != 0 && rt != 0)) { 2899 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2900 } else { 2901 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2902 } 2903 break; 2904 case OPC_NOR: 2905 if (rs != 0 && rt != 0) { 2906 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2907 } else if (rs == 0 && rt != 0) { 2908 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 2909 } else if (rs != 0 && rt == 0) { 2910 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 2911 } else { 2912 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 2913 } 2914 break; 2915 case OPC_OR: 2916 if (likely(rs != 0 && rt != 0)) { 2917 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2918 } else if (rs == 0 && rt != 0) { 2919 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2920 } else if (rs != 0 && rt == 0) { 2921 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2922 } else { 2923 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2924 } 2925 break; 2926 case OPC_XOR: 2927 if (likely(rs != 0 && rt != 0)) { 2928 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2929 } else if (rs == 0 && rt != 0) { 2930 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2931 } else if (rs != 0 && rt == 0) { 2932 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2933 } else { 2934 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2935 } 2936 break; 2937 } 2938 } 2939 2940 /* Set on lower than */ 2941 static void gen_slt(DisasContext *ctx, uint32_t opc, 2942 int rd, int rs, int rt) 2943 { 2944 TCGv t0, t1; 2945 2946 if (rd == 0) { 2947 /* If no destination, treat it as a NOP. */ 2948 return; 2949 } 2950 2951 t0 = tcg_temp_new(); 2952 t1 = tcg_temp_new(); 2953 gen_load_gpr(t0, rs); 2954 gen_load_gpr(t1, rt); 2955 switch (opc) { 2956 case OPC_SLT: 2957 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); 2958 break; 2959 case OPC_SLTU: 2960 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); 2961 break; 2962 } 2963 tcg_temp_free(t0); 2964 tcg_temp_free(t1); 2965 } 2966 2967 /* Shifts */ 2968 static void gen_shift(DisasContext *ctx, uint32_t opc, 2969 int rd, int rs, int rt) 2970 { 2971 TCGv t0, t1; 2972 2973 if (rd == 0) { 2974 /* 2975 * If no destination, treat it as a NOP. 2976 * For add & sub, we must generate the overflow exception when needed. 2977 */ 2978 return; 2979 } 2980 2981 t0 = tcg_temp_new(); 2982 t1 = tcg_temp_new(); 2983 gen_load_gpr(t0, rs); 2984 gen_load_gpr(t1, rt); 2985 switch (opc) { 2986 case OPC_SLLV: 2987 tcg_gen_andi_tl(t0, t0, 0x1f); 2988 tcg_gen_shl_tl(t0, t1, t0); 2989 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2990 break; 2991 case OPC_SRAV: 2992 tcg_gen_andi_tl(t0, t0, 0x1f); 2993 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2994 break; 2995 case OPC_SRLV: 2996 tcg_gen_ext32u_tl(t1, t1); 2997 tcg_gen_andi_tl(t0, t0, 0x1f); 2998 tcg_gen_shr_tl(t0, t1, t0); 2999 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 3000 break; 3001 case OPC_ROTRV: 3002 { 3003 TCGv_i32 t2 = tcg_temp_new_i32(); 3004 TCGv_i32 t3 = tcg_temp_new_i32(); 3005 3006 tcg_gen_trunc_tl_i32(t2, t0); 3007 tcg_gen_trunc_tl_i32(t3, t1); 3008 tcg_gen_andi_i32(t2, t2, 0x1f); 3009 tcg_gen_rotr_i32(t2, t3, t2); 3010 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3011 tcg_temp_free_i32(t2); 3012 tcg_temp_free_i32(t3); 3013 } 3014 break; 3015 #if defined(TARGET_MIPS64) 3016 case OPC_DSLLV: 3017 tcg_gen_andi_tl(t0, t0, 0x3f); 3018 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 3019 break; 3020 case OPC_DSRAV: 3021 tcg_gen_andi_tl(t0, t0, 0x3f); 3022 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 3023 break; 3024 case OPC_DSRLV: 3025 tcg_gen_andi_tl(t0, t0, 0x3f); 3026 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 3027 break; 3028 case OPC_DROTRV: 3029 tcg_gen_andi_tl(t0, t0, 0x3f); 3030 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 3031 break; 3032 #endif 3033 } 3034 tcg_temp_free(t0); 3035 tcg_temp_free(t1); 3036 } 3037 3038 /* Arithmetic on HI/LO registers */ 3039 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) 3040 { 3041 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 3042 /* Treat as NOP. */ 3043 return; 3044 } 3045 3046 if (acc != 0) { 3047 check_dsp(ctx); 3048 } 3049 3050 switch (opc) { 3051 case OPC_MFHI: 3052 #if defined(TARGET_MIPS64) 3053 if (acc != 0) { 3054 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); 3055 } else 3056 #endif 3057 { 3058 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); 3059 } 3060 break; 3061 case OPC_MFLO: 3062 #if defined(TARGET_MIPS64) 3063 if (acc != 0) { 3064 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); 3065 } else 3066 #endif 3067 { 3068 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); 3069 } 3070 break; 3071 case OPC_MTHI: 3072 if (reg != 0) { 3073 #if defined(TARGET_MIPS64) 3074 if (acc != 0) { 3075 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); 3076 } else 3077 #endif 3078 { 3079 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); 3080 } 3081 } else { 3082 tcg_gen_movi_tl(cpu_HI[acc], 0); 3083 } 3084 break; 3085 case OPC_MTLO: 3086 if (reg != 0) { 3087 #if defined(TARGET_MIPS64) 3088 if (acc != 0) { 3089 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); 3090 } else 3091 #endif 3092 { 3093 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); 3094 } 3095 } else { 3096 tcg_gen_movi_tl(cpu_LO[acc], 0); 3097 } 3098 break; 3099 } 3100 } 3101 3102 static inline void gen_r6_ld(target_long addr, int reg, int memidx, 3103 MemOp memop) 3104 { 3105 TCGv t0 = tcg_const_tl(addr); 3106 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop); 3107 gen_store_gpr(t0, reg); 3108 tcg_temp_free(t0); 3109 } 3110 3111 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, 3112 int rs) 3113 { 3114 target_long offset; 3115 target_long addr; 3116 3117 switch (MASK_OPC_PCREL_TOP2BITS(opc)) { 3118 case OPC_ADDIUPC: 3119 if (rs != 0) { 3120 offset = sextract32(ctx->opcode << 2, 0, 21); 3121 addr = addr_add(ctx, pc, offset); 3122 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3123 } 3124 break; 3125 case R6_OPC_LWPC: 3126 offset = sextract32(ctx->opcode << 2, 0, 21); 3127 addr = addr_add(ctx, pc, offset); 3128 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL); 3129 break; 3130 #if defined(TARGET_MIPS64) 3131 case OPC_LWUPC: 3132 check_mips_64(ctx); 3133 offset = sextract32(ctx->opcode << 2, 0, 21); 3134 addr = addr_add(ctx, pc, offset); 3135 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL); 3136 break; 3137 #endif 3138 default: 3139 switch (MASK_OPC_PCREL_TOP5BITS(opc)) { 3140 case OPC_AUIPC: 3141 if (rs != 0) { 3142 offset = sextract32(ctx->opcode, 0, 16) << 16; 3143 addr = addr_add(ctx, pc, offset); 3144 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3145 } 3146 break; 3147 case OPC_ALUIPC: 3148 if (rs != 0) { 3149 offset = sextract32(ctx->opcode, 0, 16) << 16; 3150 addr = ~0xFFFF & addr_add(ctx, pc, offset); 3151 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3152 } 3153 break; 3154 #if defined(TARGET_MIPS64) 3155 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */ 3156 case R6_OPC_LDPC + (1 << 16): 3157 case R6_OPC_LDPC + (2 << 16): 3158 case R6_OPC_LDPC + (3 << 16): 3159 check_mips_64(ctx); 3160 offset = sextract32(ctx->opcode << 3, 0, 21); 3161 addr = addr_add(ctx, (pc & ~0x7), offset); 3162 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ); 3163 break; 3164 #endif 3165 default: 3166 MIPS_INVAL("OPC_PCREL"); 3167 gen_reserved_instruction(ctx); 3168 break; 3169 } 3170 break; 3171 } 3172 } 3173 3174 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) 3175 { 3176 TCGv t0, t1; 3177 3178 if (rd == 0) { 3179 /* Treat as NOP. */ 3180 return; 3181 } 3182 3183 t0 = tcg_temp_new(); 3184 t1 = tcg_temp_new(); 3185 3186 gen_load_gpr(t0, rs); 3187 gen_load_gpr(t1, rt); 3188 3189 switch (opc) { 3190 case R6_OPC_DIV: 3191 { 3192 TCGv t2 = tcg_temp_new(); 3193 TCGv t3 = tcg_temp_new(); 3194 tcg_gen_ext32s_tl(t0, t0); 3195 tcg_gen_ext32s_tl(t1, t1); 3196 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3197 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3198 tcg_gen_and_tl(t2, t2, t3); 3199 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3200 tcg_gen_or_tl(t2, t2, t3); 3201 tcg_gen_movi_tl(t3, 0); 3202 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3203 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3204 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3205 tcg_temp_free(t3); 3206 tcg_temp_free(t2); 3207 } 3208 break; 3209 case R6_OPC_MOD: 3210 { 3211 TCGv t2 = tcg_temp_new(); 3212 TCGv t3 = tcg_temp_new(); 3213 tcg_gen_ext32s_tl(t0, t0); 3214 tcg_gen_ext32s_tl(t1, t1); 3215 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3216 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3217 tcg_gen_and_tl(t2, t2, t3); 3218 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3219 tcg_gen_or_tl(t2, t2, t3); 3220 tcg_gen_movi_tl(t3, 0); 3221 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3222 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3223 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3224 tcg_temp_free(t3); 3225 tcg_temp_free(t2); 3226 } 3227 break; 3228 case R6_OPC_DIVU: 3229 { 3230 TCGv t2 = tcg_const_tl(0); 3231 TCGv t3 = tcg_const_tl(1); 3232 tcg_gen_ext32u_tl(t0, t0); 3233 tcg_gen_ext32u_tl(t1, t1); 3234 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3235 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3236 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3237 tcg_temp_free(t3); 3238 tcg_temp_free(t2); 3239 } 3240 break; 3241 case R6_OPC_MODU: 3242 { 3243 TCGv t2 = tcg_const_tl(0); 3244 TCGv t3 = tcg_const_tl(1); 3245 tcg_gen_ext32u_tl(t0, t0); 3246 tcg_gen_ext32u_tl(t1, t1); 3247 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3248 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3249 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3250 tcg_temp_free(t3); 3251 tcg_temp_free(t2); 3252 } 3253 break; 3254 case R6_OPC_MUL: 3255 { 3256 TCGv_i32 t2 = tcg_temp_new_i32(); 3257 TCGv_i32 t3 = tcg_temp_new_i32(); 3258 tcg_gen_trunc_tl_i32(t2, t0); 3259 tcg_gen_trunc_tl_i32(t3, t1); 3260 tcg_gen_mul_i32(t2, t2, t3); 3261 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3262 tcg_temp_free_i32(t2); 3263 tcg_temp_free_i32(t3); 3264 } 3265 break; 3266 case R6_OPC_MUH: 3267 { 3268 TCGv_i32 t2 = tcg_temp_new_i32(); 3269 TCGv_i32 t3 = tcg_temp_new_i32(); 3270 tcg_gen_trunc_tl_i32(t2, t0); 3271 tcg_gen_trunc_tl_i32(t3, t1); 3272 tcg_gen_muls2_i32(t2, t3, t2, t3); 3273 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3274 tcg_temp_free_i32(t2); 3275 tcg_temp_free_i32(t3); 3276 } 3277 break; 3278 case R6_OPC_MULU: 3279 { 3280 TCGv_i32 t2 = tcg_temp_new_i32(); 3281 TCGv_i32 t3 = tcg_temp_new_i32(); 3282 tcg_gen_trunc_tl_i32(t2, t0); 3283 tcg_gen_trunc_tl_i32(t3, t1); 3284 tcg_gen_mul_i32(t2, t2, t3); 3285 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3286 tcg_temp_free_i32(t2); 3287 tcg_temp_free_i32(t3); 3288 } 3289 break; 3290 case R6_OPC_MUHU: 3291 { 3292 TCGv_i32 t2 = tcg_temp_new_i32(); 3293 TCGv_i32 t3 = tcg_temp_new_i32(); 3294 tcg_gen_trunc_tl_i32(t2, t0); 3295 tcg_gen_trunc_tl_i32(t3, t1); 3296 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3297 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3298 tcg_temp_free_i32(t2); 3299 tcg_temp_free_i32(t3); 3300 } 3301 break; 3302 #if defined(TARGET_MIPS64) 3303 case R6_OPC_DDIV: 3304 { 3305 TCGv t2 = tcg_temp_new(); 3306 TCGv t3 = tcg_temp_new(); 3307 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3308 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3309 tcg_gen_and_tl(t2, t2, t3); 3310 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3311 tcg_gen_or_tl(t2, t2, t3); 3312 tcg_gen_movi_tl(t3, 0); 3313 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3314 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3315 tcg_temp_free(t3); 3316 tcg_temp_free(t2); 3317 } 3318 break; 3319 case R6_OPC_DMOD: 3320 { 3321 TCGv t2 = tcg_temp_new(); 3322 TCGv t3 = tcg_temp_new(); 3323 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3324 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3325 tcg_gen_and_tl(t2, t2, t3); 3326 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3327 tcg_gen_or_tl(t2, t2, t3); 3328 tcg_gen_movi_tl(t3, 0); 3329 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3330 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3331 tcg_temp_free(t3); 3332 tcg_temp_free(t2); 3333 } 3334 break; 3335 case R6_OPC_DDIVU: 3336 { 3337 TCGv t2 = tcg_const_tl(0); 3338 TCGv t3 = tcg_const_tl(1); 3339 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3340 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); 3341 tcg_temp_free(t3); 3342 tcg_temp_free(t2); 3343 } 3344 break; 3345 case R6_OPC_DMODU: 3346 { 3347 TCGv t2 = tcg_const_tl(0); 3348 TCGv t3 = tcg_const_tl(1); 3349 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3350 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); 3351 tcg_temp_free(t3); 3352 tcg_temp_free(t2); 3353 } 3354 break; 3355 case R6_OPC_DMUL: 3356 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3357 break; 3358 case R6_OPC_DMUH: 3359 { 3360 TCGv t2 = tcg_temp_new(); 3361 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); 3362 tcg_temp_free(t2); 3363 } 3364 break; 3365 case R6_OPC_DMULU: 3366 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3367 break; 3368 case R6_OPC_DMUHU: 3369 { 3370 TCGv t2 = tcg_temp_new(); 3371 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); 3372 tcg_temp_free(t2); 3373 } 3374 break; 3375 #endif 3376 default: 3377 MIPS_INVAL("r6 mul/div"); 3378 gen_reserved_instruction(ctx); 3379 goto out; 3380 } 3381 out: 3382 tcg_temp_free(t0); 3383 tcg_temp_free(t1); 3384 } 3385 3386 #if defined(TARGET_MIPS64) 3387 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) 3388 { 3389 TCGv t0, t1; 3390 3391 t0 = tcg_temp_new(); 3392 t1 = tcg_temp_new(); 3393 3394 gen_load_gpr(t0, rs); 3395 gen_load_gpr(t1, rt); 3396 3397 switch (opc) { 3398 case MMI_OPC_DIV1: 3399 { 3400 TCGv t2 = tcg_temp_new(); 3401 TCGv t3 = tcg_temp_new(); 3402 tcg_gen_ext32s_tl(t0, t0); 3403 tcg_gen_ext32s_tl(t1, t1); 3404 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3405 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3406 tcg_gen_and_tl(t2, t2, t3); 3407 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3408 tcg_gen_or_tl(t2, t2, t3); 3409 tcg_gen_movi_tl(t3, 0); 3410 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3411 tcg_gen_div_tl(cpu_LO[1], t0, t1); 3412 tcg_gen_rem_tl(cpu_HI[1], t0, t1); 3413 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3414 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3415 tcg_temp_free(t3); 3416 tcg_temp_free(t2); 3417 } 3418 break; 3419 case MMI_OPC_DIVU1: 3420 { 3421 TCGv t2 = tcg_const_tl(0); 3422 TCGv t3 = tcg_const_tl(1); 3423 tcg_gen_ext32u_tl(t0, t0); 3424 tcg_gen_ext32u_tl(t1, t1); 3425 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3426 tcg_gen_divu_tl(cpu_LO[1], t0, t1); 3427 tcg_gen_remu_tl(cpu_HI[1], t0, t1); 3428 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3429 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3430 tcg_temp_free(t3); 3431 tcg_temp_free(t2); 3432 } 3433 break; 3434 default: 3435 MIPS_INVAL("div1 TX79"); 3436 gen_reserved_instruction(ctx); 3437 goto out; 3438 } 3439 out: 3440 tcg_temp_free(t0); 3441 tcg_temp_free(t1); 3442 } 3443 #endif 3444 3445 static void gen_muldiv(DisasContext *ctx, uint32_t opc, 3446 int acc, int rs, int rt) 3447 { 3448 TCGv t0, t1; 3449 3450 t0 = tcg_temp_new(); 3451 t1 = tcg_temp_new(); 3452 3453 gen_load_gpr(t0, rs); 3454 gen_load_gpr(t1, rt); 3455 3456 if (acc != 0) { 3457 check_dsp(ctx); 3458 } 3459 3460 switch (opc) { 3461 case OPC_DIV: 3462 { 3463 TCGv t2 = tcg_temp_new(); 3464 TCGv t3 = tcg_temp_new(); 3465 tcg_gen_ext32s_tl(t0, t0); 3466 tcg_gen_ext32s_tl(t1, t1); 3467 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3468 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3469 tcg_gen_and_tl(t2, t2, t3); 3470 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3471 tcg_gen_or_tl(t2, t2, t3); 3472 tcg_gen_movi_tl(t3, 0); 3473 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3474 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3475 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3476 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3477 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3478 tcg_temp_free(t3); 3479 tcg_temp_free(t2); 3480 } 3481 break; 3482 case OPC_DIVU: 3483 { 3484 TCGv t2 = tcg_const_tl(0); 3485 TCGv t3 = tcg_const_tl(1); 3486 tcg_gen_ext32u_tl(t0, t0); 3487 tcg_gen_ext32u_tl(t1, t1); 3488 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3489 tcg_gen_divu_tl(cpu_LO[acc], t0, t1); 3490 tcg_gen_remu_tl(cpu_HI[acc], t0, t1); 3491 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3492 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3493 tcg_temp_free(t3); 3494 tcg_temp_free(t2); 3495 } 3496 break; 3497 case OPC_MULT: 3498 { 3499 TCGv_i32 t2 = tcg_temp_new_i32(); 3500 TCGv_i32 t3 = tcg_temp_new_i32(); 3501 tcg_gen_trunc_tl_i32(t2, t0); 3502 tcg_gen_trunc_tl_i32(t3, t1); 3503 tcg_gen_muls2_i32(t2, t3, t2, t3); 3504 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3505 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3506 tcg_temp_free_i32(t2); 3507 tcg_temp_free_i32(t3); 3508 } 3509 break; 3510 case OPC_MULTU: 3511 { 3512 TCGv_i32 t2 = tcg_temp_new_i32(); 3513 TCGv_i32 t3 = tcg_temp_new_i32(); 3514 tcg_gen_trunc_tl_i32(t2, t0); 3515 tcg_gen_trunc_tl_i32(t3, t1); 3516 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3517 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3518 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3519 tcg_temp_free_i32(t2); 3520 tcg_temp_free_i32(t3); 3521 } 3522 break; 3523 #if defined(TARGET_MIPS64) 3524 case OPC_DDIV: 3525 { 3526 TCGv t2 = tcg_temp_new(); 3527 TCGv t3 = tcg_temp_new(); 3528 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3529 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3530 tcg_gen_and_tl(t2, t2, t3); 3531 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3532 tcg_gen_or_tl(t2, t2, t3); 3533 tcg_gen_movi_tl(t3, 0); 3534 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3535 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3536 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3537 tcg_temp_free(t3); 3538 tcg_temp_free(t2); 3539 } 3540 break; 3541 case OPC_DDIVU: 3542 { 3543 TCGv t2 = tcg_const_tl(0); 3544 TCGv t3 = tcg_const_tl(1); 3545 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3546 tcg_gen_divu_i64(cpu_LO[acc], t0, t1); 3547 tcg_gen_remu_i64(cpu_HI[acc], t0, t1); 3548 tcg_temp_free(t3); 3549 tcg_temp_free(t2); 3550 } 3551 break; 3552 case OPC_DMULT: 3553 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3554 break; 3555 case OPC_DMULTU: 3556 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3557 break; 3558 #endif 3559 case OPC_MADD: 3560 { 3561 TCGv_i64 t2 = tcg_temp_new_i64(); 3562 TCGv_i64 t3 = tcg_temp_new_i64(); 3563 3564 tcg_gen_ext_tl_i64(t2, t0); 3565 tcg_gen_ext_tl_i64(t3, t1); 3566 tcg_gen_mul_i64(t2, t2, t3); 3567 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3568 tcg_gen_add_i64(t2, t2, t3); 3569 tcg_temp_free_i64(t3); 3570 gen_move_low32(cpu_LO[acc], t2); 3571 gen_move_high32(cpu_HI[acc], t2); 3572 tcg_temp_free_i64(t2); 3573 } 3574 break; 3575 case OPC_MADDU: 3576 { 3577 TCGv_i64 t2 = tcg_temp_new_i64(); 3578 TCGv_i64 t3 = tcg_temp_new_i64(); 3579 3580 tcg_gen_ext32u_tl(t0, t0); 3581 tcg_gen_ext32u_tl(t1, t1); 3582 tcg_gen_extu_tl_i64(t2, t0); 3583 tcg_gen_extu_tl_i64(t3, t1); 3584 tcg_gen_mul_i64(t2, t2, t3); 3585 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3586 tcg_gen_add_i64(t2, t2, t3); 3587 tcg_temp_free_i64(t3); 3588 gen_move_low32(cpu_LO[acc], t2); 3589 gen_move_high32(cpu_HI[acc], t2); 3590 tcg_temp_free_i64(t2); 3591 } 3592 break; 3593 case OPC_MSUB: 3594 { 3595 TCGv_i64 t2 = tcg_temp_new_i64(); 3596 TCGv_i64 t3 = tcg_temp_new_i64(); 3597 3598 tcg_gen_ext_tl_i64(t2, t0); 3599 tcg_gen_ext_tl_i64(t3, t1); 3600 tcg_gen_mul_i64(t2, t2, t3); 3601 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3602 tcg_gen_sub_i64(t2, t3, t2); 3603 tcg_temp_free_i64(t3); 3604 gen_move_low32(cpu_LO[acc], t2); 3605 gen_move_high32(cpu_HI[acc], t2); 3606 tcg_temp_free_i64(t2); 3607 } 3608 break; 3609 case OPC_MSUBU: 3610 { 3611 TCGv_i64 t2 = tcg_temp_new_i64(); 3612 TCGv_i64 t3 = tcg_temp_new_i64(); 3613 3614 tcg_gen_ext32u_tl(t0, t0); 3615 tcg_gen_ext32u_tl(t1, t1); 3616 tcg_gen_extu_tl_i64(t2, t0); 3617 tcg_gen_extu_tl_i64(t3, t1); 3618 tcg_gen_mul_i64(t2, t2, t3); 3619 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3620 tcg_gen_sub_i64(t2, t3, t2); 3621 tcg_temp_free_i64(t3); 3622 gen_move_low32(cpu_LO[acc], t2); 3623 gen_move_high32(cpu_HI[acc], t2); 3624 tcg_temp_free_i64(t2); 3625 } 3626 break; 3627 default: 3628 MIPS_INVAL("mul/div"); 3629 gen_reserved_instruction(ctx); 3630 goto out; 3631 } 3632 out: 3633 tcg_temp_free(t0); 3634 tcg_temp_free(t1); 3635 } 3636 3637 /* 3638 * These MULT[U] and MADD[U] instructions implemented in for example 3639 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core 3640 * architectures are special three-operand variants with the syntax 3641 * 3642 * MULT[U][1] rd, rs, rt 3643 * 3644 * such that 3645 * 3646 * (rd, LO, HI) <- rs * rt 3647 * 3648 * and 3649 * 3650 * MADD[U][1] rd, rs, rt 3651 * 3652 * such that 3653 * 3654 * (rd, LO, HI) <- (LO, HI) + rs * rt 3655 * 3656 * where the low-order 32-bits of the result is placed into both the 3657 * GPR rd and the special register LO. The high-order 32-bits of the 3658 * result is placed into the special register HI. 3659 * 3660 * If the GPR rd is omitted in assembly language, it is taken to be 0, 3661 * which is the zero register that always reads as 0. 3662 */ 3663 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, 3664 int rd, int rs, int rt) 3665 { 3666 TCGv t0 = tcg_temp_new(); 3667 TCGv t1 = tcg_temp_new(); 3668 int acc = 0; 3669 3670 gen_load_gpr(t0, rs); 3671 gen_load_gpr(t1, rt); 3672 3673 switch (opc) { 3674 case MMI_OPC_MULT1: 3675 acc = 1; 3676 /* Fall through */ 3677 case OPC_MULT: 3678 { 3679 TCGv_i32 t2 = tcg_temp_new_i32(); 3680 TCGv_i32 t3 = tcg_temp_new_i32(); 3681 tcg_gen_trunc_tl_i32(t2, t0); 3682 tcg_gen_trunc_tl_i32(t3, t1); 3683 tcg_gen_muls2_i32(t2, t3, t2, t3); 3684 if (rd) { 3685 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3686 } 3687 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3688 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3689 tcg_temp_free_i32(t2); 3690 tcg_temp_free_i32(t3); 3691 } 3692 break; 3693 case MMI_OPC_MULTU1: 3694 acc = 1; 3695 /* Fall through */ 3696 case OPC_MULTU: 3697 { 3698 TCGv_i32 t2 = tcg_temp_new_i32(); 3699 TCGv_i32 t3 = tcg_temp_new_i32(); 3700 tcg_gen_trunc_tl_i32(t2, t0); 3701 tcg_gen_trunc_tl_i32(t3, t1); 3702 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3703 if (rd) { 3704 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3705 } 3706 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3707 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3708 tcg_temp_free_i32(t2); 3709 tcg_temp_free_i32(t3); 3710 } 3711 break; 3712 case MMI_OPC_MADD1: 3713 acc = 1; 3714 /* Fall through */ 3715 case MMI_OPC_MADD: 3716 { 3717 TCGv_i64 t2 = tcg_temp_new_i64(); 3718 TCGv_i64 t3 = tcg_temp_new_i64(); 3719 3720 tcg_gen_ext_tl_i64(t2, t0); 3721 tcg_gen_ext_tl_i64(t3, t1); 3722 tcg_gen_mul_i64(t2, t2, t3); 3723 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3724 tcg_gen_add_i64(t2, t2, t3); 3725 tcg_temp_free_i64(t3); 3726 gen_move_low32(cpu_LO[acc], t2); 3727 gen_move_high32(cpu_HI[acc], t2); 3728 if (rd) { 3729 gen_move_low32(cpu_gpr[rd], t2); 3730 } 3731 tcg_temp_free_i64(t2); 3732 } 3733 break; 3734 case MMI_OPC_MADDU1: 3735 acc = 1; 3736 /* Fall through */ 3737 case MMI_OPC_MADDU: 3738 { 3739 TCGv_i64 t2 = tcg_temp_new_i64(); 3740 TCGv_i64 t3 = tcg_temp_new_i64(); 3741 3742 tcg_gen_ext32u_tl(t0, t0); 3743 tcg_gen_ext32u_tl(t1, t1); 3744 tcg_gen_extu_tl_i64(t2, t0); 3745 tcg_gen_extu_tl_i64(t3, t1); 3746 tcg_gen_mul_i64(t2, t2, t3); 3747 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3748 tcg_gen_add_i64(t2, t2, t3); 3749 tcg_temp_free_i64(t3); 3750 gen_move_low32(cpu_LO[acc], t2); 3751 gen_move_high32(cpu_HI[acc], t2); 3752 if (rd) { 3753 gen_move_low32(cpu_gpr[rd], t2); 3754 } 3755 tcg_temp_free_i64(t2); 3756 } 3757 break; 3758 default: 3759 MIPS_INVAL("mul/madd TXx9"); 3760 gen_reserved_instruction(ctx); 3761 goto out; 3762 } 3763 3764 out: 3765 tcg_temp_free(t0); 3766 tcg_temp_free(t1); 3767 } 3768 3769 static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc, 3770 int rd, int rs, int rt) 3771 { 3772 TCGv t0 = tcg_temp_new(); 3773 TCGv t1 = tcg_temp_new(); 3774 3775 gen_load_gpr(t0, rs); 3776 gen_load_gpr(t1, rt); 3777 3778 switch (opc) { 3779 case OPC_VR54XX_MULS: 3780 gen_helper_muls(t0, cpu_env, t0, t1); 3781 break; 3782 case OPC_VR54XX_MULSU: 3783 gen_helper_mulsu(t0, cpu_env, t0, t1); 3784 break; 3785 case OPC_VR54XX_MACC: 3786 gen_helper_macc(t0, cpu_env, t0, t1); 3787 break; 3788 case OPC_VR54XX_MACCU: 3789 gen_helper_maccu(t0, cpu_env, t0, t1); 3790 break; 3791 case OPC_VR54XX_MSAC: 3792 gen_helper_msac(t0, cpu_env, t0, t1); 3793 break; 3794 case OPC_VR54XX_MSACU: 3795 gen_helper_msacu(t0, cpu_env, t0, t1); 3796 break; 3797 case OPC_VR54XX_MULHI: 3798 gen_helper_mulhi(t0, cpu_env, t0, t1); 3799 break; 3800 case OPC_VR54XX_MULHIU: 3801 gen_helper_mulhiu(t0, cpu_env, t0, t1); 3802 break; 3803 case OPC_VR54XX_MULSHI: 3804 gen_helper_mulshi(t0, cpu_env, t0, t1); 3805 break; 3806 case OPC_VR54XX_MULSHIU: 3807 gen_helper_mulshiu(t0, cpu_env, t0, t1); 3808 break; 3809 case OPC_VR54XX_MACCHI: 3810 gen_helper_macchi(t0, cpu_env, t0, t1); 3811 break; 3812 case OPC_VR54XX_MACCHIU: 3813 gen_helper_macchiu(t0, cpu_env, t0, t1); 3814 break; 3815 case OPC_VR54XX_MSACHI: 3816 gen_helper_msachi(t0, cpu_env, t0, t1); 3817 break; 3818 case OPC_VR54XX_MSACHIU: 3819 gen_helper_msachiu(t0, cpu_env, t0, t1); 3820 break; 3821 default: 3822 MIPS_INVAL("mul vr54xx"); 3823 gen_reserved_instruction(ctx); 3824 goto out; 3825 } 3826 gen_store_gpr(t0, rd); 3827 3828 out: 3829 tcg_temp_free(t0); 3830 tcg_temp_free(t1); 3831 } 3832 3833 static void gen_cl(DisasContext *ctx, uint32_t opc, 3834 int rd, int rs) 3835 { 3836 TCGv t0; 3837 3838 if (rd == 0) { 3839 /* Treat as NOP. */ 3840 return; 3841 } 3842 t0 = cpu_gpr[rd]; 3843 gen_load_gpr(t0, rs); 3844 3845 switch (opc) { 3846 case OPC_CLO: 3847 case R6_OPC_CLO: 3848 #if defined(TARGET_MIPS64) 3849 case OPC_DCLO: 3850 case R6_OPC_DCLO: 3851 #endif 3852 tcg_gen_not_tl(t0, t0); 3853 break; 3854 } 3855 3856 switch (opc) { 3857 case OPC_CLO: 3858 case R6_OPC_CLO: 3859 case OPC_CLZ: 3860 case R6_OPC_CLZ: 3861 tcg_gen_ext32u_tl(t0, t0); 3862 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); 3863 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); 3864 break; 3865 #if defined(TARGET_MIPS64) 3866 case OPC_DCLO: 3867 case R6_OPC_DCLO: 3868 case OPC_DCLZ: 3869 case R6_OPC_DCLZ: 3870 tcg_gen_clzi_i64(t0, t0, 64); 3871 break; 3872 #endif 3873 } 3874 } 3875 3876 /* Godson integer instructions */ 3877 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc, 3878 int rd, int rs, int rt) 3879 { 3880 TCGv t0, t1; 3881 3882 if (rd == 0) { 3883 /* Treat as NOP. */ 3884 return; 3885 } 3886 3887 switch (opc) { 3888 case OPC_MULT_G_2E: 3889 case OPC_MULT_G_2F: 3890 case OPC_MULTU_G_2E: 3891 case OPC_MULTU_G_2F: 3892 #if defined(TARGET_MIPS64) 3893 case OPC_DMULT_G_2E: 3894 case OPC_DMULT_G_2F: 3895 case OPC_DMULTU_G_2E: 3896 case OPC_DMULTU_G_2F: 3897 #endif 3898 t0 = tcg_temp_new(); 3899 t1 = tcg_temp_new(); 3900 break; 3901 default: 3902 t0 = tcg_temp_local_new(); 3903 t1 = tcg_temp_local_new(); 3904 break; 3905 } 3906 3907 gen_load_gpr(t0, rs); 3908 gen_load_gpr(t1, rt); 3909 3910 switch (opc) { 3911 case OPC_MULT_G_2E: 3912 case OPC_MULT_G_2F: 3913 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3914 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3915 break; 3916 case OPC_MULTU_G_2E: 3917 case OPC_MULTU_G_2F: 3918 tcg_gen_ext32u_tl(t0, t0); 3919 tcg_gen_ext32u_tl(t1, t1); 3920 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3921 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3922 break; 3923 case OPC_DIV_G_2E: 3924 case OPC_DIV_G_2F: 3925 { 3926 TCGLabel *l1 = gen_new_label(); 3927 TCGLabel *l2 = gen_new_label(); 3928 TCGLabel *l3 = gen_new_label(); 3929 tcg_gen_ext32s_tl(t0, t0); 3930 tcg_gen_ext32s_tl(t1, t1); 3931 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3932 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3933 tcg_gen_br(l3); 3934 gen_set_label(l1); 3935 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 3936 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 3937 tcg_gen_mov_tl(cpu_gpr[rd], t0); 3938 tcg_gen_br(l3); 3939 gen_set_label(l2); 3940 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3941 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3942 gen_set_label(l3); 3943 } 3944 break; 3945 case OPC_DIVU_G_2E: 3946 case OPC_DIVU_G_2F: 3947 { 3948 TCGLabel *l1 = gen_new_label(); 3949 TCGLabel *l2 = gen_new_label(); 3950 tcg_gen_ext32u_tl(t0, t0); 3951 tcg_gen_ext32u_tl(t1, t1); 3952 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3953 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3954 tcg_gen_br(l2); 3955 gen_set_label(l1); 3956 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3957 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3958 gen_set_label(l2); 3959 } 3960 break; 3961 case OPC_MOD_G_2E: 3962 case OPC_MOD_G_2F: 3963 { 3964 TCGLabel *l1 = gen_new_label(); 3965 TCGLabel *l2 = gen_new_label(); 3966 TCGLabel *l3 = gen_new_label(); 3967 tcg_gen_ext32u_tl(t0, t0); 3968 tcg_gen_ext32u_tl(t1, t1); 3969 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 3970 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 3971 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 3972 gen_set_label(l1); 3973 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3974 tcg_gen_br(l3); 3975 gen_set_label(l2); 3976 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3977 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3978 gen_set_label(l3); 3979 } 3980 break; 3981 case OPC_MODU_G_2E: 3982 case OPC_MODU_G_2F: 3983 { 3984 TCGLabel *l1 = gen_new_label(); 3985 TCGLabel *l2 = gen_new_label(); 3986 tcg_gen_ext32u_tl(t0, t0); 3987 tcg_gen_ext32u_tl(t1, t1); 3988 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3989 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3990 tcg_gen_br(l2); 3991 gen_set_label(l1); 3992 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3993 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3994 gen_set_label(l2); 3995 } 3996 break; 3997 #if defined(TARGET_MIPS64) 3998 case OPC_DMULT_G_2E: 3999 case OPC_DMULT_G_2F: 4000 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 4001 break; 4002 case OPC_DMULTU_G_2E: 4003 case OPC_DMULTU_G_2F: 4004 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 4005 break; 4006 case OPC_DDIV_G_2E: 4007 case OPC_DDIV_G_2F: 4008 { 4009 TCGLabel *l1 = gen_new_label(); 4010 TCGLabel *l2 = gen_new_label(); 4011 TCGLabel *l3 = gen_new_label(); 4012 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4013 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4014 tcg_gen_br(l3); 4015 gen_set_label(l1); 4016 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 4017 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 4018 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4019 tcg_gen_br(l3); 4020 gen_set_label(l2); 4021 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 4022 gen_set_label(l3); 4023 } 4024 break; 4025 case OPC_DDIVU_G_2E: 4026 case OPC_DDIVU_G_2F: 4027 { 4028 TCGLabel *l1 = gen_new_label(); 4029 TCGLabel *l2 = gen_new_label(); 4030 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4031 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4032 tcg_gen_br(l2); 4033 gen_set_label(l1); 4034 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 4035 gen_set_label(l2); 4036 } 4037 break; 4038 case OPC_DMOD_G_2E: 4039 case OPC_DMOD_G_2F: 4040 { 4041 TCGLabel *l1 = gen_new_label(); 4042 TCGLabel *l2 = gen_new_label(); 4043 TCGLabel *l3 = gen_new_label(); 4044 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 4045 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 4046 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 4047 gen_set_label(l1); 4048 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4049 tcg_gen_br(l3); 4050 gen_set_label(l2); 4051 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 4052 gen_set_label(l3); 4053 } 4054 break; 4055 case OPC_DMODU_G_2E: 4056 case OPC_DMODU_G_2F: 4057 { 4058 TCGLabel *l1 = gen_new_label(); 4059 TCGLabel *l2 = gen_new_label(); 4060 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4061 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4062 tcg_gen_br(l2); 4063 gen_set_label(l1); 4064 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 4065 gen_set_label(l2); 4066 } 4067 break; 4068 #endif 4069 } 4070 4071 tcg_temp_free(t0); 4072 tcg_temp_free(t1); 4073 } 4074 4075 /* Loongson multimedia instructions */ 4076 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) 4077 { 4078 uint32_t opc, shift_max; 4079 TCGv_i64 t0, t1; 4080 TCGCond cond; 4081 4082 opc = MASK_LMMI(ctx->opcode); 4083 switch (opc) { 4084 case OPC_ADD_CP2: 4085 case OPC_SUB_CP2: 4086 case OPC_DADD_CP2: 4087 case OPC_DSUB_CP2: 4088 t0 = tcg_temp_local_new_i64(); 4089 t1 = tcg_temp_local_new_i64(); 4090 break; 4091 default: 4092 t0 = tcg_temp_new_i64(); 4093 t1 = tcg_temp_new_i64(); 4094 break; 4095 } 4096 4097 check_cp1_enabled(ctx); 4098 gen_load_fpr64(ctx, t0, rs); 4099 gen_load_fpr64(ctx, t1, rt); 4100 4101 switch (opc) { 4102 case OPC_PADDSH: 4103 gen_helper_paddsh(t0, t0, t1); 4104 break; 4105 case OPC_PADDUSH: 4106 gen_helper_paddush(t0, t0, t1); 4107 break; 4108 case OPC_PADDH: 4109 gen_helper_paddh(t0, t0, t1); 4110 break; 4111 case OPC_PADDW: 4112 gen_helper_paddw(t0, t0, t1); 4113 break; 4114 case OPC_PADDSB: 4115 gen_helper_paddsb(t0, t0, t1); 4116 break; 4117 case OPC_PADDUSB: 4118 gen_helper_paddusb(t0, t0, t1); 4119 break; 4120 case OPC_PADDB: 4121 gen_helper_paddb(t0, t0, t1); 4122 break; 4123 4124 case OPC_PSUBSH: 4125 gen_helper_psubsh(t0, t0, t1); 4126 break; 4127 case OPC_PSUBUSH: 4128 gen_helper_psubush(t0, t0, t1); 4129 break; 4130 case OPC_PSUBH: 4131 gen_helper_psubh(t0, t0, t1); 4132 break; 4133 case OPC_PSUBW: 4134 gen_helper_psubw(t0, t0, t1); 4135 break; 4136 case OPC_PSUBSB: 4137 gen_helper_psubsb(t0, t0, t1); 4138 break; 4139 case OPC_PSUBUSB: 4140 gen_helper_psubusb(t0, t0, t1); 4141 break; 4142 case OPC_PSUBB: 4143 gen_helper_psubb(t0, t0, t1); 4144 break; 4145 4146 case OPC_PSHUFH: 4147 gen_helper_pshufh(t0, t0, t1); 4148 break; 4149 case OPC_PACKSSWH: 4150 gen_helper_packsswh(t0, t0, t1); 4151 break; 4152 case OPC_PACKSSHB: 4153 gen_helper_packsshb(t0, t0, t1); 4154 break; 4155 case OPC_PACKUSHB: 4156 gen_helper_packushb(t0, t0, t1); 4157 break; 4158 4159 case OPC_PUNPCKLHW: 4160 gen_helper_punpcklhw(t0, t0, t1); 4161 break; 4162 case OPC_PUNPCKHHW: 4163 gen_helper_punpckhhw(t0, t0, t1); 4164 break; 4165 case OPC_PUNPCKLBH: 4166 gen_helper_punpcklbh(t0, t0, t1); 4167 break; 4168 case OPC_PUNPCKHBH: 4169 gen_helper_punpckhbh(t0, t0, t1); 4170 break; 4171 case OPC_PUNPCKLWD: 4172 gen_helper_punpcklwd(t0, t0, t1); 4173 break; 4174 case OPC_PUNPCKHWD: 4175 gen_helper_punpckhwd(t0, t0, t1); 4176 break; 4177 4178 case OPC_PAVGH: 4179 gen_helper_pavgh(t0, t0, t1); 4180 break; 4181 case OPC_PAVGB: 4182 gen_helper_pavgb(t0, t0, t1); 4183 break; 4184 case OPC_PMAXSH: 4185 gen_helper_pmaxsh(t0, t0, t1); 4186 break; 4187 case OPC_PMINSH: 4188 gen_helper_pminsh(t0, t0, t1); 4189 break; 4190 case OPC_PMAXUB: 4191 gen_helper_pmaxub(t0, t0, t1); 4192 break; 4193 case OPC_PMINUB: 4194 gen_helper_pminub(t0, t0, t1); 4195 break; 4196 4197 case OPC_PCMPEQW: 4198 gen_helper_pcmpeqw(t0, t0, t1); 4199 break; 4200 case OPC_PCMPGTW: 4201 gen_helper_pcmpgtw(t0, t0, t1); 4202 break; 4203 case OPC_PCMPEQH: 4204 gen_helper_pcmpeqh(t0, t0, t1); 4205 break; 4206 case OPC_PCMPGTH: 4207 gen_helper_pcmpgth(t0, t0, t1); 4208 break; 4209 case OPC_PCMPEQB: 4210 gen_helper_pcmpeqb(t0, t0, t1); 4211 break; 4212 case OPC_PCMPGTB: 4213 gen_helper_pcmpgtb(t0, t0, t1); 4214 break; 4215 4216 case OPC_PSLLW: 4217 gen_helper_psllw(t0, t0, t1); 4218 break; 4219 case OPC_PSLLH: 4220 gen_helper_psllh(t0, t0, t1); 4221 break; 4222 case OPC_PSRLW: 4223 gen_helper_psrlw(t0, t0, t1); 4224 break; 4225 case OPC_PSRLH: 4226 gen_helper_psrlh(t0, t0, t1); 4227 break; 4228 case OPC_PSRAW: 4229 gen_helper_psraw(t0, t0, t1); 4230 break; 4231 case OPC_PSRAH: 4232 gen_helper_psrah(t0, t0, t1); 4233 break; 4234 4235 case OPC_PMULLH: 4236 gen_helper_pmullh(t0, t0, t1); 4237 break; 4238 case OPC_PMULHH: 4239 gen_helper_pmulhh(t0, t0, t1); 4240 break; 4241 case OPC_PMULHUH: 4242 gen_helper_pmulhuh(t0, t0, t1); 4243 break; 4244 case OPC_PMADDHW: 4245 gen_helper_pmaddhw(t0, t0, t1); 4246 break; 4247 4248 case OPC_PASUBUB: 4249 gen_helper_pasubub(t0, t0, t1); 4250 break; 4251 case OPC_BIADD: 4252 gen_helper_biadd(t0, t0); 4253 break; 4254 case OPC_PMOVMSKB: 4255 gen_helper_pmovmskb(t0, t0); 4256 break; 4257 4258 case OPC_PADDD: 4259 tcg_gen_add_i64(t0, t0, t1); 4260 break; 4261 case OPC_PSUBD: 4262 tcg_gen_sub_i64(t0, t0, t1); 4263 break; 4264 case OPC_XOR_CP2: 4265 tcg_gen_xor_i64(t0, t0, t1); 4266 break; 4267 case OPC_NOR_CP2: 4268 tcg_gen_nor_i64(t0, t0, t1); 4269 break; 4270 case OPC_AND_CP2: 4271 tcg_gen_and_i64(t0, t0, t1); 4272 break; 4273 case OPC_OR_CP2: 4274 tcg_gen_or_i64(t0, t0, t1); 4275 break; 4276 4277 case OPC_PANDN: 4278 tcg_gen_andc_i64(t0, t1, t0); 4279 break; 4280 4281 case OPC_PINSRH_0: 4282 tcg_gen_deposit_i64(t0, t0, t1, 0, 16); 4283 break; 4284 case OPC_PINSRH_1: 4285 tcg_gen_deposit_i64(t0, t0, t1, 16, 16); 4286 break; 4287 case OPC_PINSRH_2: 4288 tcg_gen_deposit_i64(t0, t0, t1, 32, 16); 4289 break; 4290 case OPC_PINSRH_3: 4291 tcg_gen_deposit_i64(t0, t0, t1, 48, 16); 4292 break; 4293 4294 case OPC_PEXTRH: 4295 tcg_gen_andi_i64(t1, t1, 3); 4296 tcg_gen_shli_i64(t1, t1, 4); 4297 tcg_gen_shr_i64(t0, t0, t1); 4298 tcg_gen_ext16u_i64(t0, t0); 4299 break; 4300 4301 case OPC_ADDU_CP2: 4302 tcg_gen_add_i64(t0, t0, t1); 4303 tcg_gen_ext32s_i64(t0, t0); 4304 break; 4305 case OPC_SUBU_CP2: 4306 tcg_gen_sub_i64(t0, t0, t1); 4307 tcg_gen_ext32s_i64(t0, t0); 4308 break; 4309 4310 case OPC_SLL_CP2: 4311 shift_max = 32; 4312 goto do_shift; 4313 case OPC_SRL_CP2: 4314 shift_max = 32; 4315 goto do_shift; 4316 case OPC_SRA_CP2: 4317 shift_max = 32; 4318 goto do_shift; 4319 case OPC_DSLL_CP2: 4320 shift_max = 64; 4321 goto do_shift; 4322 case OPC_DSRL_CP2: 4323 shift_max = 64; 4324 goto do_shift; 4325 case OPC_DSRA_CP2: 4326 shift_max = 64; 4327 goto do_shift; 4328 do_shift: 4329 /* Make sure shift count isn't TCG undefined behaviour. */ 4330 tcg_gen_andi_i64(t1, t1, shift_max - 1); 4331 4332 switch (opc) { 4333 case OPC_SLL_CP2: 4334 case OPC_DSLL_CP2: 4335 tcg_gen_shl_i64(t0, t0, t1); 4336 break; 4337 case OPC_SRA_CP2: 4338 case OPC_DSRA_CP2: 4339 /* 4340 * Since SRA is UndefinedResult without sign-extended inputs, 4341 * we can treat SRA and DSRA the same. 4342 */ 4343 tcg_gen_sar_i64(t0, t0, t1); 4344 break; 4345 case OPC_SRL_CP2: 4346 /* We want to shift in zeros for SRL; zero-extend first. */ 4347 tcg_gen_ext32u_i64(t0, t0); 4348 /* FALLTHRU */ 4349 case OPC_DSRL_CP2: 4350 tcg_gen_shr_i64(t0, t0, t1); 4351 break; 4352 } 4353 4354 if (shift_max == 32) { 4355 tcg_gen_ext32s_i64(t0, t0); 4356 } 4357 4358 /* Shifts larger than MAX produce zero. */ 4359 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); 4360 tcg_gen_neg_i64(t1, t1); 4361 tcg_gen_and_i64(t0, t0, t1); 4362 break; 4363 4364 case OPC_ADD_CP2: 4365 case OPC_DADD_CP2: 4366 { 4367 TCGv_i64 t2 = tcg_temp_new_i64(); 4368 TCGLabel *lab = gen_new_label(); 4369 4370 tcg_gen_mov_i64(t2, t0); 4371 tcg_gen_add_i64(t0, t1, t2); 4372 if (opc == OPC_ADD_CP2) { 4373 tcg_gen_ext32s_i64(t0, t0); 4374 } 4375 tcg_gen_xor_i64(t1, t1, t2); 4376 tcg_gen_xor_i64(t2, t2, t0); 4377 tcg_gen_andc_i64(t1, t2, t1); 4378 tcg_temp_free_i64(t2); 4379 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4380 generate_exception(ctx, EXCP_OVERFLOW); 4381 gen_set_label(lab); 4382 break; 4383 } 4384 4385 case OPC_SUB_CP2: 4386 case OPC_DSUB_CP2: 4387 { 4388 TCGv_i64 t2 = tcg_temp_new_i64(); 4389 TCGLabel *lab = gen_new_label(); 4390 4391 tcg_gen_mov_i64(t2, t0); 4392 tcg_gen_sub_i64(t0, t1, t2); 4393 if (opc == OPC_SUB_CP2) { 4394 tcg_gen_ext32s_i64(t0, t0); 4395 } 4396 tcg_gen_xor_i64(t1, t1, t2); 4397 tcg_gen_xor_i64(t2, t2, t0); 4398 tcg_gen_and_i64(t1, t1, t2); 4399 tcg_temp_free_i64(t2); 4400 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4401 generate_exception(ctx, EXCP_OVERFLOW); 4402 gen_set_label(lab); 4403 break; 4404 } 4405 4406 case OPC_PMULUW: 4407 tcg_gen_ext32u_i64(t0, t0); 4408 tcg_gen_ext32u_i64(t1, t1); 4409 tcg_gen_mul_i64(t0, t0, t1); 4410 break; 4411 4412 case OPC_SEQU_CP2: 4413 case OPC_SEQ_CP2: 4414 cond = TCG_COND_EQ; 4415 goto do_cc_cond; 4416 break; 4417 case OPC_SLTU_CP2: 4418 cond = TCG_COND_LTU; 4419 goto do_cc_cond; 4420 break; 4421 case OPC_SLT_CP2: 4422 cond = TCG_COND_LT; 4423 goto do_cc_cond; 4424 break; 4425 case OPC_SLEU_CP2: 4426 cond = TCG_COND_LEU; 4427 goto do_cc_cond; 4428 break; 4429 case OPC_SLE_CP2: 4430 cond = TCG_COND_LE; 4431 do_cc_cond: 4432 { 4433 int cc = (ctx->opcode >> 8) & 0x7; 4434 TCGv_i64 t64 = tcg_temp_new_i64(); 4435 TCGv_i32 t32 = tcg_temp_new_i32(); 4436 4437 tcg_gen_setcond_i64(cond, t64, t0, t1); 4438 tcg_gen_extrl_i64_i32(t32, t64); 4439 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, 4440 get_fp_bit(cc), 1); 4441 4442 tcg_temp_free_i32(t32); 4443 tcg_temp_free_i64(t64); 4444 } 4445 goto no_rd; 4446 break; 4447 default: 4448 MIPS_INVAL("loongson_cp2"); 4449 gen_reserved_instruction(ctx); 4450 return; 4451 } 4452 4453 gen_store_fpr64(ctx, t0, rd); 4454 4455 no_rd: 4456 tcg_temp_free_i64(t0); 4457 tcg_temp_free_i64(t1); 4458 } 4459 4460 static void gen_loongson_lswc2(DisasContext *ctx, int rt, 4461 int rs, int rd) 4462 { 4463 TCGv t0, t1, t2; 4464 TCGv_i32 fp0; 4465 #if defined(TARGET_MIPS64) 4466 int lsq_rt1 = ctx->opcode & 0x1f; 4467 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4; 4468 #endif 4469 int shf_offset = sextract32(ctx->opcode, 6, 8); 4470 4471 t0 = tcg_temp_new(); 4472 4473 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { 4474 #if defined(TARGET_MIPS64) 4475 case OPC_GSLQ: 4476 t1 = tcg_temp_new(); 4477 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4478 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4479 ctx->default_tcg_memop_mask); 4480 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4481 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4482 ctx->default_tcg_memop_mask); 4483 gen_store_gpr(t1, rt); 4484 gen_store_gpr(t0, lsq_rt1); 4485 tcg_temp_free(t1); 4486 break; 4487 case OPC_GSLQC1: 4488 check_cp1_enabled(ctx); 4489 t1 = tcg_temp_new(); 4490 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4491 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4492 ctx->default_tcg_memop_mask); 4493 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4494 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4495 ctx->default_tcg_memop_mask); 4496 gen_store_fpr64(ctx, t1, rt); 4497 gen_store_fpr64(ctx, t0, lsq_rt1); 4498 tcg_temp_free(t1); 4499 break; 4500 case OPC_GSSQ: 4501 t1 = tcg_temp_new(); 4502 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4503 gen_load_gpr(t1, rt); 4504 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4505 ctx->default_tcg_memop_mask); 4506 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4507 gen_load_gpr(t1, lsq_rt1); 4508 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4509 ctx->default_tcg_memop_mask); 4510 tcg_temp_free(t1); 4511 break; 4512 case OPC_GSSQC1: 4513 check_cp1_enabled(ctx); 4514 t1 = tcg_temp_new(); 4515 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4516 gen_load_fpr64(ctx, t1, rt); 4517 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4518 ctx->default_tcg_memop_mask); 4519 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4520 gen_load_fpr64(ctx, t1, lsq_rt1); 4521 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4522 ctx->default_tcg_memop_mask); 4523 tcg_temp_free(t1); 4524 break; 4525 #endif 4526 case OPC_GSSHFL: 4527 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4528 case OPC_GSLWLC1: 4529 check_cp1_enabled(ctx); 4530 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4531 t1 = tcg_temp_new(); 4532 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4533 tcg_gen_andi_tl(t1, t0, 3); 4534 #ifndef TARGET_WORDS_BIGENDIAN 4535 tcg_gen_xori_tl(t1, t1, 3); 4536 #endif 4537 tcg_gen_shli_tl(t1, t1, 3); 4538 tcg_gen_andi_tl(t0, t0, ~3); 4539 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); 4540 tcg_gen_shl_tl(t0, t0, t1); 4541 t2 = tcg_const_tl(-1); 4542 tcg_gen_shl_tl(t2, t2, t1); 4543 fp0 = tcg_temp_new_i32(); 4544 gen_load_fpr32(ctx, fp0, rt); 4545 tcg_gen_ext_i32_tl(t1, fp0); 4546 tcg_gen_andc_tl(t1, t1, t2); 4547 tcg_temp_free(t2); 4548 tcg_gen_or_tl(t0, t0, t1); 4549 tcg_temp_free(t1); 4550 #if defined(TARGET_MIPS64) 4551 tcg_gen_extrl_i64_i32(fp0, t0); 4552 #else 4553 tcg_gen_ext32s_tl(fp0, t0); 4554 #endif 4555 gen_store_fpr32(ctx, fp0, rt); 4556 tcg_temp_free_i32(fp0); 4557 break; 4558 case OPC_GSLWRC1: 4559 check_cp1_enabled(ctx); 4560 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4561 t1 = tcg_temp_new(); 4562 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4563 tcg_gen_andi_tl(t1, t0, 3); 4564 #ifdef TARGET_WORDS_BIGENDIAN 4565 tcg_gen_xori_tl(t1, t1, 3); 4566 #endif 4567 tcg_gen_shli_tl(t1, t1, 3); 4568 tcg_gen_andi_tl(t0, t0, ~3); 4569 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); 4570 tcg_gen_shr_tl(t0, t0, t1); 4571 tcg_gen_xori_tl(t1, t1, 31); 4572 t2 = tcg_const_tl(0xfffffffeull); 4573 tcg_gen_shl_tl(t2, t2, t1); 4574 fp0 = tcg_temp_new_i32(); 4575 gen_load_fpr32(ctx, fp0, rt); 4576 tcg_gen_ext_i32_tl(t1, fp0); 4577 tcg_gen_and_tl(t1, t1, t2); 4578 tcg_temp_free(t2); 4579 tcg_gen_or_tl(t0, t0, t1); 4580 tcg_temp_free(t1); 4581 #if defined(TARGET_MIPS64) 4582 tcg_gen_extrl_i64_i32(fp0, t0); 4583 #else 4584 tcg_gen_ext32s_tl(fp0, t0); 4585 #endif 4586 gen_store_fpr32(ctx, fp0, rt); 4587 tcg_temp_free_i32(fp0); 4588 break; 4589 #if defined(TARGET_MIPS64) 4590 case OPC_GSLDLC1: 4591 check_cp1_enabled(ctx); 4592 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4593 t1 = tcg_temp_new(); 4594 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4595 tcg_gen_andi_tl(t1, t0, 7); 4596 #ifndef TARGET_WORDS_BIGENDIAN 4597 tcg_gen_xori_tl(t1, t1, 7); 4598 #endif 4599 tcg_gen_shli_tl(t1, t1, 3); 4600 tcg_gen_andi_tl(t0, t0, ~7); 4601 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); 4602 tcg_gen_shl_tl(t0, t0, t1); 4603 t2 = tcg_const_tl(-1); 4604 tcg_gen_shl_tl(t2, t2, t1); 4605 gen_load_fpr64(ctx, t1, rt); 4606 tcg_gen_andc_tl(t1, t1, t2); 4607 tcg_temp_free(t2); 4608 tcg_gen_or_tl(t0, t0, t1); 4609 tcg_temp_free(t1); 4610 gen_store_fpr64(ctx, t0, rt); 4611 break; 4612 case OPC_GSLDRC1: 4613 check_cp1_enabled(ctx); 4614 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4615 t1 = tcg_temp_new(); 4616 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4617 tcg_gen_andi_tl(t1, t0, 7); 4618 #ifdef TARGET_WORDS_BIGENDIAN 4619 tcg_gen_xori_tl(t1, t1, 7); 4620 #endif 4621 tcg_gen_shli_tl(t1, t1, 3); 4622 tcg_gen_andi_tl(t0, t0, ~7); 4623 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); 4624 tcg_gen_shr_tl(t0, t0, t1); 4625 tcg_gen_xori_tl(t1, t1, 63); 4626 t2 = tcg_const_tl(0xfffffffffffffffeull); 4627 tcg_gen_shl_tl(t2, t2, t1); 4628 gen_load_fpr64(ctx, t1, rt); 4629 tcg_gen_and_tl(t1, t1, t2); 4630 tcg_temp_free(t2); 4631 tcg_gen_or_tl(t0, t0, t1); 4632 tcg_temp_free(t1); 4633 gen_store_fpr64(ctx, t0, rt); 4634 break; 4635 #endif 4636 default: 4637 MIPS_INVAL("loongson_gsshfl"); 4638 gen_reserved_instruction(ctx); 4639 break; 4640 } 4641 break; 4642 case OPC_GSSHFS: 4643 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4644 case OPC_GSSWLC1: 4645 check_cp1_enabled(ctx); 4646 t1 = tcg_temp_new(); 4647 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4648 fp0 = tcg_temp_new_i32(); 4649 gen_load_fpr32(ctx, fp0, rt); 4650 tcg_gen_ext_i32_tl(t1, fp0); 4651 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); 4652 tcg_temp_free_i32(fp0); 4653 tcg_temp_free(t1); 4654 break; 4655 case OPC_GSSWRC1: 4656 check_cp1_enabled(ctx); 4657 t1 = tcg_temp_new(); 4658 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4659 fp0 = tcg_temp_new_i32(); 4660 gen_load_fpr32(ctx, fp0, rt); 4661 tcg_gen_ext_i32_tl(t1, fp0); 4662 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); 4663 tcg_temp_free_i32(fp0); 4664 tcg_temp_free(t1); 4665 break; 4666 #if defined(TARGET_MIPS64) 4667 case OPC_GSSDLC1: 4668 check_cp1_enabled(ctx); 4669 t1 = tcg_temp_new(); 4670 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4671 gen_load_fpr64(ctx, t1, rt); 4672 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); 4673 tcg_temp_free(t1); 4674 break; 4675 case OPC_GSSDRC1: 4676 check_cp1_enabled(ctx); 4677 t1 = tcg_temp_new(); 4678 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4679 gen_load_fpr64(ctx, t1, rt); 4680 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); 4681 tcg_temp_free(t1); 4682 break; 4683 #endif 4684 default: 4685 MIPS_INVAL("loongson_gsshfs"); 4686 gen_reserved_instruction(ctx); 4687 break; 4688 } 4689 break; 4690 default: 4691 MIPS_INVAL("loongson_gslsq"); 4692 gen_reserved_instruction(ctx); 4693 break; 4694 } 4695 tcg_temp_free(t0); 4696 } 4697 4698 /* Loongson EXT LDC2/SDC2 */ 4699 static void gen_loongson_lsdc2(DisasContext *ctx, int rt, 4700 int rs, int rd) 4701 { 4702 int offset = sextract32(ctx->opcode, 3, 8); 4703 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode); 4704 TCGv t0, t1; 4705 TCGv_i32 fp0; 4706 4707 /* Pre-conditions */ 4708 switch (opc) { 4709 case OPC_GSLBX: 4710 case OPC_GSLHX: 4711 case OPC_GSLWX: 4712 case OPC_GSLDX: 4713 /* prefetch, implement as NOP */ 4714 if (rt == 0) { 4715 return; 4716 } 4717 break; 4718 case OPC_GSSBX: 4719 case OPC_GSSHX: 4720 case OPC_GSSWX: 4721 case OPC_GSSDX: 4722 break; 4723 case OPC_GSLWXC1: 4724 #if defined(TARGET_MIPS64) 4725 case OPC_GSLDXC1: 4726 #endif 4727 check_cp1_enabled(ctx); 4728 /* prefetch, implement as NOP */ 4729 if (rt == 0) { 4730 return; 4731 } 4732 break; 4733 case OPC_GSSWXC1: 4734 #if defined(TARGET_MIPS64) 4735 case OPC_GSSDXC1: 4736 #endif 4737 check_cp1_enabled(ctx); 4738 break; 4739 default: 4740 MIPS_INVAL("loongson_lsdc2"); 4741 gen_reserved_instruction(ctx); 4742 return; 4743 break; 4744 } 4745 4746 t0 = tcg_temp_new(); 4747 4748 gen_base_offset_addr(ctx, t0, rs, offset); 4749 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4750 4751 switch (opc) { 4752 case OPC_GSLBX: 4753 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); 4754 gen_store_gpr(t0, rt); 4755 break; 4756 case OPC_GSLHX: 4757 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW | 4758 ctx->default_tcg_memop_mask); 4759 gen_store_gpr(t0, rt); 4760 break; 4761 case OPC_GSLWX: 4762 gen_base_offset_addr(ctx, t0, rs, offset); 4763 if (rd) { 4764 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4765 } 4766 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL | 4767 ctx->default_tcg_memop_mask); 4768 gen_store_gpr(t0, rt); 4769 break; 4770 #if defined(TARGET_MIPS64) 4771 case OPC_GSLDX: 4772 gen_base_offset_addr(ctx, t0, rs, offset); 4773 if (rd) { 4774 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4775 } 4776 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4777 ctx->default_tcg_memop_mask); 4778 gen_store_gpr(t0, rt); 4779 break; 4780 #endif 4781 case OPC_GSLWXC1: 4782 check_cp1_enabled(ctx); 4783 gen_base_offset_addr(ctx, t0, rs, offset); 4784 if (rd) { 4785 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4786 } 4787 fp0 = tcg_temp_new_i32(); 4788 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | 4789 ctx->default_tcg_memop_mask); 4790 gen_store_fpr32(ctx, fp0, rt); 4791 tcg_temp_free_i32(fp0); 4792 break; 4793 #if defined(TARGET_MIPS64) 4794 case OPC_GSLDXC1: 4795 check_cp1_enabled(ctx); 4796 gen_base_offset_addr(ctx, t0, rs, offset); 4797 if (rd) { 4798 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4799 } 4800 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4801 ctx->default_tcg_memop_mask); 4802 gen_store_fpr64(ctx, t0, rt); 4803 break; 4804 #endif 4805 case OPC_GSSBX: 4806 t1 = tcg_temp_new(); 4807 gen_load_gpr(t1, rt); 4808 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); 4809 tcg_temp_free(t1); 4810 break; 4811 case OPC_GSSHX: 4812 t1 = tcg_temp_new(); 4813 gen_load_gpr(t1, rt); 4814 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW | 4815 ctx->default_tcg_memop_mask); 4816 tcg_temp_free(t1); 4817 break; 4818 case OPC_GSSWX: 4819 t1 = tcg_temp_new(); 4820 gen_load_gpr(t1, rt); 4821 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL | 4822 ctx->default_tcg_memop_mask); 4823 tcg_temp_free(t1); 4824 break; 4825 #if defined(TARGET_MIPS64) 4826 case OPC_GSSDX: 4827 t1 = tcg_temp_new(); 4828 gen_load_gpr(t1, rt); 4829 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4830 ctx->default_tcg_memop_mask); 4831 tcg_temp_free(t1); 4832 break; 4833 #endif 4834 case OPC_GSSWXC1: 4835 fp0 = tcg_temp_new_i32(); 4836 gen_load_fpr32(ctx, fp0, rt); 4837 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | 4838 ctx->default_tcg_memop_mask); 4839 tcg_temp_free_i32(fp0); 4840 break; 4841 #if defined(TARGET_MIPS64) 4842 case OPC_GSSDXC1: 4843 t1 = tcg_temp_new(); 4844 gen_load_fpr64(ctx, t1, rt); 4845 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ | 4846 ctx->default_tcg_memop_mask); 4847 tcg_temp_free(t1); 4848 break; 4849 #endif 4850 default: 4851 break; 4852 } 4853 4854 tcg_temp_free(t0); 4855 } 4856 4857 /* Traps */ 4858 static void gen_trap(DisasContext *ctx, uint32_t opc, 4859 int rs, int rt, int16_t imm) 4860 { 4861 int cond; 4862 TCGv t0 = tcg_temp_new(); 4863 TCGv t1 = tcg_temp_new(); 4864 4865 cond = 0; 4866 /* Load needed operands */ 4867 switch (opc) { 4868 case OPC_TEQ: 4869 case OPC_TGE: 4870 case OPC_TGEU: 4871 case OPC_TLT: 4872 case OPC_TLTU: 4873 case OPC_TNE: 4874 /* Compare two registers */ 4875 if (rs != rt) { 4876 gen_load_gpr(t0, rs); 4877 gen_load_gpr(t1, rt); 4878 cond = 1; 4879 } 4880 break; 4881 case OPC_TEQI: 4882 case OPC_TGEI: 4883 case OPC_TGEIU: 4884 case OPC_TLTI: 4885 case OPC_TLTIU: 4886 case OPC_TNEI: 4887 /* Compare register to immediate */ 4888 if (rs != 0 || imm != 0) { 4889 gen_load_gpr(t0, rs); 4890 tcg_gen_movi_tl(t1, (int32_t)imm); 4891 cond = 1; 4892 } 4893 break; 4894 } 4895 if (cond == 0) { 4896 switch (opc) { 4897 case OPC_TEQ: /* rs == rs */ 4898 case OPC_TEQI: /* r0 == 0 */ 4899 case OPC_TGE: /* rs >= rs */ 4900 case OPC_TGEI: /* r0 >= 0 */ 4901 case OPC_TGEU: /* rs >= rs unsigned */ 4902 case OPC_TGEIU: /* r0 >= 0 unsigned */ 4903 /* Always trap */ 4904 generate_exception_end(ctx, EXCP_TRAP); 4905 break; 4906 case OPC_TLT: /* rs < rs */ 4907 case OPC_TLTI: /* r0 < 0 */ 4908 case OPC_TLTU: /* rs < rs unsigned */ 4909 case OPC_TLTIU: /* r0 < 0 unsigned */ 4910 case OPC_TNE: /* rs != rs */ 4911 case OPC_TNEI: /* r0 != 0 */ 4912 /* Never trap: treat as NOP. */ 4913 break; 4914 } 4915 } else { 4916 TCGLabel *l1 = gen_new_label(); 4917 4918 switch (opc) { 4919 case OPC_TEQ: 4920 case OPC_TEQI: 4921 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 4922 break; 4923 case OPC_TGE: 4924 case OPC_TGEI: 4925 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 4926 break; 4927 case OPC_TGEU: 4928 case OPC_TGEIU: 4929 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 4930 break; 4931 case OPC_TLT: 4932 case OPC_TLTI: 4933 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 4934 break; 4935 case OPC_TLTU: 4936 case OPC_TLTIU: 4937 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 4938 break; 4939 case OPC_TNE: 4940 case OPC_TNEI: 4941 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 4942 break; 4943 } 4944 generate_exception(ctx, EXCP_TRAP); 4945 gen_set_label(l1); 4946 } 4947 tcg_temp_free(t0); 4948 tcg_temp_free(t1); 4949 } 4950 4951 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) 4952 { 4953 if (unlikely(ctx->base.singlestep_enabled)) { 4954 return false; 4955 } 4956 4957 #ifndef CONFIG_USER_ONLY 4958 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); 4959 #else 4960 return true; 4961 #endif 4962 } 4963 4964 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 4965 { 4966 if (use_goto_tb(ctx, dest)) { 4967 tcg_gen_goto_tb(n); 4968 gen_save_pc(dest); 4969 tcg_gen_exit_tb(ctx->base.tb, n); 4970 } else { 4971 gen_save_pc(dest); 4972 if (ctx->base.singlestep_enabled) { 4973 save_cpu_state(ctx, 0); 4974 gen_helper_raise_exception_debug(cpu_env); 4975 } 4976 tcg_gen_lookup_and_goto_ptr(); 4977 } 4978 } 4979 4980 /* Branches (before delay slot) */ 4981 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, 4982 int insn_bytes, 4983 int rs, int rt, int32_t offset, 4984 int delayslot_size) 4985 { 4986 target_ulong btgt = -1; 4987 int blink = 0; 4988 int bcond_compute = 0; 4989 TCGv t0 = tcg_temp_new(); 4990 TCGv t1 = tcg_temp_new(); 4991 4992 if (ctx->hflags & MIPS_HFLAG_BMASK) { 4993 #ifdef MIPS_DEBUG_DISAS 4994 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" 4995 TARGET_FMT_lx "\n", ctx->base.pc_next); 4996 #endif 4997 gen_reserved_instruction(ctx); 4998 goto out; 4999 } 5000 5001 /* Load needed operands */ 5002 switch (opc) { 5003 case OPC_BEQ: 5004 case OPC_BEQL: 5005 case OPC_BNE: 5006 case OPC_BNEL: 5007 /* Compare two registers */ 5008 if (rs != rt) { 5009 gen_load_gpr(t0, rs); 5010 gen_load_gpr(t1, rt); 5011 bcond_compute = 1; 5012 } 5013 btgt = ctx->base.pc_next + insn_bytes + offset; 5014 break; 5015 case OPC_BGEZ: 5016 case OPC_BGEZAL: 5017 case OPC_BGEZALL: 5018 case OPC_BGEZL: 5019 case OPC_BGTZ: 5020 case OPC_BGTZL: 5021 case OPC_BLEZ: 5022 case OPC_BLEZL: 5023 case OPC_BLTZ: 5024 case OPC_BLTZAL: 5025 case OPC_BLTZALL: 5026 case OPC_BLTZL: 5027 /* Compare to zero */ 5028 if (rs != 0) { 5029 gen_load_gpr(t0, rs); 5030 bcond_compute = 1; 5031 } 5032 btgt = ctx->base.pc_next + insn_bytes + offset; 5033 break; 5034 case OPC_BPOSGE32: 5035 #if defined(TARGET_MIPS64) 5036 case OPC_BPOSGE64: 5037 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F); 5038 #else 5039 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 5040 #endif 5041 bcond_compute = 1; 5042 btgt = ctx->base.pc_next + insn_bytes + offset; 5043 break; 5044 case OPC_J: 5045 case OPC_JAL: 5046 case OPC_JALX: 5047 /* Jump to immediate */ 5048 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) | 5049 (uint32_t)offset; 5050 break; 5051 case OPC_JR: 5052 case OPC_JALR: 5053 /* Jump to register */ 5054 if (offset != 0 && offset != 16) { 5055 /* 5056 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 5057 * others are reserved. 5058 */ 5059 MIPS_INVAL("jump hint"); 5060 gen_reserved_instruction(ctx); 5061 goto out; 5062 } 5063 gen_load_gpr(btarget, rs); 5064 break; 5065 default: 5066 MIPS_INVAL("branch/jump"); 5067 gen_reserved_instruction(ctx); 5068 goto out; 5069 } 5070 if (bcond_compute == 0) { 5071 /* No condition to be computed */ 5072 switch (opc) { 5073 case OPC_BEQ: /* rx == rx */ 5074 case OPC_BEQL: /* rx == rx likely */ 5075 case OPC_BGEZ: /* 0 >= 0 */ 5076 case OPC_BGEZL: /* 0 >= 0 likely */ 5077 case OPC_BLEZ: /* 0 <= 0 */ 5078 case OPC_BLEZL: /* 0 <= 0 likely */ 5079 /* Always take */ 5080 ctx->hflags |= MIPS_HFLAG_B; 5081 break; 5082 case OPC_BGEZAL: /* 0 >= 0 */ 5083 case OPC_BGEZALL: /* 0 >= 0 likely */ 5084 /* Always take and link */ 5085 blink = 31; 5086 ctx->hflags |= MIPS_HFLAG_B; 5087 break; 5088 case OPC_BNE: /* rx != rx */ 5089 case OPC_BGTZ: /* 0 > 0 */ 5090 case OPC_BLTZ: /* 0 < 0 */ 5091 /* Treat as NOP. */ 5092 goto out; 5093 case OPC_BLTZAL: /* 0 < 0 */ 5094 /* 5095 * Handle as an unconditional branch to get correct delay 5096 * slot checking. 5097 */ 5098 blink = 31; 5099 btgt = ctx->base.pc_next + insn_bytes + delayslot_size; 5100 ctx->hflags |= MIPS_HFLAG_B; 5101 break; 5102 case OPC_BLTZALL: /* 0 < 0 likely */ 5103 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 5104 /* Skip the instruction in the delay slot */ 5105 ctx->base.pc_next += 4; 5106 goto out; 5107 case OPC_BNEL: /* rx != rx likely */ 5108 case OPC_BGTZL: /* 0 > 0 likely */ 5109 case OPC_BLTZL: /* 0 < 0 likely */ 5110 /* Skip the instruction in the delay slot */ 5111 ctx->base.pc_next += 4; 5112 goto out; 5113 case OPC_J: 5114 ctx->hflags |= MIPS_HFLAG_B; 5115 break; 5116 case OPC_JALX: 5117 ctx->hflags |= MIPS_HFLAG_BX; 5118 /* Fallthrough */ 5119 case OPC_JAL: 5120 blink = 31; 5121 ctx->hflags |= MIPS_HFLAG_B; 5122 break; 5123 case OPC_JR: 5124 ctx->hflags |= MIPS_HFLAG_BR; 5125 break; 5126 case OPC_JALR: 5127 blink = rt; 5128 ctx->hflags |= MIPS_HFLAG_BR; 5129 break; 5130 default: 5131 MIPS_INVAL("branch/jump"); 5132 gen_reserved_instruction(ctx); 5133 goto out; 5134 } 5135 } else { 5136 switch (opc) { 5137 case OPC_BEQ: 5138 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 5139 goto not_likely; 5140 case OPC_BEQL: 5141 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 5142 goto likely; 5143 case OPC_BNE: 5144 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 5145 goto not_likely; 5146 case OPC_BNEL: 5147 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 5148 goto likely; 5149 case OPC_BGEZ: 5150 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5151 goto not_likely; 5152 case OPC_BGEZL: 5153 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5154 goto likely; 5155 case OPC_BGEZAL: 5156 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5157 blink = 31; 5158 goto not_likely; 5159 case OPC_BGEZALL: 5160 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5161 blink = 31; 5162 goto likely; 5163 case OPC_BGTZ: 5164 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 5165 goto not_likely; 5166 case OPC_BGTZL: 5167 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 5168 goto likely; 5169 case OPC_BLEZ: 5170 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 5171 goto not_likely; 5172 case OPC_BLEZL: 5173 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 5174 goto likely; 5175 case OPC_BLTZ: 5176 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5177 goto not_likely; 5178 case OPC_BLTZL: 5179 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5180 goto likely; 5181 case OPC_BPOSGE32: 5182 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 5183 goto not_likely; 5184 #if defined(TARGET_MIPS64) 5185 case OPC_BPOSGE64: 5186 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64); 5187 goto not_likely; 5188 #endif 5189 case OPC_BLTZAL: 5190 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5191 blink = 31; 5192 not_likely: 5193 ctx->hflags |= MIPS_HFLAG_BC; 5194 break; 5195 case OPC_BLTZALL: 5196 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5197 blink = 31; 5198 likely: 5199 ctx->hflags |= MIPS_HFLAG_BL; 5200 break; 5201 default: 5202 MIPS_INVAL("conditional branch/jump"); 5203 gen_reserved_instruction(ctx); 5204 goto out; 5205 } 5206 } 5207 5208 ctx->btarget = btgt; 5209 5210 switch (delayslot_size) { 5211 case 2: 5212 ctx->hflags |= MIPS_HFLAG_BDS16; 5213 break; 5214 case 4: 5215 ctx->hflags |= MIPS_HFLAG_BDS32; 5216 break; 5217 } 5218 5219 if (blink > 0) { 5220 int post_delay = insn_bytes + delayslot_size; 5221 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); 5222 5223 tcg_gen_movi_tl(cpu_gpr[blink], 5224 ctx->base.pc_next + post_delay + lowbit); 5225 } 5226 5227 out: 5228 if (insn_bytes == 2) { 5229 ctx->hflags |= MIPS_HFLAG_B16; 5230 } 5231 tcg_temp_free(t0); 5232 tcg_temp_free(t1); 5233 } 5234 5235 5236 /* special3 bitfield operations */ 5237 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, 5238 int rs, int lsb, int msb) 5239 { 5240 TCGv t0 = tcg_temp_new(); 5241 TCGv t1 = tcg_temp_new(); 5242 5243 gen_load_gpr(t1, rs); 5244 switch (opc) { 5245 case OPC_EXT: 5246 if (lsb + msb > 31) { 5247 goto fail; 5248 } 5249 if (msb != 31) { 5250 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 5251 } else { 5252 /* 5253 * The two checks together imply that lsb == 0, 5254 * so this is a simple sign-extension. 5255 */ 5256 tcg_gen_ext32s_tl(t0, t1); 5257 } 5258 break; 5259 #if defined(TARGET_MIPS64) 5260 case OPC_DEXTU: 5261 lsb += 32; 5262 goto do_dext; 5263 case OPC_DEXTM: 5264 msb += 32; 5265 goto do_dext; 5266 case OPC_DEXT: 5267 do_dext: 5268 if (lsb + msb > 63) { 5269 goto fail; 5270 } 5271 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 5272 break; 5273 #endif 5274 case OPC_INS: 5275 if (lsb > msb) { 5276 goto fail; 5277 } 5278 gen_load_gpr(t0, rt); 5279 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 5280 tcg_gen_ext32s_tl(t0, t0); 5281 break; 5282 #if defined(TARGET_MIPS64) 5283 case OPC_DINSU: 5284 lsb += 32; 5285 /* FALLTHRU */ 5286 case OPC_DINSM: 5287 msb += 32; 5288 /* FALLTHRU */ 5289 case OPC_DINS: 5290 if (lsb > msb) { 5291 goto fail; 5292 } 5293 gen_load_gpr(t0, rt); 5294 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 5295 break; 5296 #endif 5297 default: 5298 fail: 5299 MIPS_INVAL("bitops"); 5300 gen_reserved_instruction(ctx); 5301 tcg_temp_free(t0); 5302 tcg_temp_free(t1); 5303 return; 5304 } 5305 gen_store_gpr(t0, rt); 5306 tcg_temp_free(t0); 5307 tcg_temp_free(t1); 5308 } 5309 5310 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) 5311 { 5312 TCGv t0; 5313 5314 if (rd == 0) { 5315 /* If no destination, treat it as a NOP. */ 5316 return; 5317 } 5318 5319 t0 = tcg_temp_new(); 5320 gen_load_gpr(t0, rt); 5321 switch (op2) { 5322 case OPC_WSBH: 5323 { 5324 TCGv t1 = tcg_temp_new(); 5325 TCGv t2 = tcg_const_tl(0x00FF00FF); 5326 5327 tcg_gen_shri_tl(t1, t0, 8); 5328 tcg_gen_and_tl(t1, t1, t2); 5329 tcg_gen_and_tl(t0, t0, t2); 5330 tcg_gen_shli_tl(t0, t0, 8); 5331 tcg_gen_or_tl(t0, t0, t1); 5332 tcg_temp_free(t2); 5333 tcg_temp_free(t1); 5334 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 5335 } 5336 break; 5337 case OPC_SEB: 5338 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 5339 break; 5340 case OPC_SEH: 5341 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 5342 break; 5343 #if defined(TARGET_MIPS64) 5344 case OPC_DSBH: 5345 { 5346 TCGv t1 = tcg_temp_new(); 5347 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL); 5348 5349 tcg_gen_shri_tl(t1, t0, 8); 5350 tcg_gen_and_tl(t1, t1, t2); 5351 tcg_gen_and_tl(t0, t0, t2); 5352 tcg_gen_shli_tl(t0, t0, 8); 5353 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 5354 tcg_temp_free(t2); 5355 tcg_temp_free(t1); 5356 } 5357 break; 5358 case OPC_DSHD: 5359 { 5360 TCGv t1 = tcg_temp_new(); 5361 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL); 5362 5363 tcg_gen_shri_tl(t1, t0, 16); 5364 tcg_gen_and_tl(t1, t1, t2); 5365 tcg_gen_and_tl(t0, t0, t2); 5366 tcg_gen_shli_tl(t0, t0, 16); 5367 tcg_gen_or_tl(t0, t0, t1); 5368 tcg_gen_shri_tl(t1, t0, 32); 5369 tcg_gen_shli_tl(t0, t0, 32); 5370 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 5371 tcg_temp_free(t2); 5372 tcg_temp_free(t1); 5373 } 5374 break; 5375 #endif 5376 default: 5377 MIPS_INVAL("bsfhl"); 5378 gen_reserved_instruction(ctx); 5379 tcg_temp_free(t0); 5380 return; 5381 } 5382 tcg_temp_free(t0); 5383 } 5384 5385 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, 5386 int rt, int bits) 5387 { 5388 TCGv t0; 5389 if (rd == 0) { 5390 /* Treat as NOP. */ 5391 return; 5392 } 5393 t0 = tcg_temp_new(); 5394 if (bits == 0 || bits == wordsz) { 5395 if (bits == 0) { 5396 gen_load_gpr(t0, rt); 5397 } else { 5398 gen_load_gpr(t0, rs); 5399 } 5400 switch (wordsz) { 5401 case 32: 5402 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 5403 break; 5404 #if defined(TARGET_MIPS64) 5405 case 64: 5406 tcg_gen_mov_tl(cpu_gpr[rd], t0); 5407 break; 5408 #endif 5409 } 5410 } else { 5411 TCGv t1 = tcg_temp_new(); 5412 gen_load_gpr(t0, rt); 5413 gen_load_gpr(t1, rs); 5414 switch (wordsz) { 5415 case 32: 5416 { 5417 TCGv_i64 t2 = tcg_temp_new_i64(); 5418 tcg_gen_concat_tl_i64(t2, t1, t0); 5419 tcg_gen_shri_i64(t2, t2, 32 - bits); 5420 gen_move_low32(cpu_gpr[rd], t2); 5421 tcg_temp_free_i64(t2); 5422 } 5423 break; 5424 #if defined(TARGET_MIPS64) 5425 case 64: 5426 tcg_gen_shli_tl(t0, t0, bits); 5427 tcg_gen_shri_tl(t1, t1, 64 - bits); 5428 tcg_gen_or_tl(cpu_gpr[rd], t1, t0); 5429 break; 5430 #endif 5431 } 5432 tcg_temp_free(t1); 5433 } 5434 5435 tcg_temp_free(t0); 5436 } 5437 5438 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp) 5439 { 5440 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); 5441 } 5442 5443 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) 5444 { 5445 TCGv t0; 5446 if (rd == 0) { 5447 /* Treat as NOP. */ 5448 return; 5449 } 5450 t0 = tcg_temp_new(); 5451 gen_load_gpr(t0, rt); 5452 switch (opc) { 5453 case OPC_BITSWAP: 5454 gen_helper_bitswap(cpu_gpr[rd], t0); 5455 break; 5456 #if defined(TARGET_MIPS64) 5457 case OPC_DBITSWAP: 5458 gen_helper_dbitswap(cpu_gpr[rd], t0); 5459 break; 5460 #endif 5461 } 5462 tcg_temp_free(t0); 5463 } 5464 5465 #ifndef CONFIG_USER_ONLY 5466 /* CP0 (MMU and control) */ 5467 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off) 5468 { 5469 TCGv_i64 t0 = tcg_temp_new_i64(); 5470 TCGv_i64 t1 = tcg_temp_new_i64(); 5471 5472 tcg_gen_ext_tl_i64(t0, arg); 5473 tcg_gen_ld_i64(t1, cpu_env, off); 5474 #if defined(TARGET_MIPS64) 5475 tcg_gen_deposit_i64(t1, t1, t0, 30, 32); 5476 #else 5477 tcg_gen_concat32_i64(t1, t1, t0); 5478 #endif 5479 tcg_gen_st_i64(t1, cpu_env, off); 5480 tcg_temp_free_i64(t1); 5481 tcg_temp_free_i64(t0); 5482 } 5483 5484 static inline void gen_mthc0_store64(TCGv arg, target_ulong off) 5485 { 5486 TCGv_i64 t0 = tcg_temp_new_i64(); 5487 TCGv_i64 t1 = tcg_temp_new_i64(); 5488 5489 tcg_gen_ext_tl_i64(t0, arg); 5490 tcg_gen_ld_i64(t1, cpu_env, off); 5491 tcg_gen_concat32_i64(t1, t1, t0); 5492 tcg_gen_st_i64(t1, cpu_env, off); 5493 tcg_temp_free_i64(t1); 5494 tcg_temp_free_i64(t0); 5495 } 5496 5497 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off) 5498 { 5499 TCGv_i64 t0 = tcg_temp_new_i64(); 5500 5501 tcg_gen_ld_i64(t0, cpu_env, off); 5502 #if defined(TARGET_MIPS64) 5503 tcg_gen_shri_i64(t0, t0, 30); 5504 #else 5505 tcg_gen_shri_i64(t0, t0, 32); 5506 #endif 5507 gen_move_low32(arg, t0); 5508 tcg_temp_free_i64(t0); 5509 } 5510 5511 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift) 5512 { 5513 TCGv_i64 t0 = tcg_temp_new_i64(); 5514 5515 tcg_gen_ld_i64(t0, cpu_env, off); 5516 tcg_gen_shri_i64(t0, t0, 32 + shift); 5517 gen_move_low32(arg, t0); 5518 tcg_temp_free_i64(t0); 5519 } 5520 5521 static inline void gen_mfc0_load32(TCGv arg, target_ulong off) 5522 { 5523 TCGv_i32 t0 = tcg_temp_new_i32(); 5524 5525 tcg_gen_ld_i32(t0, cpu_env, off); 5526 tcg_gen_ext_i32_tl(arg, t0); 5527 tcg_temp_free_i32(t0); 5528 } 5529 5530 static inline void gen_mfc0_load64(TCGv arg, target_ulong off) 5531 { 5532 tcg_gen_ld_tl(arg, cpu_env, off); 5533 tcg_gen_ext32s_tl(arg, arg); 5534 } 5535 5536 static inline void gen_mtc0_store32(TCGv arg, target_ulong off) 5537 { 5538 TCGv_i32 t0 = tcg_temp_new_i32(); 5539 5540 tcg_gen_trunc_tl_i32(t0, arg); 5541 tcg_gen_st_i32(t0, cpu_env, off); 5542 tcg_temp_free_i32(t0); 5543 } 5544 5545 #define CP0_CHECK(c) \ 5546 do { \ 5547 if (!(c)) { \ 5548 goto cp0_unimplemented; \ 5549 } \ 5550 } while (0) 5551 5552 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5553 { 5554 const char *register_name = "invalid"; 5555 5556 switch (reg) { 5557 case CP0_REGISTER_02: 5558 switch (sel) { 5559 case 0: 5560 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5561 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5562 register_name = "EntryLo0"; 5563 break; 5564 default: 5565 goto cp0_unimplemented; 5566 } 5567 break; 5568 case CP0_REGISTER_03: 5569 switch (sel) { 5570 case CP0_REG03__ENTRYLO1: 5571 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5572 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5573 register_name = "EntryLo1"; 5574 break; 5575 default: 5576 goto cp0_unimplemented; 5577 } 5578 break; 5579 case CP0_REGISTER_09: 5580 switch (sel) { 5581 case CP0_REG09__SAAR: 5582 CP0_CHECK(ctx->saar); 5583 gen_helper_mfhc0_saar(arg, cpu_env); 5584 register_name = "SAAR"; 5585 break; 5586 default: 5587 goto cp0_unimplemented; 5588 } 5589 break; 5590 case CP0_REGISTER_17: 5591 switch (sel) { 5592 case CP0_REG17__LLADDR: 5593 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr), 5594 ctx->CP0_LLAddr_shift); 5595 register_name = "LLAddr"; 5596 break; 5597 case CP0_REG17__MAAR: 5598 CP0_CHECK(ctx->mrp); 5599 gen_helper_mfhc0_maar(arg, cpu_env); 5600 register_name = "MAAR"; 5601 break; 5602 default: 5603 goto cp0_unimplemented; 5604 } 5605 break; 5606 case CP0_REGISTER_19: 5607 switch (sel) { 5608 case CP0_REG19__WATCHHI0: 5609 case CP0_REG19__WATCHHI1: 5610 case CP0_REG19__WATCHHI2: 5611 case CP0_REG19__WATCHHI3: 5612 case CP0_REG19__WATCHHI4: 5613 case CP0_REG19__WATCHHI5: 5614 case CP0_REG19__WATCHHI6: 5615 case CP0_REG19__WATCHHI7: 5616 /* upper 32 bits are only available when Config5MI != 0 */ 5617 CP0_CHECK(ctx->mi); 5618 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0); 5619 register_name = "WatchHi"; 5620 break; 5621 default: 5622 goto cp0_unimplemented; 5623 } 5624 break; 5625 case CP0_REGISTER_28: 5626 switch (sel) { 5627 case 0: 5628 case 2: 5629 case 4: 5630 case 6: 5631 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0); 5632 register_name = "TagLo"; 5633 break; 5634 default: 5635 goto cp0_unimplemented; 5636 } 5637 break; 5638 default: 5639 goto cp0_unimplemented; 5640 } 5641 trace_mips_translate_c0("mfhc0", register_name, reg, sel); 5642 return; 5643 5644 cp0_unimplemented: 5645 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", 5646 register_name, reg, sel); 5647 tcg_gen_movi_tl(arg, 0); 5648 } 5649 5650 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5651 { 5652 const char *register_name = "invalid"; 5653 uint64_t mask = ctx->PAMask >> 36; 5654 5655 switch (reg) { 5656 case CP0_REGISTER_02: 5657 switch (sel) { 5658 case 0: 5659 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5660 tcg_gen_andi_tl(arg, arg, mask); 5661 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5662 register_name = "EntryLo0"; 5663 break; 5664 default: 5665 goto cp0_unimplemented; 5666 } 5667 break; 5668 case CP0_REGISTER_03: 5669 switch (sel) { 5670 case CP0_REG03__ENTRYLO1: 5671 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5672 tcg_gen_andi_tl(arg, arg, mask); 5673 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5674 register_name = "EntryLo1"; 5675 break; 5676 default: 5677 goto cp0_unimplemented; 5678 } 5679 break; 5680 case CP0_REGISTER_09: 5681 switch (sel) { 5682 case CP0_REG09__SAAR: 5683 CP0_CHECK(ctx->saar); 5684 gen_helper_mthc0_saar(cpu_env, arg); 5685 register_name = "SAAR"; 5686 break; 5687 default: 5688 goto cp0_unimplemented; 5689 } 5690 break; 5691 case CP0_REGISTER_17: 5692 switch (sel) { 5693 case CP0_REG17__LLADDR: 5694 /* 5695 * LLAddr is read-only (the only exception is bit 0 if LLB is 5696 * supported); the CP0_LLAddr_rw_bitmask does not seem to be 5697 * relevant for modern MIPS cores supporting MTHC0, therefore 5698 * treating MTHC0 to LLAddr as NOP. 5699 */ 5700 register_name = "LLAddr"; 5701 break; 5702 case CP0_REG17__MAAR: 5703 CP0_CHECK(ctx->mrp); 5704 gen_helper_mthc0_maar(cpu_env, arg); 5705 register_name = "MAAR"; 5706 break; 5707 default: 5708 goto cp0_unimplemented; 5709 } 5710 break; 5711 case CP0_REGISTER_19: 5712 switch (sel) { 5713 case CP0_REG19__WATCHHI0: 5714 case CP0_REG19__WATCHHI1: 5715 case CP0_REG19__WATCHHI2: 5716 case CP0_REG19__WATCHHI3: 5717 case CP0_REG19__WATCHHI4: 5718 case CP0_REG19__WATCHHI5: 5719 case CP0_REG19__WATCHHI6: 5720 case CP0_REG19__WATCHHI7: 5721 /* upper 32 bits are only available when Config5MI != 0 */ 5722 CP0_CHECK(ctx->mi); 5723 gen_helper_0e1i(mthc0_watchhi, arg, sel); 5724 register_name = "WatchHi"; 5725 break; 5726 default: 5727 goto cp0_unimplemented; 5728 } 5729 break; 5730 case CP0_REGISTER_28: 5731 switch (sel) { 5732 case 0: 5733 case 2: 5734 case 4: 5735 case 6: 5736 tcg_gen_andi_tl(arg, arg, mask); 5737 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo)); 5738 register_name = "TagLo"; 5739 break; 5740 default: 5741 goto cp0_unimplemented; 5742 } 5743 break; 5744 default: 5745 goto cp0_unimplemented; 5746 } 5747 trace_mips_translate_c0("mthc0", register_name, reg, sel); 5748 return; 5749 5750 cp0_unimplemented: 5751 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", 5752 register_name, reg, sel); 5753 } 5754 5755 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg) 5756 { 5757 if (ctx->insn_flags & ISA_MIPS_R6) { 5758 tcg_gen_movi_tl(arg, 0); 5759 } else { 5760 tcg_gen_movi_tl(arg, ~0); 5761 } 5762 } 5763 5764 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5765 { 5766 const char *register_name = "invalid"; 5767 5768 if (sel != 0) { 5769 check_insn(ctx, ISA_MIPS_R1); 5770 } 5771 5772 switch (reg) { 5773 case CP0_REGISTER_00: 5774 switch (sel) { 5775 case CP0_REG00__INDEX: 5776 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 5777 register_name = "Index"; 5778 break; 5779 case CP0_REG00__MVPCONTROL: 5780 CP0_CHECK(ctx->insn_flags & ASE_MT); 5781 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 5782 register_name = "MVPControl"; 5783 break; 5784 case CP0_REG00__MVPCONF0: 5785 CP0_CHECK(ctx->insn_flags & ASE_MT); 5786 gen_helper_mfc0_mvpconf0(arg, cpu_env); 5787 register_name = "MVPConf0"; 5788 break; 5789 case CP0_REG00__MVPCONF1: 5790 CP0_CHECK(ctx->insn_flags & ASE_MT); 5791 gen_helper_mfc0_mvpconf1(arg, cpu_env); 5792 register_name = "MVPConf1"; 5793 break; 5794 case CP0_REG00__VPCONTROL: 5795 CP0_CHECK(ctx->vp); 5796 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 5797 register_name = "VPControl"; 5798 break; 5799 default: 5800 goto cp0_unimplemented; 5801 } 5802 break; 5803 case CP0_REGISTER_01: 5804 switch (sel) { 5805 case CP0_REG01__RANDOM: 5806 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5807 gen_helper_mfc0_random(arg, cpu_env); 5808 register_name = "Random"; 5809 break; 5810 case CP0_REG01__VPECONTROL: 5811 CP0_CHECK(ctx->insn_flags & ASE_MT); 5812 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 5813 register_name = "VPEControl"; 5814 break; 5815 case CP0_REG01__VPECONF0: 5816 CP0_CHECK(ctx->insn_flags & ASE_MT); 5817 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 5818 register_name = "VPEConf0"; 5819 break; 5820 case CP0_REG01__VPECONF1: 5821 CP0_CHECK(ctx->insn_flags & ASE_MT); 5822 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 5823 register_name = "VPEConf1"; 5824 break; 5825 case CP0_REG01__YQMASK: 5826 CP0_CHECK(ctx->insn_flags & ASE_MT); 5827 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 5828 register_name = "YQMask"; 5829 break; 5830 case CP0_REG01__VPESCHEDULE: 5831 CP0_CHECK(ctx->insn_flags & ASE_MT); 5832 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 5833 register_name = "VPESchedule"; 5834 break; 5835 case CP0_REG01__VPESCHEFBACK: 5836 CP0_CHECK(ctx->insn_flags & ASE_MT); 5837 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5838 register_name = "VPEScheFBack"; 5839 break; 5840 case CP0_REG01__VPEOPT: 5841 CP0_CHECK(ctx->insn_flags & ASE_MT); 5842 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 5843 register_name = "VPEOpt"; 5844 break; 5845 default: 5846 goto cp0_unimplemented; 5847 } 5848 break; 5849 case CP0_REGISTER_02: 5850 switch (sel) { 5851 case CP0_REG02__ENTRYLO0: 5852 { 5853 TCGv_i64 tmp = tcg_temp_new_i64(); 5854 tcg_gen_ld_i64(tmp, cpu_env, 5855 offsetof(CPUMIPSState, CP0_EntryLo0)); 5856 #if defined(TARGET_MIPS64) 5857 if (ctx->rxi) { 5858 /* Move RI/XI fields to bits 31:30 */ 5859 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5860 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5861 } 5862 #endif 5863 gen_move_low32(arg, tmp); 5864 tcg_temp_free_i64(tmp); 5865 } 5866 register_name = "EntryLo0"; 5867 break; 5868 case CP0_REG02__TCSTATUS: 5869 CP0_CHECK(ctx->insn_flags & ASE_MT); 5870 gen_helper_mfc0_tcstatus(arg, cpu_env); 5871 register_name = "TCStatus"; 5872 break; 5873 case CP0_REG02__TCBIND: 5874 CP0_CHECK(ctx->insn_flags & ASE_MT); 5875 gen_helper_mfc0_tcbind(arg, cpu_env); 5876 register_name = "TCBind"; 5877 break; 5878 case CP0_REG02__TCRESTART: 5879 CP0_CHECK(ctx->insn_flags & ASE_MT); 5880 gen_helper_mfc0_tcrestart(arg, cpu_env); 5881 register_name = "TCRestart"; 5882 break; 5883 case CP0_REG02__TCHALT: 5884 CP0_CHECK(ctx->insn_flags & ASE_MT); 5885 gen_helper_mfc0_tchalt(arg, cpu_env); 5886 register_name = "TCHalt"; 5887 break; 5888 case CP0_REG02__TCCONTEXT: 5889 CP0_CHECK(ctx->insn_flags & ASE_MT); 5890 gen_helper_mfc0_tccontext(arg, cpu_env); 5891 register_name = "TCContext"; 5892 break; 5893 case CP0_REG02__TCSCHEDULE: 5894 CP0_CHECK(ctx->insn_flags & ASE_MT); 5895 gen_helper_mfc0_tcschedule(arg, cpu_env); 5896 register_name = "TCSchedule"; 5897 break; 5898 case CP0_REG02__TCSCHEFBACK: 5899 CP0_CHECK(ctx->insn_flags & ASE_MT); 5900 gen_helper_mfc0_tcschefback(arg, cpu_env); 5901 register_name = "TCScheFBack"; 5902 break; 5903 default: 5904 goto cp0_unimplemented; 5905 } 5906 break; 5907 case CP0_REGISTER_03: 5908 switch (sel) { 5909 case CP0_REG03__ENTRYLO1: 5910 { 5911 TCGv_i64 tmp = tcg_temp_new_i64(); 5912 tcg_gen_ld_i64(tmp, cpu_env, 5913 offsetof(CPUMIPSState, CP0_EntryLo1)); 5914 #if defined(TARGET_MIPS64) 5915 if (ctx->rxi) { 5916 /* Move RI/XI fields to bits 31:30 */ 5917 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5918 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5919 } 5920 #endif 5921 gen_move_low32(arg, tmp); 5922 tcg_temp_free_i64(tmp); 5923 } 5924 register_name = "EntryLo1"; 5925 break; 5926 case CP0_REG03__GLOBALNUM: 5927 CP0_CHECK(ctx->vp); 5928 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 5929 register_name = "GlobalNumber"; 5930 break; 5931 default: 5932 goto cp0_unimplemented; 5933 } 5934 break; 5935 case CP0_REGISTER_04: 5936 switch (sel) { 5937 case CP0_REG04__CONTEXT: 5938 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 5939 tcg_gen_ext32s_tl(arg, arg); 5940 register_name = "Context"; 5941 break; 5942 case CP0_REG04__CONTEXTCONFIG: 5943 /* SmartMIPS ASE */ 5944 /* gen_helper_mfc0_contextconfig(arg); */ 5945 register_name = "ContextConfig"; 5946 goto cp0_unimplemented; 5947 case CP0_REG04__USERLOCAL: 5948 CP0_CHECK(ctx->ulri); 5949 tcg_gen_ld_tl(arg, cpu_env, 5950 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 5951 tcg_gen_ext32s_tl(arg, arg); 5952 register_name = "UserLocal"; 5953 break; 5954 case CP0_REG04__MMID: 5955 CP0_CHECK(ctx->mi); 5956 gen_helper_mtc0_memorymapid(cpu_env, arg); 5957 register_name = "MMID"; 5958 break; 5959 default: 5960 goto cp0_unimplemented; 5961 } 5962 break; 5963 case CP0_REGISTER_05: 5964 switch (sel) { 5965 case CP0_REG05__PAGEMASK: 5966 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 5967 register_name = "PageMask"; 5968 break; 5969 case CP0_REG05__PAGEGRAIN: 5970 check_insn(ctx, ISA_MIPS_R2); 5971 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 5972 register_name = "PageGrain"; 5973 break; 5974 case CP0_REG05__SEGCTL0: 5975 CP0_CHECK(ctx->sc); 5976 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 5977 tcg_gen_ext32s_tl(arg, arg); 5978 register_name = "SegCtl0"; 5979 break; 5980 case CP0_REG05__SEGCTL1: 5981 CP0_CHECK(ctx->sc); 5982 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 5983 tcg_gen_ext32s_tl(arg, arg); 5984 register_name = "SegCtl1"; 5985 break; 5986 case CP0_REG05__SEGCTL2: 5987 CP0_CHECK(ctx->sc); 5988 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 5989 tcg_gen_ext32s_tl(arg, arg); 5990 register_name = "SegCtl2"; 5991 break; 5992 case CP0_REG05__PWBASE: 5993 check_pw(ctx); 5994 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 5995 register_name = "PWBase"; 5996 break; 5997 case CP0_REG05__PWFIELD: 5998 check_pw(ctx); 5999 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField)); 6000 register_name = "PWField"; 6001 break; 6002 case CP0_REG05__PWSIZE: 6003 check_pw(ctx); 6004 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize)); 6005 register_name = "PWSize"; 6006 break; 6007 default: 6008 goto cp0_unimplemented; 6009 } 6010 break; 6011 case CP0_REGISTER_06: 6012 switch (sel) { 6013 case CP0_REG06__WIRED: 6014 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 6015 register_name = "Wired"; 6016 break; 6017 case CP0_REG06__SRSCONF0: 6018 check_insn(ctx, ISA_MIPS_R2); 6019 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 6020 register_name = "SRSConf0"; 6021 break; 6022 case CP0_REG06__SRSCONF1: 6023 check_insn(ctx, ISA_MIPS_R2); 6024 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 6025 register_name = "SRSConf1"; 6026 break; 6027 case CP0_REG06__SRSCONF2: 6028 check_insn(ctx, ISA_MIPS_R2); 6029 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 6030 register_name = "SRSConf2"; 6031 break; 6032 case CP0_REG06__SRSCONF3: 6033 check_insn(ctx, ISA_MIPS_R2); 6034 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 6035 register_name = "SRSConf3"; 6036 break; 6037 case CP0_REG06__SRSCONF4: 6038 check_insn(ctx, ISA_MIPS_R2); 6039 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 6040 register_name = "SRSConf4"; 6041 break; 6042 case CP0_REG06__PWCTL: 6043 check_pw(ctx); 6044 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 6045 register_name = "PWCtl"; 6046 break; 6047 default: 6048 goto cp0_unimplemented; 6049 } 6050 break; 6051 case CP0_REGISTER_07: 6052 switch (sel) { 6053 case CP0_REG07__HWRENA: 6054 check_insn(ctx, ISA_MIPS_R2); 6055 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 6056 register_name = "HWREna"; 6057 break; 6058 default: 6059 goto cp0_unimplemented; 6060 } 6061 break; 6062 case CP0_REGISTER_08: 6063 switch (sel) { 6064 case CP0_REG08__BADVADDR: 6065 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 6066 tcg_gen_ext32s_tl(arg, arg); 6067 register_name = "BadVAddr"; 6068 break; 6069 case CP0_REG08__BADINSTR: 6070 CP0_CHECK(ctx->bi); 6071 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 6072 register_name = "BadInstr"; 6073 break; 6074 case CP0_REG08__BADINSTRP: 6075 CP0_CHECK(ctx->bp); 6076 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 6077 register_name = "BadInstrP"; 6078 break; 6079 case CP0_REG08__BADINSTRX: 6080 CP0_CHECK(ctx->bi); 6081 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 6082 tcg_gen_andi_tl(arg, arg, ~0xffff); 6083 register_name = "BadInstrX"; 6084 break; 6085 default: 6086 goto cp0_unimplemented; 6087 } 6088 break; 6089 case CP0_REGISTER_09: 6090 switch (sel) { 6091 case CP0_REG09__COUNT: 6092 /* Mark as an IO operation because we read the time. */ 6093 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 6094 gen_io_start(); 6095 } 6096 gen_helper_mfc0_count(arg, cpu_env); 6097 /* 6098 * Break the TB to be able to take timer interrupts immediately 6099 * after reading count. DISAS_STOP isn't sufficient, we need to 6100 * ensure we break completely out of translated code. 6101 */ 6102 gen_save_pc(ctx->base.pc_next + 4); 6103 ctx->base.is_jmp = DISAS_EXIT; 6104 register_name = "Count"; 6105 break; 6106 case CP0_REG09__SAARI: 6107 CP0_CHECK(ctx->saar); 6108 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); 6109 register_name = "SAARI"; 6110 break; 6111 case CP0_REG09__SAAR: 6112 CP0_CHECK(ctx->saar); 6113 gen_helper_mfc0_saar(arg, cpu_env); 6114 register_name = "SAAR"; 6115 break; 6116 default: 6117 goto cp0_unimplemented; 6118 } 6119 break; 6120 case CP0_REGISTER_10: 6121 switch (sel) { 6122 case CP0_REG10__ENTRYHI: 6123 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 6124 tcg_gen_ext32s_tl(arg, arg); 6125 register_name = "EntryHi"; 6126 break; 6127 default: 6128 goto cp0_unimplemented; 6129 } 6130 break; 6131 case CP0_REGISTER_11: 6132 switch (sel) { 6133 case CP0_REG11__COMPARE: 6134 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 6135 register_name = "Compare"; 6136 break; 6137 /* 6,7 are implementation dependent */ 6138 default: 6139 goto cp0_unimplemented; 6140 } 6141 break; 6142 case CP0_REGISTER_12: 6143 switch (sel) { 6144 case CP0_REG12__STATUS: 6145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 6146 register_name = "Status"; 6147 break; 6148 case CP0_REG12__INTCTL: 6149 check_insn(ctx, ISA_MIPS_R2); 6150 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 6151 register_name = "IntCtl"; 6152 break; 6153 case CP0_REG12__SRSCTL: 6154 check_insn(ctx, ISA_MIPS_R2); 6155 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 6156 register_name = "SRSCtl"; 6157 break; 6158 case CP0_REG12__SRSMAP: 6159 check_insn(ctx, ISA_MIPS_R2); 6160 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6161 register_name = "SRSMap"; 6162 break; 6163 default: 6164 goto cp0_unimplemented; 6165 } 6166 break; 6167 case CP0_REGISTER_13: 6168 switch (sel) { 6169 case CP0_REG13__CAUSE: 6170 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 6171 register_name = "Cause"; 6172 break; 6173 default: 6174 goto cp0_unimplemented; 6175 } 6176 break; 6177 case CP0_REGISTER_14: 6178 switch (sel) { 6179 case CP0_REG14__EPC: 6180 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 6181 tcg_gen_ext32s_tl(arg, arg); 6182 register_name = "EPC"; 6183 break; 6184 default: 6185 goto cp0_unimplemented; 6186 } 6187 break; 6188 case CP0_REGISTER_15: 6189 switch (sel) { 6190 case CP0_REG15__PRID: 6191 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 6192 register_name = "PRid"; 6193 break; 6194 case CP0_REG15__EBASE: 6195 check_insn(ctx, ISA_MIPS_R2); 6196 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); 6197 tcg_gen_ext32s_tl(arg, arg); 6198 register_name = "EBase"; 6199 break; 6200 case CP0_REG15__CMGCRBASE: 6201 check_insn(ctx, ISA_MIPS_R2); 6202 CP0_CHECK(ctx->cmgcr); 6203 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 6204 tcg_gen_ext32s_tl(arg, arg); 6205 register_name = "CMGCRBase"; 6206 break; 6207 default: 6208 goto cp0_unimplemented; 6209 } 6210 break; 6211 case CP0_REGISTER_16: 6212 switch (sel) { 6213 case CP0_REG16__CONFIG: 6214 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 6215 register_name = "Config"; 6216 break; 6217 case CP0_REG16__CONFIG1: 6218 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 6219 register_name = "Config1"; 6220 break; 6221 case CP0_REG16__CONFIG2: 6222 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 6223 register_name = "Config2"; 6224 break; 6225 case CP0_REG16__CONFIG3: 6226 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 6227 register_name = "Config3"; 6228 break; 6229 case CP0_REG16__CONFIG4: 6230 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 6231 register_name = "Config4"; 6232 break; 6233 case CP0_REG16__CONFIG5: 6234 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 6235 register_name = "Config5"; 6236 break; 6237 /* 6,7 are implementation dependent */ 6238 case CP0_REG16__CONFIG6: 6239 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 6240 register_name = "Config6"; 6241 break; 6242 case CP0_REG16__CONFIG7: 6243 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 6244 register_name = "Config7"; 6245 break; 6246 default: 6247 goto cp0_unimplemented; 6248 } 6249 break; 6250 case CP0_REGISTER_17: 6251 switch (sel) { 6252 case CP0_REG17__LLADDR: 6253 gen_helper_mfc0_lladdr(arg, cpu_env); 6254 register_name = "LLAddr"; 6255 break; 6256 case CP0_REG17__MAAR: 6257 CP0_CHECK(ctx->mrp); 6258 gen_helper_mfc0_maar(arg, cpu_env); 6259 register_name = "MAAR"; 6260 break; 6261 case CP0_REG17__MAARI: 6262 CP0_CHECK(ctx->mrp); 6263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 6264 register_name = "MAARI"; 6265 break; 6266 default: 6267 goto cp0_unimplemented; 6268 } 6269 break; 6270 case CP0_REGISTER_18: 6271 switch (sel) { 6272 case CP0_REG18__WATCHLO0: 6273 case CP0_REG18__WATCHLO1: 6274 case CP0_REG18__WATCHLO2: 6275 case CP0_REG18__WATCHLO3: 6276 case CP0_REG18__WATCHLO4: 6277 case CP0_REG18__WATCHLO5: 6278 case CP0_REG18__WATCHLO6: 6279 case CP0_REG18__WATCHLO7: 6280 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6281 gen_helper_1e0i(mfc0_watchlo, arg, sel); 6282 register_name = "WatchLo"; 6283 break; 6284 default: 6285 goto cp0_unimplemented; 6286 } 6287 break; 6288 case CP0_REGISTER_19: 6289 switch (sel) { 6290 case CP0_REG19__WATCHHI0: 6291 case CP0_REG19__WATCHHI1: 6292 case CP0_REG19__WATCHHI2: 6293 case CP0_REG19__WATCHHI3: 6294 case CP0_REG19__WATCHHI4: 6295 case CP0_REG19__WATCHHI5: 6296 case CP0_REG19__WATCHHI6: 6297 case CP0_REG19__WATCHHI7: 6298 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6299 gen_helper_1e0i(mfc0_watchhi, arg, sel); 6300 register_name = "WatchHi"; 6301 break; 6302 default: 6303 goto cp0_unimplemented; 6304 } 6305 break; 6306 case CP0_REGISTER_20: 6307 switch (sel) { 6308 case CP0_REG20__XCONTEXT: 6309 #if defined(TARGET_MIPS64) 6310 check_insn(ctx, ISA_MIPS3); 6311 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 6312 tcg_gen_ext32s_tl(arg, arg); 6313 register_name = "XContext"; 6314 break; 6315 #endif 6316 default: 6317 goto cp0_unimplemented; 6318 } 6319 break; 6320 case CP0_REGISTER_21: 6321 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6322 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6323 switch (sel) { 6324 case 0: 6325 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 6326 register_name = "Framemask"; 6327 break; 6328 default: 6329 goto cp0_unimplemented; 6330 } 6331 break; 6332 case CP0_REGISTER_22: 6333 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 6334 register_name = "'Diagnostic"; /* implementation dependent */ 6335 break; 6336 case CP0_REGISTER_23: 6337 switch (sel) { 6338 case CP0_REG23__DEBUG: 6339 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 6340 register_name = "Debug"; 6341 break; 6342 case CP0_REG23__TRACECONTROL: 6343 /* PDtrace support */ 6344 /* gen_helper_mfc0_tracecontrol(arg); */ 6345 register_name = "TraceControl"; 6346 goto cp0_unimplemented; 6347 case CP0_REG23__TRACECONTROL2: 6348 /* PDtrace support */ 6349 /* gen_helper_mfc0_tracecontrol2(arg); */ 6350 register_name = "TraceControl2"; 6351 goto cp0_unimplemented; 6352 case CP0_REG23__USERTRACEDATA1: 6353 /* PDtrace support */ 6354 /* gen_helper_mfc0_usertracedata1(arg);*/ 6355 register_name = "UserTraceData1"; 6356 goto cp0_unimplemented; 6357 case CP0_REG23__TRACEIBPC: 6358 /* PDtrace support */ 6359 /* gen_helper_mfc0_traceibpc(arg); */ 6360 register_name = "TraceIBPC"; 6361 goto cp0_unimplemented; 6362 case CP0_REG23__TRACEDBPC: 6363 /* PDtrace support */ 6364 /* gen_helper_mfc0_tracedbpc(arg); */ 6365 register_name = "TraceDBPC"; 6366 goto cp0_unimplemented; 6367 default: 6368 goto cp0_unimplemented; 6369 } 6370 break; 6371 case CP0_REGISTER_24: 6372 switch (sel) { 6373 case CP0_REG24__DEPC: 6374 /* EJTAG support */ 6375 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 6376 tcg_gen_ext32s_tl(arg, arg); 6377 register_name = "DEPC"; 6378 break; 6379 default: 6380 goto cp0_unimplemented; 6381 } 6382 break; 6383 case CP0_REGISTER_25: 6384 switch (sel) { 6385 case CP0_REG25__PERFCTL0: 6386 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 6387 register_name = "Performance0"; 6388 break; 6389 case CP0_REG25__PERFCNT0: 6390 /* gen_helper_mfc0_performance1(arg); */ 6391 register_name = "Performance1"; 6392 goto cp0_unimplemented; 6393 case CP0_REG25__PERFCTL1: 6394 /* gen_helper_mfc0_performance2(arg); */ 6395 register_name = "Performance2"; 6396 goto cp0_unimplemented; 6397 case CP0_REG25__PERFCNT1: 6398 /* gen_helper_mfc0_performance3(arg); */ 6399 register_name = "Performance3"; 6400 goto cp0_unimplemented; 6401 case CP0_REG25__PERFCTL2: 6402 /* gen_helper_mfc0_performance4(arg); */ 6403 register_name = "Performance4"; 6404 goto cp0_unimplemented; 6405 case CP0_REG25__PERFCNT2: 6406 /* gen_helper_mfc0_performance5(arg); */ 6407 register_name = "Performance5"; 6408 goto cp0_unimplemented; 6409 case CP0_REG25__PERFCTL3: 6410 /* gen_helper_mfc0_performance6(arg); */ 6411 register_name = "Performance6"; 6412 goto cp0_unimplemented; 6413 case CP0_REG25__PERFCNT3: 6414 /* gen_helper_mfc0_performance7(arg); */ 6415 register_name = "Performance7"; 6416 goto cp0_unimplemented; 6417 default: 6418 goto cp0_unimplemented; 6419 } 6420 break; 6421 case CP0_REGISTER_26: 6422 switch (sel) { 6423 case CP0_REG26__ERRCTL: 6424 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 6425 register_name = "ErrCtl"; 6426 break; 6427 default: 6428 goto cp0_unimplemented; 6429 } 6430 break; 6431 case CP0_REGISTER_27: 6432 switch (sel) { 6433 case CP0_REG27__CACHERR: 6434 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 6435 register_name = "CacheErr"; 6436 break; 6437 default: 6438 goto cp0_unimplemented; 6439 } 6440 break; 6441 case CP0_REGISTER_28: 6442 switch (sel) { 6443 case CP0_REG28__TAGLO: 6444 case CP0_REG28__TAGLO1: 6445 case CP0_REG28__TAGLO2: 6446 case CP0_REG28__TAGLO3: 6447 { 6448 TCGv_i64 tmp = tcg_temp_new_i64(); 6449 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo)); 6450 gen_move_low32(arg, tmp); 6451 tcg_temp_free_i64(tmp); 6452 } 6453 register_name = "TagLo"; 6454 break; 6455 case CP0_REG28__DATALO: 6456 case CP0_REG28__DATALO1: 6457 case CP0_REG28__DATALO2: 6458 case CP0_REG28__DATALO3: 6459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 6460 register_name = "DataLo"; 6461 break; 6462 default: 6463 goto cp0_unimplemented; 6464 } 6465 break; 6466 case CP0_REGISTER_29: 6467 switch (sel) { 6468 case CP0_REG29__TAGHI: 6469 case CP0_REG29__TAGHI1: 6470 case CP0_REG29__TAGHI2: 6471 case CP0_REG29__TAGHI3: 6472 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 6473 register_name = "TagHi"; 6474 break; 6475 case CP0_REG29__DATAHI: 6476 case CP0_REG29__DATAHI1: 6477 case CP0_REG29__DATAHI2: 6478 case CP0_REG29__DATAHI3: 6479 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 6480 register_name = "DataHi"; 6481 break; 6482 default: 6483 goto cp0_unimplemented; 6484 } 6485 break; 6486 case CP0_REGISTER_30: 6487 switch (sel) { 6488 case CP0_REG30__ERROREPC: 6489 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 6490 tcg_gen_ext32s_tl(arg, arg); 6491 register_name = "ErrorEPC"; 6492 break; 6493 default: 6494 goto cp0_unimplemented; 6495 } 6496 break; 6497 case CP0_REGISTER_31: 6498 switch (sel) { 6499 case CP0_REG31__DESAVE: 6500 /* EJTAG support */ 6501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 6502 register_name = "DESAVE"; 6503 break; 6504 case CP0_REG31__KSCRATCH1: 6505 case CP0_REG31__KSCRATCH2: 6506 case CP0_REG31__KSCRATCH3: 6507 case CP0_REG31__KSCRATCH4: 6508 case CP0_REG31__KSCRATCH5: 6509 case CP0_REG31__KSCRATCH6: 6510 CP0_CHECK(ctx->kscrexist & (1 << sel)); 6511 tcg_gen_ld_tl(arg, cpu_env, 6512 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 6513 tcg_gen_ext32s_tl(arg, arg); 6514 register_name = "KScratch"; 6515 break; 6516 default: 6517 goto cp0_unimplemented; 6518 } 6519 break; 6520 default: 6521 goto cp0_unimplemented; 6522 } 6523 trace_mips_translate_c0("mfc0", register_name, reg, sel); 6524 return; 6525 6526 cp0_unimplemented: 6527 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", 6528 register_name, reg, sel); 6529 gen_mfc0_unimplemented(ctx, arg); 6530 } 6531 6532 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 6533 { 6534 const char *register_name = "invalid"; 6535 6536 if (sel != 0) { 6537 check_insn(ctx, ISA_MIPS_R1); 6538 } 6539 6540 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 6541 gen_io_start(); 6542 } 6543 6544 switch (reg) { 6545 case CP0_REGISTER_00: 6546 switch (sel) { 6547 case CP0_REG00__INDEX: 6548 gen_helper_mtc0_index(cpu_env, arg); 6549 register_name = "Index"; 6550 break; 6551 case CP0_REG00__MVPCONTROL: 6552 CP0_CHECK(ctx->insn_flags & ASE_MT); 6553 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 6554 register_name = "MVPControl"; 6555 break; 6556 case CP0_REG00__MVPCONF0: 6557 CP0_CHECK(ctx->insn_flags & ASE_MT); 6558 /* ignored */ 6559 register_name = "MVPConf0"; 6560 break; 6561 case CP0_REG00__MVPCONF1: 6562 CP0_CHECK(ctx->insn_flags & ASE_MT); 6563 /* ignored */ 6564 register_name = "MVPConf1"; 6565 break; 6566 case CP0_REG00__VPCONTROL: 6567 CP0_CHECK(ctx->vp); 6568 /* ignored */ 6569 register_name = "VPControl"; 6570 break; 6571 default: 6572 goto cp0_unimplemented; 6573 } 6574 break; 6575 case CP0_REGISTER_01: 6576 switch (sel) { 6577 case CP0_REG01__RANDOM: 6578 /* ignored */ 6579 register_name = "Random"; 6580 break; 6581 case CP0_REG01__VPECONTROL: 6582 CP0_CHECK(ctx->insn_flags & ASE_MT); 6583 gen_helper_mtc0_vpecontrol(cpu_env, arg); 6584 register_name = "VPEControl"; 6585 break; 6586 case CP0_REG01__VPECONF0: 6587 CP0_CHECK(ctx->insn_flags & ASE_MT); 6588 gen_helper_mtc0_vpeconf0(cpu_env, arg); 6589 register_name = "VPEConf0"; 6590 break; 6591 case CP0_REG01__VPECONF1: 6592 CP0_CHECK(ctx->insn_flags & ASE_MT); 6593 gen_helper_mtc0_vpeconf1(cpu_env, arg); 6594 register_name = "VPEConf1"; 6595 break; 6596 case CP0_REG01__YQMASK: 6597 CP0_CHECK(ctx->insn_flags & ASE_MT); 6598 gen_helper_mtc0_yqmask(cpu_env, arg); 6599 register_name = "YQMask"; 6600 break; 6601 case CP0_REG01__VPESCHEDULE: 6602 CP0_CHECK(ctx->insn_flags & ASE_MT); 6603 tcg_gen_st_tl(arg, cpu_env, 6604 offsetof(CPUMIPSState, CP0_VPESchedule)); 6605 register_name = "VPESchedule"; 6606 break; 6607 case CP0_REG01__VPESCHEFBACK: 6608 CP0_CHECK(ctx->insn_flags & ASE_MT); 6609 tcg_gen_st_tl(arg, cpu_env, 6610 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6611 register_name = "VPEScheFBack"; 6612 break; 6613 case CP0_REG01__VPEOPT: 6614 CP0_CHECK(ctx->insn_flags & ASE_MT); 6615 gen_helper_mtc0_vpeopt(cpu_env, arg); 6616 register_name = "VPEOpt"; 6617 break; 6618 default: 6619 goto cp0_unimplemented; 6620 } 6621 break; 6622 case CP0_REGISTER_02: 6623 switch (sel) { 6624 case CP0_REG02__ENTRYLO0: 6625 gen_helper_mtc0_entrylo0(cpu_env, arg); 6626 register_name = "EntryLo0"; 6627 break; 6628 case CP0_REG02__TCSTATUS: 6629 CP0_CHECK(ctx->insn_flags & ASE_MT); 6630 gen_helper_mtc0_tcstatus(cpu_env, arg); 6631 register_name = "TCStatus"; 6632 break; 6633 case CP0_REG02__TCBIND: 6634 CP0_CHECK(ctx->insn_flags & ASE_MT); 6635 gen_helper_mtc0_tcbind(cpu_env, arg); 6636 register_name = "TCBind"; 6637 break; 6638 case CP0_REG02__TCRESTART: 6639 CP0_CHECK(ctx->insn_flags & ASE_MT); 6640 gen_helper_mtc0_tcrestart(cpu_env, arg); 6641 register_name = "TCRestart"; 6642 break; 6643 case CP0_REG02__TCHALT: 6644 CP0_CHECK(ctx->insn_flags & ASE_MT); 6645 gen_helper_mtc0_tchalt(cpu_env, arg); 6646 register_name = "TCHalt"; 6647 break; 6648 case CP0_REG02__TCCONTEXT: 6649 CP0_CHECK(ctx->insn_flags & ASE_MT); 6650 gen_helper_mtc0_tccontext(cpu_env, arg); 6651 register_name = "TCContext"; 6652 break; 6653 case CP0_REG02__TCSCHEDULE: 6654 CP0_CHECK(ctx->insn_flags & ASE_MT); 6655 gen_helper_mtc0_tcschedule(cpu_env, arg); 6656 register_name = "TCSchedule"; 6657 break; 6658 case CP0_REG02__TCSCHEFBACK: 6659 CP0_CHECK(ctx->insn_flags & ASE_MT); 6660 gen_helper_mtc0_tcschefback(cpu_env, arg); 6661 register_name = "TCScheFBack"; 6662 break; 6663 default: 6664 goto cp0_unimplemented; 6665 } 6666 break; 6667 case CP0_REGISTER_03: 6668 switch (sel) { 6669 case CP0_REG03__ENTRYLO1: 6670 gen_helper_mtc0_entrylo1(cpu_env, arg); 6671 register_name = "EntryLo1"; 6672 break; 6673 case CP0_REG03__GLOBALNUM: 6674 CP0_CHECK(ctx->vp); 6675 /* ignored */ 6676 register_name = "GlobalNumber"; 6677 break; 6678 default: 6679 goto cp0_unimplemented; 6680 } 6681 break; 6682 case CP0_REGISTER_04: 6683 switch (sel) { 6684 case CP0_REG04__CONTEXT: 6685 gen_helper_mtc0_context(cpu_env, arg); 6686 register_name = "Context"; 6687 break; 6688 case CP0_REG04__CONTEXTCONFIG: 6689 /* SmartMIPS ASE */ 6690 /* gen_helper_mtc0_contextconfig(arg); */ 6691 register_name = "ContextConfig"; 6692 goto cp0_unimplemented; 6693 case CP0_REG04__USERLOCAL: 6694 CP0_CHECK(ctx->ulri); 6695 tcg_gen_st_tl(arg, cpu_env, 6696 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6697 register_name = "UserLocal"; 6698 break; 6699 case CP0_REG04__MMID: 6700 CP0_CHECK(ctx->mi); 6701 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 6702 register_name = "MMID"; 6703 break; 6704 default: 6705 goto cp0_unimplemented; 6706 } 6707 break; 6708 case CP0_REGISTER_05: 6709 switch (sel) { 6710 case CP0_REG05__PAGEMASK: 6711 gen_helper_mtc0_pagemask(cpu_env, arg); 6712 register_name = "PageMask"; 6713 break; 6714 case CP0_REG05__PAGEGRAIN: 6715 check_insn(ctx, ISA_MIPS_R2); 6716 gen_helper_mtc0_pagegrain(cpu_env, arg); 6717 register_name = "PageGrain"; 6718 ctx->base.is_jmp = DISAS_STOP; 6719 break; 6720 case CP0_REG05__SEGCTL0: 6721 CP0_CHECK(ctx->sc); 6722 gen_helper_mtc0_segctl0(cpu_env, arg); 6723 register_name = "SegCtl0"; 6724 break; 6725 case CP0_REG05__SEGCTL1: 6726 CP0_CHECK(ctx->sc); 6727 gen_helper_mtc0_segctl1(cpu_env, arg); 6728 register_name = "SegCtl1"; 6729 break; 6730 case CP0_REG05__SEGCTL2: 6731 CP0_CHECK(ctx->sc); 6732 gen_helper_mtc0_segctl2(cpu_env, arg); 6733 register_name = "SegCtl2"; 6734 break; 6735 case CP0_REG05__PWBASE: 6736 check_pw(ctx); 6737 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 6738 register_name = "PWBase"; 6739 break; 6740 case CP0_REG05__PWFIELD: 6741 check_pw(ctx); 6742 gen_helper_mtc0_pwfield(cpu_env, arg); 6743 register_name = "PWField"; 6744 break; 6745 case CP0_REG05__PWSIZE: 6746 check_pw(ctx); 6747 gen_helper_mtc0_pwsize(cpu_env, arg); 6748 register_name = "PWSize"; 6749 break; 6750 default: 6751 goto cp0_unimplemented; 6752 } 6753 break; 6754 case CP0_REGISTER_06: 6755 switch (sel) { 6756 case CP0_REG06__WIRED: 6757 gen_helper_mtc0_wired(cpu_env, arg); 6758 register_name = "Wired"; 6759 break; 6760 case CP0_REG06__SRSCONF0: 6761 check_insn(ctx, ISA_MIPS_R2); 6762 gen_helper_mtc0_srsconf0(cpu_env, arg); 6763 register_name = "SRSConf0"; 6764 break; 6765 case CP0_REG06__SRSCONF1: 6766 check_insn(ctx, ISA_MIPS_R2); 6767 gen_helper_mtc0_srsconf1(cpu_env, arg); 6768 register_name = "SRSConf1"; 6769 break; 6770 case CP0_REG06__SRSCONF2: 6771 check_insn(ctx, ISA_MIPS_R2); 6772 gen_helper_mtc0_srsconf2(cpu_env, arg); 6773 register_name = "SRSConf2"; 6774 break; 6775 case CP0_REG06__SRSCONF3: 6776 check_insn(ctx, ISA_MIPS_R2); 6777 gen_helper_mtc0_srsconf3(cpu_env, arg); 6778 register_name = "SRSConf3"; 6779 break; 6780 case CP0_REG06__SRSCONF4: 6781 check_insn(ctx, ISA_MIPS_R2); 6782 gen_helper_mtc0_srsconf4(cpu_env, arg); 6783 register_name = "SRSConf4"; 6784 break; 6785 case CP0_REG06__PWCTL: 6786 check_pw(ctx); 6787 gen_helper_mtc0_pwctl(cpu_env, arg); 6788 register_name = "PWCtl"; 6789 break; 6790 default: 6791 goto cp0_unimplemented; 6792 } 6793 break; 6794 case CP0_REGISTER_07: 6795 switch (sel) { 6796 case CP0_REG07__HWRENA: 6797 check_insn(ctx, ISA_MIPS_R2); 6798 gen_helper_mtc0_hwrena(cpu_env, arg); 6799 ctx->base.is_jmp = DISAS_STOP; 6800 register_name = "HWREna"; 6801 break; 6802 default: 6803 goto cp0_unimplemented; 6804 } 6805 break; 6806 case CP0_REGISTER_08: 6807 switch (sel) { 6808 case CP0_REG08__BADVADDR: 6809 /* ignored */ 6810 register_name = "BadVAddr"; 6811 break; 6812 case CP0_REG08__BADINSTR: 6813 /* ignored */ 6814 register_name = "BadInstr"; 6815 break; 6816 case CP0_REG08__BADINSTRP: 6817 /* ignored */ 6818 register_name = "BadInstrP"; 6819 break; 6820 case CP0_REG08__BADINSTRX: 6821 /* ignored */ 6822 register_name = "BadInstrX"; 6823 break; 6824 default: 6825 goto cp0_unimplemented; 6826 } 6827 break; 6828 case CP0_REGISTER_09: 6829 switch (sel) { 6830 case CP0_REG09__COUNT: 6831 gen_helper_mtc0_count(cpu_env, arg); 6832 register_name = "Count"; 6833 break; 6834 case CP0_REG09__SAARI: 6835 CP0_CHECK(ctx->saar); 6836 gen_helper_mtc0_saari(cpu_env, arg); 6837 register_name = "SAARI"; 6838 break; 6839 case CP0_REG09__SAAR: 6840 CP0_CHECK(ctx->saar); 6841 gen_helper_mtc0_saar(cpu_env, arg); 6842 register_name = "SAAR"; 6843 break; 6844 default: 6845 goto cp0_unimplemented; 6846 } 6847 break; 6848 case CP0_REGISTER_10: 6849 switch (sel) { 6850 case CP0_REG10__ENTRYHI: 6851 gen_helper_mtc0_entryhi(cpu_env, arg); 6852 register_name = "EntryHi"; 6853 break; 6854 default: 6855 goto cp0_unimplemented; 6856 } 6857 break; 6858 case CP0_REGISTER_11: 6859 switch (sel) { 6860 case CP0_REG11__COMPARE: 6861 gen_helper_mtc0_compare(cpu_env, arg); 6862 register_name = "Compare"; 6863 break; 6864 /* 6,7 are implementation dependent */ 6865 default: 6866 goto cp0_unimplemented; 6867 } 6868 break; 6869 case CP0_REGISTER_12: 6870 switch (sel) { 6871 case CP0_REG12__STATUS: 6872 save_cpu_state(ctx, 1); 6873 gen_helper_mtc0_status(cpu_env, arg); 6874 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6875 gen_save_pc(ctx->base.pc_next + 4); 6876 ctx->base.is_jmp = DISAS_EXIT; 6877 register_name = "Status"; 6878 break; 6879 case CP0_REG12__INTCTL: 6880 check_insn(ctx, ISA_MIPS_R2); 6881 gen_helper_mtc0_intctl(cpu_env, arg); 6882 /* Stop translation as we may have switched the execution mode */ 6883 ctx->base.is_jmp = DISAS_STOP; 6884 register_name = "IntCtl"; 6885 break; 6886 case CP0_REG12__SRSCTL: 6887 check_insn(ctx, ISA_MIPS_R2); 6888 gen_helper_mtc0_srsctl(cpu_env, arg); 6889 /* Stop translation as we may have switched the execution mode */ 6890 ctx->base.is_jmp = DISAS_STOP; 6891 register_name = "SRSCtl"; 6892 break; 6893 case CP0_REG12__SRSMAP: 6894 check_insn(ctx, ISA_MIPS_R2); 6895 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6896 /* Stop translation as we may have switched the execution mode */ 6897 ctx->base.is_jmp = DISAS_STOP; 6898 register_name = "SRSMap"; 6899 break; 6900 default: 6901 goto cp0_unimplemented; 6902 } 6903 break; 6904 case CP0_REGISTER_13: 6905 switch (sel) { 6906 case CP0_REG13__CAUSE: 6907 save_cpu_state(ctx, 1); 6908 gen_helper_mtc0_cause(cpu_env, arg); 6909 /* 6910 * Stop translation as we may have triggered an interrupt. 6911 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6912 * translated code to check for pending interrupts. 6913 */ 6914 gen_save_pc(ctx->base.pc_next + 4); 6915 ctx->base.is_jmp = DISAS_EXIT; 6916 register_name = "Cause"; 6917 break; 6918 default: 6919 goto cp0_unimplemented; 6920 } 6921 break; 6922 case CP0_REGISTER_14: 6923 switch (sel) { 6924 case CP0_REG14__EPC: 6925 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 6926 register_name = "EPC"; 6927 break; 6928 default: 6929 goto cp0_unimplemented; 6930 } 6931 break; 6932 case CP0_REGISTER_15: 6933 switch (sel) { 6934 case CP0_REG15__PRID: 6935 /* ignored */ 6936 register_name = "PRid"; 6937 break; 6938 case CP0_REG15__EBASE: 6939 check_insn(ctx, ISA_MIPS_R2); 6940 gen_helper_mtc0_ebase(cpu_env, arg); 6941 register_name = "EBase"; 6942 break; 6943 default: 6944 goto cp0_unimplemented; 6945 } 6946 break; 6947 case CP0_REGISTER_16: 6948 switch (sel) { 6949 case CP0_REG16__CONFIG: 6950 gen_helper_mtc0_config0(cpu_env, arg); 6951 register_name = "Config"; 6952 /* Stop translation as we may have switched the execution mode */ 6953 ctx->base.is_jmp = DISAS_STOP; 6954 break; 6955 case CP0_REG16__CONFIG1: 6956 /* ignored, read only */ 6957 register_name = "Config1"; 6958 break; 6959 case CP0_REG16__CONFIG2: 6960 gen_helper_mtc0_config2(cpu_env, arg); 6961 register_name = "Config2"; 6962 /* Stop translation as we may have switched the execution mode */ 6963 ctx->base.is_jmp = DISAS_STOP; 6964 break; 6965 case CP0_REG16__CONFIG3: 6966 gen_helper_mtc0_config3(cpu_env, arg); 6967 register_name = "Config3"; 6968 /* Stop translation as we may have switched the execution mode */ 6969 ctx->base.is_jmp = DISAS_STOP; 6970 break; 6971 case CP0_REG16__CONFIG4: 6972 gen_helper_mtc0_config4(cpu_env, arg); 6973 register_name = "Config4"; 6974 ctx->base.is_jmp = DISAS_STOP; 6975 break; 6976 case CP0_REG16__CONFIG5: 6977 gen_helper_mtc0_config5(cpu_env, arg); 6978 register_name = "Config5"; 6979 /* Stop translation as we may have switched the execution mode */ 6980 ctx->base.is_jmp = DISAS_STOP; 6981 break; 6982 /* 6,7 are implementation dependent */ 6983 case CP0_REG16__CONFIG6: 6984 /* ignored */ 6985 register_name = "Config6"; 6986 break; 6987 case CP0_REG16__CONFIG7: 6988 /* ignored */ 6989 register_name = "Config7"; 6990 break; 6991 default: 6992 register_name = "Invalid config selector"; 6993 goto cp0_unimplemented; 6994 } 6995 break; 6996 case CP0_REGISTER_17: 6997 switch (sel) { 6998 case CP0_REG17__LLADDR: 6999 gen_helper_mtc0_lladdr(cpu_env, arg); 7000 register_name = "LLAddr"; 7001 break; 7002 case CP0_REG17__MAAR: 7003 CP0_CHECK(ctx->mrp); 7004 gen_helper_mtc0_maar(cpu_env, arg); 7005 register_name = "MAAR"; 7006 break; 7007 case CP0_REG17__MAARI: 7008 CP0_CHECK(ctx->mrp); 7009 gen_helper_mtc0_maari(cpu_env, arg); 7010 register_name = "MAARI"; 7011 break; 7012 default: 7013 goto cp0_unimplemented; 7014 } 7015 break; 7016 case CP0_REGISTER_18: 7017 switch (sel) { 7018 case CP0_REG18__WATCHLO0: 7019 case CP0_REG18__WATCHLO1: 7020 case CP0_REG18__WATCHLO2: 7021 case CP0_REG18__WATCHLO3: 7022 case CP0_REG18__WATCHLO4: 7023 case CP0_REG18__WATCHLO5: 7024 case CP0_REG18__WATCHLO6: 7025 case CP0_REG18__WATCHLO7: 7026 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7027 gen_helper_0e1i(mtc0_watchlo, arg, sel); 7028 register_name = "WatchLo"; 7029 break; 7030 default: 7031 goto cp0_unimplemented; 7032 } 7033 break; 7034 case CP0_REGISTER_19: 7035 switch (sel) { 7036 case CP0_REG19__WATCHHI0: 7037 case CP0_REG19__WATCHHI1: 7038 case CP0_REG19__WATCHHI2: 7039 case CP0_REG19__WATCHHI3: 7040 case CP0_REG19__WATCHHI4: 7041 case CP0_REG19__WATCHHI5: 7042 case CP0_REG19__WATCHHI6: 7043 case CP0_REG19__WATCHHI7: 7044 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7045 gen_helper_0e1i(mtc0_watchhi, arg, sel); 7046 register_name = "WatchHi"; 7047 break; 7048 default: 7049 goto cp0_unimplemented; 7050 } 7051 break; 7052 case CP0_REGISTER_20: 7053 switch (sel) { 7054 case CP0_REG20__XCONTEXT: 7055 #if defined(TARGET_MIPS64) 7056 check_insn(ctx, ISA_MIPS3); 7057 gen_helper_mtc0_xcontext(cpu_env, arg); 7058 register_name = "XContext"; 7059 break; 7060 #endif 7061 default: 7062 goto cp0_unimplemented; 7063 } 7064 break; 7065 case CP0_REGISTER_21: 7066 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7067 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7068 switch (sel) { 7069 case 0: 7070 gen_helper_mtc0_framemask(cpu_env, arg); 7071 register_name = "Framemask"; 7072 break; 7073 default: 7074 goto cp0_unimplemented; 7075 } 7076 break; 7077 case CP0_REGISTER_22: 7078 /* ignored */ 7079 register_name = "Diagnostic"; /* implementation dependent */ 7080 break; 7081 case CP0_REGISTER_23: 7082 switch (sel) { 7083 case CP0_REG23__DEBUG: 7084 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 7085 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7086 gen_save_pc(ctx->base.pc_next + 4); 7087 ctx->base.is_jmp = DISAS_EXIT; 7088 register_name = "Debug"; 7089 break; 7090 case CP0_REG23__TRACECONTROL: 7091 /* PDtrace support */ 7092 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ 7093 register_name = "TraceControl"; 7094 /* Stop translation as we may have switched the execution mode */ 7095 ctx->base.is_jmp = DISAS_STOP; 7096 goto cp0_unimplemented; 7097 case CP0_REG23__TRACECONTROL2: 7098 /* PDtrace support */ 7099 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ 7100 register_name = "TraceControl2"; 7101 /* Stop translation as we may have switched the execution mode */ 7102 ctx->base.is_jmp = DISAS_STOP; 7103 goto cp0_unimplemented; 7104 case CP0_REG23__USERTRACEDATA1: 7105 /* Stop translation as we may have switched the execution mode */ 7106 ctx->base.is_jmp = DISAS_STOP; 7107 /* PDtrace support */ 7108 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ 7109 register_name = "UserTraceData"; 7110 /* Stop translation as we may have switched the execution mode */ 7111 ctx->base.is_jmp = DISAS_STOP; 7112 goto cp0_unimplemented; 7113 case CP0_REG23__TRACEIBPC: 7114 /* PDtrace support */ 7115 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ 7116 /* Stop translation as we may have switched the execution mode */ 7117 ctx->base.is_jmp = DISAS_STOP; 7118 register_name = "TraceIBPC"; 7119 goto cp0_unimplemented; 7120 case CP0_REG23__TRACEDBPC: 7121 /* PDtrace support */ 7122 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ 7123 /* Stop translation as we may have switched the execution mode */ 7124 ctx->base.is_jmp = DISAS_STOP; 7125 register_name = "TraceDBPC"; 7126 goto cp0_unimplemented; 7127 default: 7128 goto cp0_unimplemented; 7129 } 7130 break; 7131 case CP0_REGISTER_24: 7132 switch (sel) { 7133 case CP0_REG24__DEPC: 7134 /* EJTAG support */ 7135 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 7136 register_name = "DEPC"; 7137 break; 7138 default: 7139 goto cp0_unimplemented; 7140 } 7141 break; 7142 case CP0_REGISTER_25: 7143 switch (sel) { 7144 case CP0_REG25__PERFCTL0: 7145 gen_helper_mtc0_performance0(cpu_env, arg); 7146 register_name = "Performance0"; 7147 break; 7148 case CP0_REG25__PERFCNT0: 7149 /* gen_helper_mtc0_performance1(arg); */ 7150 register_name = "Performance1"; 7151 goto cp0_unimplemented; 7152 case CP0_REG25__PERFCTL1: 7153 /* gen_helper_mtc0_performance2(arg); */ 7154 register_name = "Performance2"; 7155 goto cp0_unimplemented; 7156 case CP0_REG25__PERFCNT1: 7157 /* gen_helper_mtc0_performance3(arg); */ 7158 register_name = "Performance3"; 7159 goto cp0_unimplemented; 7160 case CP0_REG25__PERFCTL2: 7161 /* gen_helper_mtc0_performance4(arg); */ 7162 register_name = "Performance4"; 7163 goto cp0_unimplemented; 7164 case CP0_REG25__PERFCNT2: 7165 /* gen_helper_mtc0_performance5(arg); */ 7166 register_name = "Performance5"; 7167 goto cp0_unimplemented; 7168 case CP0_REG25__PERFCTL3: 7169 /* gen_helper_mtc0_performance6(arg); */ 7170 register_name = "Performance6"; 7171 goto cp0_unimplemented; 7172 case CP0_REG25__PERFCNT3: 7173 /* gen_helper_mtc0_performance7(arg); */ 7174 register_name = "Performance7"; 7175 goto cp0_unimplemented; 7176 default: 7177 goto cp0_unimplemented; 7178 } 7179 break; 7180 case CP0_REGISTER_26: 7181 switch (sel) { 7182 case CP0_REG26__ERRCTL: 7183 gen_helper_mtc0_errctl(cpu_env, arg); 7184 ctx->base.is_jmp = DISAS_STOP; 7185 register_name = "ErrCtl"; 7186 break; 7187 default: 7188 goto cp0_unimplemented; 7189 } 7190 break; 7191 case CP0_REGISTER_27: 7192 switch (sel) { 7193 case CP0_REG27__CACHERR: 7194 /* ignored */ 7195 register_name = "CacheErr"; 7196 break; 7197 default: 7198 goto cp0_unimplemented; 7199 } 7200 break; 7201 case CP0_REGISTER_28: 7202 switch (sel) { 7203 case CP0_REG28__TAGLO: 7204 case CP0_REG28__TAGLO1: 7205 case CP0_REG28__TAGLO2: 7206 case CP0_REG28__TAGLO3: 7207 gen_helper_mtc0_taglo(cpu_env, arg); 7208 register_name = "TagLo"; 7209 break; 7210 case CP0_REG28__DATALO: 7211 case CP0_REG28__DATALO1: 7212 case CP0_REG28__DATALO2: 7213 case CP0_REG28__DATALO3: 7214 gen_helper_mtc0_datalo(cpu_env, arg); 7215 register_name = "DataLo"; 7216 break; 7217 default: 7218 goto cp0_unimplemented; 7219 } 7220 break; 7221 case CP0_REGISTER_29: 7222 switch (sel) { 7223 case CP0_REG29__TAGHI: 7224 case CP0_REG29__TAGHI1: 7225 case CP0_REG29__TAGHI2: 7226 case CP0_REG29__TAGHI3: 7227 gen_helper_mtc0_taghi(cpu_env, arg); 7228 register_name = "TagHi"; 7229 break; 7230 case CP0_REG29__DATAHI: 7231 case CP0_REG29__DATAHI1: 7232 case CP0_REG29__DATAHI2: 7233 case CP0_REG29__DATAHI3: 7234 gen_helper_mtc0_datahi(cpu_env, arg); 7235 register_name = "DataHi"; 7236 break; 7237 default: 7238 register_name = "invalid sel"; 7239 goto cp0_unimplemented; 7240 } 7241 break; 7242 case CP0_REGISTER_30: 7243 switch (sel) { 7244 case CP0_REG30__ERROREPC: 7245 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7246 register_name = "ErrorEPC"; 7247 break; 7248 default: 7249 goto cp0_unimplemented; 7250 } 7251 break; 7252 case CP0_REGISTER_31: 7253 switch (sel) { 7254 case CP0_REG31__DESAVE: 7255 /* EJTAG support */ 7256 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7257 register_name = "DESAVE"; 7258 break; 7259 case CP0_REG31__KSCRATCH1: 7260 case CP0_REG31__KSCRATCH2: 7261 case CP0_REG31__KSCRATCH3: 7262 case CP0_REG31__KSCRATCH4: 7263 case CP0_REG31__KSCRATCH5: 7264 case CP0_REG31__KSCRATCH6: 7265 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7266 tcg_gen_st_tl(arg, cpu_env, 7267 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7268 register_name = "KScratch"; 7269 break; 7270 default: 7271 goto cp0_unimplemented; 7272 } 7273 break; 7274 default: 7275 goto cp0_unimplemented; 7276 } 7277 trace_mips_translate_c0("mtc0", register_name, reg, sel); 7278 7279 /* For simplicity assume that all writes can cause interrupts. */ 7280 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7281 /* 7282 * DISAS_STOP isn't sufficient, we need to ensure we break out of 7283 * translated code to check for pending interrupts. 7284 */ 7285 gen_save_pc(ctx->base.pc_next + 4); 7286 ctx->base.is_jmp = DISAS_EXIT; 7287 } 7288 return; 7289 7290 cp0_unimplemented: 7291 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", 7292 register_name, reg, sel); 7293 } 7294 7295 #if defined(TARGET_MIPS64) 7296 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7297 { 7298 const char *register_name = "invalid"; 7299 7300 if (sel != 0) { 7301 check_insn(ctx, ISA_MIPS_R1); 7302 } 7303 7304 switch (reg) { 7305 case CP0_REGISTER_00: 7306 switch (sel) { 7307 case CP0_REG00__INDEX: 7308 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 7309 register_name = "Index"; 7310 break; 7311 case CP0_REG00__MVPCONTROL: 7312 CP0_CHECK(ctx->insn_flags & ASE_MT); 7313 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 7314 register_name = "MVPControl"; 7315 break; 7316 case CP0_REG00__MVPCONF0: 7317 CP0_CHECK(ctx->insn_flags & ASE_MT); 7318 gen_helper_mfc0_mvpconf0(arg, cpu_env); 7319 register_name = "MVPConf0"; 7320 break; 7321 case CP0_REG00__MVPCONF1: 7322 CP0_CHECK(ctx->insn_flags & ASE_MT); 7323 gen_helper_mfc0_mvpconf1(arg, cpu_env); 7324 register_name = "MVPConf1"; 7325 break; 7326 case CP0_REG00__VPCONTROL: 7327 CP0_CHECK(ctx->vp); 7328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 7329 register_name = "VPControl"; 7330 break; 7331 default: 7332 goto cp0_unimplemented; 7333 } 7334 break; 7335 case CP0_REGISTER_01: 7336 switch (sel) { 7337 case CP0_REG01__RANDOM: 7338 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7339 gen_helper_mfc0_random(arg, cpu_env); 7340 register_name = "Random"; 7341 break; 7342 case CP0_REG01__VPECONTROL: 7343 CP0_CHECK(ctx->insn_flags & ASE_MT); 7344 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 7345 register_name = "VPEControl"; 7346 break; 7347 case CP0_REG01__VPECONF0: 7348 CP0_CHECK(ctx->insn_flags & ASE_MT); 7349 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 7350 register_name = "VPEConf0"; 7351 break; 7352 case CP0_REG01__VPECONF1: 7353 CP0_CHECK(ctx->insn_flags & ASE_MT); 7354 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 7355 register_name = "VPEConf1"; 7356 break; 7357 case CP0_REG01__YQMASK: 7358 CP0_CHECK(ctx->insn_flags & ASE_MT); 7359 tcg_gen_ld_tl(arg, cpu_env, 7360 offsetof(CPUMIPSState, CP0_YQMask)); 7361 register_name = "YQMask"; 7362 break; 7363 case CP0_REG01__VPESCHEDULE: 7364 CP0_CHECK(ctx->insn_flags & ASE_MT); 7365 tcg_gen_ld_tl(arg, cpu_env, 7366 offsetof(CPUMIPSState, CP0_VPESchedule)); 7367 register_name = "VPESchedule"; 7368 break; 7369 case CP0_REG01__VPESCHEFBACK: 7370 CP0_CHECK(ctx->insn_flags & ASE_MT); 7371 tcg_gen_ld_tl(arg, cpu_env, 7372 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7373 register_name = "VPEScheFBack"; 7374 break; 7375 case CP0_REG01__VPEOPT: 7376 CP0_CHECK(ctx->insn_flags & ASE_MT); 7377 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 7378 register_name = "VPEOpt"; 7379 break; 7380 default: 7381 goto cp0_unimplemented; 7382 } 7383 break; 7384 case CP0_REGISTER_02: 7385 switch (sel) { 7386 case CP0_REG02__ENTRYLO0: 7387 tcg_gen_ld_tl(arg, cpu_env, 7388 offsetof(CPUMIPSState, CP0_EntryLo0)); 7389 register_name = "EntryLo0"; 7390 break; 7391 case CP0_REG02__TCSTATUS: 7392 CP0_CHECK(ctx->insn_flags & ASE_MT); 7393 gen_helper_mfc0_tcstatus(arg, cpu_env); 7394 register_name = "TCStatus"; 7395 break; 7396 case CP0_REG02__TCBIND: 7397 CP0_CHECK(ctx->insn_flags & ASE_MT); 7398 gen_helper_mfc0_tcbind(arg, cpu_env); 7399 register_name = "TCBind"; 7400 break; 7401 case CP0_REG02__TCRESTART: 7402 CP0_CHECK(ctx->insn_flags & ASE_MT); 7403 gen_helper_dmfc0_tcrestart(arg, cpu_env); 7404 register_name = "TCRestart"; 7405 break; 7406 case CP0_REG02__TCHALT: 7407 CP0_CHECK(ctx->insn_flags & ASE_MT); 7408 gen_helper_dmfc0_tchalt(arg, cpu_env); 7409 register_name = "TCHalt"; 7410 break; 7411 case CP0_REG02__TCCONTEXT: 7412 CP0_CHECK(ctx->insn_flags & ASE_MT); 7413 gen_helper_dmfc0_tccontext(arg, cpu_env); 7414 register_name = "TCContext"; 7415 break; 7416 case CP0_REG02__TCSCHEDULE: 7417 CP0_CHECK(ctx->insn_flags & ASE_MT); 7418 gen_helper_dmfc0_tcschedule(arg, cpu_env); 7419 register_name = "TCSchedule"; 7420 break; 7421 case CP0_REG02__TCSCHEFBACK: 7422 CP0_CHECK(ctx->insn_flags & ASE_MT); 7423 gen_helper_dmfc0_tcschefback(arg, cpu_env); 7424 register_name = "TCScheFBack"; 7425 break; 7426 default: 7427 goto cp0_unimplemented; 7428 } 7429 break; 7430 case CP0_REGISTER_03: 7431 switch (sel) { 7432 case CP0_REG03__ENTRYLO1: 7433 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 7434 register_name = "EntryLo1"; 7435 break; 7436 case CP0_REG03__GLOBALNUM: 7437 CP0_CHECK(ctx->vp); 7438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 7439 register_name = "GlobalNumber"; 7440 break; 7441 default: 7442 goto cp0_unimplemented; 7443 } 7444 break; 7445 case CP0_REGISTER_04: 7446 switch (sel) { 7447 case CP0_REG04__CONTEXT: 7448 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 7449 register_name = "Context"; 7450 break; 7451 case CP0_REG04__CONTEXTCONFIG: 7452 /* SmartMIPS ASE */ 7453 /* gen_helper_dmfc0_contextconfig(arg); */ 7454 register_name = "ContextConfig"; 7455 goto cp0_unimplemented; 7456 case CP0_REG04__USERLOCAL: 7457 CP0_CHECK(ctx->ulri); 7458 tcg_gen_ld_tl(arg, cpu_env, 7459 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 7460 register_name = "UserLocal"; 7461 break; 7462 case CP0_REG04__MMID: 7463 CP0_CHECK(ctx->mi); 7464 gen_helper_mtc0_memorymapid(cpu_env, arg); 7465 register_name = "MMID"; 7466 break; 7467 default: 7468 goto cp0_unimplemented; 7469 } 7470 break; 7471 case CP0_REGISTER_05: 7472 switch (sel) { 7473 case CP0_REG05__PAGEMASK: 7474 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 7475 register_name = "PageMask"; 7476 break; 7477 case CP0_REG05__PAGEGRAIN: 7478 check_insn(ctx, ISA_MIPS_R2); 7479 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 7480 register_name = "PageGrain"; 7481 break; 7482 case CP0_REG05__SEGCTL0: 7483 CP0_CHECK(ctx->sc); 7484 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 7485 register_name = "SegCtl0"; 7486 break; 7487 case CP0_REG05__SEGCTL1: 7488 CP0_CHECK(ctx->sc); 7489 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 7490 register_name = "SegCtl1"; 7491 break; 7492 case CP0_REG05__SEGCTL2: 7493 CP0_CHECK(ctx->sc); 7494 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 7495 register_name = "SegCtl2"; 7496 break; 7497 case CP0_REG05__PWBASE: 7498 check_pw(ctx); 7499 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); 7500 register_name = "PWBase"; 7501 break; 7502 case CP0_REG05__PWFIELD: 7503 check_pw(ctx); 7504 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField)); 7505 register_name = "PWField"; 7506 break; 7507 case CP0_REG05__PWSIZE: 7508 check_pw(ctx); 7509 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize)); 7510 register_name = "PWSize"; 7511 break; 7512 default: 7513 goto cp0_unimplemented; 7514 } 7515 break; 7516 case CP0_REGISTER_06: 7517 switch (sel) { 7518 case CP0_REG06__WIRED: 7519 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 7520 register_name = "Wired"; 7521 break; 7522 case CP0_REG06__SRSCONF0: 7523 check_insn(ctx, ISA_MIPS_R2); 7524 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 7525 register_name = "SRSConf0"; 7526 break; 7527 case CP0_REG06__SRSCONF1: 7528 check_insn(ctx, ISA_MIPS_R2); 7529 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 7530 register_name = "SRSConf1"; 7531 break; 7532 case CP0_REG06__SRSCONF2: 7533 check_insn(ctx, ISA_MIPS_R2); 7534 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 7535 register_name = "SRSConf2"; 7536 break; 7537 case CP0_REG06__SRSCONF3: 7538 check_insn(ctx, ISA_MIPS_R2); 7539 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 7540 register_name = "SRSConf3"; 7541 break; 7542 case CP0_REG06__SRSCONF4: 7543 check_insn(ctx, ISA_MIPS_R2); 7544 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 7545 register_name = "SRSConf4"; 7546 break; 7547 case CP0_REG06__PWCTL: 7548 check_pw(ctx); 7549 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 7550 register_name = "PWCtl"; 7551 break; 7552 default: 7553 goto cp0_unimplemented; 7554 } 7555 break; 7556 case CP0_REGISTER_07: 7557 switch (sel) { 7558 case CP0_REG07__HWRENA: 7559 check_insn(ctx, ISA_MIPS_R2); 7560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 7561 register_name = "HWREna"; 7562 break; 7563 default: 7564 goto cp0_unimplemented; 7565 } 7566 break; 7567 case CP0_REGISTER_08: 7568 switch (sel) { 7569 case CP0_REG08__BADVADDR: 7570 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 7571 register_name = "BadVAddr"; 7572 break; 7573 case CP0_REG08__BADINSTR: 7574 CP0_CHECK(ctx->bi); 7575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 7576 register_name = "BadInstr"; 7577 break; 7578 case CP0_REG08__BADINSTRP: 7579 CP0_CHECK(ctx->bp); 7580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 7581 register_name = "BadInstrP"; 7582 break; 7583 case CP0_REG08__BADINSTRX: 7584 CP0_CHECK(ctx->bi); 7585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 7586 tcg_gen_andi_tl(arg, arg, ~0xffff); 7587 register_name = "BadInstrX"; 7588 break; 7589 default: 7590 goto cp0_unimplemented; 7591 } 7592 break; 7593 case CP0_REGISTER_09: 7594 switch (sel) { 7595 case CP0_REG09__COUNT: 7596 /* Mark as an IO operation because we read the time. */ 7597 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7598 gen_io_start(); 7599 } 7600 gen_helper_mfc0_count(arg, cpu_env); 7601 /* 7602 * Break the TB to be able to take timer interrupts immediately 7603 * after reading count. DISAS_STOP isn't sufficient, we need to 7604 * ensure we break completely out of translated code. 7605 */ 7606 gen_save_pc(ctx->base.pc_next + 4); 7607 ctx->base.is_jmp = DISAS_EXIT; 7608 register_name = "Count"; 7609 break; 7610 case CP0_REG09__SAARI: 7611 CP0_CHECK(ctx->saar); 7612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); 7613 register_name = "SAARI"; 7614 break; 7615 case CP0_REG09__SAAR: 7616 CP0_CHECK(ctx->saar); 7617 gen_helper_dmfc0_saar(arg, cpu_env); 7618 register_name = "SAAR"; 7619 break; 7620 default: 7621 goto cp0_unimplemented; 7622 } 7623 break; 7624 case CP0_REGISTER_10: 7625 switch (sel) { 7626 case CP0_REG10__ENTRYHI: 7627 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 7628 register_name = "EntryHi"; 7629 break; 7630 default: 7631 goto cp0_unimplemented; 7632 } 7633 break; 7634 case CP0_REGISTER_11: 7635 switch (sel) { 7636 case CP0_REG11__COMPARE: 7637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 7638 register_name = "Compare"; 7639 break; 7640 /* 6,7 are implementation dependent */ 7641 default: 7642 goto cp0_unimplemented; 7643 } 7644 break; 7645 case CP0_REGISTER_12: 7646 switch (sel) { 7647 case CP0_REG12__STATUS: 7648 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 7649 register_name = "Status"; 7650 break; 7651 case CP0_REG12__INTCTL: 7652 check_insn(ctx, ISA_MIPS_R2); 7653 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 7654 register_name = "IntCtl"; 7655 break; 7656 case CP0_REG12__SRSCTL: 7657 check_insn(ctx, ISA_MIPS_R2); 7658 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 7659 register_name = "SRSCtl"; 7660 break; 7661 case CP0_REG12__SRSMAP: 7662 check_insn(ctx, ISA_MIPS_R2); 7663 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7664 register_name = "SRSMap"; 7665 break; 7666 default: 7667 goto cp0_unimplemented; 7668 } 7669 break; 7670 case CP0_REGISTER_13: 7671 switch (sel) { 7672 case CP0_REG13__CAUSE: 7673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 7674 register_name = "Cause"; 7675 break; 7676 default: 7677 goto cp0_unimplemented; 7678 } 7679 break; 7680 case CP0_REGISTER_14: 7681 switch (sel) { 7682 case CP0_REG14__EPC: 7683 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 7684 register_name = "EPC"; 7685 break; 7686 default: 7687 goto cp0_unimplemented; 7688 } 7689 break; 7690 case CP0_REGISTER_15: 7691 switch (sel) { 7692 case CP0_REG15__PRID: 7693 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 7694 register_name = "PRid"; 7695 break; 7696 case CP0_REG15__EBASE: 7697 check_insn(ctx, ISA_MIPS_R2); 7698 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); 7699 register_name = "EBase"; 7700 break; 7701 case CP0_REG15__CMGCRBASE: 7702 check_insn(ctx, ISA_MIPS_R2); 7703 CP0_CHECK(ctx->cmgcr); 7704 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 7705 register_name = "CMGCRBase"; 7706 break; 7707 default: 7708 goto cp0_unimplemented; 7709 } 7710 break; 7711 case CP0_REGISTER_16: 7712 switch (sel) { 7713 case CP0_REG16__CONFIG: 7714 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 7715 register_name = "Config"; 7716 break; 7717 case CP0_REG16__CONFIG1: 7718 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 7719 register_name = "Config1"; 7720 break; 7721 case CP0_REG16__CONFIG2: 7722 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 7723 register_name = "Config2"; 7724 break; 7725 case CP0_REG16__CONFIG3: 7726 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 7727 register_name = "Config3"; 7728 break; 7729 case CP0_REG16__CONFIG4: 7730 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 7731 register_name = "Config4"; 7732 break; 7733 case CP0_REG16__CONFIG5: 7734 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 7735 register_name = "Config5"; 7736 break; 7737 /* 6,7 are implementation dependent */ 7738 case CP0_REG16__CONFIG6: 7739 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 7740 register_name = "Config6"; 7741 break; 7742 case CP0_REG16__CONFIG7: 7743 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 7744 register_name = "Config7"; 7745 break; 7746 default: 7747 goto cp0_unimplemented; 7748 } 7749 break; 7750 case CP0_REGISTER_17: 7751 switch (sel) { 7752 case CP0_REG17__LLADDR: 7753 gen_helper_dmfc0_lladdr(arg, cpu_env); 7754 register_name = "LLAddr"; 7755 break; 7756 case CP0_REG17__MAAR: 7757 CP0_CHECK(ctx->mrp); 7758 gen_helper_dmfc0_maar(arg, cpu_env); 7759 register_name = "MAAR"; 7760 break; 7761 case CP0_REG17__MAARI: 7762 CP0_CHECK(ctx->mrp); 7763 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 7764 register_name = "MAARI"; 7765 break; 7766 default: 7767 goto cp0_unimplemented; 7768 } 7769 break; 7770 case CP0_REGISTER_18: 7771 switch (sel) { 7772 case CP0_REG18__WATCHLO0: 7773 case CP0_REG18__WATCHLO1: 7774 case CP0_REG18__WATCHLO2: 7775 case CP0_REG18__WATCHLO3: 7776 case CP0_REG18__WATCHLO4: 7777 case CP0_REG18__WATCHLO5: 7778 case CP0_REG18__WATCHLO6: 7779 case CP0_REG18__WATCHLO7: 7780 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7781 gen_helper_1e0i(dmfc0_watchlo, arg, sel); 7782 register_name = "WatchLo"; 7783 break; 7784 default: 7785 goto cp0_unimplemented; 7786 } 7787 break; 7788 case CP0_REGISTER_19: 7789 switch (sel) { 7790 case CP0_REG19__WATCHHI0: 7791 case CP0_REG19__WATCHHI1: 7792 case CP0_REG19__WATCHHI2: 7793 case CP0_REG19__WATCHHI3: 7794 case CP0_REG19__WATCHHI4: 7795 case CP0_REG19__WATCHHI5: 7796 case CP0_REG19__WATCHHI6: 7797 case CP0_REG19__WATCHHI7: 7798 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7799 gen_helper_1e0i(dmfc0_watchhi, arg, sel); 7800 register_name = "WatchHi"; 7801 break; 7802 default: 7803 goto cp0_unimplemented; 7804 } 7805 break; 7806 case CP0_REGISTER_20: 7807 switch (sel) { 7808 case CP0_REG20__XCONTEXT: 7809 check_insn(ctx, ISA_MIPS3); 7810 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 7811 register_name = "XContext"; 7812 break; 7813 default: 7814 goto cp0_unimplemented; 7815 } 7816 break; 7817 case CP0_REGISTER_21: 7818 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7819 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7820 switch (sel) { 7821 case 0: 7822 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 7823 register_name = "Framemask"; 7824 break; 7825 default: 7826 goto cp0_unimplemented; 7827 } 7828 break; 7829 case CP0_REGISTER_22: 7830 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7831 register_name = "'Diagnostic"; /* implementation dependent */ 7832 break; 7833 case CP0_REGISTER_23: 7834 switch (sel) { 7835 case CP0_REG23__DEBUG: 7836 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 7837 register_name = "Debug"; 7838 break; 7839 case CP0_REG23__TRACECONTROL: 7840 /* PDtrace support */ 7841 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */ 7842 register_name = "TraceControl"; 7843 goto cp0_unimplemented; 7844 case CP0_REG23__TRACECONTROL2: 7845 /* PDtrace support */ 7846 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */ 7847 register_name = "TraceControl2"; 7848 goto cp0_unimplemented; 7849 case CP0_REG23__USERTRACEDATA1: 7850 /* PDtrace support */ 7851 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/ 7852 register_name = "UserTraceData1"; 7853 goto cp0_unimplemented; 7854 case CP0_REG23__TRACEIBPC: 7855 /* PDtrace support */ 7856 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */ 7857 register_name = "TraceIBPC"; 7858 goto cp0_unimplemented; 7859 case CP0_REG23__TRACEDBPC: 7860 /* PDtrace support */ 7861 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */ 7862 register_name = "TraceDBPC"; 7863 goto cp0_unimplemented; 7864 default: 7865 goto cp0_unimplemented; 7866 } 7867 break; 7868 case CP0_REGISTER_24: 7869 switch (sel) { 7870 case CP0_REG24__DEPC: 7871 /* EJTAG support */ 7872 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 7873 register_name = "DEPC"; 7874 break; 7875 default: 7876 goto cp0_unimplemented; 7877 } 7878 break; 7879 case CP0_REGISTER_25: 7880 switch (sel) { 7881 case CP0_REG25__PERFCTL0: 7882 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 7883 register_name = "Performance0"; 7884 break; 7885 case CP0_REG25__PERFCNT0: 7886 /* gen_helper_dmfc0_performance1(arg); */ 7887 register_name = "Performance1"; 7888 goto cp0_unimplemented; 7889 case CP0_REG25__PERFCTL1: 7890 /* gen_helper_dmfc0_performance2(arg); */ 7891 register_name = "Performance2"; 7892 goto cp0_unimplemented; 7893 case CP0_REG25__PERFCNT1: 7894 /* gen_helper_dmfc0_performance3(arg); */ 7895 register_name = "Performance3"; 7896 goto cp0_unimplemented; 7897 case CP0_REG25__PERFCTL2: 7898 /* gen_helper_dmfc0_performance4(arg); */ 7899 register_name = "Performance4"; 7900 goto cp0_unimplemented; 7901 case CP0_REG25__PERFCNT2: 7902 /* gen_helper_dmfc0_performance5(arg); */ 7903 register_name = "Performance5"; 7904 goto cp0_unimplemented; 7905 case CP0_REG25__PERFCTL3: 7906 /* gen_helper_dmfc0_performance6(arg); */ 7907 register_name = "Performance6"; 7908 goto cp0_unimplemented; 7909 case CP0_REG25__PERFCNT3: 7910 /* gen_helper_dmfc0_performance7(arg); */ 7911 register_name = "Performance7"; 7912 goto cp0_unimplemented; 7913 default: 7914 goto cp0_unimplemented; 7915 } 7916 break; 7917 case CP0_REGISTER_26: 7918 switch (sel) { 7919 case CP0_REG26__ERRCTL: 7920 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 7921 register_name = "ErrCtl"; 7922 break; 7923 default: 7924 goto cp0_unimplemented; 7925 } 7926 break; 7927 case CP0_REGISTER_27: 7928 switch (sel) { 7929 /* ignored */ 7930 case CP0_REG27__CACHERR: 7931 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7932 register_name = "CacheErr"; 7933 break; 7934 default: 7935 goto cp0_unimplemented; 7936 } 7937 break; 7938 case CP0_REGISTER_28: 7939 switch (sel) { 7940 case CP0_REG28__TAGLO: 7941 case CP0_REG28__TAGLO1: 7942 case CP0_REG28__TAGLO2: 7943 case CP0_REG28__TAGLO3: 7944 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 7945 register_name = "TagLo"; 7946 break; 7947 case CP0_REG28__DATALO: 7948 case CP0_REG28__DATALO1: 7949 case CP0_REG28__DATALO2: 7950 case CP0_REG28__DATALO3: 7951 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 7952 register_name = "DataLo"; 7953 break; 7954 default: 7955 goto cp0_unimplemented; 7956 } 7957 break; 7958 case CP0_REGISTER_29: 7959 switch (sel) { 7960 case CP0_REG29__TAGHI: 7961 case CP0_REG29__TAGHI1: 7962 case CP0_REG29__TAGHI2: 7963 case CP0_REG29__TAGHI3: 7964 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 7965 register_name = "TagHi"; 7966 break; 7967 case CP0_REG29__DATAHI: 7968 case CP0_REG29__DATAHI1: 7969 case CP0_REG29__DATAHI2: 7970 case CP0_REG29__DATAHI3: 7971 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 7972 register_name = "DataHi"; 7973 break; 7974 default: 7975 goto cp0_unimplemented; 7976 } 7977 break; 7978 case CP0_REGISTER_30: 7979 switch (sel) { 7980 case CP0_REG30__ERROREPC: 7981 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7982 register_name = "ErrorEPC"; 7983 break; 7984 default: 7985 goto cp0_unimplemented; 7986 } 7987 break; 7988 case CP0_REGISTER_31: 7989 switch (sel) { 7990 case CP0_REG31__DESAVE: 7991 /* EJTAG support */ 7992 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7993 register_name = "DESAVE"; 7994 break; 7995 case CP0_REG31__KSCRATCH1: 7996 case CP0_REG31__KSCRATCH2: 7997 case CP0_REG31__KSCRATCH3: 7998 case CP0_REG31__KSCRATCH4: 7999 case CP0_REG31__KSCRATCH5: 8000 case CP0_REG31__KSCRATCH6: 8001 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8002 tcg_gen_ld_tl(arg, cpu_env, 8003 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8004 register_name = "KScratch"; 8005 break; 8006 default: 8007 goto cp0_unimplemented; 8008 } 8009 break; 8010 default: 8011 goto cp0_unimplemented; 8012 } 8013 trace_mips_translate_c0("dmfc0", register_name, reg, sel); 8014 return; 8015 8016 cp0_unimplemented: 8017 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", 8018 register_name, reg, sel); 8019 gen_mfc0_unimplemented(ctx, arg); 8020 } 8021 8022 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 8023 { 8024 const char *register_name = "invalid"; 8025 8026 if (sel != 0) { 8027 check_insn(ctx, ISA_MIPS_R1); 8028 } 8029 8030 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 8031 gen_io_start(); 8032 } 8033 8034 switch (reg) { 8035 case CP0_REGISTER_00: 8036 switch (sel) { 8037 case CP0_REG00__INDEX: 8038 gen_helper_mtc0_index(cpu_env, arg); 8039 register_name = "Index"; 8040 break; 8041 case CP0_REG00__MVPCONTROL: 8042 CP0_CHECK(ctx->insn_flags & ASE_MT); 8043 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 8044 register_name = "MVPControl"; 8045 break; 8046 case CP0_REG00__MVPCONF0: 8047 CP0_CHECK(ctx->insn_flags & ASE_MT); 8048 /* ignored */ 8049 register_name = "MVPConf0"; 8050 break; 8051 case CP0_REG00__MVPCONF1: 8052 CP0_CHECK(ctx->insn_flags & ASE_MT); 8053 /* ignored */ 8054 register_name = "MVPConf1"; 8055 break; 8056 case CP0_REG00__VPCONTROL: 8057 CP0_CHECK(ctx->vp); 8058 /* ignored */ 8059 register_name = "VPControl"; 8060 break; 8061 default: 8062 goto cp0_unimplemented; 8063 } 8064 break; 8065 case CP0_REGISTER_01: 8066 switch (sel) { 8067 case CP0_REG01__RANDOM: 8068 /* ignored */ 8069 register_name = "Random"; 8070 break; 8071 case CP0_REG01__VPECONTROL: 8072 CP0_CHECK(ctx->insn_flags & ASE_MT); 8073 gen_helper_mtc0_vpecontrol(cpu_env, arg); 8074 register_name = "VPEControl"; 8075 break; 8076 case CP0_REG01__VPECONF0: 8077 CP0_CHECK(ctx->insn_flags & ASE_MT); 8078 gen_helper_mtc0_vpeconf0(cpu_env, arg); 8079 register_name = "VPEConf0"; 8080 break; 8081 case CP0_REG01__VPECONF1: 8082 CP0_CHECK(ctx->insn_flags & ASE_MT); 8083 gen_helper_mtc0_vpeconf1(cpu_env, arg); 8084 register_name = "VPEConf1"; 8085 break; 8086 case CP0_REG01__YQMASK: 8087 CP0_CHECK(ctx->insn_flags & ASE_MT); 8088 gen_helper_mtc0_yqmask(cpu_env, arg); 8089 register_name = "YQMask"; 8090 break; 8091 case CP0_REG01__VPESCHEDULE: 8092 CP0_CHECK(ctx->insn_flags & ASE_MT); 8093 tcg_gen_st_tl(arg, cpu_env, 8094 offsetof(CPUMIPSState, CP0_VPESchedule)); 8095 register_name = "VPESchedule"; 8096 break; 8097 case CP0_REG01__VPESCHEFBACK: 8098 CP0_CHECK(ctx->insn_flags & ASE_MT); 8099 tcg_gen_st_tl(arg, cpu_env, 8100 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 8101 register_name = "VPEScheFBack"; 8102 break; 8103 case CP0_REG01__VPEOPT: 8104 CP0_CHECK(ctx->insn_flags & ASE_MT); 8105 gen_helper_mtc0_vpeopt(cpu_env, arg); 8106 register_name = "VPEOpt"; 8107 break; 8108 default: 8109 goto cp0_unimplemented; 8110 } 8111 break; 8112 case CP0_REGISTER_02: 8113 switch (sel) { 8114 case CP0_REG02__ENTRYLO0: 8115 gen_helper_dmtc0_entrylo0(cpu_env, arg); 8116 register_name = "EntryLo0"; 8117 break; 8118 case CP0_REG02__TCSTATUS: 8119 CP0_CHECK(ctx->insn_flags & ASE_MT); 8120 gen_helper_mtc0_tcstatus(cpu_env, arg); 8121 register_name = "TCStatus"; 8122 break; 8123 case CP0_REG02__TCBIND: 8124 CP0_CHECK(ctx->insn_flags & ASE_MT); 8125 gen_helper_mtc0_tcbind(cpu_env, arg); 8126 register_name = "TCBind"; 8127 break; 8128 case CP0_REG02__TCRESTART: 8129 CP0_CHECK(ctx->insn_flags & ASE_MT); 8130 gen_helper_mtc0_tcrestart(cpu_env, arg); 8131 register_name = "TCRestart"; 8132 break; 8133 case CP0_REG02__TCHALT: 8134 CP0_CHECK(ctx->insn_flags & ASE_MT); 8135 gen_helper_mtc0_tchalt(cpu_env, arg); 8136 register_name = "TCHalt"; 8137 break; 8138 case CP0_REG02__TCCONTEXT: 8139 CP0_CHECK(ctx->insn_flags & ASE_MT); 8140 gen_helper_mtc0_tccontext(cpu_env, arg); 8141 register_name = "TCContext"; 8142 break; 8143 case CP0_REG02__TCSCHEDULE: 8144 CP0_CHECK(ctx->insn_flags & ASE_MT); 8145 gen_helper_mtc0_tcschedule(cpu_env, arg); 8146 register_name = "TCSchedule"; 8147 break; 8148 case CP0_REG02__TCSCHEFBACK: 8149 CP0_CHECK(ctx->insn_flags & ASE_MT); 8150 gen_helper_mtc0_tcschefback(cpu_env, arg); 8151 register_name = "TCScheFBack"; 8152 break; 8153 default: 8154 goto cp0_unimplemented; 8155 } 8156 break; 8157 case CP0_REGISTER_03: 8158 switch (sel) { 8159 case CP0_REG03__ENTRYLO1: 8160 gen_helper_dmtc0_entrylo1(cpu_env, arg); 8161 register_name = "EntryLo1"; 8162 break; 8163 case CP0_REG03__GLOBALNUM: 8164 CP0_CHECK(ctx->vp); 8165 /* ignored */ 8166 register_name = "GlobalNumber"; 8167 break; 8168 default: 8169 goto cp0_unimplemented; 8170 } 8171 break; 8172 case CP0_REGISTER_04: 8173 switch (sel) { 8174 case CP0_REG04__CONTEXT: 8175 gen_helper_mtc0_context(cpu_env, arg); 8176 register_name = "Context"; 8177 break; 8178 case CP0_REG04__CONTEXTCONFIG: 8179 /* SmartMIPS ASE */ 8180 /* gen_helper_dmtc0_contextconfig(arg); */ 8181 register_name = "ContextConfig"; 8182 goto cp0_unimplemented; 8183 case CP0_REG04__USERLOCAL: 8184 CP0_CHECK(ctx->ulri); 8185 tcg_gen_st_tl(arg, cpu_env, 8186 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 8187 register_name = "UserLocal"; 8188 break; 8189 case CP0_REG04__MMID: 8190 CP0_CHECK(ctx->mi); 8191 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 8192 register_name = "MMID"; 8193 break; 8194 default: 8195 goto cp0_unimplemented; 8196 } 8197 break; 8198 case CP0_REGISTER_05: 8199 switch (sel) { 8200 case CP0_REG05__PAGEMASK: 8201 gen_helper_mtc0_pagemask(cpu_env, arg); 8202 register_name = "PageMask"; 8203 break; 8204 case CP0_REG05__PAGEGRAIN: 8205 check_insn(ctx, ISA_MIPS_R2); 8206 gen_helper_mtc0_pagegrain(cpu_env, arg); 8207 register_name = "PageGrain"; 8208 break; 8209 case CP0_REG05__SEGCTL0: 8210 CP0_CHECK(ctx->sc); 8211 gen_helper_mtc0_segctl0(cpu_env, arg); 8212 register_name = "SegCtl0"; 8213 break; 8214 case CP0_REG05__SEGCTL1: 8215 CP0_CHECK(ctx->sc); 8216 gen_helper_mtc0_segctl1(cpu_env, arg); 8217 register_name = "SegCtl1"; 8218 break; 8219 case CP0_REG05__SEGCTL2: 8220 CP0_CHECK(ctx->sc); 8221 gen_helper_mtc0_segctl2(cpu_env, arg); 8222 register_name = "SegCtl2"; 8223 break; 8224 case CP0_REG05__PWBASE: 8225 check_pw(ctx); 8226 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); 8227 register_name = "PWBase"; 8228 break; 8229 case CP0_REG05__PWFIELD: 8230 check_pw(ctx); 8231 gen_helper_mtc0_pwfield(cpu_env, arg); 8232 register_name = "PWField"; 8233 break; 8234 case CP0_REG05__PWSIZE: 8235 check_pw(ctx); 8236 gen_helper_mtc0_pwsize(cpu_env, arg); 8237 register_name = "PWSize"; 8238 break; 8239 default: 8240 goto cp0_unimplemented; 8241 } 8242 break; 8243 case CP0_REGISTER_06: 8244 switch (sel) { 8245 case CP0_REG06__WIRED: 8246 gen_helper_mtc0_wired(cpu_env, arg); 8247 register_name = "Wired"; 8248 break; 8249 case CP0_REG06__SRSCONF0: 8250 check_insn(ctx, ISA_MIPS_R2); 8251 gen_helper_mtc0_srsconf0(cpu_env, arg); 8252 register_name = "SRSConf0"; 8253 break; 8254 case CP0_REG06__SRSCONF1: 8255 check_insn(ctx, ISA_MIPS_R2); 8256 gen_helper_mtc0_srsconf1(cpu_env, arg); 8257 register_name = "SRSConf1"; 8258 break; 8259 case CP0_REG06__SRSCONF2: 8260 check_insn(ctx, ISA_MIPS_R2); 8261 gen_helper_mtc0_srsconf2(cpu_env, arg); 8262 register_name = "SRSConf2"; 8263 break; 8264 case CP0_REG06__SRSCONF3: 8265 check_insn(ctx, ISA_MIPS_R2); 8266 gen_helper_mtc0_srsconf3(cpu_env, arg); 8267 register_name = "SRSConf3"; 8268 break; 8269 case CP0_REG06__SRSCONF4: 8270 check_insn(ctx, ISA_MIPS_R2); 8271 gen_helper_mtc0_srsconf4(cpu_env, arg); 8272 register_name = "SRSConf4"; 8273 break; 8274 case CP0_REG06__PWCTL: 8275 check_pw(ctx); 8276 gen_helper_mtc0_pwctl(cpu_env, arg); 8277 register_name = "PWCtl"; 8278 break; 8279 default: 8280 goto cp0_unimplemented; 8281 } 8282 break; 8283 case CP0_REGISTER_07: 8284 switch (sel) { 8285 case CP0_REG07__HWRENA: 8286 check_insn(ctx, ISA_MIPS_R2); 8287 gen_helper_mtc0_hwrena(cpu_env, arg); 8288 ctx->base.is_jmp = DISAS_STOP; 8289 register_name = "HWREna"; 8290 break; 8291 default: 8292 goto cp0_unimplemented; 8293 } 8294 break; 8295 case CP0_REGISTER_08: 8296 switch (sel) { 8297 case CP0_REG08__BADVADDR: 8298 /* ignored */ 8299 register_name = "BadVAddr"; 8300 break; 8301 case CP0_REG08__BADINSTR: 8302 /* ignored */ 8303 register_name = "BadInstr"; 8304 break; 8305 case CP0_REG08__BADINSTRP: 8306 /* ignored */ 8307 register_name = "BadInstrP"; 8308 break; 8309 case CP0_REG08__BADINSTRX: 8310 /* ignored */ 8311 register_name = "BadInstrX"; 8312 break; 8313 default: 8314 goto cp0_unimplemented; 8315 } 8316 break; 8317 case CP0_REGISTER_09: 8318 switch (sel) { 8319 case CP0_REG09__COUNT: 8320 gen_helper_mtc0_count(cpu_env, arg); 8321 register_name = "Count"; 8322 break; 8323 case CP0_REG09__SAARI: 8324 CP0_CHECK(ctx->saar); 8325 gen_helper_mtc0_saari(cpu_env, arg); 8326 register_name = "SAARI"; 8327 break; 8328 case CP0_REG09__SAAR: 8329 CP0_CHECK(ctx->saar); 8330 gen_helper_mtc0_saar(cpu_env, arg); 8331 register_name = "SAAR"; 8332 break; 8333 default: 8334 goto cp0_unimplemented; 8335 } 8336 /* Stop translation as we may have switched the execution mode */ 8337 ctx->base.is_jmp = DISAS_STOP; 8338 break; 8339 case CP0_REGISTER_10: 8340 switch (sel) { 8341 case CP0_REG10__ENTRYHI: 8342 gen_helper_mtc0_entryhi(cpu_env, arg); 8343 register_name = "EntryHi"; 8344 break; 8345 default: 8346 goto cp0_unimplemented; 8347 } 8348 break; 8349 case CP0_REGISTER_11: 8350 switch (sel) { 8351 case CP0_REG11__COMPARE: 8352 gen_helper_mtc0_compare(cpu_env, arg); 8353 register_name = "Compare"; 8354 break; 8355 /* 6,7 are implementation dependent */ 8356 default: 8357 goto cp0_unimplemented; 8358 } 8359 /* Stop translation as we may have switched the execution mode */ 8360 ctx->base.is_jmp = DISAS_STOP; 8361 break; 8362 case CP0_REGISTER_12: 8363 switch (sel) { 8364 case CP0_REG12__STATUS: 8365 save_cpu_state(ctx, 1); 8366 gen_helper_mtc0_status(cpu_env, arg); 8367 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 8368 gen_save_pc(ctx->base.pc_next + 4); 8369 ctx->base.is_jmp = DISAS_EXIT; 8370 register_name = "Status"; 8371 break; 8372 case CP0_REG12__INTCTL: 8373 check_insn(ctx, ISA_MIPS_R2); 8374 gen_helper_mtc0_intctl(cpu_env, arg); 8375 /* Stop translation as we may have switched the execution mode */ 8376 ctx->base.is_jmp = DISAS_STOP; 8377 register_name = "IntCtl"; 8378 break; 8379 case CP0_REG12__SRSCTL: 8380 check_insn(ctx, ISA_MIPS_R2); 8381 gen_helper_mtc0_srsctl(cpu_env, arg); 8382 /* Stop translation as we may have switched the execution mode */ 8383 ctx->base.is_jmp = DISAS_STOP; 8384 register_name = "SRSCtl"; 8385 break; 8386 case CP0_REG12__SRSMAP: 8387 check_insn(ctx, ISA_MIPS_R2); 8388 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 8389 /* Stop translation as we may have switched the execution mode */ 8390 ctx->base.is_jmp = DISAS_STOP; 8391 register_name = "SRSMap"; 8392 break; 8393 default: 8394 goto cp0_unimplemented; 8395 } 8396 break; 8397 case CP0_REGISTER_13: 8398 switch (sel) { 8399 case CP0_REG13__CAUSE: 8400 save_cpu_state(ctx, 1); 8401 gen_helper_mtc0_cause(cpu_env, arg); 8402 /* 8403 * Stop translation as we may have triggered an interrupt. 8404 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8405 * translated code to check for pending interrupts. 8406 */ 8407 gen_save_pc(ctx->base.pc_next + 4); 8408 ctx->base.is_jmp = DISAS_EXIT; 8409 register_name = "Cause"; 8410 break; 8411 default: 8412 goto cp0_unimplemented; 8413 } 8414 break; 8415 case CP0_REGISTER_14: 8416 switch (sel) { 8417 case CP0_REG14__EPC: 8418 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 8419 register_name = "EPC"; 8420 break; 8421 default: 8422 goto cp0_unimplemented; 8423 } 8424 break; 8425 case CP0_REGISTER_15: 8426 switch (sel) { 8427 case CP0_REG15__PRID: 8428 /* ignored */ 8429 register_name = "PRid"; 8430 break; 8431 case CP0_REG15__EBASE: 8432 check_insn(ctx, ISA_MIPS_R2); 8433 gen_helper_mtc0_ebase(cpu_env, arg); 8434 register_name = "EBase"; 8435 break; 8436 default: 8437 goto cp0_unimplemented; 8438 } 8439 break; 8440 case CP0_REGISTER_16: 8441 switch (sel) { 8442 case CP0_REG16__CONFIG: 8443 gen_helper_mtc0_config0(cpu_env, arg); 8444 register_name = "Config"; 8445 /* Stop translation as we may have switched the execution mode */ 8446 ctx->base.is_jmp = DISAS_STOP; 8447 break; 8448 case CP0_REG16__CONFIG1: 8449 /* ignored, read only */ 8450 register_name = "Config1"; 8451 break; 8452 case CP0_REG16__CONFIG2: 8453 gen_helper_mtc0_config2(cpu_env, arg); 8454 register_name = "Config2"; 8455 /* Stop translation as we may have switched the execution mode */ 8456 ctx->base.is_jmp = DISAS_STOP; 8457 break; 8458 case CP0_REG16__CONFIG3: 8459 gen_helper_mtc0_config3(cpu_env, arg); 8460 register_name = "Config3"; 8461 /* Stop translation as we may have switched the execution mode */ 8462 ctx->base.is_jmp = DISAS_STOP; 8463 break; 8464 case CP0_REG16__CONFIG4: 8465 /* currently ignored */ 8466 register_name = "Config4"; 8467 break; 8468 case CP0_REG16__CONFIG5: 8469 gen_helper_mtc0_config5(cpu_env, arg); 8470 register_name = "Config5"; 8471 /* Stop translation as we may have switched the execution mode */ 8472 ctx->base.is_jmp = DISAS_STOP; 8473 break; 8474 /* 6,7 are implementation dependent */ 8475 default: 8476 register_name = "Invalid config selector"; 8477 goto cp0_unimplemented; 8478 } 8479 break; 8480 case CP0_REGISTER_17: 8481 switch (sel) { 8482 case CP0_REG17__LLADDR: 8483 gen_helper_mtc0_lladdr(cpu_env, arg); 8484 register_name = "LLAddr"; 8485 break; 8486 case CP0_REG17__MAAR: 8487 CP0_CHECK(ctx->mrp); 8488 gen_helper_mtc0_maar(cpu_env, arg); 8489 register_name = "MAAR"; 8490 break; 8491 case CP0_REG17__MAARI: 8492 CP0_CHECK(ctx->mrp); 8493 gen_helper_mtc0_maari(cpu_env, arg); 8494 register_name = "MAARI"; 8495 break; 8496 default: 8497 goto cp0_unimplemented; 8498 } 8499 break; 8500 case CP0_REGISTER_18: 8501 switch (sel) { 8502 case CP0_REG18__WATCHLO0: 8503 case CP0_REG18__WATCHLO1: 8504 case CP0_REG18__WATCHLO2: 8505 case CP0_REG18__WATCHLO3: 8506 case CP0_REG18__WATCHLO4: 8507 case CP0_REG18__WATCHLO5: 8508 case CP0_REG18__WATCHLO6: 8509 case CP0_REG18__WATCHLO7: 8510 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8511 gen_helper_0e1i(mtc0_watchlo, arg, sel); 8512 register_name = "WatchLo"; 8513 break; 8514 default: 8515 goto cp0_unimplemented; 8516 } 8517 break; 8518 case CP0_REGISTER_19: 8519 switch (sel) { 8520 case CP0_REG19__WATCHHI0: 8521 case CP0_REG19__WATCHHI1: 8522 case CP0_REG19__WATCHHI2: 8523 case CP0_REG19__WATCHHI3: 8524 case CP0_REG19__WATCHHI4: 8525 case CP0_REG19__WATCHHI5: 8526 case CP0_REG19__WATCHHI6: 8527 case CP0_REG19__WATCHHI7: 8528 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8529 gen_helper_0e1i(mtc0_watchhi, arg, sel); 8530 register_name = "WatchHi"; 8531 break; 8532 default: 8533 goto cp0_unimplemented; 8534 } 8535 break; 8536 case CP0_REGISTER_20: 8537 switch (sel) { 8538 case CP0_REG20__XCONTEXT: 8539 check_insn(ctx, ISA_MIPS3); 8540 gen_helper_mtc0_xcontext(cpu_env, arg); 8541 register_name = "XContext"; 8542 break; 8543 default: 8544 goto cp0_unimplemented; 8545 } 8546 break; 8547 case CP0_REGISTER_21: 8548 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 8549 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 8550 switch (sel) { 8551 case 0: 8552 gen_helper_mtc0_framemask(cpu_env, arg); 8553 register_name = "Framemask"; 8554 break; 8555 default: 8556 goto cp0_unimplemented; 8557 } 8558 break; 8559 case CP0_REGISTER_22: 8560 /* ignored */ 8561 register_name = "Diagnostic"; /* implementation dependent */ 8562 break; 8563 case CP0_REGISTER_23: 8564 switch (sel) { 8565 case CP0_REG23__DEBUG: 8566 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 8567 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 8568 gen_save_pc(ctx->base.pc_next + 4); 8569 ctx->base.is_jmp = DISAS_EXIT; 8570 register_name = "Debug"; 8571 break; 8572 case CP0_REG23__TRACECONTROL: 8573 /* PDtrace support */ 8574 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ 8575 /* Stop translation as we may have switched the execution mode */ 8576 ctx->base.is_jmp = DISAS_STOP; 8577 register_name = "TraceControl"; 8578 goto cp0_unimplemented; 8579 case CP0_REG23__TRACECONTROL2: 8580 /* PDtrace support */ 8581 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ 8582 /* Stop translation as we may have switched the execution mode */ 8583 ctx->base.is_jmp = DISAS_STOP; 8584 register_name = "TraceControl2"; 8585 goto cp0_unimplemented; 8586 case CP0_REG23__USERTRACEDATA1: 8587 /* PDtrace support */ 8588 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ 8589 /* Stop translation as we may have switched the execution mode */ 8590 ctx->base.is_jmp = DISAS_STOP; 8591 register_name = "UserTraceData1"; 8592 goto cp0_unimplemented; 8593 case CP0_REG23__TRACEIBPC: 8594 /* PDtrace support */ 8595 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ 8596 /* Stop translation as we may have switched the execution mode */ 8597 ctx->base.is_jmp = DISAS_STOP; 8598 register_name = "TraceIBPC"; 8599 goto cp0_unimplemented; 8600 case CP0_REG23__TRACEDBPC: 8601 /* PDtrace support */ 8602 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ 8603 /* Stop translation as we may have switched the execution mode */ 8604 ctx->base.is_jmp = DISAS_STOP; 8605 register_name = "TraceDBPC"; 8606 goto cp0_unimplemented; 8607 default: 8608 goto cp0_unimplemented; 8609 } 8610 break; 8611 case CP0_REGISTER_24: 8612 switch (sel) { 8613 case CP0_REG24__DEPC: 8614 /* EJTAG support */ 8615 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 8616 register_name = "DEPC"; 8617 break; 8618 default: 8619 goto cp0_unimplemented; 8620 } 8621 break; 8622 case CP0_REGISTER_25: 8623 switch (sel) { 8624 case CP0_REG25__PERFCTL0: 8625 gen_helper_mtc0_performance0(cpu_env, arg); 8626 register_name = "Performance0"; 8627 break; 8628 case CP0_REG25__PERFCNT0: 8629 /* gen_helper_mtc0_performance1(cpu_env, arg); */ 8630 register_name = "Performance1"; 8631 goto cp0_unimplemented; 8632 case CP0_REG25__PERFCTL1: 8633 /* gen_helper_mtc0_performance2(cpu_env, arg); */ 8634 register_name = "Performance2"; 8635 goto cp0_unimplemented; 8636 case CP0_REG25__PERFCNT1: 8637 /* gen_helper_mtc0_performance3(cpu_env, arg); */ 8638 register_name = "Performance3"; 8639 goto cp0_unimplemented; 8640 case CP0_REG25__PERFCTL2: 8641 /* gen_helper_mtc0_performance4(cpu_env, arg); */ 8642 register_name = "Performance4"; 8643 goto cp0_unimplemented; 8644 case CP0_REG25__PERFCNT2: 8645 /* gen_helper_mtc0_performance5(cpu_env, arg); */ 8646 register_name = "Performance5"; 8647 goto cp0_unimplemented; 8648 case CP0_REG25__PERFCTL3: 8649 /* gen_helper_mtc0_performance6(cpu_env, arg); */ 8650 register_name = "Performance6"; 8651 goto cp0_unimplemented; 8652 case CP0_REG25__PERFCNT3: 8653 /* gen_helper_mtc0_performance7(cpu_env, arg); */ 8654 register_name = "Performance7"; 8655 goto cp0_unimplemented; 8656 default: 8657 goto cp0_unimplemented; 8658 } 8659 break; 8660 case CP0_REGISTER_26: 8661 switch (sel) { 8662 case CP0_REG26__ERRCTL: 8663 gen_helper_mtc0_errctl(cpu_env, arg); 8664 ctx->base.is_jmp = DISAS_STOP; 8665 register_name = "ErrCtl"; 8666 break; 8667 default: 8668 goto cp0_unimplemented; 8669 } 8670 break; 8671 case CP0_REGISTER_27: 8672 switch (sel) { 8673 case CP0_REG27__CACHERR: 8674 /* ignored */ 8675 register_name = "CacheErr"; 8676 break; 8677 default: 8678 goto cp0_unimplemented; 8679 } 8680 break; 8681 case CP0_REGISTER_28: 8682 switch (sel) { 8683 case CP0_REG28__TAGLO: 8684 case CP0_REG28__TAGLO1: 8685 case CP0_REG28__TAGLO2: 8686 case CP0_REG28__TAGLO3: 8687 gen_helper_mtc0_taglo(cpu_env, arg); 8688 register_name = "TagLo"; 8689 break; 8690 case CP0_REG28__DATALO: 8691 case CP0_REG28__DATALO1: 8692 case CP0_REG28__DATALO2: 8693 case CP0_REG28__DATALO3: 8694 gen_helper_mtc0_datalo(cpu_env, arg); 8695 register_name = "DataLo"; 8696 break; 8697 default: 8698 goto cp0_unimplemented; 8699 } 8700 break; 8701 case CP0_REGISTER_29: 8702 switch (sel) { 8703 case CP0_REG29__TAGHI: 8704 case CP0_REG29__TAGHI1: 8705 case CP0_REG29__TAGHI2: 8706 case CP0_REG29__TAGHI3: 8707 gen_helper_mtc0_taghi(cpu_env, arg); 8708 register_name = "TagHi"; 8709 break; 8710 case CP0_REG29__DATAHI: 8711 case CP0_REG29__DATAHI1: 8712 case CP0_REG29__DATAHI2: 8713 case CP0_REG29__DATAHI3: 8714 gen_helper_mtc0_datahi(cpu_env, arg); 8715 register_name = "DataHi"; 8716 break; 8717 default: 8718 register_name = "invalid sel"; 8719 goto cp0_unimplemented; 8720 } 8721 break; 8722 case CP0_REGISTER_30: 8723 switch (sel) { 8724 case CP0_REG30__ERROREPC: 8725 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 8726 register_name = "ErrorEPC"; 8727 break; 8728 default: 8729 goto cp0_unimplemented; 8730 } 8731 break; 8732 case CP0_REGISTER_31: 8733 switch (sel) { 8734 case CP0_REG31__DESAVE: 8735 /* EJTAG support */ 8736 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 8737 register_name = "DESAVE"; 8738 break; 8739 case CP0_REG31__KSCRATCH1: 8740 case CP0_REG31__KSCRATCH2: 8741 case CP0_REG31__KSCRATCH3: 8742 case CP0_REG31__KSCRATCH4: 8743 case CP0_REG31__KSCRATCH5: 8744 case CP0_REG31__KSCRATCH6: 8745 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8746 tcg_gen_st_tl(arg, cpu_env, 8747 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8748 register_name = "KScratch"; 8749 break; 8750 default: 8751 goto cp0_unimplemented; 8752 } 8753 break; 8754 default: 8755 goto cp0_unimplemented; 8756 } 8757 trace_mips_translate_c0("dmtc0", register_name, reg, sel); 8758 8759 /* For simplicity assume that all writes can cause interrupts. */ 8760 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 8761 /* 8762 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8763 * translated code to check for pending interrupts. 8764 */ 8765 gen_save_pc(ctx->base.pc_next + 4); 8766 ctx->base.is_jmp = DISAS_EXIT; 8767 } 8768 return; 8769 8770 cp0_unimplemented: 8771 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", 8772 register_name, reg, sel); 8773 } 8774 #endif /* TARGET_MIPS64 */ 8775 8776 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 8777 int u, int sel, int h) 8778 { 8779 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8780 TCGv t0 = tcg_temp_local_new(); 8781 8782 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8783 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8784 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8785 tcg_gen_movi_tl(t0, -1); 8786 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8787 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8788 tcg_gen_movi_tl(t0, -1); 8789 } else if (u == 0) { 8790 switch (rt) { 8791 case 1: 8792 switch (sel) { 8793 case 1: 8794 gen_helper_mftc0_vpecontrol(t0, cpu_env); 8795 break; 8796 case 2: 8797 gen_helper_mftc0_vpeconf0(t0, cpu_env); 8798 break; 8799 default: 8800 goto die; 8801 break; 8802 } 8803 break; 8804 case 2: 8805 switch (sel) { 8806 case 1: 8807 gen_helper_mftc0_tcstatus(t0, cpu_env); 8808 break; 8809 case 2: 8810 gen_helper_mftc0_tcbind(t0, cpu_env); 8811 break; 8812 case 3: 8813 gen_helper_mftc0_tcrestart(t0, cpu_env); 8814 break; 8815 case 4: 8816 gen_helper_mftc0_tchalt(t0, cpu_env); 8817 break; 8818 case 5: 8819 gen_helper_mftc0_tccontext(t0, cpu_env); 8820 break; 8821 case 6: 8822 gen_helper_mftc0_tcschedule(t0, cpu_env); 8823 break; 8824 case 7: 8825 gen_helper_mftc0_tcschefback(t0, cpu_env); 8826 break; 8827 default: 8828 gen_mfc0(ctx, t0, rt, sel); 8829 break; 8830 } 8831 break; 8832 case 10: 8833 switch (sel) { 8834 case 0: 8835 gen_helper_mftc0_entryhi(t0, cpu_env); 8836 break; 8837 default: 8838 gen_mfc0(ctx, t0, rt, sel); 8839 break; 8840 } 8841 break; 8842 case 12: 8843 switch (sel) { 8844 case 0: 8845 gen_helper_mftc0_status(t0, cpu_env); 8846 break; 8847 default: 8848 gen_mfc0(ctx, t0, rt, sel); 8849 break; 8850 } 8851 break; 8852 case 13: 8853 switch (sel) { 8854 case 0: 8855 gen_helper_mftc0_cause(t0, cpu_env); 8856 break; 8857 default: 8858 goto die; 8859 break; 8860 } 8861 break; 8862 case 14: 8863 switch (sel) { 8864 case 0: 8865 gen_helper_mftc0_epc(t0, cpu_env); 8866 break; 8867 default: 8868 goto die; 8869 break; 8870 } 8871 break; 8872 case 15: 8873 switch (sel) { 8874 case 1: 8875 gen_helper_mftc0_ebase(t0, cpu_env); 8876 break; 8877 default: 8878 goto die; 8879 break; 8880 } 8881 break; 8882 case 16: 8883 switch (sel) { 8884 case 0: 8885 case 1: 8886 case 2: 8887 case 3: 8888 case 4: 8889 case 5: 8890 case 6: 8891 case 7: 8892 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel)); 8893 break; 8894 default: 8895 goto die; 8896 break; 8897 } 8898 break; 8899 case 23: 8900 switch (sel) { 8901 case 0: 8902 gen_helper_mftc0_debug(t0, cpu_env); 8903 break; 8904 default: 8905 gen_mfc0(ctx, t0, rt, sel); 8906 break; 8907 } 8908 break; 8909 default: 8910 gen_mfc0(ctx, t0, rt, sel); 8911 } 8912 } else { 8913 switch (sel) { 8914 /* GPR registers. */ 8915 case 0: 8916 gen_helper_1e0i(mftgpr, t0, rt); 8917 break; 8918 /* Auxiliary CPU registers */ 8919 case 1: 8920 switch (rt) { 8921 case 0: 8922 gen_helper_1e0i(mftlo, t0, 0); 8923 break; 8924 case 1: 8925 gen_helper_1e0i(mfthi, t0, 0); 8926 break; 8927 case 2: 8928 gen_helper_1e0i(mftacx, t0, 0); 8929 break; 8930 case 4: 8931 gen_helper_1e0i(mftlo, t0, 1); 8932 break; 8933 case 5: 8934 gen_helper_1e0i(mfthi, t0, 1); 8935 break; 8936 case 6: 8937 gen_helper_1e0i(mftacx, t0, 1); 8938 break; 8939 case 8: 8940 gen_helper_1e0i(mftlo, t0, 2); 8941 break; 8942 case 9: 8943 gen_helper_1e0i(mfthi, t0, 2); 8944 break; 8945 case 10: 8946 gen_helper_1e0i(mftacx, t0, 2); 8947 break; 8948 case 12: 8949 gen_helper_1e0i(mftlo, t0, 3); 8950 break; 8951 case 13: 8952 gen_helper_1e0i(mfthi, t0, 3); 8953 break; 8954 case 14: 8955 gen_helper_1e0i(mftacx, t0, 3); 8956 break; 8957 case 16: 8958 gen_helper_mftdsp(t0, cpu_env); 8959 break; 8960 default: 8961 goto die; 8962 } 8963 break; 8964 /* Floating point (COP1). */ 8965 case 2: 8966 /* XXX: For now we support only a single FPU context. */ 8967 if (h == 0) { 8968 TCGv_i32 fp0 = tcg_temp_new_i32(); 8969 8970 gen_load_fpr32(ctx, fp0, rt); 8971 tcg_gen_ext_i32_tl(t0, fp0); 8972 tcg_temp_free_i32(fp0); 8973 } else { 8974 TCGv_i32 fp0 = tcg_temp_new_i32(); 8975 8976 gen_load_fpr32h(ctx, fp0, rt); 8977 tcg_gen_ext_i32_tl(t0, fp0); 8978 tcg_temp_free_i32(fp0); 8979 } 8980 break; 8981 case 3: 8982 /* XXX: For now we support only a single FPU context. */ 8983 gen_helper_1e0i(cfc1, t0, rt); 8984 break; 8985 /* COP2: Not implemented. */ 8986 case 4: 8987 case 5: 8988 /* fall through */ 8989 default: 8990 goto die; 8991 } 8992 } 8993 trace_mips_translate_tr("mftr", rt, u, sel, h); 8994 gen_store_gpr(t0, rd); 8995 tcg_temp_free(t0); 8996 return; 8997 8998 die: 8999 tcg_temp_free(t0); 9000 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 9001 gen_reserved_instruction(ctx); 9002 } 9003 9004 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 9005 int u, int sel, int h) 9006 { 9007 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 9008 TCGv t0 = tcg_temp_local_new(); 9009 9010 gen_load_gpr(t0, rt); 9011 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 9012 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 9013 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 9014 /* NOP */ 9015 ; 9016 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 9017 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 9018 /* NOP */ 9019 ; 9020 } else if (u == 0) { 9021 switch (rd) { 9022 case 1: 9023 switch (sel) { 9024 case 1: 9025 gen_helper_mttc0_vpecontrol(cpu_env, t0); 9026 break; 9027 case 2: 9028 gen_helper_mttc0_vpeconf0(cpu_env, t0); 9029 break; 9030 default: 9031 goto die; 9032 break; 9033 } 9034 break; 9035 case 2: 9036 switch (sel) { 9037 case 1: 9038 gen_helper_mttc0_tcstatus(cpu_env, t0); 9039 break; 9040 case 2: 9041 gen_helper_mttc0_tcbind(cpu_env, t0); 9042 break; 9043 case 3: 9044 gen_helper_mttc0_tcrestart(cpu_env, t0); 9045 break; 9046 case 4: 9047 gen_helper_mttc0_tchalt(cpu_env, t0); 9048 break; 9049 case 5: 9050 gen_helper_mttc0_tccontext(cpu_env, t0); 9051 break; 9052 case 6: 9053 gen_helper_mttc0_tcschedule(cpu_env, t0); 9054 break; 9055 case 7: 9056 gen_helper_mttc0_tcschefback(cpu_env, t0); 9057 break; 9058 default: 9059 gen_mtc0(ctx, t0, rd, sel); 9060 break; 9061 } 9062 break; 9063 case 10: 9064 switch (sel) { 9065 case 0: 9066 gen_helper_mttc0_entryhi(cpu_env, t0); 9067 break; 9068 default: 9069 gen_mtc0(ctx, t0, rd, sel); 9070 break; 9071 } 9072 break; 9073 case 12: 9074 switch (sel) { 9075 case 0: 9076 gen_helper_mttc0_status(cpu_env, t0); 9077 break; 9078 default: 9079 gen_mtc0(ctx, t0, rd, sel); 9080 break; 9081 } 9082 break; 9083 case 13: 9084 switch (sel) { 9085 case 0: 9086 gen_helper_mttc0_cause(cpu_env, t0); 9087 break; 9088 default: 9089 goto die; 9090 break; 9091 } 9092 break; 9093 case 15: 9094 switch (sel) { 9095 case 1: 9096 gen_helper_mttc0_ebase(cpu_env, t0); 9097 break; 9098 default: 9099 goto die; 9100 break; 9101 } 9102 break; 9103 case 23: 9104 switch (sel) { 9105 case 0: 9106 gen_helper_mttc0_debug(cpu_env, t0); 9107 break; 9108 default: 9109 gen_mtc0(ctx, t0, rd, sel); 9110 break; 9111 } 9112 break; 9113 default: 9114 gen_mtc0(ctx, t0, rd, sel); 9115 } 9116 } else { 9117 switch (sel) { 9118 /* GPR registers. */ 9119 case 0: 9120 gen_helper_0e1i(mttgpr, t0, rd); 9121 break; 9122 /* Auxiliary CPU registers */ 9123 case 1: 9124 switch (rd) { 9125 case 0: 9126 gen_helper_0e1i(mttlo, t0, 0); 9127 break; 9128 case 1: 9129 gen_helper_0e1i(mtthi, t0, 0); 9130 break; 9131 case 2: 9132 gen_helper_0e1i(mttacx, t0, 0); 9133 break; 9134 case 4: 9135 gen_helper_0e1i(mttlo, t0, 1); 9136 break; 9137 case 5: 9138 gen_helper_0e1i(mtthi, t0, 1); 9139 break; 9140 case 6: 9141 gen_helper_0e1i(mttacx, t0, 1); 9142 break; 9143 case 8: 9144 gen_helper_0e1i(mttlo, t0, 2); 9145 break; 9146 case 9: 9147 gen_helper_0e1i(mtthi, t0, 2); 9148 break; 9149 case 10: 9150 gen_helper_0e1i(mttacx, t0, 2); 9151 break; 9152 case 12: 9153 gen_helper_0e1i(mttlo, t0, 3); 9154 break; 9155 case 13: 9156 gen_helper_0e1i(mtthi, t0, 3); 9157 break; 9158 case 14: 9159 gen_helper_0e1i(mttacx, t0, 3); 9160 break; 9161 case 16: 9162 gen_helper_mttdsp(cpu_env, t0); 9163 break; 9164 default: 9165 goto die; 9166 } 9167 break; 9168 /* Floating point (COP1). */ 9169 case 2: 9170 /* XXX: For now we support only a single FPU context. */ 9171 if (h == 0) { 9172 TCGv_i32 fp0 = tcg_temp_new_i32(); 9173 9174 tcg_gen_trunc_tl_i32(fp0, t0); 9175 gen_store_fpr32(ctx, fp0, rd); 9176 tcg_temp_free_i32(fp0); 9177 } else { 9178 TCGv_i32 fp0 = tcg_temp_new_i32(); 9179 9180 tcg_gen_trunc_tl_i32(fp0, t0); 9181 gen_store_fpr32h(ctx, fp0, rd); 9182 tcg_temp_free_i32(fp0); 9183 } 9184 break; 9185 case 3: 9186 /* XXX: For now we support only a single FPU context. */ 9187 { 9188 TCGv_i32 fs_tmp = tcg_const_i32(rd); 9189 9190 gen_helper_0e2i(ctc1, t0, fs_tmp, rt); 9191 tcg_temp_free_i32(fs_tmp); 9192 } 9193 /* Stop translation as we may have changed hflags */ 9194 ctx->base.is_jmp = DISAS_STOP; 9195 break; 9196 /* COP2: Not implemented. */ 9197 case 4: 9198 case 5: 9199 /* fall through */ 9200 default: 9201 goto die; 9202 } 9203 } 9204 trace_mips_translate_tr("mttr", rd, u, sel, h); 9205 tcg_temp_free(t0); 9206 return; 9207 9208 die: 9209 tcg_temp_free(t0); 9210 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 9211 gen_reserved_instruction(ctx); 9212 } 9213 9214 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 9215 int rt, int rd) 9216 { 9217 const char *opn = "ldst"; 9218 9219 check_cp0_enabled(ctx); 9220 switch (opc) { 9221 case OPC_MFC0: 9222 if (rt == 0) { 9223 /* Treat as NOP. */ 9224 return; 9225 } 9226 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9227 opn = "mfc0"; 9228 break; 9229 case OPC_MTC0: 9230 { 9231 TCGv t0 = tcg_temp_new(); 9232 9233 gen_load_gpr(t0, rt); 9234 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7); 9235 tcg_temp_free(t0); 9236 } 9237 opn = "mtc0"; 9238 break; 9239 #if defined(TARGET_MIPS64) 9240 case OPC_DMFC0: 9241 check_insn(ctx, ISA_MIPS3); 9242 if (rt == 0) { 9243 /* Treat as NOP. */ 9244 return; 9245 } 9246 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9247 opn = "dmfc0"; 9248 break; 9249 case OPC_DMTC0: 9250 check_insn(ctx, ISA_MIPS3); 9251 { 9252 TCGv t0 = tcg_temp_new(); 9253 9254 gen_load_gpr(t0, rt); 9255 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7); 9256 tcg_temp_free(t0); 9257 } 9258 opn = "dmtc0"; 9259 break; 9260 #endif 9261 case OPC_MFHC0: 9262 check_mvh(ctx); 9263 if (rt == 0) { 9264 /* Treat as NOP. */ 9265 return; 9266 } 9267 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9268 opn = "mfhc0"; 9269 break; 9270 case OPC_MTHC0: 9271 check_mvh(ctx); 9272 { 9273 TCGv t0 = tcg_temp_new(); 9274 gen_load_gpr(t0, rt); 9275 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7); 9276 tcg_temp_free(t0); 9277 } 9278 opn = "mthc0"; 9279 break; 9280 case OPC_MFTR: 9281 check_cp0_enabled(ctx); 9282 if (rd == 0) { 9283 /* Treat as NOP. */ 9284 return; 9285 } 9286 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 9287 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 9288 opn = "mftr"; 9289 break; 9290 case OPC_MTTR: 9291 check_cp0_enabled(ctx); 9292 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 9293 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 9294 opn = "mttr"; 9295 break; 9296 case OPC_TLBWI: 9297 opn = "tlbwi"; 9298 if (!env->tlb->helper_tlbwi) { 9299 goto die; 9300 } 9301 gen_helper_tlbwi(cpu_env); 9302 break; 9303 case OPC_TLBINV: 9304 opn = "tlbinv"; 9305 if (ctx->ie >= 2) { 9306 if (!env->tlb->helper_tlbinv) { 9307 goto die; 9308 } 9309 gen_helper_tlbinv(cpu_env); 9310 } /* treat as nop if TLBINV not supported */ 9311 break; 9312 case OPC_TLBINVF: 9313 opn = "tlbinvf"; 9314 if (ctx->ie >= 2) { 9315 if (!env->tlb->helper_tlbinvf) { 9316 goto die; 9317 } 9318 gen_helper_tlbinvf(cpu_env); 9319 } /* treat as nop if TLBINV not supported */ 9320 break; 9321 case OPC_TLBWR: 9322 opn = "tlbwr"; 9323 if (!env->tlb->helper_tlbwr) { 9324 goto die; 9325 } 9326 gen_helper_tlbwr(cpu_env); 9327 break; 9328 case OPC_TLBP: 9329 opn = "tlbp"; 9330 if (!env->tlb->helper_tlbp) { 9331 goto die; 9332 } 9333 gen_helper_tlbp(cpu_env); 9334 break; 9335 case OPC_TLBR: 9336 opn = "tlbr"; 9337 if (!env->tlb->helper_tlbr) { 9338 goto die; 9339 } 9340 gen_helper_tlbr(cpu_env); 9341 break; 9342 case OPC_ERET: /* OPC_ERETNC */ 9343 if ((ctx->insn_flags & ISA_MIPS_R6) && 9344 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9345 goto die; 9346 } else { 9347 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6; 9348 if (ctx->opcode & (1 << bit_shift)) { 9349 /* OPC_ERETNC */ 9350 opn = "eretnc"; 9351 check_insn(ctx, ISA_MIPS_R5); 9352 gen_helper_eretnc(cpu_env); 9353 } else { 9354 /* OPC_ERET */ 9355 opn = "eret"; 9356 check_insn(ctx, ISA_MIPS2); 9357 gen_helper_eret(cpu_env); 9358 } 9359 ctx->base.is_jmp = DISAS_EXIT; 9360 } 9361 break; 9362 case OPC_DERET: 9363 opn = "deret"; 9364 check_insn(ctx, ISA_MIPS_R1); 9365 if ((ctx->insn_flags & ISA_MIPS_R6) && 9366 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9367 goto die; 9368 } 9369 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 9370 MIPS_INVAL(opn); 9371 gen_reserved_instruction(ctx); 9372 } else { 9373 gen_helper_deret(cpu_env); 9374 ctx->base.is_jmp = DISAS_EXIT; 9375 } 9376 break; 9377 case OPC_WAIT: 9378 opn = "wait"; 9379 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 9380 if ((ctx->insn_flags & ISA_MIPS_R6) && 9381 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9382 goto die; 9383 } 9384 /* If we get an exception, we want to restart at next instruction */ 9385 ctx->base.pc_next += 4; 9386 save_cpu_state(ctx, 1); 9387 ctx->base.pc_next -= 4; 9388 gen_helper_wait(cpu_env); 9389 ctx->base.is_jmp = DISAS_NORETURN; 9390 break; 9391 default: 9392 die: 9393 MIPS_INVAL(opn); 9394 gen_reserved_instruction(ctx); 9395 return; 9396 } 9397 (void)opn; /* avoid a compiler warning */ 9398 } 9399 #endif /* !CONFIG_USER_ONLY */ 9400 9401 /* CP1 Branches (before delay slot) */ 9402 static void gen_compute_branch1(DisasContext *ctx, uint32_t op, 9403 int32_t cc, int32_t offset) 9404 { 9405 target_ulong btarget; 9406 TCGv_i32 t0 = tcg_temp_new_i32(); 9407 9408 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { 9409 gen_reserved_instruction(ctx); 9410 goto out; 9411 } 9412 9413 if (cc != 0) { 9414 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 9415 } 9416 9417 btarget = ctx->base.pc_next + 4 + offset; 9418 9419 switch (op) { 9420 case OPC_BC1F: 9421 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9422 tcg_gen_not_i32(t0, t0); 9423 tcg_gen_andi_i32(t0, t0, 1); 9424 tcg_gen_extu_i32_tl(bcond, t0); 9425 goto not_likely; 9426 case OPC_BC1FL: 9427 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9428 tcg_gen_not_i32(t0, t0); 9429 tcg_gen_andi_i32(t0, t0, 1); 9430 tcg_gen_extu_i32_tl(bcond, t0); 9431 goto likely; 9432 case OPC_BC1T: 9433 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9434 tcg_gen_andi_i32(t0, t0, 1); 9435 tcg_gen_extu_i32_tl(bcond, t0); 9436 goto not_likely; 9437 case OPC_BC1TL: 9438 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9439 tcg_gen_andi_i32(t0, t0, 1); 9440 tcg_gen_extu_i32_tl(bcond, t0); 9441 likely: 9442 ctx->hflags |= MIPS_HFLAG_BL; 9443 break; 9444 case OPC_BC1FANY2: 9445 { 9446 TCGv_i32 t1 = tcg_temp_new_i32(); 9447 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9448 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9449 tcg_gen_nand_i32(t0, t0, t1); 9450 tcg_temp_free_i32(t1); 9451 tcg_gen_andi_i32(t0, t0, 1); 9452 tcg_gen_extu_i32_tl(bcond, t0); 9453 } 9454 goto not_likely; 9455 case OPC_BC1TANY2: 9456 { 9457 TCGv_i32 t1 = tcg_temp_new_i32(); 9458 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9459 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9460 tcg_gen_or_i32(t0, t0, t1); 9461 tcg_temp_free_i32(t1); 9462 tcg_gen_andi_i32(t0, t0, 1); 9463 tcg_gen_extu_i32_tl(bcond, t0); 9464 } 9465 goto not_likely; 9466 case OPC_BC1FANY4: 9467 { 9468 TCGv_i32 t1 = tcg_temp_new_i32(); 9469 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9470 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9471 tcg_gen_and_i32(t0, t0, t1); 9472 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 9473 tcg_gen_and_i32(t0, t0, t1); 9474 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 9475 tcg_gen_nand_i32(t0, t0, t1); 9476 tcg_temp_free_i32(t1); 9477 tcg_gen_andi_i32(t0, t0, 1); 9478 tcg_gen_extu_i32_tl(bcond, t0); 9479 } 9480 goto not_likely; 9481 case OPC_BC1TANY4: 9482 { 9483 TCGv_i32 t1 = tcg_temp_new_i32(); 9484 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9485 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9486 tcg_gen_or_i32(t0, t0, t1); 9487 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 9488 tcg_gen_or_i32(t0, t0, t1); 9489 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 9490 tcg_gen_or_i32(t0, t0, t1); 9491 tcg_temp_free_i32(t1); 9492 tcg_gen_andi_i32(t0, t0, 1); 9493 tcg_gen_extu_i32_tl(bcond, t0); 9494 } 9495 not_likely: 9496 ctx->hflags |= MIPS_HFLAG_BC; 9497 break; 9498 default: 9499 MIPS_INVAL("cp1 cond branch"); 9500 gen_reserved_instruction(ctx); 9501 goto out; 9502 } 9503 ctx->btarget = btarget; 9504 ctx->hflags |= MIPS_HFLAG_BDS32; 9505 out: 9506 tcg_temp_free_i32(t0); 9507 } 9508 9509 /* R6 CP1 Branches */ 9510 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, 9511 int32_t ft, int32_t offset, 9512 int delayslot_size) 9513 { 9514 target_ulong btarget; 9515 TCGv_i64 t0 = tcg_temp_new_i64(); 9516 9517 if (ctx->hflags & MIPS_HFLAG_BMASK) { 9518 #ifdef MIPS_DEBUG_DISAS 9519 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx 9520 "\n", ctx->base.pc_next); 9521 #endif 9522 gen_reserved_instruction(ctx); 9523 goto out; 9524 } 9525 9526 gen_load_fpr64(ctx, t0, ft); 9527 tcg_gen_andi_i64(t0, t0, 1); 9528 9529 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 9530 9531 switch (op) { 9532 case OPC_BC1EQZ: 9533 tcg_gen_xori_i64(t0, t0, 1); 9534 ctx->hflags |= MIPS_HFLAG_BC; 9535 break; 9536 case OPC_BC1NEZ: 9537 /* t0 already set */ 9538 ctx->hflags |= MIPS_HFLAG_BC; 9539 break; 9540 default: 9541 MIPS_INVAL("cp1 cond branch"); 9542 gen_reserved_instruction(ctx); 9543 goto out; 9544 } 9545 9546 tcg_gen_trunc_i64_tl(bcond, t0); 9547 9548 ctx->btarget = btarget; 9549 9550 switch (delayslot_size) { 9551 case 2: 9552 ctx->hflags |= MIPS_HFLAG_BDS16; 9553 break; 9554 case 4: 9555 ctx->hflags |= MIPS_HFLAG_BDS32; 9556 break; 9557 } 9558 9559 out: 9560 tcg_temp_free_i64(t0); 9561 } 9562 9563 /* Coprocessor 1 (FPU) */ 9564 9565 #define FOP(func, fmt) (((fmt) << 21) | (func)) 9566 9567 enum fopcode { 9568 OPC_ADD_S = FOP(0, FMT_S), 9569 OPC_SUB_S = FOP(1, FMT_S), 9570 OPC_MUL_S = FOP(2, FMT_S), 9571 OPC_DIV_S = FOP(3, FMT_S), 9572 OPC_SQRT_S = FOP(4, FMT_S), 9573 OPC_ABS_S = FOP(5, FMT_S), 9574 OPC_MOV_S = FOP(6, FMT_S), 9575 OPC_NEG_S = FOP(7, FMT_S), 9576 OPC_ROUND_L_S = FOP(8, FMT_S), 9577 OPC_TRUNC_L_S = FOP(9, FMT_S), 9578 OPC_CEIL_L_S = FOP(10, FMT_S), 9579 OPC_FLOOR_L_S = FOP(11, FMT_S), 9580 OPC_ROUND_W_S = FOP(12, FMT_S), 9581 OPC_TRUNC_W_S = FOP(13, FMT_S), 9582 OPC_CEIL_W_S = FOP(14, FMT_S), 9583 OPC_FLOOR_W_S = FOP(15, FMT_S), 9584 OPC_SEL_S = FOP(16, FMT_S), 9585 OPC_MOVCF_S = FOP(17, FMT_S), 9586 OPC_MOVZ_S = FOP(18, FMT_S), 9587 OPC_MOVN_S = FOP(19, FMT_S), 9588 OPC_SELEQZ_S = FOP(20, FMT_S), 9589 OPC_RECIP_S = FOP(21, FMT_S), 9590 OPC_RSQRT_S = FOP(22, FMT_S), 9591 OPC_SELNEZ_S = FOP(23, FMT_S), 9592 OPC_MADDF_S = FOP(24, FMT_S), 9593 OPC_MSUBF_S = FOP(25, FMT_S), 9594 OPC_RINT_S = FOP(26, FMT_S), 9595 OPC_CLASS_S = FOP(27, FMT_S), 9596 OPC_MIN_S = FOP(28, FMT_S), 9597 OPC_RECIP2_S = FOP(28, FMT_S), 9598 OPC_MINA_S = FOP(29, FMT_S), 9599 OPC_RECIP1_S = FOP(29, FMT_S), 9600 OPC_MAX_S = FOP(30, FMT_S), 9601 OPC_RSQRT1_S = FOP(30, FMT_S), 9602 OPC_MAXA_S = FOP(31, FMT_S), 9603 OPC_RSQRT2_S = FOP(31, FMT_S), 9604 OPC_CVT_D_S = FOP(33, FMT_S), 9605 OPC_CVT_W_S = FOP(36, FMT_S), 9606 OPC_CVT_L_S = FOP(37, FMT_S), 9607 OPC_CVT_PS_S = FOP(38, FMT_S), 9608 OPC_CMP_F_S = FOP(48, FMT_S), 9609 OPC_CMP_UN_S = FOP(49, FMT_S), 9610 OPC_CMP_EQ_S = FOP(50, FMT_S), 9611 OPC_CMP_UEQ_S = FOP(51, FMT_S), 9612 OPC_CMP_OLT_S = FOP(52, FMT_S), 9613 OPC_CMP_ULT_S = FOP(53, FMT_S), 9614 OPC_CMP_OLE_S = FOP(54, FMT_S), 9615 OPC_CMP_ULE_S = FOP(55, FMT_S), 9616 OPC_CMP_SF_S = FOP(56, FMT_S), 9617 OPC_CMP_NGLE_S = FOP(57, FMT_S), 9618 OPC_CMP_SEQ_S = FOP(58, FMT_S), 9619 OPC_CMP_NGL_S = FOP(59, FMT_S), 9620 OPC_CMP_LT_S = FOP(60, FMT_S), 9621 OPC_CMP_NGE_S = FOP(61, FMT_S), 9622 OPC_CMP_LE_S = FOP(62, FMT_S), 9623 OPC_CMP_NGT_S = FOP(63, FMT_S), 9624 9625 OPC_ADD_D = FOP(0, FMT_D), 9626 OPC_SUB_D = FOP(1, FMT_D), 9627 OPC_MUL_D = FOP(2, FMT_D), 9628 OPC_DIV_D = FOP(3, FMT_D), 9629 OPC_SQRT_D = FOP(4, FMT_D), 9630 OPC_ABS_D = FOP(5, FMT_D), 9631 OPC_MOV_D = FOP(6, FMT_D), 9632 OPC_NEG_D = FOP(7, FMT_D), 9633 OPC_ROUND_L_D = FOP(8, FMT_D), 9634 OPC_TRUNC_L_D = FOP(9, FMT_D), 9635 OPC_CEIL_L_D = FOP(10, FMT_D), 9636 OPC_FLOOR_L_D = FOP(11, FMT_D), 9637 OPC_ROUND_W_D = FOP(12, FMT_D), 9638 OPC_TRUNC_W_D = FOP(13, FMT_D), 9639 OPC_CEIL_W_D = FOP(14, FMT_D), 9640 OPC_FLOOR_W_D = FOP(15, FMT_D), 9641 OPC_SEL_D = FOP(16, FMT_D), 9642 OPC_MOVCF_D = FOP(17, FMT_D), 9643 OPC_MOVZ_D = FOP(18, FMT_D), 9644 OPC_MOVN_D = FOP(19, FMT_D), 9645 OPC_SELEQZ_D = FOP(20, FMT_D), 9646 OPC_RECIP_D = FOP(21, FMT_D), 9647 OPC_RSQRT_D = FOP(22, FMT_D), 9648 OPC_SELNEZ_D = FOP(23, FMT_D), 9649 OPC_MADDF_D = FOP(24, FMT_D), 9650 OPC_MSUBF_D = FOP(25, FMT_D), 9651 OPC_RINT_D = FOP(26, FMT_D), 9652 OPC_CLASS_D = FOP(27, FMT_D), 9653 OPC_MIN_D = FOP(28, FMT_D), 9654 OPC_RECIP2_D = FOP(28, FMT_D), 9655 OPC_MINA_D = FOP(29, FMT_D), 9656 OPC_RECIP1_D = FOP(29, FMT_D), 9657 OPC_MAX_D = FOP(30, FMT_D), 9658 OPC_RSQRT1_D = FOP(30, FMT_D), 9659 OPC_MAXA_D = FOP(31, FMT_D), 9660 OPC_RSQRT2_D = FOP(31, FMT_D), 9661 OPC_CVT_S_D = FOP(32, FMT_D), 9662 OPC_CVT_W_D = FOP(36, FMT_D), 9663 OPC_CVT_L_D = FOP(37, FMT_D), 9664 OPC_CMP_F_D = FOP(48, FMT_D), 9665 OPC_CMP_UN_D = FOP(49, FMT_D), 9666 OPC_CMP_EQ_D = FOP(50, FMT_D), 9667 OPC_CMP_UEQ_D = FOP(51, FMT_D), 9668 OPC_CMP_OLT_D = FOP(52, FMT_D), 9669 OPC_CMP_ULT_D = FOP(53, FMT_D), 9670 OPC_CMP_OLE_D = FOP(54, FMT_D), 9671 OPC_CMP_ULE_D = FOP(55, FMT_D), 9672 OPC_CMP_SF_D = FOP(56, FMT_D), 9673 OPC_CMP_NGLE_D = FOP(57, FMT_D), 9674 OPC_CMP_SEQ_D = FOP(58, FMT_D), 9675 OPC_CMP_NGL_D = FOP(59, FMT_D), 9676 OPC_CMP_LT_D = FOP(60, FMT_D), 9677 OPC_CMP_NGE_D = FOP(61, FMT_D), 9678 OPC_CMP_LE_D = FOP(62, FMT_D), 9679 OPC_CMP_NGT_D = FOP(63, FMT_D), 9680 9681 OPC_CVT_S_W = FOP(32, FMT_W), 9682 OPC_CVT_D_W = FOP(33, FMT_W), 9683 OPC_CVT_S_L = FOP(32, FMT_L), 9684 OPC_CVT_D_L = FOP(33, FMT_L), 9685 OPC_CVT_PS_PW = FOP(38, FMT_W), 9686 9687 OPC_ADD_PS = FOP(0, FMT_PS), 9688 OPC_SUB_PS = FOP(1, FMT_PS), 9689 OPC_MUL_PS = FOP(2, FMT_PS), 9690 OPC_DIV_PS = FOP(3, FMT_PS), 9691 OPC_ABS_PS = FOP(5, FMT_PS), 9692 OPC_MOV_PS = FOP(6, FMT_PS), 9693 OPC_NEG_PS = FOP(7, FMT_PS), 9694 OPC_MOVCF_PS = FOP(17, FMT_PS), 9695 OPC_MOVZ_PS = FOP(18, FMT_PS), 9696 OPC_MOVN_PS = FOP(19, FMT_PS), 9697 OPC_ADDR_PS = FOP(24, FMT_PS), 9698 OPC_MULR_PS = FOP(26, FMT_PS), 9699 OPC_RECIP2_PS = FOP(28, FMT_PS), 9700 OPC_RECIP1_PS = FOP(29, FMT_PS), 9701 OPC_RSQRT1_PS = FOP(30, FMT_PS), 9702 OPC_RSQRT2_PS = FOP(31, FMT_PS), 9703 9704 OPC_CVT_S_PU = FOP(32, FMT_PS), 9705 OPC_CVT_PW_PS = FOP(36, FMT_PS), 9706 OPC_CVT_S_PL = FOP(40, FMT_PS), 9707 OPC_PLL_PS = FOP(44, FMT_PS), 9708 OPC_PLU_PS = FOP(45, FMT_PS), 9709 OPC_PUL_PS = FOP(46, FMT_PS), 9710 OPC_PUU_PS = FOP(47, FMT_PS), 9711 OPC_CMP_F_PS = FOP(48, FMT_PS), 9712 OPC_CMP_UN_PS = FOP(49, FMT_PS), 9713 OPC_CMP_EQ_PS = FOP(50, FMT_PS), 9714 OPC_CMP_UEQ_PS = FOP(51, FMT_PS), 9715 OPC_CMP_OLT_PS = FOP(52, FMT_PS), 9716 OPC_CMP_ULT_PS = FOP(53, FMT_PS), 9717 OPC_CMP_OLE_PS = FOP(54, FMT_PS), 9718 OPC_CMP_ULE_PS = FOP(55, FMT_PS), 9719 OPC_CMP_SF_PS = FOP(56, FMT_PS), 9720 OPC_CMP_NGLE_PS = FOP(57, FMT_PS), 9721 OPC_CMP_SEQ_PS = FOP(58, FMT_PS), 9722 OPC_CMP_NGL_PS = FOP(59, FMT_PS), 9723 OPC_CMP_LT_PS = FOP(60, FMT_PS), 9724 OPC_CMP_NGE_PS = FOP(61, FMT_PS), 9725 OPC_CMP_LE_PS = FOP(62, FMT_PS), 9726 OPC_CMP_NGT_PS = FOP(63, FMT_PS), 9727 }; 9728 9729 enum r6_f_cmp_op { 9730 R6_OPC_CMP_AF_S = FOP(0, FMT_W), 9731 R6_OPC_CMP_UN_S = FOP(1, FMT_W), 9732 R6_OPC_CMP_EQ_S = FOP(2, FMT_W), 9733 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W), 9734 R6_OPC_CMP_LT_S = FOP(4, FMT_W), 9735 R6_OPC_CMP_ULT_S = FOP(5, FMT_W), 9736 R6_OPC_CMP_LE_S = FOP(6, FMT_W), 9737 R6_OPC_CMP_ULE_S = FOP(7, FMT_W), 9738 R6_OPC_CMP_SAF_S = FOP(8, FMT_W), 9739 R6_OPC_CMP_SUN_S = FOP(9, FMT_W), 9740 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W), 9741 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W), 9742 R6_OPC_CMP_SLT_S = FOP(12, FMT_W), 9743 R6_OPC_CMP_SULT_S = FOP(13, FMT_W), 9744 R6_OPC_CMP_SLE_S = FOP(14, FMT_W), 9745 R6_OPC_CMP_SULE_S = FOP(15, FMT_W), 9746 R6_OPC_CMP_OR_S = FOP(17, FMT_W), 9747 R6_OPC_CMP_UNE_S = FOP(18, FMT_W), 9748 R6_OPC_CMP_NE_S = FOP(19, FMT_W), 9749 R6_OPC_CMP_SOR_S = FOP(25, FMT_W), 9750 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W), 9751 R6_OPC_CMP_SNE_S = FOP(27, FMT_W), 9752 9753 R6_OPC_CMP_AF_D = FOP(0, FMT_L), 9754 R6_OPC_CMP_UN_D = FOP(1, FMT_L), 9755 R6_OPC_CMP_EQ_D = FOP(2, FMT_L), 9756 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L), 9757 R6_OPC_CMP_LT_D = FOP(4, FMT_L), 9758 R6_OPC_CMP_ULT_D = FOP(5, FMT_L), 9759 R6_OPC_CMP_LE_D = FOP(6, FMT_L), 9760 R6_OPC_CMP_ULE_D = FOP(7, FMT_L), 9761 R6_OPC_CMP_SAF_D = FOP(8, FMT_L), 9762 R6_OPC_CMP_SUN_D = FOP(9, FMT_L), 9763 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L), 9764 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L), 9765 R6_OPC_CMP_SLT_D = FOP(12, FMT_L), 9766 R6_OPC_CMP_SULT_D = FOP(13, FMT_L), 9767 R6_OPC_CMP_SLE_D = FOP(14, FMT_L), 9768 R6_OPC_CMP_SULE_D = FOP(15, FMT_L), 9769 R6_OPC_CMP_OR_D = FOP(17, FMT_L), 9770 R6_OPC_CMP_UNE_D = FOP(18, FMT_L), 9771 R6_OPC_CMP_NE_D = FOP(19, FMT_L), 9772 R6_OPC_CMP_SOR_D = FOP(25, FMT_L), 9773 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L), 9774 R6_OPC_CMP_SNE_D = FOP(27, FMT_L), 9775 }; 9776 9777 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) 9778 { 9779 TCGv t0 = tcg_temp_new(); 9780 9781 switch (opc) { 9782 case OPC_MFC1: 9783 { 9784 TCGv_i32 fp0 = tcg_temp_new_i32(); 9785 9786 gen_load_fpr32(ctx, fp0, fs); 9787 tcg_gen_ext_i32_tl(t0, fp0); 9788 tcg_temp_free_i32(fp0); 9789 } 9790 gen_store_gpr(t0, rt); 9791 break; 9792 case OPC_MTC1: 9793 gen_load_gpr(t0, rt); 9794 { 9795 TCGv_i32 fp0 = tcg_temp_new_i32(); 9796 9797 tcg_gen_trunc_tl_i32(fp0, t0); 9798 gen_store_fpr32(ctx, fp0, fs); 9799 tcg_temp_free_i32(fp0); 9800 } 9801 break; 9802 case OPC_CFC1: 9803 gen_helper_1e0i(cfc1, t0, fs); 9804 gen_store_gpr(t0, rt); 9805 break; 9806 case OPC_CTC1: 9807 gen_load_gpr(t0, rt); 9808 save_cpu_state(ctx, 0); 9809 { 9810 TCGv_i32 fs_tmp = tcg_const_i32(fs); 9811 9812 gen_helper_0e2i(ctc1, t0, fs_tmp, rt); 9813 tcg_temp_free_i32(fs_tmp); 9814 } 9815 /* Stop translation as we may have changed hflags */ 9816 ctx->base.is_jmp = DISAS_STOP; 9817 break; 9818 #if defined(TARGET_MIPS64) 9819 case OPC_DMFC1: 9820 gen_load_fpr64(ctx, t0, fs); 9821 gen_store_gpr(t0, rt); 9822 break; 9823 case OPC_DMTC1: 9824 gen_load_gpr(t0, rt); 9825 gen_store_fpr64(ctx, t0, fs); 9826 break; 9827 #endif 9828 case OPC_MFHC1: 9829 { 9830 TCGv_i32 fp0 = tcg_temp_new_i32(); 9831 9832 gen_load_fpr32h(ctx, fp0, fs); 9833 tcg_gen_ext_i32_tl(t0, fp0); 9834 tcg_temp_free_i32(fp0); 9835 } 9836 gen_store_gpr(t0, rt); 9837 break; 9838 case OPC_MTHC1: 9839 gen_load_gpr(t0, rt); 9840 { 9841 TCGv_i32 fp0 = tcg_temp_new_i32(); 9842 9843 tcg_gen_trunc_tl_i32(fp0, t0); 9844 gen_store_fpr32h(ctx, fp0, fs); 9845 tcg_temp_free_i32(fp0); 9846 } 9847 break; 9848 default: 9849 MIPS_INVAL("cp1 move"); 9850 gen_reserved_instruction(ctx); 9851 goto out; 9852 } 9853 9854 out: 9855 tcg_temp_free(t0); 9856 } 9857 9858 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf) 9859 { 9860 TCGLabel *l1; 9861 TCGCond cond; 9862 TCGv_i32 t0; 9863 9864 if (rd == 0) { 9865 /* Treat as NOP. */ 9866 return; 9867 } 9868 9869 if (tf) { 9870 cond = TCG_COND_EQ; 9871 } else { 9872 cond = TCG_COND_NE; 9873 } 9874 9875 l1 = gen_new_label(); 9876 t0 = tcg_temp_new_i32(); 9877 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9878 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9879 tcg_temp_free_i32(t0); 9880 gen_load_gpr(cpu_gpr[rd], rs); 9881 gen_set_label(l1); 9882 } 9883 9884 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, 9885 int tf) 9886 { 9887 int cond; 9888 TCGv_i32 t0 = tcg_temp_new_i32(); 9889 TCGLabel *l1 = gen_new_label(); 9890 9891 if (tf) { 9892 cond = TCG_COND_EQ; 9893 } else { 9894 cond = TCG_COND_NE; 9895 } 9896 9897 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9898 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9899 gen_load_fpr32(ctx, t0, fs); 9900 gen_store_fpr32(ctx, t0, fd); 9901 gen_set_label(l1); 9902 tcg_temp_free_i32(t0); 9903 } 9904 9905 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, 9906 int tf) 9907 { 9908 int cond; 9909 TCGv_i32 t0 = tcg_temp_new_i32(); 9910 TCGv_i64 fp0; 9911 TCGLabel *l1 = gen_new_label(); 9912 9913 if (tf) { 9914 cond = TCG_COND_EQ; 9915 } else { 9916 cond = TCG_COND_NE; 9917 } 9918 9919 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9920 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9921 tcg_temp_free_i32(t0); 9922 fp0 = tcg_temp_new_i64(); 9923 gen_load_fpr64(ctx, fp0, fs); 9924 gen_store_fpr64(ctx, fp0, fd); 9925 tcg_temp_free_i64(fp0); 9926 gen_set_label(l1); 9927 } 9928 9929 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, 9930 int cc, int tf) 9931 { 9932 int cond; 9933 TCGv_i32 t0 = tcg_temp_new_i32(); 9934 TCGLabel *l1 = gen_new_label(); 9935 TCGLabel *l2 = gen_new_label(); 9936 9937 if (tf) { 9938 cond = TCG_COND_EQ; 9939 } else { 9940 cond = TCG_COND_NE; 9941 } 9942 9943 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9944 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9945 gen_load_fpr32(ctx, t0, fs); 9946 gen_store_fpr32(ctx, t0, fd); 9947 gen_set_label(l1); 9948 9949 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1)); 9950 tcg_gen_brcondi_i32(cond, t0, 0, l2); 9951 gen_load_fpr32h(ctx, t0, fs); 9952 gen_store_fpr32h(ctx, t0, fd); 9953 tcg_temp_free_i32(t0); 9954 gen_set_label(l2); 9955 } 9956 9957 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9958 int fs) 9959 { 9960 TCGv_i32 t1 = tcg_const_i32(0); 9961 TCGv_i32 fp0 = tcg_temp_new_i32(); 9962 TCGv_i32 fp1 = tcg_temp_new_i32(); 9963 TCGv_i32 fp2 = tcg_temp_new_i32(); 9964 gen_load_fpr32(ctx, fp0, fd); 9965 gen_load_fpr32(ctx, fp1, ft); 9966 gen_load_fpr32(ctx, fp2, fs); 9967 9968 switch (op1) { 9969 case OPC_SEL_S: 9970 tcg_gen_andi_i32(fp0, fp0, 1); 9971 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9972 break; 9973 case OPC_SELEQZ_S: 9974 tcg_gen_andi_i32(fp1, fp1, 1); 9975 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9976 break; 9977 case OPC_SELNEZ_S: 9978 tcg_gen_andi_i32(fp1, fp1, 1); 9979 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9980 break; 9981 default: 9982 MIPS_INVAL("gen_sel_s"); 9983 gen_reserved_instruction(ctx); 9984 break; 9985 } 9986 9987 gen_store_fpr32(ctx, fp0, fd); 9988 tcg_temp_free_i32(fp2); 9989 tcg_temp_free_i32(fp1); 9990 tcg_temp_free_i32(fp0); 9991 tcg_temp_free_i32(t1); 9992 } 9993 9994 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9995 int fs) 9996 { 9997 TCGv_i64 t1 = tcg_const_i64(0); 9998 TCGv_i64 fp0 = tcg_temp_new_i64(); 9999 TCGv_i64 fp1 = tcg_temp_new_i64(); 10000 TCGv_i64 fp2 = tcg_temp_new_i64(); 10001 gen_load_fpr64(ctx, fp0, fd); 10002 gen_load_fpr64(ctx, fp1, ft); 10003 gen_load_fpr64(ctx, fp2, fs); 10004 10005 switch (op1) { 10006 case OPC_SEL_D: 10007 tcg_gen_andi_i64(fp0, fp0, 1); 10008 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 10009 break; 10010 case OPC_SELEQZ_D: 10011 tcg_gen_andi_i64(fp1, fp1, 1); 10012 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 10013 break; 10014 case OPC_SELNEZ_D: 10015 tcg_gen_andi_i64(fp1, fp1, 1); 10016 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 10017 break; 10018 default: 10019 MIPS_INVAL("gen_sel_d"); 10020 gen_reserved_instruction(ctx); 10021 break; 10022 } 10023 10024 gen_store_fpr64(ctx, fp0, fd); 10025 tcg_temp_free_i64(fp2); 10026 tcg_temp_free_i64(fp1); 10027 tcg_temp_free_i64(fp0); 10028 tcg_temp_free_i64(t1); 10029 } 10030 10031 static void gen_farith(DisasContext *ctx, enum fopcode op1, 10032 int ft, int fs, int fd, int cc) 10033 { 10034 uint32_t func = ctx->opcode & 0x3f; 10035 switch (op1) { 10036 case OPC_ADD_S: 10037 { 10038 TCGv_i32 fp0 = tcg_temp_new_i32(); 10039 TCGv_i32 fp1 = tcg_temp_new_i32(); 10040 10041 gen_load_fpr32(ctx, fp0, fs); 10042 gen_load_fpr32(ctx, fp1, ft); 10043 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1); 10044 tcg_temp_free_i32(fp1); 10045 gen_store_fpr32(ctx, fp0, fd); 10046 tcg_temp_free_i32(fp0); 10047 } 10048 break; 10049 case OPC_SUB_S: 10050 { 10051 TCGv_i32 fp0 = tcg_temp_new_i32(); 10052 TCGv_i32 fp1 = tcg_temp_new_i32(); 10053 10054 gen_load_fpr32(ctx, fp0, fs); 10055 gen_load_fpr32(ctx, fp1, ft); 10056 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1); 10057 tcg_temp_free_i32(fp1); 10058 gen_store_fpr32(ctx, fp0, fd); 10059 tcg_temp_free_i32(fp0); 10060 } 10061 break; 10062 case OPC_MUL_S: 10063 { 10064 TCGv_i32 fp0 = tcg_temp_new_i32(); 10065 TCGv_i32 fp1 = tcg_temp_new_i32(); 10066 10067 gen_load_fpr32(ctx, fp0, fs); 10068 gen_load_fpr32(ctx, fp1, ft); 10069 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1); 10070 tcg_temp_free_i32(fp1); 10071 gen_store_fpr32(ctx, fp0, fd); 10072 tcg_temp_free_i32(fp0); 10073 } 10074 break; 10075 case OPC_DIV_S: 10076 { 10077 TCGv_i32 fp0 = tcg_temp_new_i32(); 10078 TCGv_i32 fp1 = tcg_temp_new_i32(); 10079 10080 gen_load_fpr32(ctx, fp0, fs); 10081 gen_load_fpr32(ctx, fp1, ft); 10082 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1); 10083 tcg_temp_free_i32(fp1); 10084 gen_store_fpr32(ctx, fp0, fd); 10085 tcg_temp_free_i32(fp0); 10086 } 10087 break; 10088 case OPC_SQRT_S: 10089 { 10090 TCGv_i32 fp0 = tcg_temp_new_i32(); 10091 10092 gen_load_fpr32(ctx, fp0, fs); 10093 gen_helper_float_sqrt_s(fp0, cpu_env, fp0); 10094 gen_store_fpr32(ctx, fp0, fd); 10095 tcg_temp_free_i32(fp0); 10096 } 10097 break; 10098 case OPC_ABS_S: 10099 { 10100 TCGv_i32 fp0 = tcg_temp_new_i32(); 10101 10102 gen_load_fpr32(ctx, fp0, fs); 10103 if (ctx->abs2008) { 10104 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL); 10105 } else { 10106 gen_helper_float_abs_s(fp0, fp0); 10107 } 10108 gen_store_fpr32(ctx, fp0, fd); 10109 tcg_temp_free_i32(fp0); 10110 } 10111 break; 10112 case OPC_MOV_S: 10113 { 10114 TCGv_i32 fp0 = tcg_temp_new_i32(); 10115 10116 gen_load_fpr32(ctx, fp0, fs); 10117 gen_store_fpr32(ctx, fp0, fd); 10118 tcg_temp_free_i32(fp0); 10119 } 10120 break; 10121 case OPC_NEG_S: 10122 { 10123 TCGv_i32 fp0 = tcg_temp_new_i32(); 10124 10125 gen_load_fpr32(ctx, fp0, fs); 10126 if (ctx->abs2008) { 10127 tcg_gen_xori_i32(fp0, fp0, 1UL << 31); 10128 } else { 10129 gen_helper_float_chs_s(fp0, fp0); 10130 } 10131 gen_store_fpr32(ctx, fp0, fd); 10132 tcg_temp_free_i32(fp0); 10133 } 10134 break; 10135 case OPC_ROUND_L_S: 10136 check_cp1_64bitmode(ctx); 10137 { 10138 TCGv_i32 fp32 = tcg_temp_new_i32(); 10139 TCGv_i64 fp64 = tcg_temp_new_i64(); 10140 10141 gen_load_fpr32(ctx, fp32, fs); 10142 if (ctx->nan2008) { 10143 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32); 10144 } else { 10145 gen_helper_float_round_l_s(fp64, cpu_env, fp32); 10146 } 10147 tcg_temp_free_i32(fp32); 10148 gen_store_fpr64(ctx, fp64, fd); 10149 tcg_temp_free_i64(fp64); 10150 } 10151 break; 10152 case OPC_TRUNC_L_S: 10153 check_cp1_64bitmode(ctx); 10154 { 10155 TCGv_i32 fp32 = tcg_temp_new_i32(); 10156 TCGv_i64 fp64 = tcg_temp_new_i64(); 10157 10158 gen_load_fpr32(ctx, fp32, fs); 10159 if (ctx->nan2008) { 10160 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32); 10161 } else { 10162 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32); 10163 } 10164 tcg_temp_free_i32(fp32); 10165 gen_store_fpr64(ctx, fp64, fd); 10166 tcg_temp_free_i64(fp64); 10167 } 10168 break; 10169 case OPC_CEIL_L_S: 10170 check_cp1_64bitmode(ctx); 10171 { 10172 TCGv_i32 fp32 = tcg_temp_new_i32(); 10173 TCGv_i64 fp64 = tcg_temp_new_i64(); 10174 10175 gen_load_fpr32(ctx, fp32, fs); 10176 if (ctx->nan2008) { 10177 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32); 10178 } else { 10179 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32); 10180 } 10181 tcg_temp_free_i32(fp32); 10182 gen_store_fpr64(ctx, fp64, fd); 10183 tcg_temp_free_i64(fp64); 10184 } 10185 break; 10186 case OPC_FLOOR_L_S: 10187 check_cp1_64bitmode(ctx); 10188 { 10189 TCGv_i32 fp32 = tcg_temp_new_i32(); 10190 TCGv_i64 fp64 = tcg_temp_new_i64(); 10191 10192 gen_load_fpr32(ctx, fp32, fs); 10193 if (ctx->nan2008) { 10194 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32); 10195 } else { 10196 gen_helper_float_floor_l_s(fp64, cpu_env, fp32); 10197 } 10198 tcg_temp_free_i32(fp32); 10199 gen_store_fpr64(ctx, fp64, fd); 10200 tcg_temp_free_i64(fp64); 10201 } 10202 break; 10203 case OPC_ROUND_W_S: 10204 { 10205 TCGv_i32 fp0 = tcg_temp_new_i32(); 10206 10207 gen_load_fpr32(ctx, fp0, fs); 10208 if (ctx->nan2008) { 10209 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0); 10210 } else { 10211 gen_helper_float_round_w_s(fp0, cpu_env, fp0); 10212 } 10213 gen_store_fpr32(ctx, fp0, fd); 10214 tcg_temp_free_i32(fp0); 10215 } 10216 break; 10217 case OPC_TRUNC_W_S: 10218 { 10219 TCGv_i32 fp0 = tcg_temp_new_i32(); 10220 10221 gen_load_fpr32(ctx, fp0, fs); 10222 if (ctx->nan2008) { 10223 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0); 10224 } else { 10225 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0); 10226 } 10227 gen_store_fpr32(ctx, fp0, fd); 10228 tcg_temp_free_i32(fp0); 10229 } 10230 break; 10231 case OPC_CEIL_W_S: 10232 { 10233 TCGv_i32 fp0 = tcg_temp_new_i32(); 10234 10235 gen_load_fpr32(ctx, fp0, fs); 10236 if (ctx->nan2008) { 10237 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0); 10238 } else { 10239 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0); 10240 } 10241 gen_store_fpr32(ctx, fp0, fd); 10242 tcg_temp_free_i32(fp0); 10243 } 10244 break; 10245 case OPC_FLOOR_W_S: 10246 { 10247 TCGv_i32 fp0 = tcg_temp_new_i32(); 10248 10249 gen_load_fpr32(ctx, fp0, fs); 10250 if (ctx->nan2008) { 10251 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0); 10252 } else { 10253 gen_helper_float_floor_w_s(fp0, cpu_env, fp0); 10254 } 10255 gen_store_fpr32(ctx, fp0, fd); 10256 tcg_temp_free_i32(fp0); 10257 } 10258 break; 10259 case OPC_SEL_S: 10260 check_insn(ctx, ISA_MIPS_R6); 10261 gen_sel_s(ctx, op1, fd, ft, fs); 10262 break; 10263 case OPC_SELEQZ_S: 10264 check_insn(ctx, ISA_MIPS_R6); 10265 gen_sel_s(ctx, op1, fd, ft, fs); 10266 break; 10267 case OPC_SELNEZ_S: 10268 check_insn(ctx, ISA_MIPS_R6); 10269 gen_sel_s(ctx, op1, fd, ft, fs); 10270 break; 10271 case OPC_MOVCF_S: 10272 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10273 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10274 break; 10275 case OPC_MOVZ_S: 10276 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10277 { 10278 TCGLabel *l1 = gen_new_label(); 10279 TCGv_i32 fp0; 10280 10281 if (ft != 0) { 10282 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10283 } 10284 fp0 = tcg_temp_new_i32(); 10285 gen_load_fpr32(ctx, fp0, fs); 10286 gen_store_fpr32(ctx, fp0, fd); 10287 tcg_temp_free_i32(fp0); 10288 gen_set_label(l1); 10289 } 10290 break; 10291 case OPC_MOVN_S: 10292 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10293 { 10294 TCGLabel *l1 = gen_new_label(); 10295 TCGv_i32 fp0; 10296 10297 if (ft != 0) { 10298 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10299 fp0 = tcg_temp_new_i32(); 10300 gen_load_fpr32(ctx, fp0, fs); 10301 gen_store_fpr32(ctx, fp0, fd); 10302 tcg_temp_free_i32(fp0); 10303 gen_set_label(l1); 10304 } 10305 } 10306 break; 10307 case OPC_RECIP_S: 10308 { 10309 TCGv_i32 fp0 = tcg_temp_new_i32(); 10310 10311 gen_load_fpr32(ctx, fp0, fs); 10312 gen_helper_float_recip_s(fp0, cpu_env, fp0); 10313 gen_store_fpr32(ctx, fp0, fd); 10314 tcg_temp_free_i32(fp0); 10315 } 10316 break; 10317 case OPC_RSQRT_S: 10318 { 10319 TCGv_i32 fp0 = tcg_temp_new_i32(); 10320 10321 gen_load_fpr32(ctx, fp0, fs); 10322 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0); 10323 gen_store_fpr32(ctx, fp0, fd); 10324 tcg_temp_free_i32(fp0); 10325 } 10326 break; 10327 case OPC_MADDF_S: 10328 check_insn(ctx, ISA_MIPS_R6); 10329 { 10330 TCGv_i32 fp0 = tcg_temp_new_i32(); 10331 TCGv_i32 fp1 = tcg_temp_new_i32(); 10332 TCGv_i32 fp2 = tcg_temp_new_i32(); 10333 gen_load_fpr32(ctx, fp0, fs); 10334 gen_load_fpr32(ctx, fp1, ft); 10335 gen_load_fpr32(ctx, fp2, fd); 10336 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2); 10337 gen_store_fpr32(ctx, fp2, fd); 10338 tcg_temp_free_i32(fp2); 10339 tcg_temp_free_i32(fp1); 10340 tcg_temp_free_i32(fp0); 10341 } 10342 break; 10343 case OPC_MSUBF_S: 10344 check_insn(ctx, ISA_MIPS_R6); 10345 { 10346 TCGv_i32 fp0 = tcg_temp_new_i32(); 10347 TCGv_i32 fp1 = tcg_temp_new_i32(); 10348 TCGv_i32 fp2 = tcg_temp_new_i32(); 10349 gen_load_fpr32(ctx, fp0, fs); 10350 gen_load_fpr32(ctx, fp1, ft); 10351 gen_load_fpr32(ctx, fp2, fd); 10352 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2); 10353 gen_store_fpr32(ctx, fp2, fd); 10354 tcg_temp_free_i32(fp2); 10355 tcg_temp_free_i32(fp1); 10356 tcg_temp_free_i32(fp0); 10357 } 10358 break; 10359 case OPC_RINT_S: 10360 check_insn(ctx, ISA_MIPS_R6); 10361 { 10362 TCGv_i32 fp0 = tcg_temp_new_i32(); 10363 gen_load_fpr32(ctx, fp0, fs); 10364 gen_helper_float_rint_s(fp0, cpu_env, fp0); 10365 gen_store_fpr32(ctx, fp0, fd); 10366 tcg_temp_free_i32(fp0); 10367 } 10368 break; 10369 case OPC_CLASS_S: 10370 check_insn(ctx, ISA_MIPS_R6); 10371 { 10372 TCGv_i32 fp0 = tcg_temp_new_i32(); 10373 gen_load_fpr32(ctx, fp0, fs); 10374 gen_helper_float_class_s(fp0, cpu_env, fp0); 10375 gen_store_fpr32(ctx, fp0, fd); 10376 tcg_temp_free_i32(fp0); 10377 } 10378 break; 10379 case OPC_MIN_S: /* OPC_RECIP2_S */ 10380 if (ctx->insn_flags & ISA_MIPS_R6) { 10381 /* OPC_MIN_S */ 10382 TCGv_i32 fp0 = tcg_temp_new_i32(); 10383 TCGv_i32 fp1 = tcg_temp_new_i32(); 10384 TCGv_i32 fp2 = tcg_temp_new_i32(); 10385 gen_load_fpr32(ctx, fp0, fs); 10386 gen_load_fpr32(ctx, fp1, ft); 10387 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1); 10388 gen_store_fpr32(ctx, fp2, fd); 10389 tcg_temp_free_i32(fp2); 10390 tcg_temp_free_i32(fp1); 10391 tcg_temp_free_i32(fp0); 10392 } else { 10393 /* OPC_RECIP2_S */ 10394 check_cp1_64bitmode(ctx); 10395 { 10396 TCGv_i32 fp0 = tcg_temp_new_i32(); 10397 TCGv_i32 fp1 = tcg_temp_new_i32(); 10398 10399 gen_load_fpr32(ctx, fp0, fs); 10400 gen_load_fpr32(ctx, fp1, ft); 10401 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1); 10402 tcg_temp_free_i32(fp1); 10403 gen_store_fpr32(ctx, fp0, fd); 10404 tcg_temp_free_i32(fp0); 10405 } 10406 } 10407 break; 10408 case OPC_MINA_S: /* OPC_RECIP1_S */ 10409 if (ctx->insn_flags & ISA_MIPS_R6) { 10410 /* OPC_MINA_S */ 10411 TCGv_i32 fp0 = tcg_temp_new_i32(); 10412 TCGv_i32 fp1 = tcg_temp_new_i32(); 10413 TCGv_i32 fp2 = tcg_temp_new_i32(); 10414 gen_load_fpr32(ctx, fp0, fs); 10415 gen_load_fpr32(ctx, fp1, ft); 10416 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1); 10417 gen_store_fpr32(ctx, fp2, fd); 10418 tcg_temp_free_i32(fp2); 10419 tcg_temp_free_i32(fp1); 10420 tcg_temp_free_i32(fp0); 10421 } else { 10422 /* OPC_RECIP1_S */ 10423 check_cp1_64bitmode(ctx); 10424 { 10425 TCGv_i32 fp0 = tcg_temp_new_i32(); 10426 10427 gen_load_fpr32(ctx, fp0, fs); 10428 gen_helper_float_recip1_s(fp0, cpu_env, fp0); 10429 gen_store_fpr32(ctx, fp0, fd); 10430 tcg_temp_free_i32(fp0); 10431 } 10432 } 10433 break; 10434 case OPC_MAX_S: /* OPC_RSQRT1_S */ 10435 if (ctx->insn_flags & ISA_MIPS_R6) { 10436 /* OPC_MAX_S */ 10437 TCGv_i32 fp0 = tcg_temp_new_i32(); 10438 TCGv_i32 fp1 = tcg_temp_new_i32(); 10439 gen_load_fpr32(ctx, fp0, fs); 10440 gen_load_fpr32(ctx, fp1, ft); 10441 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1); 10442 gen_store_fpr32(ctx, fp1, fd); 10443 tcg_temp_free_i32(fp1); 10444 tcg_temp_free_i32(fp0); 10445 } else { 10446 /* OPC_RSQRT1_S */ 10447 check_cp1_64bitmode(ctx); 10448 { 10449 TCGv_i32 fp0 = tcg_temp_new_i32(); 10450 10451 gen_load_fpr32(ctx, fp0, fs); 10452 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0); 10453 gen_store_fpr32(ctx, fp0, fd); 10454 tcg_temp_free_i32(fp0); 10455 } 10456 } 10457 break; 10458 case OPC_MAXA_S: /* OPC_RSQRT2_S */ 10459 if (ctx->insn_flags & ISA_MIPS_R6) { 10460 /* OPC_MAXA_S */ 10461 TCGv_i32 fp0 = tcg_temp_new_i32(); 10462 TCGv_i32 fp1 = tcg_temp_new_i32(); 10463 gen_load_fpr32(ctx, fp0, fs); 10464 gen_load_fpr32(ctx, fp1, ft); 10465 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1); 10466 gen_store_fpr32(ctx, fp1, fd); 10467 tcg_temp_free_i32(fp1); 10468 tcg_temp_free_i32(fp0); 10469 } else { 10470 /* OPC_RSQRT2_S */ 10471 check_cp1_64bitmode(ctx); 10472 { 10473 TCGv_i32 fp0 = tcg_temp_new_i32(); 10474 TCGv_i32 fp1 = tcg_temp_new_i32(); 10475 10476 gen_load_fpr32(ctx, fp0, fs); 10477 gen_load_fpr32(ctx, fp1, ft); 10478 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1); 10479 tcg_temp_free_i32(fp1); 10480 gen_store_fpr32(ctx, fp0, fd); 10481 tcg_temp_free_i32(fp0); 10482 } 10483 } 10484 break; 10485 case OPC_CVT_D_S: 10486 check_cp1_registers(ctx, fd); 10487 { 10488 TCGv_i32 fp32 = tcg_temp_new_i32(); 10489 TCGv_i64 fp64 = tcg_temp_new_i64(); 10490 10491 gen_load_fpr32(ctx, fp32, fs); 10492 gen_helper_float_cvtd_s(fp64, cpu_env, fp32); 10493 tcg_temp_free_i32(fp32); 10494 gen_store_fpr64(ctx, fp64, fd); 10495 tcg_temp_free_i64(fp64); 10496 } 10497 break; 10498 case OPC_CVT_W_S: 10499 { 10500 TCGv_i32 fp0 = tcg_temp_new_i32(); 10501 10502 gen_load_fpr32(ctx, fp0, fs); 10503 if (ctx->nan2008) { 10504 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0); 10505 } else { 10506 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0); 10507 } 10508 gen_store_fpr32(ctx, fp0, fd); 10509 tcg_temp_free_i32(fp0); 10510 } 10511 break; 10512 case OPC_CVT_L_S: 10513 check_cp1_64bitmode(ctx); 10514 { 10515 TCGv_i32 fp32 = tcg_temp_new_i32(); 10516 TCGv_i64 fp64 = tcg_temp_new_i64(); 10517 10518 gen_load_fpr32(ctx, fp32, fs); 10519 if (ctx->nan2008) { 10520 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32); 10521 } else { 10522 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32); 10523 } 10524 tcg_temp_free_i32(fp32); 10525 gen_store_fpr64(ctx, fp64, fd); 10526 tcg_temp_free_i64(fp64); 10527 } 10528 break; 10529 case OPC_CVT_PS_S: 10530 check_ps(ctx); 10531 { 10532 TCGv_i64 fp64 = tcg_temp_new_i64(); 10533 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 10534 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 10535 10536 gen_load_fpr32(ctx, fp32_0, fs); 10537 gen_load_fpr32(ctx, fp32_1, ft); 10538 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); 10539 tcg_temp_free_i32(fp32_1); 10540 tcg_temp_free_i32(fp32_0); 10541 gen_store_fpr64(ctx, fp64, fd); 10542 tcg_temp_free_i64(fp64); 10543 } 10544 break; 10545 case OPC_CMP_F_S: 10546 case OPC_CMP_UN_S: 10547 case OPC_CMP_EQ_S: 10548 case OPC_CMP_UEQ_S: 10549 case OPC_CMP_OLT_S: 10550 case OPC_CMP_ULT_S: 10551 case OPC_CMP_OLE_S: 10552 case OPC_CMP_ULE_S: 10553 case OPC_CMP_SF_S: 10554 case OPC_CMP_NGLE_S: 10555 case OPC_CMP_SEQ_S: 10556 case OPC_CMP_NGL_S: 10557 case OPC_CMP_LT_S: 10558 case OPC_CMP_NGE_S: 10559 case OPC_CMP_LE_S: 10560 case OPC_CMP_NGT_S: 10561 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10562 if (ctx->opcode & (1 << 6)) { 10563 gen_cmpabs_s(ctx, func - 48, ft, fs, cc); 10564 } else { 10565 gen_cmp_s(ctx, func - 48, ft, fs, cc); 10566 } 10567 break; 10568 case OPC_ADD_D: 10569 check_cp1_registers(ctx, fs | ft | fd); 10570 { 10571 TCGv_i64 fp0 = tcg_temp_new_i64(); 10572 TCGv_i64 fp1 = tcg_temp_new_i64(); 10573 10574 gen_load_fpr64(ctx, fp0, fs); 10575 gen_load_fpr64(ctx, fp1, ft); 10576 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1); 10577 tcg_temp_free_i64(fp1); 10578 gen_store_fpr64(ctx, fp0, fd); 10579 tcg_temp_free_i64(fp0); 10580 } 10581 break; 10582 case OPC_SUB_D: 10583 check_cp1_registers(ctx, fs | ft | fd); 10584 { 10585 TCGv_i64 fp0 = tcg_temp_new_i64(); 10586 TCGv_i64 fp1 = tcg_temp_new_i64(); 10587 10588 gen_load_fpr64(ctx, fp0, fs); 10589 gen_load_fpr64(ctx, fp1, ft); 10590 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1); 10591 tcg_temp_free_i64(fp1); 10592 gen_store_fpr64(ctx, fp0, fd); 10593 tcg_temp_free_i64(fp0); 10594 } 10595 break; 10596 case OPC_MUL_D: 10597 check_cp1_registers(ctx, fs | ft | fd); 10598 { 10599 TCGv_i64 fp0 = tcg_temp_new_i64(); 10600 TCGv_i64 fp1 = tcg_temp_new_i64(); 10601 10602 gen_load_fpr64(ctx, fp0, fs); 10603 gen_load_fpr64(ctx, fp1, ft); 10604 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1); 10605 tcg_temp_free_i64(fp1); 10606 gen_store_fpr64(ctx, fp0, fd); 10607 tcg_temp_free_i64(fp0); 10608 } 10609 break; 10610 case OPC_DIV_D: 10611 check_cp1_registers(ctx, fs | ft | fd); 10612 { 10613 TCGv_i64 fp0 = tcg_temp_new_i64(); 10614 TCGv_i64 fp1 = tcg_temp_new_i64(); 10615 10616 gen_load_fpr64(ctx, fp0, fs); 10617 gen_load_fpr64(ctx, fp1, ft); 10618 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1); 10619 tcg_temp_free_i64(fp1); 10620 gen_store_fpr64(ctx, fp0, fd); 10621 tcg_temp_free_i64(fp0); 10622 } 10623 break; 10624 case OPC_SQRT_D: 10625 check_cp1_registers(ctx, fs | fd); 10626 { 10627 TCGv_i64 fp0 = tcg_temp_new_i64(); 10628 10629 gen_load_fpr64(ctx, fp0, fs); 10630 gen_helper_float_sqrt_d(fp0, cpu_env, fp0); 10631 gen_store_fpr64(ctx, fp0, fd); 10632 tcg_temp_free_i64(fp0); 10633 } 10634 break; 10635 case OPC_ABS_D: 10636 check_cp1_registers(ctx, fs | fd); 10637 { 10638 TCGv_i64 fp0 = tcg_temp_new_i64(); 10639 10640 gen_load_fpr64(ctx, fp0, fs); 10641 if (ctx->abs2008) { 10642 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL); 10643 } else { 10644 gen_helper_float_abs_d(fp0, fp0); 10645 } 10646 gen_store_fpr64(ctx, fp0, fd); 10647 tcg_temp_free_i64(fp0); 10648 } 10649 break; 10650 case OPC_MOV_D: 10651 check_cp1_registers(ctx, fs | fd); 10652 { 10653 TCGv_i64 fp0 = tcg_temp_new_i64(); 10654 10655 gen_load_fpr64(ctx, fp0, fs); 10656 gen_store_fpr64(ctx, fp0, fd); 10657 tcg_temp_free_i64(fp0); 10658 } 10659 break; 10660 case OPC_NEG_D: 10661 check_cp1_registers(ctx, fs | fd); 10662 { 10663 TCGv_i64 fp0 = tcg_temp_new_i64(); 10664 10665 gen_load_fpr64(ctx, fp0, fs); 10666 if (ctx->abs2008) { 10667 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63); 10668 } else { 10669 gen_helper_float_chs_d(fp0, fp0); 10670 } 10671 gen_store_fpr64(ctx, fp0, fd); 10672 tcg_temp_free_i64(fp0); 10673 } 10674 break; 10675 case OPC_ROUND_L_D: 10676 check_cp1_64bitmode(ctx); 10677 { 10678 TCGv_i64 fp0 = tcg_temp_new_i64(); 10679 10680 gen_load_fpr64(ctx, fp0, fs); 10681 if (ctx->nan2008) { 10682 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0); 10683 } else { 10684 gen_helper_float_round_l_d(fp0, cpu_env, fp0); 10685 } 10686 gen_store_fpr64(ctx, fp0, fd); 10687 tcg_temp_free_i64(fp0); 10688 } 10689 break; 10690 case OPC_TRUNC_L_D: 10691 check_cp1_64bitmode(ctx); 10692 { 10693 TCGv_i64 fp0 = tcg_temp_new_i64(); 10694 10695 gen_load_fpr64(ctx, fp0, fs); 10696 if (ctx->nan2008) { 10697 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0); 10698 } else { 10699 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0); 10700 } 10701 gen_store_fpr64(ctx, fp0, fd); 10702 tcg_temp_free_i64(fp0); 10703 } 10704 break; 10705 case OPC_CEIL_L_D: 10706 check_cp1_64bitmode(ctx); 10707 { 10708 TCGv_i64 fp0 = tcg_temp_new_i64(); 10709 10710 gen_load_fpr64(ctx, fp0, fs); 10711 if (ctx->nan2008) { 10712 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0); 10713 } else { 10714 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0); 10715 } 10716 gen_store_fpr64(ctx, fp0, fd); 10717 tcg_temp_free_i64(fp0); 10718 } 10719 break; 10720 case OPC_FLOOR_L_D: 10721 check_cp1_64bitmode(ctx); 10722 { 10723 TCGv_i64 fp0 = tcg_temp_new_i64(); 10724 10725 gen_load_fpr64(ctx, fp0, fs); 10726 if (ctx->nan2008) { 10727 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0); 10728 } else { 10729 gen_helper_float_floor_l_d(fp0, cpu_env, fp0); 10730 } 10731 gen_store_fpr64(ctx, fp0, fd); 10732 tcg_temp_free_i64(fp0); 10733 } 10734 break; 10735 case OPC_ROUND_W_D: 10736 check_cp1_registers(ctx, fs); 10737 { 10738 TCGv_i32 fp32 = tcg_temp_new_i32(); 10739 TCGv_i64 fp64 = tcg_temp_new_i64(); 10740 10741 gen_load_fpr64(ctx, fp64, fs); 10742 if (ctx->nan2008) { 10743 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64); 10744 } else { 10745 gen_helper_float_round_w_d(fp32, cpu_env, fp64); 10746 } 10747 tcg_temp_free_i64(fp64); 10748 gen_store_fpr32(ctx, fp32, fd); 10749 tcg_temp_free_i32(fp32); 10750 } 10751 break; 10752 case OPC_TRUNC_W_D: 10753 check_cp1_registers(ctx, fs); 10754 { 10755 TCGv_i32 fp32 = tcg_temp_new_i32(); 10756 TCGv_i64 fp64 = tcg_temp_new_i64(); 10757 10758 gen_load_fpr64(ctx, fp64, fs); 10759 if (ctx->nan2008) { 10760 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64); 10761 } else { 10762 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64); 10763 } 10764 tcg_temp_free_i64(fp64); 10765 gen_store_fpr32(ctx, fp32, fd); 10766 tcg_temp_free_i32(fp32); 10767 } 10768 break; 10769 case OPC_CEIL_W_D: 10770 check_cp1_registers(ctx, fs); 10771 { 10772 TCGv_i32 fp32 = tcg_temp_new_i32(); 10773 TCGv_i64 fp64 = tcg_temp_new_i64(); 10774 10775 gen_load_fpr64(ctx, fp64, fs); 10776 if (ctx->nan2008) { 10777 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64); 10778 } else { 10779 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64); 10780 } 10781 tcg_temp_free_i64(fp64); 10782 gen_store_fpr32(ctx, fp32, fd); 10783 tcg_temp_free_i32(fp32); 10784 } 10785 break; 10786 case OPC_FLOOR_W_D: 10787 check_cp1_registers(ctx, fs); 10788 { 10789 TCGv_i32 fp32 = tcg_temp_new_i32(); 10790 TCGv_i64 fp64 = tcg_temp_new_i64(); 10791 10792 gen_load_fpr64(ctx, fp64, fs); 10793 if (ctx->nan2008) { 10794 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64); 10795 } else { 10796 gen_helper_float_floor_w_d(fp32, cpu_env, fp64); 10797 } 10798 tcg_temp_free_i64(fp64); 10799 gen_store_fpr32(ctx, fp32, fd); 10800 tcg_temp_free_i32(fp32); 10801 } 10802 break; 10803 case OPC_SEL_D: 10804 check_insn(ctx, ISA_MIPS_R6); 10805 gen_sel_d(ctx, op1, fd, ft, fs); 10806 break; 10807 case OPC_SELEQZ_D: 10808 check_insn(ctx, ISA_MIPS_R6); 10809 gen_sel_d(ctx, op1, fd, ft, fs); 10810 break; 10811 case OPC_SELNEZ_D: 10812 check_insn(ctx, ISA_MIPS_R6); 10813 gen_sel_d(ctx, op1, fd, ft, fs); 10814 break; 10815 case OPC_MOVCF_D: 10816 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10817 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10818 break; 10819 case OPC_MOVZ_D: 10820 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10821 { 10822 TCGLabel *l1 = gen_new_label(); 10823 TCGv_i64 fp0; 10824 10825 if (ft != 0) { 10826 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10827 } 10828 fp0 = tcg_temp_new_i64(); 10829 gen_load_fpr64(ctx, fp0, fs); 10830 gen_store_fpr64(ctx, fp0, fd); 10831 tcg_temp_free_i64(fp0); 10832 gen_set_label(l1); 10833 } 10834 break; 10835 case OPC_MOVN_D: 10836 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10837 { 10838 TCGLabel *l1 = gen_new_label(); 10839 TCGv_i64 fp0; 10840 10841 if (ft != 0) { 10842 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10843 fp0 = tcg_temp_new_i64(); 10844 gen_load_fpr64(ctx, fp0, fs); 10845 gen_store_fpr64(ctx, fp0, fd); 10846 tcg_temp_free_i64(fp0); 10847 gen_set_label(l1); 10848 } 10849 } 10850 break; 10851 case OPC_RECIP_D: 10852 check_cp1_registers(ctx, fs | fd); 10853 { 10854 TCGv_i64 fp0 = tcg_temp_new_i64(); 10855 10856 gen_load_fpr64(ctx, fp0, fs); 10857 gen_helper_float_recip_d(fp0, cpu_env, fp0); 10858 gen_store_fpr64(ctx, fp0, fd); 10859 tcg_temp_free_i64(fp0); 10860 } 10861 break; 10862 case OPC_RSQRT_D: 10863 check_cp1_registers(ctx, fs | fd); 10864 { 10865 TCGv_i64 fp0 = tcg_temp_new_i64(); 10866 10867 gen_load_fpr64(ctx, fp0, fs); 10868 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0); 10869 gen_store_fpr64(ctx, fp0, fd); 10870 tcg_temp_free_i64(fp0); 10871 } 10872 break; 10873 case OPC_MADDF_D: 10874 check_insn(ctx, ISA_MIPS_R6); 10875 { 10876 TCGv_i64 fp0 = tcg_temp_new_i64(); 10877 TCGv_i64 fp1 = tcg_temp_new_i64(); 10878 TCGv_i64 fp2 = tcg_temp_new_i64(); 10879 gen_load_fpr64(ctx, fp0, fs); 10880 gen_load_fpr64(ctx, fp1, ft); 10881 gen_load_fpr64(ctx, fp2, fd); 10882 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2); 10883 gen_store_fpr64(ctx, fp2, fd); 10884 tcg_temp_free_i64(fp2); 10885 tcg_temp_free_i64(fp1); 10886 tcg_temp_free_i64(fp0); 10887 } 10888 break; 10889 case OPC_MSUBF_D: 10890 check_insn(ctx, ISA_MIPS_R6); 10891 { 10892 TCGv_i64 fp0 = tcg_temp_new_i64(); 10893 TCGv_i64 fp1 = tcg_temp_new_i64(); 10894 TCGv_i64 fp2 = tcg_temp_new_i64(); 10895 gen_load_fpr64(ctx, fp0, fs); 10896 gen_load_fpr64(ctx, fp1, ft); 10897 gen_load_fpr64(ctx, fp2, fd); 10898 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2); 10899 gen_store_fpr64(ctx, fp2, fd); 10900 tcg_temp_free_i64(fp2); 10901 tcg_temp_free_i64(fp1); 10902 tcg_temp_free_i64(fp0); 10903 } 10904 break; 10905 case OPC_RINT_D: 10906 check_insn(ctx, ISA_MIPS_R6); 10907 { 10908 TCGv_i64 fp0 = tcg_temp_new_i64(); 10909 gen_load_fpr64(ctx, fp0, fs); 10910 gen_helper_float_rint_d(fp0, cpu_env, fp0); 10911 gen_store_fpr64(ctx, fp0, fd); 10912 tcg_temp_free_i64(fp0); 10913 } 10914 break; 10915 case OPC_CLASS_D: 10916 check_insn(ctx, ISA_MIPS_R6); 10917 { 10918 TCGv_i64 fp0 = tcg_temp_new_i64(); 10919 gen_load_fpr64(ctx, fp0, fs); 10920 gen_helper_float_class_d(fp0, cpu_env, fp0); 10921 gen_store_fpr64(ctx, fp0, fd); 10922 tcg_temp_free_i64(fp0); 10923 } 10924 break; 10925 case OPC_MIN_D: /* OPC_RECIP2_D */ 10926 if (ctx->insn_flags & ISA_MIPS_R6) { 10927 /* OPC_MIN_D */ 10928 TCGv_i64 fp0 = tcg_temp_new_i64(); 10929 TCGv_i64 fp1 = tcg_temp_new_i64(); 10930 gen_load_fpr64(ctx, fp0, fs); 10931 gen_load_fpr64(ctx, fp1, ft); 10932 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1); 10933 gen_store_fpr64(ctx, fp1, fd); 10934 tcg_temp_free_i64(fp1); 10935 tcg_temp_free_i64(fp0); 10936 } else { 10937 /* OPC_RECIP2_D */ 10938 check_cp1_64bitmode(ctx); 10939 { 10940 TCGv_i64 fp0 = tcg_temp_new_i64(); 10941 TCGv_i64 fp1 = tcg_temp_new_i64(); 10942 10943 gen_load_fpr64(ctx, fp0, fs); 10944 gen_load_fpr64(ctx, fp1, ft); 10945 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1); 10946 tcg_temp_free_i64(fp1); 10947 gen_store_fpr64(ctx, fp0, fd); 10948 tcg_temp_free_i64(fp0); 10949 } 10950 } 10951 break; 10952 case OPC_MINA_D: /* OPC_RECIP1_D */ 10953 if (ctx->insn_flags & ISA_MIPS_R6) { 10954 /* OPC_MINA_D */ 10955 TCGv_i64 fp0 = tcg_temp_new_i64(); 10956 TCGv_i64 fp1 = tcg_temp_new_i64(); 10957 gen_load_fpr64(ctx, fp0, fs); 10958 gen_load_fpr64(ctx, fp1, ft); 10959 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1); 10960 gen_store_fpr64(ctx, fp1, fd); 10961 tcg_temp_free_i64(fp1); 10962 tcg_temp_free_i64(fp0); 10963 } else { 10964 /* OPC_RECIP1_D */ 10965 check_cp1_64bitmode(ctx); 10966 { 10967 TCGv_i64 fp0 = tcg_temp_new_i64(); 10968 10969 gen_load_fpr64(ctx, fp0, fs); 10970 gen_helper_float_recip1_d(fp0, cpu_env, fp0); 10971 gen_store_fpr64(ctx, fp0, fd); 10972 tcg_temp_free_i64(fp0); 10973 } 10974 } 10975 break; 10976 case OPC_MAX_D: /* OPC_RSQRT1_D */ 10977 if (ctx->insn_flags & ISA_MIPS_R6) { 10978 /* OPC_MAX_D */ 10979 TCGv_i64 fp0 = tcg_temp_new_i64(); 10980 TCGv_i64 fp1 = tcg_temp_new_i64(); 10981 gen_load_fpr64(ctx, fp0, fs); 10982 gen_load_fpr64(ctx, fp1, ft); 10983 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1); 10984 gen_store_fpr64(ctx, fp1, fd); 10985 tcg_temp_free_i64(fp1); 10986 tcg_temp_free_i64(fp0); 10987 } else { 10988 /* OPC_RSQRT1_D */ 10989 check_cp1_64bitmode(ctx); 10990 { 10991 TCGv_i64 fp0 = tcg_temp_new_i64(); 10992 10993 gen_load_fpr64(ctx, fp0, fs); 10994 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0); 10995 gen_store_fpr64(ctx, fp0, fd); 10996 tcg_temp_free_i64(fp0); 10997 } 10998 } 10999 break; 11000 case OPC_MAXA_D: /* OPC_RSQRT2_D */ 11001 if (ctx->insn_flags & ISA_MIPS_R6) { 11002 /* OPC_MAXA_D */ 11003 TCGv_i64 fp0 = tcg_temp_new_i64(); 11004 TCGv_i64 fp1 = tcg_temp_new_i64(); 11005 gen_load_fpr64(ctx, fp0, fs); 11006 gen_load_fpr64(ctx, fp1, ft); 11007 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1); 11008 gen_store_fpr64(ctx, fp1, fd); 11009 tcg_temp_free_i64(fp1); 11010 tcg_temp_free_i64(fp0); 11011 } else { 11012 /* OPC_RSQRT2_D */ 11013 check_cp1_64bitmode(ctx); 11014 { 11015 TCGv_i64 fp0 = tcg_temp_new_i64(); 11016 TCGv_i64 fp1 = tcg_temp_new_i64(); 11017 11018 gen_load_fpr64(ctx, fp0, fs); 11019 gen_load_fpr64(ctx, fp1, ft); 11020 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1); 11021 tcg_temp_free_i64(fp1); 11022 gen_store_fpr64(ctx, fp0, fd); 11023 tcg_temp_free_i64(fp0); 11024 } 11025 } 11026 break; 11027 case OPC_CMP_F_D: 11028 case OPC_CMP_UN_D: 11029 case OPC_CMP_EQ_D: 11030 case OPC_CMP_UEQ_D: 11031 case OPC_CMP_OLT_D: 11032 case OPC_CMP_ULT_D: 11033 case OPC_CMP_OLE_D: 11034 case OPC_CMP_ULE_D: 11035 case OPC_CMP_SF_D: 11036 case OPC_CMP_NGLE_D: 11037 case OPC_CMP_SEQ_D: 11038 case OPC_CMP_NGL_D: 11039 case OPC_CMP_LT_D: 11040 case OPC_CMP_NGE_D: 11041 case OPC_CMP_LE_D: 11042 case OPC_CMP_NGT_D: 11043 check_insn_opc_removed(ctx, ISA_MIPS_R6); 11044 if (ctx->opcode & (1 << 6)) { 11045 gen_cmpabs_d(ctx, func - 48, ft, fs, cc); 11046 } else { 11047 gen_cmp_d(ctx, func - 48, ft, fs, cc); 11048 } 11049 break; 11050 case OPC_CVT_S_D: 11051 check_cp1_registers(ctx, fs); 11052 { 11053 TCGv_i32 fp32 = tcg_temp_new_i32(); 11054 TCGv_i64 fp64 = tcg_temp_new_i64(); 11055 11056 gen_load_fpr64(ctx, fp64, fs); 11057 gen_helper_float_cvts_d(fp32, cpu_env, fp64); 11058 tcg_temp_free_i64(fp64); 11059 gen_store_fpr32(ctx, fp32, fd); 11060 tcg_temp_free_i32(fp32); 11061 } 11062 break; 11063 case OPC_CVT_W_D: 11064 check_cp1_registers(ctx, fs); 11065 { 11066 TCGv_i32 fp32 = tcg_temp_new_i32(); 11067 TCGv_i64 fp64 = tcg_temp_new_i64(); 11068 11069 gen_load_fpr64(ctx, fp64, fs); 11070 if (ctx->nan2008) { 11071 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64); 11072 } else { 11073 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64); 11074 } 11075 tcg_temp_free_i64(fp64); 11076 gen_store_fpr32(ctx, fp32, fd); 11077 tcg_temp_free_i32(fp32); 11078 } 11079 break; 11080 case OPC_CVT_L_D: 11081 check_cp1_64bitmode(ctx); 11082 { 11083 TCGv_i64 fp0 = tcg_temp_new_i64(); 11084 11085 gen_load_fpr64(ctx, fp0, fs); 11086 if (ctx->nan2008) { 11087 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0); 11088 } else { 11089 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0); 11090 } 11091 gen_store_fpr64(ctx, fp0, fd); 11092 tcg_temp_free_i64(fp0); 11093 } 11094 break; 11095 case OPC_CVT_S_W: 11096 { 11097 TCGv_i32 fp0 = tcg_temp_new_i32(); 11098 11099 gen_load_fpr32(ctx, fp0, fs); 11100 gen_helper_float_cvts_w(fp0, cpu_env, fp0); 11101 gen_store_fpr32(ctx, fp0, fd); 11102 tcg_temp_free_i32(fp0); 11103 } 11104 break; 11105 case OPC_CVT_D_W: 11106 check_cp1_registers(ctx, fd); 11107 { 11108 TCGv_i32 fp32 = tcg_temp_new_i32(); 11109 TCGv_i64 fp64 = tcg_temp_new_i64(); 11110 11111 gen_load_fpr32(ctx, fp32, fs); 11112 gen_helper_float_cvtd_w(fp64, cpu_env, fp32); 11113 tcg_temp_free_i32(fp32); 11114 gen_store_fpr64(ctx, fp64, fd); 11115 tcg_temp_free_i64(fp64); 11116 } 11117 break; 11118 case OPC_CVT_S_L: 11119 check_cp1_64bitmode(ctx); 11120 { 11121 TCGv_i32 fp32 = tcg_temp_new_i32(); 11122 TCGv_i64 fp64 = tcg_temp_new_i64(); 11123 11124 gen_load_fpr64(ctx, fp64, fs); 11125 gen_helper_float_cvts_l(fp32, cpu_env, fp64); 11126 tcg_temp_free_i64(fp64); 11127 gen_store_fpr32(ctx, fp32, fd); 11128 tcg_temp_free_i32(fp32); 11129 } 11130 break; 11131 case OPC_CVT_D_L: 11132 check_cp1_64bitmode(ctx); 11133 { 11134 TCGv_i64 fp0 = tcg_temp_new_i64(); 11135 11136 gen_load_fpr64(ctx, fp0, fs); 11137 gen_helper_float_cvtd_l(fp0, cpu_env, fp0); 11138 gen_store_fpr64(ctx, fp0, fd); 11139 tcg_temp_free_i64(fp0); 11140 } 11141 break; 11142 case OPC_CVT_PS_PW: 11143 check_ps(ctx); 11144 { 11145 TCGv_i64 fp0 = tcg_temp_new_i64(); 11146 11147 gen_load_fpr64(ctx, fp0, fs); 11148 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0); 11149 gen_store_fpr64(ctx, fp0, fd); 11150 tcg_temp_free_i64(fp0); 11151 } 11152 break; 11153 case OPC_ADD_PS: 11154 check_ps(ctx); 11155 { 11156 TCGv_i64 fp0 = tcg_temp_new_i64(); 11157 TCGv_i64 fp1 = tcg_temp_new_i64(); 11158 11159 gen_load_fpr64(ctx, fp0, fs); 11160 gen_load_fpr64(ctx, fp1, ft); 11161 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1); 11162 tcg_temp_free_i64(fp1); 11163 gen_store_fpr64(ctx, fp0, fd); 11164 tcg_temp_free_i64(fp0); 11165 } 11166 break; 11167 case OPC_SUB_PS: 11168 check_ps(ctx); 11169 { 11170 TCGv_i64 fp0 = tcg_temp_new_i64(); 11171 TCGv_i64 fp1 = tcg_temp_new_i64(); 11172 11173 gen_load_fpr64(ctx, fp0, fs); 11174 gen_load_fpr64(ctx, fp1, ft); 11175 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1); 11176 tcg_temp_free_i64(fp1); 11177 gen_store_fpr64(ctx, fp0, fd); 11178 tcg_temp_free_i64(fp0); 11179 } 11180 break; 11181 case OPC_MUL_PS: 11182 check_ps(ctx); 11183 { 11184 TCGv_i64 fp0 = tcg_temp_new_i64(); 11185 TCGv_i64 fp1 = tcg_temp_new_i64(); 11186 11187 gen_load_fpr64(ctx, fp0, fs); 11188 gen_load_fpr64(ctx, fp1, ft); 11189 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1); 11190 tcg_temp_free_i64(fp1); 11191 gen_store_fpr64(ctx, fp0, fd); 11192 tcg_temp_free_i64(fp0); 11193 } 11194 break; 11195 case OPC_ABS_PS: 11196 check_ps(ctx); 11197 { 11198 TCGv_i64 fp0 = tcg_temp_new_i64(); 11199 11200 gen_load_fpr64(ctx, fp0, fs); 11201 gen_helper_float_abs_ps(fp0, fp0); 11202 gen_store_fpr64(ctx, fp0, fd); 11203 tcg_temp_free_i64(fp0); 11204 } 11205 break; 11206 case OPC_MOV_PS: 11207 check_ps(ctx); 11208 { 11209 TCGv_i64 fp0 = tcg_temp_new_i64(); 11210 11211 gen_load_fpr64(ctx, fp0, fs); 11212 gen_store_fpr64(ctx, fp0, fd); 11213 tcg_temp_free_i64(fp0); 11214 } 11215 break; 11216 case OPC_NEG_PS: 11217 check_ps(ctx); 11218 { 11219 TCGv_i64 fp0 = tcg_temp_new_i64(); 11220 11221 gen_load_fpr64(ctx, fp0, fs); 11222 gen_helper_float_chs_ps(fp0, fp0); 11223 gen_store_fpr64(ctx, fp0, fd); 11224 tcg_temp_free_i64(fp0); 11225 } 11226 break; 11227 case OPC_MOVCF_PS: 11228 check_ps(ctx); 11229 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 11230 break; 11231 case OPC_MOVZ_PS: 11232 check_ps(ctx); 11233 { 11234 TCGLabel *l1 = gen_new_label(); 11235 TCGv_i64 fp0; 11236 11237 if (ft != 0) { 11238 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 11239 } 11240 fp0 = tcg_temp_new_i64(); 11241 gen_load_fpr64(ctx, fp0, fs); 11242 gen_store_fpr64(ctx, fp0, fd); 11243 tcg_temp_free_i64(fp0); 11244 gen_set_label(l1); 11245 } 11246 break; 11247 case OPC_MOVN_PS: 11248 check_ps(ctx); 11249 { 11250 TCGLabel *l1 = gen_new_label(); 11251 TCGv_i64 fp0; 11252 11253 if (ft != 0) { 11254 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 11255 fp0 = tcg_temp_new_i64(); 11256 gen_load_fpr64(ctx, fp0, fs); 11257 gen_store_fpr64(ctx, fp0, fd); 11258 tcg_temp_free_i64(fp0); 11259 gen_set_label(l1); 11260 } 11261 } 11262 break; 11263 case OPC_ADDR_PS: 11264 check_ps(ctx); 11265 { 11266 TCGv_i64 fp0 = tcg_temp_new_i64(); 11267 TCGv_i64 fp1 = tcg_temp_new_i64(); 11268 11269 gen_load_fpr64(ctx, fp0, ft); 11270 gen_load_fpr64(ctx, fp1, fs); 11271 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1); 11272 tcg_temp_free_i64(fp1); 11273 gen_store_fpr64(ctx, fp0, fd); 11274 tcg_temp_free_i64(fp0); 11275 } 11276 break; 11277 case OPC_MULR_PS: 11278 check_ps(ctx); 11279 { 11280 TCGv_i64 fp0 = tcg_temp_new_i64(); 11281 TCGv_i64 fp1 = tcg_temp_new_i64(); 11282 11283 gen_load_fpr64(ctx, fp0, ft); 11284 gen_load_fpr64(ctx, fp1, fs); 11285 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1); 11286 tcg_temp_free_i64(fp1); 11287 gen_store_fpr64(ctx, fp0, fd); 11288 tcg_temp_free_i64(fp0); 11289 } 11290 break; 11291 case OPC_RECIP2_PS: 11292 check_ps(ctx); 11293 { 11294 TCGv_i64 fp0 = tcg_temp_new_i64(); 11295 TCGv_i64 fp1 = tcg_temp_new_i64(); 11296 11297 gen_load_fpr64(ctx, fp0, fs); 11298 gen_load_fpr64(ctx, fp1, ft); 11299 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1); 11300 tcg_temp_free_i64(fp1); 11301 gen_store_fpr64(ctx, fp0, fd); 11302 tcg_temp_free_i64(fp0); 11303 } 11304 break; 11305 case OPC_RECIP1_PS: 11306 check_ps(ctx); 11307 { 11308 TCGv_i64 fp0 = tcg_temp_new_i64(); 11309 11310 gen_load_fpr64(ctx, fp0, fs); 11311 gen_helper_float_recip1_ps(fp0, cpu_env, fp0); 11312 gen_store_fpr64(ctx, fp0, fd); 11313 tcg_temp_free_i64(fp0); 11314 } 11315 break; 11316 case OPC_RSQRT1_PS: 11317 check_ps(ctx); 11318 { 11319 TCGv_i64 fp0 = tcg_temp_new_i64(); 11320 11321 gen_load_fpr64(ctx, fp0, fs); 11322 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0); 11323 gen_store_fpr64(ctx, fp0, fd); 11324 tcg_temp_free_i64(fp0); 11325 } 11326 break; 11327 case OPC_RSQRT2_PS: 11328 check_ps(ctx); 11329 { 11330 TCGv_i64 fp0 = tcg_temp_new_i64(); 11331 TCGv_i64 fp1 = tcg_temp_new_i64(); 11332 11333 gen_load_fpr64(ctx, fp0, fs); 11334 gen_load_fpr64(ctx, fp1, ft); 11335 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1); 11336 tcg_temp_free_i64(fp1); 11337 gen_store_fpr64(ctx, fp0, fd); 11338 tcg_temp_free_i64(fp0); 11339 } 11340 break; 11341 case OPC_CVT_S_PU: 11342 check_cp1_64bitmode(ctx); 11343 { 11344 TCGv_i32 fp0 = tcg_temp_new_i32(); 11345 11346 gen_load_fpr32h(ctx, fp0, fs); 11347 gen_helper_float_cvts_pu(fp0, cpu_env, fp0); 11348 gen_store_fpr32(ctx, fp0, fd); 11349 tcg_temp_free_i32(fp0); 11350 } 11351 break; 11352 case OPC_CVT_PW_PS: 11353 check_ps(ctx); 11354 { 11355 TCGv_i64 fp0 = tcg_temp_new_i64(); 11356 11357 gen_load_fpr64(ctx, fp0, fs); 11358 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0); 11359 gen_store_fpr64(ctx, fp0, fd); 11360 tcg_temp_free_i64(fp0); 11361 } 11362 break; 11363 case OPC_CVT_S_PL: 11364 check_cp1_64bitmode(ctx); 11365 { 11366 TCGv_i32 fp0 = tcg_temp_new_i32(); 11367 11368 gen_load_fpr32(ctx, fp0, fs); 11369 gen_helper_float_cvts_pl(fp0, cpu_env, fp0); 11370 gen_store_fpr32(ctx, fp0, fd); 11371 tcg_temp_free_i32(fp0); 11372 } 11373 break; 11374 case OPC_PLL_PS: 11375 check_ps(ctx); 11376 { 11377 TCGv_i32 fp0 = tcg_temp_new_i32(); 11378 TCGv_i32 fp1 = tcg_temp_new_i32(); 11379 11380 gen_load_fpr32(ctx, fp0, fs); 11381 gen_load_fpr32(ctx, fp1, ft); 11382 gen_store_fpr32h(ctx, fp0, fd); 11383 gen_store_fpr32(ctx, fp1, fd); 11384 tcg_temp_free_i32(fp0); 11385 tcg_temp_free_i32(fp1); 11386 } 11387 break; 11388 case OPC_PLU_PS: 11389 check_ps(ctx); 11390 { 11391 TCGv_i32 fp0 = tcg_temp_new_i32(); 11392 TCGv_i32 fp1 = tcg_temp_new_i32(); 11393 11394 gen_load_fpr32(ctx, fp0, fs); 11395 gen_load_fpr32h(ctx, fp1, ft); 11396 gen_store_fpr32(ctx, fp1, fd); 11397 gen_store_fpr32h(ctx, fp0, fd); 11398 tcg_temp_free_i32(fp0); 11399 tcg_temp_free_i32(fp1); 11400 } 11401 break; 11402 case OPC_PUL_PS: 11403 check_ps(ctx); 11404 { 11405 TCGv_i32 fp0 = tcg_temp_new_i32(); 11406 TCGv_i32 fp1 = tcg_temp_new_i32(); 11407 11408 gen_load_fpr32h(ctx, fp0, fs); 11409 gen_load_fpr32(ctx, fp1, ft); 11410 gen_store_fpr32(ctx, fp1, fd); 11411 gen_store_fpr32h(ctx, fp0, fd); 11412 tcg_temp_free_i32(fp0); 11413 tcg_temp_free_i32(fp1); 11414 } 11415 break; 11416 case OPC_PUU_PS: 11417 check_ps(ctx); 11418 { 11419 TCGv_i32 fp0 = tcg_temp_new_i32(); 11420 TCGv_i32 fp1 = tcg_temp_new_i32(); 11421 11422 gen_load_fpr32h(ctx, fp0, fs); 11423 gen_load_fpr32h(ctx, fp1, ft); 11424 gen_store_fpr32(ctx, fp1, fd); 11425 gen_store_fpr32h(ctx, fp0, fd); 11426 tcg_temp_free_i32(fp0); 11427 tcg_temp_free_i32(fp1); 11428 } 11429 break; 11430 case OPC_CMP_F_PS: 11431 case OPC_CMP_UN_PS: 11432 case OPC_CMP_EQ_PS: 11433 case OPC_CMP_UEQ_PS: 11434 case OPC_CMP_OLT_PS: 11435 case OPC_CMP_ULT_PS: 11436 case OPC_CMP_OLE_PS: 11437 case OPC_CMP_ULE_PS: 11438 case OPC_CMP_SF_PS: 11439 case OPC_CMP_NGLE_PS: 11440 case OPC_CMP_SEQ_PS: 11441 case OPC_CMP_NGL_PS: 11442 case OPC_CMP_LT_PS: 11443 case OPC_CMP_NGE_PS: 11444 case OPC_CMP_LE_PS: 11445 case OPC_CMP_NGT_PS: 11446 if (ctx->opcode & (1 << 6)) { 11447 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc); 11448 } else { 11449 gen_cmp_ps(ctx, func - 48, ft, fs, cc); 11450 } 11451 break; 11452 default: 11453 MIPS_INVAL("farith"); 11454 gen_reserved_instruction(ctx); 11455 return; 11456 } 11457 } 11458 11459 /* Coprocessor 3 (FPU) */ 11460 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, 11461 int fd, int fs, int base, int index) 11462 { 11463 TCGv t0 = tcg_temp_new(); 11464 11465 if (base == 0) { 11466 gen_load_gpr(t0, index); 11467 } else if (index == 0) { 11468 gen_load_gpr(t0, base); 11469 } else { 11470 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); 11471 } 11472 /* 11473 * Don't do NOP if destination is zero: we must perform the actual 11474 * memory access. 11475 */ 11476 switch (opc) { 11477 case OPC_LWXC1: 11478 check_cop1x(ctx); 11479 { 11480 TCGv_i32 fp0 = tcg_temp_new_i32(); 11481 11482 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); 11483 tcg_gen_trunc_tl_i32(fp0, t0); 11484 gen_store_fpr32(ctx, fp0, fd); 11485 tcg_temp_free_i32(fp0); 11486 } 11487 break; 11488 case OPC_LDXC1: 11489 check_cop1x(ctx); 11490 check_cp1_registers(ctx, fd); 11491 { 11492 TCGv_i64 fp0 = tcg_temp_new_i64(); 11493 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11494 gen_store_fpr64(ctx, fp0, fd); 11495 tcg_temp_free_i64(fp0); 11496 } 11497 break; 11498 case OPC_LUXC1: 11499 check_cp1_64bitmode(ctx); 11500 tcg_gen_andi_tl(t0, t0, ~0x7); 11501 { 11502 TCGv_i64 fp0 = tcg_temp_new_i64(); 11503 11504 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11505 gen_store_fpr64(ctx, fp0, fd); 11506 tcg_temp_free_i64(fp0); 11507 } 11508 break; 11509 case OPC_SWXC1: 11510 check_cop1x(ctx); 11511 { 11512 TCGv_i32 fp0 = tcg_temp_new_i32(); 11513 gen_load_fpr32(ctx, fp0, fs); 11514 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL); 11515 tcg_temp_free_i32(fp0); 11516 } 11517 break; 11518 case OPC_SDXC1: 11519 check_cop1x(ctx); 11520 check_cp1_registers(ctx, fs); 11521 { 11522 TCGv_i64 fp0 = tcg_temp_new_i64(); 11523 gen_load_fpr64(ctx, fp0, fs); 11524 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11525 tcg_temp_free_i64(fp0); 11526 } 11527 break; 11528 case OPC_SUXC1: 11529 check_cp1_64bitmode(ctx); 11530 tcg_gen_andi_tl(t0, t0, ~0x7); 11531 { 11532 TCGv_i64 fp0 = tcg_temp_new_i64(); 11533 gen_load_fpr64(ctx, fp0, fs); 11534 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11535 tcg_temp_free_i64(fp0); 11536 } 11537 break; 11538 } 11539 tcg_temp_free(t0); 11540 } 11541 11542 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, 11543 int fd, int fr, int fs, int ft) 11544 { 11545 switch (opc) { 11546 case OPC_ALNV_PS: 11547 check_ps(ctx); 11548 { 11549 TCGv t0 = tcg_temp_local_new(); 11550 TCGv_i32 fp = tcg_temp_new_i32(); 11551 TCGv_i32 fph = tcg_temp_new_i32(); 11552 TCGLabel *l1 = gen_new_label(); 11553 TCGLabel *l2 = gen_new_label(); 11554 11555 gen_load_gpr(t0, fr); 11556 tcg_gen_andi_tl(t0, t0, 0x7); 11557 11558 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 11559 gen_load_fpr32(ctx, fp, fs); 11560 gen_load_fpr32h(ctx, fph, fs); 11561 gen_store_fpr32(ctx, fp, fd); 11562 gen_store_fpr32h(ctx, fph, fd); 11563 tcg_gen_br(l2); 11564 gen_set_label(l1); 11565 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 11566 tcg_temp_free(t0); 11567 #ifdef TARGET_WORDS_BIGENDIAN 11568 gen_load_fpr32(ctx, fp, fs); 11569 gen_load_fpr32h(ctx, fph, ft); 11570 gen_store_fpr32h(ctx, fp, fd); 11571 gen_store_fpr32(ctx, fph, fd); 11572 #else 11573 gen_load_fpr32h(ctx, fph, fs); 11574 gen_load_fpr32(ctx, fp, ft); 11575 gen_store_fpr32(ctx, fph, fd); 11576 gen_store_fpr32h(ctx, fp, fd); 11577 #endif 11578 gen_set_label(l2); 11579 tcg_temp_free_i32(fp); 11580 tcg_temp_free_i32(fph); 11581 } 11582 break; 11583 case OPC_MADD_S: 11584 check_cop1x(ctx); 11585 { 11586 TCGv_i32 fp0 = tcg_temp_new_i32(); 11587 TCGv_i32 fp1 = tcg_temp_new_i32(); 11588 TCGv_i32 fp2 = tcg_temp_new_i32(); 11589 11590 gen_load_fpr32(ctx, fp0, fs); 11591 gen_load_fpr32(ctx, fp1, ft); 11592 gen_load_fpr32(ctx, fp2, fr); 11593 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2); 11594 tcg_temp_free_i32(fp0); 11595 tcg_temp_free_i32(fp1); 11596 gen_store_fpr32(ctx, fp2, fd); 11597 tcg_temp_free_i32(fp2); 11598 } 11599 break; 11600 case OPC_MADD_D: 11601 check_cop1x(ctx); 11602 check_cp1_registers(ctx, fd | fs | ft | fr); 11603 { 11604 TCGv_i64 fp0 = tcg_temp_new_i64(); 11605 TCGv_i64 fp1 = tcg_temp_new_i64(); 11606 TCGv_i64 fp2 = tcg_temp_new_i64(); 11607 11608 gen_load_fpr64(ctx, fp0, fs); 11609 gen_load_fpr64(ctx, fp1, ft); 11610 gen_load_fpr64(ctx, fp2, fr); 11611 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2); 11612 tcg_temp_free_i64(fp0); 11613 tcg_temp_free_i64(fp1); 11614 gen_store_fpr64(ctx, fp2, fd); 11615 tcg_temp_free_i64(fp2); 11616 } 11617 break; 11618 case OPC_MADD_PS: 11619 check_ps(ctx); 11620 { 11621 TCGv_i64 fp0 = tcg_temp_new_i64(); 11622 TCGv_i64 fp1 = tcg_temp_new_i64(); 11623 TCGv_i64 fp2 = tcg_temp_new_i64(); 11624 11625 gen_load_fpr64(ctx, fp0, fs); 11626 gen_load_fpr64(ctx, fp1, ft); 11627 gen_load_fpr64(ctx, fp2, fr); 11628 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2); 11629 tcg_temp_free_i64(fp0); 11630 tcg_temp_free_i64(fp1); 11631 gen_store_fpr64(ctx, fp2, fd); 11632 tcg_temp_free_i64(fp2); 11633 } 11634 break; 11635 case OPC_MSUB_S: 11636 check_cop1x(ctx); 11637 { 11638 TCGv_i32 fp0 = tcg_temp_new_i32(); 11639 TCGv_i32 fp1 = tcg_temp_new_i32(); 11640 TCGv_i32 fp2 = tcg_temp_new_i32(); 11641 11642 gen_load_fpr32(ctx, fp0, fs); 11643 gen_load_fpr32(ctx, fp1, ft); 11644 gen_load_fpr32(ctx, fp2, fr); 11645 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2); 11646 tcg_temp_free_i32(fp0); 11647 tcg_temp_free_i32(fp1); 11648 gen_store_fpr32(ctx, fp2, fd); 11649 tcg_temp_free_i32(fp2); 11650 } 11651 break; 11652 case OPC_MSUB_D: 11653 check_cop1x(ctx); 11654 check_cp1_registers(ctx, fd | fs | ft | fr); 11655 { 11656 TCGv_i64 fp0 = tcg_temp_new_i64(); 11657 TCGv_i64 fp1 = tcg_temp_new_i64(); 11658 TCGv_i64 fp2 = tcg_temp_new_i64(); 11659 11660 gen_load_fpr64(ctx, fp0, fs); 11661 gen_load_fpr64(ctx, fp1, ft); 11662 gen_load_fpr64(ctx, fp2, fr); 11663 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2); 11664 tcg_temp_free_i64(fp0); 11665 tcg_temp_free_i64(fp1); 11666 gen_store_fpr64(ctx, fp2, fd); 11667 tcg_temp_free_i64(fp2); 11668 } 11669 break; 11670 case OPC_MSUB_PS: 11671 check_ps(ctx); 11672 { 11673 TCGv_i64 fp0 = tcg_temp_new_i64(); 11674 TCGv_i64 fp1 = tcg_temp_new_i64(); 11675 TCGv_i64 fp2 = tcg_temp_new_i64(); 11676 11677 gen_load_fpr64(ctx, fp0, fs); 11678 gen_load_fpr64(ctx, fp1, ft); 11679 gen_load_fpr64(ctx, fp2, fr); 11680 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2); 11681 tcg_temp_free_i64(fp0); 11682 tcg_temp_free_i64(fp1); 11683 gen_store_fpr64(ctx, fp2, fd); 11684 tcg_temp_free_i64(fp2); 11685 } 11686 break; 11687 case OPC_NMADD_S: 11688 check_cop1x(ctx); 11689 { 11690 TCGv_i32 fp0 = tcg_temp_new_i32(); 11691 TCGv_i32 fp1 = tcg_temp_new_i32(); 11692 TCGv_i32 fp2 = tcg_temp_new_i32(); 11693 11694 gen_load_fpr32(ctx, fp0, fs); 11695 gen_load_fpr32(ctx, fp1, ft); 11696 gen_load_fpr32(ctx, fp2, fr); 11697 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2); 11698 tcg_temp_free_i32(fp0); 11699 tcg_temp_free_i32(fp1); 11700 gen_store_fpr32(ctx, fp2, fd); 11701 tcg_temp_free_i32(fp2); 11702 } 11703 break; 11704 case OPC_NMADD_D: 11705 check_cop1x(ctx); 11706 check_cp1_registers(ctx, fd | fs | ft | fr); 11707 { 11708 TCGv_i64 fp0 = tcg_temp_new_i64(); 11709 TCGv_i64 fp1 = tcg_temp_new_i64(); 11710 TCGv_i64 fp2 = tcg_temp_new_i64(); 11711 11712 gen_load_fpr64(ctx, fp0, fs); 11713 gen_load_fpr64(ctx, fp1, ft); 11714 gen_load_fpr64(ctx, fp2, fr); 11715 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2); 11716 tcg_temp_free_i64(fp0); 11717 tcg_temp_free_i64(fp1); 11718 gen_store_fpr64(ctx, fp2, fd); 11719 tcg_temp_free_i64(fp2); 11720 } 11721 break; 11722 case OPC_NMADD_PS: 11723 check_ps(ctx); 11724 { 11725 TCGv_i64 fp0 = tcg_temp_new_i64(); 11726 TCGv_i64 fp1 = tcg_temp_new_i64(); 11727 TCGv_i64 fp2 = tcg_temp_new_i64(); 11728 11729 gen_load_fpr64(ctx, fp0, fs); 11730 gen_load_fpr64(ctx, fp1, ft); 11731 gen_load_fpr64(ctx, fp2, fr); 11732 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2); 11733 tcg_temp_free_i64(fp0); 11734 tcg_temp_free_i64(fp1); 11735 gen_store_fpr64(ctx, fp2, fd); 11736 tcg_temp_free_i64(fp2); 11737 } 11738 break; 11739 case OPC_NMSUB_S: 11740 check_cop1x(ctx); 11741 { 11742 TCGv_i32 fp0 = tcg_temp_new_i32(); 11743 TCGv_i32 fp1 = tcg_temp_new_i32(); 11744 TCGv_i32 fp2 = tcg_temp_new_i32(); 11745 11746 gen_load_fpr32(ctx, fp0, fs); 11747 gen_load_fpr32(ctx, fp1, ft); 11748 gen_load_fpr32(ctx, fp2, fr); 11749 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2); 11750 tcg_temp_free_i32(fp0); 11751 tcg_temp_free_i32(fp1); 11752 gen_store_fpr32(ctx, fp2, fd); 11753 tcg_temp_free_i32(fp2); 11754 } 11755 break; 11756 case OPC_NMSUB_D: 11757 check_cop1x(ctx); 11758 check_cp1_registers(ctx, fd | fs | ft | fr); 11759 { 11760 TCGv_i64 fp0 = tcg_temp_new_i64(); 11761 TCGv_i64 fp1 = tcg_temp_new_i64(); 11762 TCGv_i64 fp2 = tcg_temp_new_i64(); 11763 11764 gen_load_fpr64(ctx, fp0, fs); 11765 gen_load_fpr64(ctx, fp1, ft); 11766 gen_load_fpr64(ctx, fp2, fr); 11767 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2); 11768 tcg_temp_free_i64(fp0); 11769 tcg_temp_free_i64(fp1); 11770 gen_store_fpr64(ctx, fp2, fd); 11771 tcg_temp_free_i64(fp2); 11772 } 11773 break; 11774 case OPC_NMSUB_PS: 11775 check_ps(ctx); 11776 { 11777 TCGv_i64 fp0 = tcg_temp_new_i64(); 11778 TCGv_i64 fp1 = tcg_temp_new_i64(); 11779 TCGv_i64 fp2 = tcg_temp_new_i64(); 11780 11781 gen_load_fpr64(ctx, fp0, fs); 11782 gen_load_fpr64(ctx, fp1, ft); 11783 gen_load_fpr64(ctx, fp2, fr); 11784 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2); 11785 tcg_temp_free_i64(fp0); 11786 tcg_temp_free_i64(fp1); 11787 gen_store_fpr64(ctx, fp2, fd); 11788 tcg_temp_free_i64(fp2); 11789 } 11790 break; 11791 default: 11792 MIPS_INVAL("flt3_arith"); 11793 gen_reserved_instruction(ctx); 11794 return; 11795 } 11796 } 11797 11798 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) 11799 { 11800 TCGv t0; 11801 11802 #if !defined(CONFIG_USER_ONLY) 11803 /* 11804 * The Linux kernel will emulate rdhwr if it's not supported natively. 11805 * Therefore only check the ISA in system mode. 11806 */ 11807 check_insn(ctx, ISA_MIPS_R2); 11808 #endif 11809 t0 = tcg_temp_new(); 11810 11811 switch (rd) { 11812 case 0: 11813 gen_helper_rdhwr_cpunum(t0, cpu_env); 11814 gen_store_gpr(t0, rt); 11815 break; 11816 case 1: 11817 gen_helper_rdhwr_synci_step(t0, cpu_env); 11818 gen_store_gpr(t0, rt); 11819 break; 11820 case 2: 11821 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 11822 gen_io_start(); 11823 } 11824 gen_helper_rdhwr_cc(t0, cpu_env); 11825 gen_store_gpr(t0, rt); 11826 /* 11827 * Break the TB to be able to take timer interrupts immediately 11828 * after reading count. DISAS_STOP isn't sufficient, we need to ensure 11829 * we break completely out of translated code. 11830 */ 11831 gen_save_pc(ctx->base.pc_next + 4); 11832 ctx->base.is_jmp = DISAS_EXIT; 11833 break; 11834 case 3: 11835 gen_helper_rdhwr_ccres(t0, cpu_env); 11836 gen_store_gpr(t0, rt); 11837 break; 11838 case 4: 11839 check_insn(ctx, ISA_MIPS_R6); 11840 if (sel != 0) { 11841 /* 11842 * Performance counter registers are not implemented other than 11843 * control register 0. 11844 */ 11845 generate_exception(ctx, EXCP_RI); 11846 } 11847 gen_helper_rdhwr_performance(t0, cpu_env); 11848 gen_store_gpr(t0, rt); 11849 break; 11850 case 5: 11851 check_insn(ctx, ISA_MIPS_R6); 11852 gen_helper_rdhwr_xnp(t0, cpu_env); 11853 gen_store_gpr(t0, rt); 11854 break; 11855 case 29: 11856 #if defined(CONFIG_USER_ONLY) 11857 tcg_gen_ld_tl(t0, cpu_env, 11858 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 11859 gen_store_gpr(t0, rt); 11860 break; 11861 #else 11862 if ((ctx->hflags & MIPS_HFLAG_CP0) || 11863 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) { 11864 tcg_gen_ld_tl(t0, cpu_env, 11865 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 11866 gen_store_gpr(t0, rt); 11867 } else { 11868 gen_reserved_instruction(ctx); 11869 } 11870 break; 11871 #endif 11872 default: /* Invalid */ 11873 MIPS_INVAL("rdhwr"); 11874 gen_reserved_instruction(ctx); 11875 break; 11876 } 11877 tcg_temp_free(t0); 11878 } 11879 11880 static inline void clear_branch_hflags(DisasContext *ctx) 11881 { 11882 ctx->hflags &= ~MIPS_HFLAG_BMASK; 11883 if (ctx->base.is_jmp == DISAS_NEXT) { 11884 save_cpu_state(ctx, 0); 11885 } else { 11886 /* 11887 * It is not safe to save ctx->hflags as hflags may be changed 11888 * in execution time by the instruction in delay / forbidden slot. 11889 */ 11890 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK); 11891 } 11892 } 11893 11894 static void gen_branch(DisasContext *ctx, int insn_bytes) 11895 { 11896 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11897 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK; 11898 /* Branches completion */ 11899 clear_branch_hflags(ctx); 11900 ctx->base.is_jmp = DISAS_NORETURN; 11901 /* FIXME: Need to clear can_do_io. */ 11902 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) { 11903 case MIPS_HFLAG_FBNSLOT: 11904 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes); 11905 break; 11906 case MIPS_HFLAG_B: 11907 /* unconditional branch */ 11908 if (proc_hflags & MIPS_HFLAG_BX) { 11909 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16); 11910 } 11911 gen_goto_tb(ctx, 0, ctx->btarget); 11912 break; 11913 case MIPS_HFLAG_BL: 11914 /* blikely taken case */ 11915 gen_goto_tb(ctx, 0, ctx->btarget); 11916 break; 11917 case MIPS_HFLAG_BC: 11918 /* Conditional branch */ 11919 { 11920 TCGLabel *l1 = gen_new_label(); 11921 11922 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 11923 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); 11924 gen_set_label(l1); 11925 gen_goto_tb(ctx, 0, ctx->btarget); 11926 } 11927 break; 11928 case MIPS_HFLAG_BR: 11929 /* unconditional branch to register */ 11930 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) { 11931 TCGv t0 = tcg_temp_new(); 11932 TCGv_i32 t1 = tcg_temp_new_i32(); 11933 11934 tcg_gen_andi_tl(t0, btarget, 0x1); 11935 tcg_gen_trunc_tl_i32(t1, t0); 11936 tcg_temp_free(t0); 11937 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16); 11938 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT); 11939 tcg_gen_or_i32(hflags, hflags, t1); 11940 tcg_temp_free_i32(t1); 11941 11942 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1); 11943 } else { 11944 tcg_gen_mov_tl(cpu_PC, btarget); 11945 } 11946 if (ctx->base.singlestep_enabled) { 11947 save_cpu_state(ctx, 0); 11948 gen_helper_raise_exception_debug(cpu_env); 11949 } 11950 tcg_gen_lookup_and_goto_ptr(); 11951 break; 11952 default: 11953 LOG_DISAS("unknown branch 0x%x\n", proc_hflags); 11954 gen_reserved_instruction(ctx); 11955 } 11956 } 11957 } 11958 11959 /* Compact Branches */ 11960 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, 11961 int rs, int rt, int32_t offset) 11962 { 11963 int bcond_compute = 0; 11964 TCGv t0 = tcg_temp_new(); 11965 TCGv t1 = tcg_temp_new(); 11966 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; 11967 11968 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11969 #ifdef MIPS_DEBUG_DISAS 11970 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx 11971 "\n", ctx->base.pc_next); 11972 #endif 11973 gen_reserved_instruction(ctx); 11974 goto out; 11975 } 11976 11977 /* Load needed operands and calculate btarget */ 11978 switch (opc) { 11979 /* compact branch */ 11980 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11981 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11982 gen_load_gpr(t0, rs); 11983 gen_load_gpr(t1, rt); 11984 bcond_compute = 1; 11985 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11986 if (rs <= rt && rs == 0) { 11987 /* OPC_BEQZALC, OPC_BNEZALC */ 11988 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11989 } 11990 break; 11991 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11992 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11993 gen_load_gpr(t0, rs); 11994 gen_load_gpr(t1, rt); 11995 bcond_compute = 1; 11996 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11997 break; 11998 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11999 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 12000 if (rs == 0 || rs == rt) { 12001 /* OPC_BLEZALC, OPC_BGEZALC */ 12002 /* OPC_BGTZALC, OPC_BLTZALC */ 12003 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 12004 } 12005 gen_load_gpr(t0, rs); 12006 gen_load_gpr(t1, rt); 12007 bcond_compute = 1; 12008 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 12009 break; 12010 case OPC_BC: 12011 case OPC_BALC: 12012 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 12013 break; 12014 case OPC_BEQZC: 12015 case OPC_BNEZC: 12016 if (rs != 0) { 12017 /* OPC_BEQZC, OPC_BNEZC */ 12018 gen_load_gpr(t0, rs); 12019 bcond_compute = 1; 12020 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 12021 } else { 12022 /* OPC_JIC, OPC_JIALC */ 12023 TCGv tbase = tcg_temp_new(); 12024 TCGv toffset = tcg_temp_new(); 12025 12026 gen_load_gpr(tbase, rt); 12027 tcg_gen_movi_tl(toffset, offset); 12028 gen_op_addr_add(ctx, btarget, tbase, toffset); 12029 tcg_temp_free(tbase); 12030 tcg_temp_free(toffset); 12031 } 12032 break; 12033 default: 12034 MIPS_INVAL("Compact branch/jump"); 12035 gen_reserved_instruction(ctx); 12036 goto out; 12037 } 12038 12039 if (bcond_compute == 0) { 12040 /* Unconditional compact branch */ 12041 switch (opc) { 12042 case OPC_JIALC: 12043 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 12044 /* Fallthrough */ 12045 case OPC_JIC: 12046 ctx->hflags |= MIPS_HFLAG_BR; 12047 break; 12048 case OPC_BALC: 12049 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 12050 /* Fallthrough */ 12051 case OPC_BC: 12052 ctx->hflags |= MIPS_HFLAG_B; 12053 break; 12054 default: 12055 MIPS_INVAL("Compact branch/jump"); 12056 gen_reserved_instruction(ctx); 12057 goto out; 12058 } 12059 12060 /* Generating branch here as compact branches don't have delay slot */ 12061 gen_branch(ctx, 4); 12062 } else { 12063 /* Conditional compact branch */ 12064 TCGLabel *fs = gen_new_label(); 12065 save_cpu_state(ctx, 0); 12066 12067 switch (opc) { 12068 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 12069 if (rs == 0 && rt != 0) { 12070 /* OPC_BLEZALC */ 12071 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 12072 } else if (rs != 0 && rt != 0 && rs == rt) { 12073 /* OPC_BGEZALC */ 12074 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 12075 } else { 12076 /* OPC_BGEUC */ 12077 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 12078 } 12079 break; 12080 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 12081 if (rs == 0 && rt != 0) { 12082 /* OPC_BGTZALC */ 12083 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 12084 } else if (rs != 0 && rt != 0 && rs == rt) { 12085 /* OPC_BLTZALC */ 12086 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 12087 } else { 12088 /* OPC_BLTUC */ 12089 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 12090 } 12091 break; 12092 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 12093 if (rs == 0 && rt != 0) { 12094 /* OPC_BLEZC */ 12095 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 12096 } else if (rs != 0 && rt != 0 && rs == rt) { 12097 /* OPC_BGEZC */ 12098 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 12099 } else { 12100 /* OPC_BGEC */ 12101 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 12102 } 12103 break; 12104 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 12105 if (rs == 0 && rt != 0) { 12106 /* OPC_BGTZC */ 12107 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 12108 } else if (rs != 0 && rt != 0 && rs == rt) { 12109 /* OPC_BLTZC */ 12110 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 12111 } else { 12112 /* OPC_BLTC */ 12113 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 12114 } 12115 break; 12116 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 12117 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 12118 if (rs >= rt) { 12119 /* OPC_BOVC, OPC_BNVC */ 12120 TCGv t2 = tcg_temp_new(); 12121 TCGv t3 = tcg_temp_new(); 12122 TCGv t4 = tcg_temp_new(); 12123 TCGv input_overflow = tcg_temp_new(); 12124 12125 gen_load_gpr(t0, rs); 12126 gen_load_gpr(t1, rt); 12127 tcg_gen_ext32s_tl(t2, t0); 12128 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0); 12129 tcg_gen_ext32s_tl(t3, t1); 12130 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1); 12131 tcg_gen_or_tl(input_overflow, input_overflow, t4); 12132 12133 tcg_gen_add_tl(t4, t2, t3); 12134 tcg_gen_ext32s_tl(t4, t4); 12135 tcg_gen_xor_tl(t2, t2, t3); 12136 tcg_gen_xor_tl(t3, t4, t3); 12137 tcg_gen_andc_tl(t2, t3, t2); 12138 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0); 12139 tcg_gen_or_tl(t4, t4, input_overflow); 12140 if (opc == OPC_BOVC) { 12141 /* OPC_BOVC */ 12142 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs); 12143 } else { 12144 /* OPC_BNVC */ 12145 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs); 12146 } 12147 tcg_temp_free(input_overflow); 12148 tcg_temp_free(t4); 12149 tcg_temp_free(t3); 12150 tcg_temp_free(t2); 12151 } else if (rs < rt && rs == 0) { 12152 /* OPC_BEQZALC, OPC_BNEZALC */ 12153 if (opc == OPC_BEQZALC) { 12154 /* OPC_BEQZALC */ 12155 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs); 12156 } else { 12157 /* OPC_BNEZALC */ 12158 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs); 12159 } 12160 } else { 12161 /* OPC_BEQC, OPC_BNEC */ 12162 if (opc == OPC_BEQC) { 12163 /* OPC_BEQC */ 12164 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); 12165 } else { 12166 /* OPC_BNEC */ 12167 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); 12168 } 12169 } 12170 break; 12171 case OPC_BEQZC: 12172 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 12173 break; 12174 case OPC_BNEZC: 12175 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs); 12176 break; 12177 default: 12178 MIPS_INVAL("Compact conditional branch/jump"); 12179 gen_reserved_instruction(ctx); 12180 goto out; 12181 } 12182 12183 /* Generating branch here as compact branches don't have delay slot */ 12184 gen_goto_tb(ctx, 1, ctx->btarget); 12185 gen_set_label(fs); 12186 12187 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 12188 } 12189 12190 out: 12191 tcg_temp_free(t0); 12192 tcg_temp_free(t1); 12193 } 12194 12195 void gen_addiupc(DisasContext *ctx, int rx, int imm, 12196 int is_64_bit, int extended) 12197 { 12198 TCGv t0; 12199 12200 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { 12201 gen_reserved_instruction(ctx); 12202 return; 12203 } 12204 12205 t0 = tcg_temp_new(); 12206 12207 tcg_gen_movi_tl(t0, pc_relative_pc(ctx)); 12208 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm); 12209 if (!is_64_bit) { 12210 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); 12211 } 12212 12213 tcg_temp_free(t0); 12214 } 12215 12216 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, 12217 int16_t offset) 12218 { 12219 TCGv_i32 t0 = tcg_const_i32(op); 12220 TCGv t1 = tcg_temp_new(); 12221 gen_base_offset_addr(ctx, t1, base, offset); 12222 gen_helper_cache(cpu_env, t1, t0); 12223 tcg_temp_free(t1); 12224 tcg_temp_free_i32(t0); 12225 } 12226 12227 static inline bool is_uhi(int sdbbp_code) 12228 { 12229 #ifdef CONFIG_USER_ONLY 12230 return false; 12231 #else 12232 return semihosting_enabled() && sdbbp_code == 1; 12233 #endif 12234 } 12235 12236 #ifdef CONFIG_USER_ONLY 12237 /* The above should dead-code away any calls to this..*/ 12238 static inline void gen_helper_do_semihosting(void *env) 12239 { 12240 g_assert_not_reached(); 12241 } 12242 #endif 12243 12244 void gen_ldxs(DisasContext *ctx, int base, int index, int rd) 12245 { 12246 TCGv t0 = tcg_temp_new(); 12247 TCGv t1 = tcg_temp_new(); 12248 12249 gen_load_gpr(t0, base); 12250 12251 if (index != 0) { 12252 gen_load_gpr(t1, index); 12253 tcg_gen_shli_tl(t1, t1, 2); 12254 gen_op_addr_add(ctx, t0, t1, t0); 12255 } 12256 12257 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); 12258 gen_store_gpr(t1, rd); 12259 12260 tcg_temp_free(t0); 12261 tcg_temp_free(t1); 12262 } 12263 12264 static void gen_sync(int stype) 12265 { 12266 TCGBar tcg_mo = TCG_BAR_SC; 12267 12268 switch (stype) { 12269 case 0x4: /* SYNC_WMB */ 12270 tcg_mo |= TCG_MO_ST_ST; 12271 break; 12272 case 0x10: /* SYNC_MB */ 12273 tcg_mo |= TCG_MO_ALL; 12274 break; 12275 case 0x11: /* SYNC_ACQUIRE */ 12276 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; 12277 break; 12278 case 0x12: /* SYNC_RELEASE */ 12279 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; 12280 break; 12281 case 0x13: /* SYNC_RMB */ 12282 tcg_mo |= TCG_MO_LD_LD; 12283 break; 12284 default: 12285 tcg_mo |= TCG_MO_ALL; 12286 break; 12287 } 12288 12289 tcg_gen_mb(tcg_mo); 12290 } 12291 12292 /* ISA extensions (ASEs) */ 12293 12294 /* MIPS16 extension to MIPS32 */ 12295 #include "mips16e_translate.c.inc" 12296 12297 /* microMIPS extension to MIPS32/MIPS64 */ 12298 12299 /* 12300 * Values for microMIPS fmt field. Variable-width, depending on which 12301 * formats the instruction supports. 12302 */ 12303 enum { 12304 FMT_SD_S = 0, 12305 FMT_SD_D = 1, 12306 12307 FMT_SDPS_S = 0, 12308 FMT_SDPS_D = 1, 12309 FMT_SDPS_PS = 2, 12310 12311 FMT_SWL_S = 0, 12312 FMT_SWL_W = 1, 12313 FMT_SWL_L = 2, 12314 12315 FMT_DWL_D = 0, 12316 FMT_DWL_W = 1, 12317 FMT_DWL_L = 2 12318 }; 12319 12320 #include "micromips_translate.c.inc" 12321 12322 #include "nanomips_translate.c.inc" 12323 12324 /* MIPSDSP functions. */ 12325 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc, 12326 int rd, int base, int offset) 12327 { 12328 TCGv t0; 12329 12330 check_dsp(ctx); 12331 t0 = tcg_temp_new(); 12332 12333 if (base == 0) { 12334 gen_load_gpr(t0, offset); 12335 } else if (offset == 0) { 12336 gen_load_gpr(t0, base); 12337 } else { 12338 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]); 12339 } 12340 12341 switch (opc) { 12342 case OPC_LBUX: 12343 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB); 12344 gen_store_gpr(t0, rd); 12345 break; 12346 case OPC_LHX: 12347 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW); 12348 gen_store_gpr(t0, rd); 12349 break; 12350 case OPC_LWX: 12351 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); 12352 gen_store_gpr(t0, rd); 12353 break; 12354 #if defined(TARGET_MIPS64) 12355 case OPC_LDX: 12356 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); 12357 gen_store_gpr(t0, rd); 12358 break; 12359 #endif 12360 } 12361 tcg_temp_free(t0); 12362 } 12363 12364 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2, 12365 int ret, int v1, int v2) 12366 { 12367 TCGv v1_t; 12368 TCGv v2_t; 12369 12370 if (ret == 0) { 12371 /* Treat as NOP. */ 12372 return; 12373 } 12374 12375 v1_t = tcg_temp_new(); 12376 v2_t = tcg_temp_new(); 12377 12378 gen_load_gpr(v1_t, v1); 12379 gen_load_gpr(v2_t, v2); 12380 12381 switch (op1) { 12382 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */ 12383 case OPC_MULT_G_2E: 12384 check_dsp_r2(ctx); 12385 switch (op2) { 12386 case OPC_ADDUH_QB: 12387 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); 12388 break; 12389 case OPC_ADDUH_R_QB: 12390 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); 12391 break; 12392 case OPC_ADDQH_PH: 12393 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); 12394 break; 12395 case OPC_ADDQH_R_PH: 12396 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 12397 break; 12398 case OPC_ADDQH_W: 12399 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); 12400 break; 12401 case OPC_ADDQH_R_W: 12402 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); 12403 break; 12404 case OPC_SUBUH_QB: 12405 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); 12406 break; 12407 case OPC_SUBUH_R_QB: 12408 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); 12409 break; 12410 case OPC_SUBQH_PH: 12411 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); 12412 break; 12413 case OPC_SUBQH_R_PH: 12414 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 12415 break; 12416 case OPC_SUBQH_W: 12417 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); 12418 break; 12419 case OPC_SUBQH_R_W: 12420 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); 12421 break; 12422 } 12423 break; 12424 case OPC_ABSQ_S_PH_DSP: 12425 switch (op2) { 12426 case OPC_ABSQ_S_QB: 12427 check_dsp_r2(ctx); 12428 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env); 12429 break; 12430 case OPC_ABSQ_S_PH: 12431 check_dsp(ctx); 12432 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env); 12433 break; 12434 case OPC_ABSQ_S_W: 12435 check_dsp(ctx); 12436 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env); 12437 break; 12438 case OPC_PRECEQ_W_PHL: 12439 check_dsp(ctx); 12440 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); 12441 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12442 break; 12443 case OPC_PRECEQ_W_PHR: 12444 check_dsp(ctx); 12445 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); 12446 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); 12447 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12448 break; 12449 case OPC_PRECEQU_PH_QBL: 12450 check_dsp(ctx); 12451 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); 12452 break; 12453 case OPC_PRECEQU_PH_QBR: 12454 check_dsp(ctx); 12455 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); 12456 break; 12457 case OPC_PRECEQU_PH_QBLA: 12458 check_dsp(ctx); 12459 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); 12460 break; 12461 case OPC_PRECEQU_PH_QBRA: 12462 check_dsp(ctx); 12463 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); 12464 break; 12465 case OPC_PRECEU_PH_QBL: 12466 check_dsp(ctx); 12467 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); 12468 break; 12469 case OPC_PRECEU_PH_QBR: 12470 check_dsp(ctx); 12471 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); 12472 break; 12473 case OPC_PRECEU_PH_QBLA: 12474 check_dsp(ctx); 12475 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); 12476 break; 12477 case OPC_PRECEU_PH_QBRA: 12478 check_dsp(ctx); 12479 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); 12480 break; 12481 } 12482 break; 12483 case OPC_ADDU_QB_DSP: 12484 switch (op2) { 12485 case OPC_ADDQ_PH: 12486 check_dsp(ctx); 12487 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12488 break; 12489 case OPC_ADDQ_S_PH: 12490 check_dsp(ctx); 12491 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12492 break; 12493 case OPC_ADDQ_S_W: 12494 check_dsp(ctx); 12495 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12496 break; 12497 case OPC_ADDU_QB: 12498 check_dsp(ctx); 12499 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12500 break; 12501 case OPC_ADDU_S_QB: 12502 check_dsp(ctx); 12503 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12504 break; 12505 case OPC_ADDU_PH: 12506 check_dsp_r2(ctx); 12507 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12508 break; 12509 case OPC_ADDU_S_PH: 12510 check_dsp_r2(ctx); 12511 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12512 break; 12513 case OPC_SUBQ_PH: 12514 check_dsp(ctx); 12515 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12516 break; 12517 case OPC_SUBQ_S_PH: 12518 check_dsp(ctx); 12519 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12520 break; 12521 case OPC_SUBQ_S_W: 12522 check_dsp(ctx); 12523 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12524 break; 12525 case OPC_SUBU_QB: 12526 check_dsp(ctx); 12527 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12528 break; 12529 case OPC_SUBU_S_QB: 12530 check_dsp(ctx); 12531 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12532 break; 12533 case OPC_SUBU_PH: 12534 check_dsp_r2(ctx); 12535 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12536 break; 12537 case OPC_SUBU_S_PH: 12538 check_dsp_r2(ctx); 12539 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12540 break; 12541 case OPC_ADDSC: 12542 check_dsp(ctx); 12543 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12544 break; 12545 case OPC_ADDWC: 12546 check_dsp(ctx); 12547 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12548 break; 12549 case OPC_MODSUB: 12550 check_dsp(ctx); 12551 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); 12552 break; 12553 case OPC_RADDU_W_QB: 12554 check_dsp(ctx); 12555 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); 12556 break; 12557 } 12558 break; 12559 case OPC_CMPU_EQ_QB_DSP: 12560 switch (op2) { 12561 case OPC_PRECR_QB_PH: 12562 check_dsp_r2(ctx); 12563 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); 12564 break; 12565 case OPC_PRECRQ_QB_PH: 12566 check_dsp(ctx); 12567 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); 12568 break; 12569 case OPC_PRECR_SRA_PH_W: 12570 check_dsp_r2(ctx); 12571 { 12572 TCGv_i32 sa_t = tcg_const_i32(v2); 12573 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, 12574 cpu_gpr[ret]); 12575 tcg_temp_free_i32(sa_t); 12576 break; 12577 } 12578 case OPC_PRECR_SRA_R_PH_W: 12579 check_dsp_r2(ctx); 12580 { 12581 TCGv_i32 sa_t = tcg_const_i32(v2); 12582 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, 12583 cpu_gpr[ret]); 12584 tcg_temp_free_i32(sa_t); 12585 break; 12586 } 12587 case OPC_PRECRQ_PH_W: 12588 check_dsp(ctx); 12589 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); 12590 break; 12591 case OPC_PRECRQ_RS_PH_W: 12592 check_dsp(ctx); 12593 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12594 break; 12595 case OPC_PRECRQU_S_QB_PH: 12596 check_dsp(ctx); 12597 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12598 break; 12599 } 12600 break; 12601 #ifdef TARGET_MIPS64 12602 case OPC_ABSQ_S_QH_DSP: 12603 switch (op2) { 12604 case OPC_PRECEQ_L_PWL: 12605 check_dsp(ctx); 12606 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); 12607 break; 12608 case OPC_PRECEQ_L_PWR: 12609 check_dsp(ctx); 12610 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); 12611 break; 12612 case OPC_PRECEQ_PW_QHL: 12613 check_dsp(ctx); 12614 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); 12615 break; 12616 case OPC_PRECEQ_PW_QHR: 12617 check_dsp(ctx); 12618 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); 12619 break; 12620 case OPC_PRECEQ_PW_QHLA: 12621 check_dsp(ctx); 12622 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); 12623 break; 12624 case OPC_PRECEQ_PW_QHRA: 12625 check_dsp(ctx); 12626 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); 12627 break; 12628 case OPC_PRECEQU_QH_OBL: 12629 check_dsp(ctx); 12630 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); 12631 break; 12632 case OPC_PRECEQU_QH_OBR: 12633 check_dsp(ctx); 12634 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); 12635 break; 12636 case OPC_PRECEQU_QH_OBLA: 12637 check_dsp(ctx); 12638 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); 12639 break; 12640 case OPC_PRECEQU_QH_OBRA: 12641 check_dsp(ctx); 12642 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); 12643 break; 12644 case OPC_PRECEU_QH_OBL: 12645 check_dsp(ctx); 12646 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); 12647 break; 12648 case OPC_PRECEU_QH_OBR: 12649 check_dsp(ctx); 12650 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); 12651 break; 12652 case OPC_PRECEU_QH_OBLA: 12653 check_dsp(ctx); 12654 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); 12655 break; 12656 case OPC_PRECEU_QH_OBRA: 12657 check_dsp(ctx); 12658 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); 12659 break; 12660 case OPC_ABSQ_S_OB: 12661 check_dsp_r2(ctx); 12662 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env); 12663 break; 12664 case OPC_ABSQ_S_PW: 12665 check_dsp(ctx); 12666 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env); 12667 break; 12668 case OPC_ABSQ_S_QH: 12669 check_dsp(ctx); 12670 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env); 12671 break; 12672 } 12673 break; 12674 case OPC_ADDU_OB_DSP: 12675 switch (op2) { 12676 case OPC_RADDU_L_OB: 12677 check_dsp(ctx); 12678 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); 12679 break; 12680 case OPC_SUBQ_PW: 12681 check_dsp(ctx); 12682 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12683 break; 12684 case OPC_SUBQ_S_PW: 12685 check_dsp(ctx); 12686 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12687 break; 12688 case OPC_SUBQ_QH: 12689 check_dsp(ctx); 12690 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12691 break; 12692 case OPC_SUBQ_S_QH: 12693 check_dsp(ctx); 12694 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12695 break; 12696 case OPC_SUBU_OB: 12697 check_dsp(ctx); 12698 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12699 break; 12700 case OPC_SUBU_S_OB: 12701 check_dsp(ctx); 12702 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12703 break; 12704 case OPC_SUBU_QH: 12705 check_dsp_r2(ctx); 12706 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12707 break; 12708 case OPC_SUBU_S_QH: 12709 check_dsp_r2(ctx); 12710 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12711 break; 12712 case OPC_SUBUH_OB: 12713 check_dsp_r2(ctx); 12714 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); 12715 break; 12716 case OPC_SUBUH_R_OB: 12717 check_dsp_r2(ctx); 12718 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); 12719 break; 12720 case OPC_ADDQ_PW: 12721 check_dsp(ctx); 12722 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12723 break; 12724 case OPC_ADDQ_S_PW: 12725 check_dsp(ctx); 12726 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12727 break; 12728 case OPC_ADDQ_QH: 12729 check_dsp(ctx); 12730 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12731 break; 12732 case OPC_ADDQ_S_QH: 12733 check_dsp(ctx); 12734 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12735 break; 12736 case OPC_ADDU_OB: 12737 check_dsp(ctx); 12738 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12739 break; 12740 case OPC_ADDU_S_OB: 12741 check_dsp(ctx); 12742 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12743 break; 12744 case OPC_ADDU_QH: 12745 check_dsp_r2(ctx); 12746 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12747 break; 12748 case OPC_ADDU_S_QH: 12749 check_dsp_r2(ctx); 12750 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12751 break; 12752 case OPC_ADDUH_OB: 12753 check_dsp_r2(ctx); 12754 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); 12755 break; 12756 case OPC_ADDUH_R_OB: 12757 check_dsp_r2(ctx); 12758 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); 12759 break; 12760 } 12761 break; 12762 case OPC_CMPU_EQ_OB_DSP: 12763 switch (op2) { 12764 case OPC_PRECR_OB_QH: 12765 check_dsp_r2(ctx); 12766 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); 12767 break; 12768 case OPC_PRECR_SRA_QH_PW: 12769 check_dsp_r2(ctx); 12770 { 12771 TCGv_i32 ret_t = tcg_const_i32(ret); 12772 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); 12773 tcg_temp_free_i32(ret_t); 12774 break; 12775 } 12776 case OPC_PRECR_SRA_R_QH_PW: 12777 check_dsp_r2(ctx); 12778 { 12779 TCGv_i32 sa_v = tcg_const_i32(ret); 12780 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); 12781 tcg_temp_free_i32(sa_v); 12782 break; 12783 } 12784 case OPC_PRECRQ_OB_QH: 12785 check_dsp(ctx); 12786 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); 12787 break; 12788 case OPC_PRECRQ_PW_L: 12789 check_dsp(ctx); 12790 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); 12791 break; 12792 case OPC_PRECRQ_QH_PW: 12793 check_dsp(ctx); 12794 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); 12795 break; 12796 case OPC_PRECRQ_RS_QH_PW: 12797 check_dsp(ctx); 12798 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12799 break; 12800 case OPC_PRECRQU_S_OB_QH: 12801 check_dsp(ctx); 12802 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12803 break; 12804 } 12805 break; 12806 #endif 12807 } 12808 12809 tcg_temp_free(v1_t); 12810 tcg_temp_free(v2_t); 12811 } 12812 12813 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, 12814 int ret, int v1, int v2) 12815 { 12816 uint32_t op2; 12817 TCGv t0; 12818 TCGv v1_t; 12819 TCGv v2_t; 12820 12821 if (ret == 0) { 12822 /* Treat as NOP. */ 12823 return; 12824 } 12825 12826 t0 = tcg_temp_new(); 12827 v1_t = tcg_temp_new(); 12828 v2_t = tcg_temp_new(); 12829 12830 tcg_gen_movi_tl(t0, v1); 12831 gen_load_gpr(v1_t, v1); 12832 gen_load_gpr(v2_t, v2); 12833 12834 switch (opc) { 12835 case OPC_SHLL_QB_DSP: 12836 { 12837 op2 = MASK_SHLL_QB(ctx->opcode); 12838 switch (op2) { 12839 case OPC_SHLL_QB: 12840 check_dsp(ctx); 12841 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env); 12842 break; 12843 case OPC_SHLLV_QB: 12844 check_dsp(ctx); 12845 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12846 break; 12847 case OPC_SHLL_PH: 12848 check_dsp(ctx); 12849 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env); 12850 break; 12851 case OPC_SHLLV_PH: 12852 check_dsp(ctx); 12853 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12854 break; 12855 case OPC_SHLL_S_PH: 12856 check_dsp(ctx); 12857 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env); 12858 break; 12859 case OPC_SHLLV_S_PH: 12860 check_dsp(ctx); 12861 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12862 break; 12863 case OPC_SHLL_S_W: 12864 check_dsp(ctx); 12865 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env); 12866 break; 12867 case OPC_SHLLV_S_W: 12868 check_dsp(ctx); 12869 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12870 break; 12871 case OPC_SHRL_QB: 12872 check_dsp(ctx); 12873 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); 12874 break; 12875 case OPC_SHRLV_QB: 12876 check_dsp(ctx); 12877 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); 12878 break; 12879 case OPC_SHRL_PH: 12880 check_dsp_r2(ctx); 12881 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); 12882 break; 12883 case OPC_SHRLV_PH: 12884 check_dsp_r2(ctx); 12885 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); 12886 break; 12887 case OPC_SHRA_QB: 12888 check_dsp_r2(ctx); 12889 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); 12890 break; 12891 case OPC_SHRA_R_QB: 12892 check_dsp_r2(ctx); 12893 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); 12894 break; 12895 case OPC_SHRAV_QB: 12896 check_dsp_r2(ctx); 12897 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); 12898 break; 12899 case OPC_SHRAV_R_QB: 12900 check_dsp_r2(ctx); 12901 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); 12902 break; 12903 case OPC_SHRA_PH: 12904 check_dsp(ctx); 12905 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); 12906 break; 12907 case OPC_SHRA_R_PH: 12908 check_dsp(ctx); 12909 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); 12910 break; 12911 case OPC_SHRAV_PH: 12912 check_dsp(ctx); 12913 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); 12914 break; 12915 case OPC_SHRAV_R_PH: 12916 check_dsp(ctx); 12917 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); 12918 break; 12919 case OPC_SHRA_R_W: 12920 check_dsp(ctx); 12921 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); 12922 break; 12923 case OPC_SHRAV_R_W: 12924 check_dsp(ctx); 12925 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); 12926 break; 12927 default: /* Invalid */ 12928 MIPS_INVAL("MASK SHLL.QB"); 12929 gen_reserved_instruction(ctx); 12930 break; 12931 } 12932 break; 12933 } 12934 #ifdef TARGET_MIPS64 12935 case OPC_SHLL_OB_DSP: 12936 op2 = MASK_SHLL_OB(ctx->opcode); 12937 switch (op2) { 12938 case OPC_SHLL_PW: 12939 check_dsp(ctx); 12940 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env); 12941 break; 12942 case OPC_SHLLV_PW: 12943 check_dsp(ctx); 12944 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12945 break; 12946 case OPC_SHLL_S_PW: 12947 check_dsp(ctx); 12948 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env); 12949 break; 12950 case OPC_SHLLV_S_PW: 12951 check_dsp(ctx); 12952 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12953 break; 12954 case OPC_SHLL_OB: 12955 check_dsp(ctx); 12956 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env); 12957 break; 12958 case OPC_SHLLV_OB: 12959 check_dsp(ctx); 12960 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12961 break; 12962 case OPC_SHLL_QH: 12963 check_dsp(ctx); 12964 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env); 12965 break; 12966 case OPC_SHLLV_QH: 12967 check_dsp(ctx); 12968 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12969 break; 12970 case OPC_SHLL_S_QH: 12971 check_dsp(ctx); 12972 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env); 12973 break; 12974 case OPC_SHLLV_S_QH: 12975 check_dsp(ctx); 12976 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12977 break; 12978 case OPC_SHRA_OB: 12979 check_dsp_r2(ctx); 12980 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); 12981 break; 12982 case OPC_SHRAV_OB: 12983 check_dsp_r2(ctx); 12984 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); 12985 break; 12986 case OPC_SHRA_R_OB: 12987 check_dsp_r2(ctx); 12988 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); 12989 break; 12990 case OPC_SHRAV_R_OB: 12991 check_dsp_r2(ctx); 12992 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); 12993 break; 12994 case OPC_SHRA_PW: 12995 check_dsp(ctx); 12996 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); 12997 break; 12998 case OPC_SHRAV_PW: 12999 check_dsp(ctx); 13000 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); 13001 break; 13002 case OPC_SHRA_R_PW: 13003 check_dsp(ctx); 13004 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); 13005 break; 13006 case OPC_SHRAV_R_PW: 13007 check_dsp(ctx); 13008 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); 13009 break; 13010 case OPC_SHRA_QH: 13011 check_dsp(ctx); 13012 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); 13013 break; 13014 case OPC_SHRAV_QH: 13015 check_dsp(ctx); 13016 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); 13017 break; 13018 case OPC_SHRA_R_QH: 13019 check_dsp(ctx); 13020 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); 13021 break; 13022 case OPC_SHRAV_R_QH: 13023 check_dsp(ctx); 13024 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); 13025 break; 13026 case OPC_SHRL_OB: 13027 check_dsp(ctx); 13028 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); 13029 break; 13030 case OPC_SHRLV_OB: 13031 check_dsp(ctx); 13032 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); 13033 break; 13034 case OPC_SHRL_QH: 13035 check_dsp_r2(ctx); 13036 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); 13037 break; 13038 case OPC_SHRLV_QH: 13039 check_dsp_r2(ctx); 13040 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); 13041 break; 13042 default: /* Invalid */ 13043 MIPS_INVAL("MASK SHLL.OB"); 13044 gen_reserved_instruction(ctx); 13045 break; 13046 } 13047 break; 13048 #endif 13049 } 13050 13051 tcg_temp_free(t0); 13052 tcg_temp_free(v1_t); 13053 tcg_temp_free(v2_t); 13054 } 13055 13056 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2, 13057 int ret, int v1, int v2, int check_ret) 13058 { 13059 TCGv_i32 t0; 13060 TCGv v1_t; 13061 TCGv v2_t; 13062 13063 if ((ret == 0) && (check_ret == 1)) { 13064 /* Treat as NOP. */ 13065 return; 13066 } 13067 13068 t0 = tcg_temp_new_i32(); 13069 v1_t = tcg_temp_new(); 13070 v2_t = tcg_temp_new(); 13071 13072 tcg_gen_movi_i32(t0, ret); 13073 gen_load_gpr(v1_t, v1); 13074 gen_load_gpr(v2_t, v2); 13075 13076 switch (op1) { 13077 /* 13078 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 13079 * the same mask and op1. 13080 */ 13081 case OPC_MULT_G_2E: 13082 check_dsp_r2(ctx); 13083 switch (op2) { 13084 case OPC_MUL_PH: 13085 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13086 break; 13087 case OPC_MUL_S_PH: 13088 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13089 break; 13090 case OPC_MULQ_S_W: 13091 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13092 break; 13093 case OPC_MULQ_RS_W: 13094 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13095 break; 13096 } 13097 break; 13098 case OPC_DPA_W_PH_DSP: 13099 switch (op2) { 13100 case OPC_DPAU_H_QBL: 13101 check_dsp(ctx); 13102 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env); 13103 break; 13104 case OPC_DPAU_H_QBR: 13105 check_dsp(ctx); 13106 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env); 13107 break; 13108 case OPC_DPSU_H_QBL: 13109 check_dsp(ctx); 13110 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env); 13111 break; 13112 case OPC_DPSU_H_QBR: 13113 check_dsp(ctx); 13114 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env); 13115 break; 13116 case OPC_DPA_W_PH: 13117 check_dsp_r2(ctx); 13118 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env); 13119 break; 13120 case OPC_DPAX_W_PH: 13121 check_dsp_r2(ctx); 13122 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env); 13123 break; 13124 case OPC_DPAQ_S_W_PH: 13125 check_dsp(ctx); 13126 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env); 13127 break; 13128 case OPC_DPAQX_S_W_PH: 13129 check_dsp_r2(ctx); 13130 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env); 13131 break; 13132 case OPC_DPAQX_SA_W_PH: 13133 check_dsp_r2(ctx); 13134 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); 13135 break; 13136 case OPC_DPS_W_PH: 13137 check_dsp_r2(ctx); 13138 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env); 13139 break; 13140 case OPC_DPSX_W_PH: 13141 check_dsp_r2(ctx); 13142 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env); 13143 break; 13144 case OPC_DPSQ_S_W_PH: 13145 check_dsp(ctx); 13146 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env); 13147 break; 13148 case OPC_DPSQX_S_W_PH: 13149 check_dsp_r2(ctx); 13150 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env); 13151 break; 13152 case OPC_DPSQX_SA_W_PH: 13153 check_dsp_r2(ctx); 13154 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); 13155 break; 13156 case OPC_MULSAQ_S_W_PH: 13157 check_dsp(ctx); 13158 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env); 13159 break; 13160 case OPC_DPAQ_SA_L_W: 13161 check_dsp(ctx); 13162 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env); 13163 break; 13164 case OPC_DPSQ_SA_L_W: 13165 check_dsp(ctx); 13166 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env); 13167 break; 13168 case OPC_MAQ_S_W_PHL: 13169 check_dsp(ctx); 13170 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env); 13171 break; 13172 case OPC_MAQ_S_W_PHR: 13173 check_dsp(ctx); 13174 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env); 13175 break; 13176 case OPC_MAQ_SA_W_PHL: 13177 check_dsp(ctx); 13178 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env); 13179 break; 13180 case OPC_MAQ_SA_W_PHR: 13181 check_dsp(ctx); 13182 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env); 13183 break; 13184 case OPC_MULSA_W_PH: 13185 check_dsp_r2(ctx); 13186 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env); 13187 break; 13188 } 13189 break; 13190 #ifdef TARGET_MIPS64 13191 case OPC_DPAQ_W_QH_DSP: 13192 { 13193 int ac = ret & 0x03; 13194 tcg_gen_movi_i32(t0, ac); 13195 13196 switch (op2) { 13197 case OPC_DMADD: 13198 check_dsp(ctx); 13199 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env); 13200 break; 13201 case OPC_DMADDU: 13202 check_dsp(ctx); 13203 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env); 13204 break; 13205 case OPC_DMSUB: 13206 check_dsp(ctx); 13207 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env); 13208 break; 13209 case OPC_DMSUBU: 13210 check_dsp(ctx); 13211 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env); 13212 break; 13213 case OPC_DPA_W_QH: 13214 check_dsp_r2(ctx); 13215 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env); 13216 break; 13217 case OPC_DPAQ_S_W_QH: 13218 check_dsp(ctx); 13219 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13220 break; 13221 case OPC_DPAQ_SA_L_PW: 13222 check_dsp(ctx); 13223 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env); 13224 break; 13225 case OPC_DPAU_H_OBL: 13226 check_dsp(ctx); 13227 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env); 13228 break; 13229 case OPC_DPAU_H_OBR: 13230 check_dsp(ctx); 13231 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env); 13232 break; 13233 case OPC_DPS_W_QH: 13234 check_dsp_r2(ctx); 13235 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env); 13236 break; 13237 case OPC_DPSQ_S_W_QH: 13238 check_dsp(ctx); 13239 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13240 break; 13241 case OPC_DPSQ_SA_L_PW: 13242 check_dsp(ctx); 13243 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env); 13244 break; 13245 case OPC_DPSU_H_OBL: 13246 check_dsp(ctx); 13247 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env); 13248 break; 13249 case OPC_DPSU_H_OBR: 13250 check_dsp(ctx); 13251 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env); 13252 break; 13253 case OPC_MAQ_S_L_PWL: 13254 check_dsp(ctx); 13255 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env); 13256 break; 13257 case OPC_MAQ_S_L_PWR: 13258 check_dsp(ctx); 13259 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env); 13260 break; 13261 case OPC_MAQ_S_W_QHLL: 13262 check_dsp(ctx); 13263 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env); 13264 break; 13265 case OPC_MAQ_SA_W_QHLL: 13266 check_dsp(ctx); 13267 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env); 13268 break; 13269 case OPC_MAQ_S_W_QHLR: 13270 check_dsp(ctx); 13271 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env); 13272 break; 13273 case OPC_MAQ_SA_W_QHLR: 13274 check_dsp(ctx); 13275 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env); 13276 break; 13277 case OPC_MAQ_S_W_QHRL: 13278 check_dsp(ctx); 13279 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env); 13280 break; 13281 case OPC_MAQ_SA_W_QHRL: 13282 check_dsp(ctx); 13283 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env); 13284 break; 13285 case OPC_MAQ_S_W_QHRR: 13286 check_dsp(ctx); 13287 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env); 13288 break; 13289 case OPC_MAQ_SA_W_QHRR: 13290 check_dsp(ctx); 13291 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env); 13292 break; 13293 case OPC_MULSAQ_S_L_PW: 13294 check_dsp(ctx); 13295 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env); 13296 break; 13297 case OPC_MULSAQ_S_W_QH: 13298 check_dsp(ctx); 13299 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13300 break; 13301 } 13302 } 13303 break; 13304 #endif 13305 case OPC_ADDU_QB_DSP: 13306 switch (op2) { 13307 case OPC_MULEU_S_PH_QBL: 13308 check_dsp(ctx); 13309 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13310 break; 13311 case OPC_MULEU_S_PH_QBR: 13312 check_dsp(ctx); 13313 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13314 break; 13315 case OPC_MULQ_RS_PH: 13316 check_dsp(ctx); 13317 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13318 break; 13319 case OPC_MULEQ_S_W_PHL: 13320 check_dsp(ctx); 13321 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13322 break; 13323 case OPC_MULEQ_S_W_PHR: 13324 check_dsp(ctx); 13325 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13326 break; 13327 case OPC_MULQ_S_PH: 13328 check_dsp_r2(ctx); 13329 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13330 break; 13331 } 13332 break; 13333 #ifdef TARGET_MIPS64 13334 case OPC_ADDU_OB_DSP: 13335 switch (op2) { 13336 case OPC_MULEQ_S_PW_QHL: 13337 check_dsp(ctx); 13338 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13339 break; 13340 case OPC_MULEQ_S_PW_QHR: 13341 check_dsp(ctx); 13342 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13343 break; 13344 case OPC_MULEU_S_QH_OBL: 13345 check_dsp(ctx); 13346 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13347 break; 13348 case OPC_MULEU_S_QH_OBR: 13349 check_dsp(ctx); 13350 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13351 break; 13352 case OPC_MULQ_RS_QH: 13353 check_dsp(ctx); 13354 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13355 break; 13356 } 13357 break; 13358 #endif 13359 } 13360 13361 tcg_temp_free_i32(t0); 13362 tcg_temp_free(v1_t); 13363 tcg_temp_free(v2_t); 13364 } 13365 13366 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 13367 int ret, int val) 13368 { 13369 int16_t imm; 13370 TCGv t0; 13371 TCGv val_t; 13372 13373 if (ret == 0) { 13374 /* Treat as NOP. */ 13375 return; 13376 } 13377 13378 t0 = tcg_temp_new(); 13379 val_t = tcg_temp_new(); 13380 gen_load_gpr(val_t, val); 13381 13382 switch (op1) { 13383 case OPC_ABSQ_S_PH_DSP: 13384 switch (op2) { 13385 case OPC_BITREV: 13386 check_dsp(ctx); 13387 gen_helper_bitrev(cpu_gpr[ret], val_t); 13388 break; 13389 case OPC_REPL_QB: 13390 check_dsp(ctx); 13391 { 13392 target_long result; 13393 imm = (ctx->opcode >> 16) & 0xFF; 13394 result = (uint32_t)imm << 24 | 13395 (uint32_t)imm << 16 | 13396 (uint32_t)imm << 8 | 13397 (uint32_t)imm; 13398 result = (int32_t)result; 13399 tcg_gen_movi_tl(cpu_gpr[ret], result); 13400 } 13401 break; 13402 case OPC_REPLV_QB: 13403 check_dsp(ctx); 13404 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 13405 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 13406 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13407 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13408 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13409 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 13410 break; 13411 case OPC_REPL_PH: 13412 check_dsp(ctx); 13413 { 13414 imm = (ctx->opcode >> 16) & 0x03FF; 13415 imm = (int16_t)(imm << 6) >> 6; 13416 tcg_gen_movi_tl(cpu_gpr[ret], \ 13417 (target_long)((int32_t)imm << 16 | \ 13418 (uint16_t)imm)); 13419 } 13420 break; 13421 case OPC_REPLV_PH: 13422 check_dsp(ctx); 13423 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 13424 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13425 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13426 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 13427 break; 13428 } 13429 break; 13430 #ifdef TARGET_MIPS64 13431 case OPC_ABSQ_S_QH_DSP: 13432 switch (op2) { 13433 case OPC_REPL_OB: 13434 check_dsp(ctx); 13435 { 13436 target_long temp; 13437 13438 imm = (ctx->opcode >> 16) & 0xFF; 13439 temp = ((uint64_t)imm << 8) | (uint64_t)imm; 13440 temp = (temp << 16) | temp; 13441 temp = (temp << 32) | temp; 13442 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13443 break; 13444 } 13445 case OPC_REPL_PW: 13446 check_dsp(ctx); 13447 { 13448 target_long temp; 13449 13450 imm = (ctx->opcode >> 16) & 0x03FF; 13451 imm = (int16_t)(imm << 6) >> 6; 13452 temp = ((target_long)imm << 32) \ 13453 | ((target_long)imm & 0xFFFFFFFF); 13454 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13455 break; 13456 } 13457 case OPC_REPL_QH: 13458 check_dsp(ctx); 13459 { 13460 target_long temp; 13461 13462 imm = (ctx->opcode >> 16) & 0x03FF; 13463 imm = (int16_t)(imm << 6) >> 6; 13464 13465 temp = ((uint64_t)(uint16_t)imm << 48) | 13466 ((uint64_t)(uint16_t)imm << 32) | 13467 ((uint64_t)(uint16_t)imm << 16) | 13468 (uint64_t)(uint16_t)imm; 13469 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13470 break; 13471 } 13472 case OPC_REPLV_OB: 13473 check_dsp(ctx); 13474 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 13475 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 13476 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13477 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13478 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13479 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13480 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13481 break; 13482 case OPC_REPLV_PW: 13483 check_dsp(ctx); 13484 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); 13485 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13486 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13487 break; 13488 case OPC_REPLV_QH: 13489 check_dsp(ctx); 13490 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 13491 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13492 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13493 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13494 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13495 break; 13496 } 13497 break; 13498 #endif 13499 } 13500 tcg_temp_free(t0); 13501 tcg_temp_free(val_t); 13502 } 13503 13504 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, 13505 uint32_t op1, uint32_t op2, 13506 int ret, int v1, int v2, int check_ret) 13507 { 13508 TCGv t1; 13509 TCGv v1_t; 13510 TCGv v2_t; 13511 13512 if ((ret == 0) && (check_ret == 1)) { 13513 /* Treat as NOP. */ 13514 return; 13515 } 13516 13517 t1 = tcg_temp_new(); 13518 v1_t = tcg_temp_new(); 13519 v2_t = tcg_temp_new(); 13520 13521 gen_load_gpr(v1_t, v1); 13522 gen_load_gpr(v2_t, v2); 13523 13524 switch (op1) { 13525 case OPC_CMPU_EQ_QB_DSP: 13526 switch (op2) { 13527 case OPC_CMPU_EQ_QB: 13528 check_dsp(ctx); 13529 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); 13530 break; 13531 case OPC_CMPU_LT_QB: 13532 check_dsp(ctx); 13533 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); 13534 break; 13535 case OPC_CMPU_LE_QB: 13536 check_dsp(ctx); 13537 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); 13538 break; 13539 case OPC_CMPGU_EQ_QB: 13540 check_dsp(ctx); 13541 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); 13542 break; 13543 case OPC_CMPGU_LT_QB: 13544 check_dsp(ctx); 13545 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); 13546 break; 13547 case OPC_CMPGU_LE_QB: 13548 check_dsp(ctx); 13549 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); 13550 break; 13551 case OPC_CMPGDU_EQ_QB: 13552 check_dsp_r2(ctx); 13553 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); 13554 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13555 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13556 tcg_gen_shli_tl(t1, t1, 24); 13557 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13558 break; 13559 case OPC_CMPGDU_LT_QB: 13560 check_dsp_r2(ctx); 13561 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); 13562 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13563 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13564 tcg_gen_shli_tl(t1, t1, 24); 13565 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13566 break; 13567 case OPC_CMPGDU_LE_QB: 13568 check_dsp_r2(ctx); 13569 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); 13570 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13571 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13572 tcg_gen_shli_tl(t1, t1, 24); 13573 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13574 break; 13575 case OPC_CMP_EQ_PH: 13576 check_dsp(ctx); 13577 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); 13578 break; 13579 case OPC_CMP_LT_PH: 13580 check_dsp(ctx); 13581 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); 13582 break; 13583 case OPC_CMP_LE_PH: 13584 check_dsp(ctx); 13585 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); 13586 break; 13587 case OPC_PICK_QB: 13588 check_dsp(ctx); 13589 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13590 break; 13591 case OPC_PICK_PH: 13592 check_dsp(ctx); 13593 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13594 break; 13595 case OPC_PACKRL_PH: 13596 check_dsp(ctx); 13597 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); 13598 break; 13599 } 13600 break; 13601 #ifdef TARGET_MIPS64 13602 case OPC_CMPU_EQ_OB_DSP: 13603 switch (op2) { 13604 case OPC_CMP_EQ_PW: 13605 check_dsp(ctx); 13606 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env); 13607 break; 13608 case OPC_CMP_LT_PW: 13609 check_dsp(ctx); 13610 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env); 13611 break; 13612 case OPC_CMP_LE_PW: 13613 check_dsp(ctx); 13614 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env); 13615 break; 13616 case OPC_CMP_EQ_QH: 13617 check_dsp(ctx); 13618 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env); 13619 break; 13620 case OPC_CMP_LT_QH: 13621 check_dsp(ctx); 13622 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env); 13623 break; 13624 case OPC_CMP_LE_QH: 13625 check_dsp(ctx); 13626 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env); 13627 break; 13628 case OPC_CMPGDU_EQ_OB: 13629 check_dsp_r2(ctx); 13630 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13631 break; 13632 case OPC_CMPGDU_LT_OB: 13633 check_dsp_r2(ctx); 13634 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13635 break; 13636 case OPC_CMPGDU_LE_OB: 13637 check_dsp_r2(ctx); 13638 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13639 break; 13640 case OPC_CMPGU_EQ_OB: 13641 check_dsp(ctx); 13642 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); 13643 break; 13644 case OPC_CMPGU_LT_OB: 13645 check_dsp(ctx); 13646 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); 13647 break; 13648 case OPC_CMPGU_LE_OB: 13649 check_dsp(ctx); 13650 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); 13651 break; 13652 case OPC_CMPU_EQ_OB: 13653 check_dsp(ctx); 13654 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env); 13655 break; 13656 case OPC_CMPU_LT_OB: 13657 check_dsp(ctx); 13658 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env); 13659 break; 13660 case OPC_CMPU_LE_OB: 13661 check_dsp(ctx); 13662 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env); 13663 break; 13664 case OPC_PACKRL_PW: 13665 check_dsp(ctx); 13666 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); 13667 break; 13668 case OPC_PICK_OB: 13669 check_dsp(ctx); 13670 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13671 break; 13672 case OPC_PICK_PW: 13673 check_dsp(ctx); 13674 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13675 break; 13676 case OPC_PICK_QH: 13677 check_dsp(ctx); 13678 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13679 break; 13680 } 13681 break; 13682 #endif 13683 } 13684 13685 tcg_temp_free(t1); 13686 tcg_temp_free(v1_t); 13687 tcg_temp_free(v2_t); 13688 } 13689 13690 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, 13691 uint32_t op1, int rt, int rs, int sa) 13692 { 13693 TCGv t0; 13694 13695 check_dsp_r2(ctx); 13696 13697 if (rt == 0) { 13698 /* Treat as NOP. */ 13699 return; 13700 } 13701 13702 t0 = tcg_temp_new(); 13703 gen_load_gpr(t0, rs); 13704 13705 switch (op1) { 13706 case OPC_APPEND_DSP: 13707 switch (MASK_APPEND(ctx->opcode)) { 13708 case OPC_APPEND: 13709 if (sa != 0) { 13710 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa); 13711 } 13712 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13713 break; 13714 case OPC_PREPEND: 13715 if (sa != 0) { 13716 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); 13717 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 13718 tcg_gen_shli_tl(t0, t0, 32 - sa); 13719 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13720 } 13721 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13722 break; 13723 case OPC_BALIGN: 13724 sa &= 3; 13725 if (sa != 0 && sa != 2) { 13726 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 13727 tcg_gen_ext32u_tl(t0, t0); 13728 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); 13729 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13730 } 13731 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13732 break; 13733 default: /* Invalid */ 13734 MIPS_INVAL("MASK APPEND"); 13735 gen_reserved_instruction(ctx); 13736 break; 13737 } 13738 break; 13739 #ifdef TARGET_MIPS64 13740 case OPC_DAPPEND_DSP: 13741 switch (MASK_DAPPEND(ctx->opcode)) { 13742 case OPC_DAPPEND: 13743 if (sa != 0) { 13744 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa); 13745 } 13746 break; 13747 case OPC_PREPENDD: 13748 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); 13749 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); 13750 tcg_gen_or_tl(cpu_gpr[rt], t0, t0); 13751 break; 13752 case OPC_PREPENDW: 13753 if (sa != 0) { 13754 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 13755 tcg_gen_shli_tl(t0, t0, 64 - sa); 13756 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13757 } 13758 break; 13759 case OPC_DBALIGN: 13760 sa &= 7; 13761 if (sa != 0 && sa != 2 && sa != 4) { 13762 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 13763 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); 13764 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13765 } 13766 break; 13767 default: /* Invalid */ 13768 MIPS_INVAL("MASK DAPPEND"); 13769 gen_reserved_instruction(ctx); 13770 break; 13771 } 13772 break; 13773 #endif 13774 } 13775 tcg_temp_free(t0); 13776 } 13777 13778 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 13779 int ret, int v1, int v2, int check_ret) 13780 13781 { 13782 TCGv t0; 13783 TCGv t1; 13784 TCGv v1_t; 13785 TCGv v2_t; 13786 int16_t imm; 13787 13788 if ((ret == 0) && (check_ret == 1)) { 13789 /* Treat as NOP. */ 13790 return; 13791 } 13792 13793 t0 = tcg_temp_new(); 13794 t1 = tcg_temp_new(); 13795 v1_t = tcg_temp_new(); 13796 v2_t = tcg_temp_new(); 13797 13798 gen_load_gpr(v1_t, v1); 13799 gen_load_gpr(v2_t, v2); 13800 13801 switch (op1) { 13802 case OPC_EXTR_W_DSP: 13803 check_dsp(ctx); 13804 switch (op2) { 13805 case OPC_EXTR_W: 13806 tcg_gen_movi_tl(t0, v2); 13807 tcg_gen_movi_tl(t1, v1); 13808 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env); 13809 break; 13810 case OPC_EXTR_R_W: 13811 tcg_gen_movi_tl(t0, v2); 13812 tcg_gen_movi_tl(t1, v1); 13813 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env); 13814 break; 13815 case OPC_EXTR_RS_W: 13816 tcg_gen_movi_tl(t0, v2); 13817 tcg_gen_movi_tl(t1, v1); 13818 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); 13819 break; 13820 case OPC_EXTR_S_H: 13821 tcg_gen_movi_tl(t0, v2); 13822 tcg_gen_movi_tl(t1, v1); 13823 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13824 break; 13825 case OPC_EXTRV_S_H: 13826 tcg_gen_movi_tl(t0, v2); 13827 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env); 13828 break; 13829 case OPC_EXTRV_W: 13830 tcg_gen_movi_tl(t0, v2); 13831 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13832 break; 13833 case OPC_EXTRV_R_W: 13834 tcg_gen_movi_tl(t0, v2); 13835 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13836 break; 13837 case OPC_EXTRV_RS_W: 13838 tcg_gen_movi_tl(t0, v2); 13839 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13840 break; 13841 case OPC_EXTP: 13842 tcg_gen_movi_tl(t0, v2); 13843 tcg_gen_movi_tl(t1, v1); 13844 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env); 13845 break; 13846 case OPC_EXTPV: 13847 tcg_gen_movi_tl(t0, v2); 13848 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env); 13849 break; 13850 case OPC_EXTPDP: 13851 tcg_gen_movi_tl(t0, v2); 13852 tcg_gen_movi_tl(t1, v1); 13853 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env); 13854 break; 13855 case OPC_EXTPDPV: 13856 tcg_gen_movi_tl(t0, v2); 13857 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env); 13858 break; 13859 case OPC_SHILO: 13860 imm = (ctx->opcode >> 20) & 0x3F; 13861 tcg_gen_movi_tl(t0, ret); 13862 tcg_gen_movi_tl(t1, imm); 13863 gen_helper_shilo(t0, t1, cpu_env); 13864 break; 13865 case OPC_SHILOV: 13866 tcg_gen_movi_tl(t0, ret); 13867 gen_helper_shilo(t0, v1_t, cpu_env); 13868 break; 13869 case OPC_MTHLIP: 13870 tcg_gen_movi_tl(t0, ret); 13871 gen_helper_mthlip(t0, v1_t, cpu_env); 13872 break; 13873 case OPC_WRDSP: 13874 imm = (ctx->opcode >> 11) & 0x3FF; 13875 tcg_gen_movi_tl(t0, imm); 13876 gen_helper_wrdsp(v1_t, t0, cpu_env); 13877 break; 13878 case OPC_RDDSP: 13879 imm = (ctx->opcode >> 16) & 0x03FF; 13880 tcg_gen_movi_tl(t0, imm); 13881 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env); 13882 break; 13883 } 13884 break; 13885 #ifdef TARGET_MIPS64 13886 case OPC_DEXTR_W_DSP: 13887 check_dsp(ctx); 13888 switch (op2) { 13889 case OPC_DMTHLIP: 13890 tcg_gen_movi_tl(t0, ret); 13891 gen_helper_dmthlip(v1_t, t0, cpu_env); 13892 break; 13893 case OPC_DSHILO: 13894 { 13895 int shift = (ctx->opcode >> 19) & 0x7F; 13896 int ac = (ctx->opcode >> 11) & 0x03; 13897 tcg_gen_movi_tl(t0, shift); 13898 tcg_gen_movi_tl(t1, ac); 13899 gen_helper_dshilo(t0, t1, cpu_env); 13900 break; 13901 } 13902 case OPC_DSHILOV: 13903 { 13904 int ac = (ctx->opcode >> 11) & 0x03; 13905 tcg_gen_movi_tl(t0, ac); 13906 gen_helper_dshilo(v1_t, t0, cpu_env); 13907 break; 13908 } 13909 case OPC_DEXTP: 13910 tcg_gen_movi_tl(t0, v2); 13911 tcg_gen_movi_tl(t1, v1); 13912 13913 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env); 13914 break; 13915 case OPC_DEXTPV: 13916 tcg_gen_movi_tl(t0, v2); 13917 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env); 13918 break; 13919 case OPC_DEXTPDP: 13920 tcg_gen_movi_tl(t0, v2); 13921 tcg_gen_movi_tl(t1, v1); 13922 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env); 13923 break; 13924 case OPC_DEXTPDPV: 13925 tcg_gen_movi_tl(t0, v2); 13926 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env); 13927 break; 13928 case OPC_DEXTR_L: 13929 tcg_gen_movi_tl(t0, v2); 13930 tcg_gen_movi_tl(t1, v1); 13931 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env); 13932 break; 13933 case OPC_DEXTR_R_L: 13934 tcg_gen_movi_tl(t0, v2); 13935 tcg_gen_movi_tl(t1, v1); 13936 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env); 13937 break; 13938 case OPC_DEXTR_RS_L: 13939 tcg_gen_movi_tl(t0, v2); 13940 tcg_gen_movi_tl(t1, v1); 13941 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env); 13942 break; 13943 case OPC_DEXTR_W: 13944 tcg_gen_movi_tl(t0, v2); 13945 tcg_gen_movi_tl(t1, v1); 13946 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env); 13947 break; 13948 case OPC_DEXTR_R_W: 13949 tcg_gen_movi_tl(t0, v2); 13950 tcg_gen_movi_tl(t1, v1); 13951 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env); 13952 break; 13953 case OPC_DEXTR_RS_W: 13954 tcg_gen_movi_tl(t0, v2); 13955 tcg_gen_movi_tl(t1, v1); 13956 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); 13957 break; 13958 case OPC_DEXTR_S_H: 13959 tcg_gen_movi_tl(t0, v2); 13960 tcg_gen_movi_tl(t1, v1); 13961 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13962 break; 13963 case OPC_DEXTRV_S_H: 13964 tcg_gen_movi_tl(t0, v2); 13965 tcg_gen_movi_tl(t1, v1); 13966 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13967 break; 13968 case OPC_DEXTRV_L: 13969 tcg_gen_movi_tl(t0, v2); 13970 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13971 break; 13972 case OPC_DEXTRV_R_L: 13973 tcg_gen_movi_tl(t0, v2); 13974 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13975 break; 13976 case OPC_DEXTRV_RS_L: 13977 tcg_gen_movi_tl(t0, v2); 13978 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13979 break; 13980 case OPC_DEXTRV_W: 13981 tcg_gen_movi_tl(t0, v2); 13982 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13983 break; 13984 case OPC_DEXTRV_R_W: 13985 tcg_gen_movi_tl(t0, v2); 13986 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13987 break; 13988 case OPC_DEXTRV_RS_W: 13989 tcg_gen_movi_tl(t0, v2); 13990 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13991 break; 13992 } 13993 break; 13994 #endif 13995 } 13996 13997 tcg_temp_free(t0); 13998 tcg_temp_free(t1); 13999 tcg_temp_free(v1_t); 14000 tcg_temp_free(v2_t); 14001 } 14002 14003 /* End MIPSDSP functions. */ 14004 14005 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) 14006 { 14007 int rs, rt, rd, sa; 14008 uint32_t op1, op2; 14009 14010 rs = (ctx->opcode >> 21) & 0x1f; 14011 rt = (ctx->opcode >> 16) & 0x1f; 14012 rd = (ctx->opcode >> 11) & 0x1f; 14013 sa = (ctx->opcode >> 6) & 0x1f; 14014 14015 op1 = MASK_SPECIAL(ctx->opcode); 14016 switch (op1) { 14017 case OPC_MULT: 14018 case OPC_MULTU: 14019 case OPC_DIV: 14020 case OPC_DIVU: 14021 op2 = MASK_R6_MULDIV(ctx->opcode); 14022 switch (op2) { 14023 case R6_OPC_MUL: 14024 case R6_OPC_MUH: 14025 case R6_OPC_MULU: 14026 case R6_OPC_MUHU: 14027 case R6_OPC_DIV: 14028 case R6_OPC_MOD: 14029 case R6_OPC_DIVU: 14030 case R6_OPC_MODU: 14031 gen_r6_muldiv(ctx, op2, rd, rs, rt); 14032 break; 14033 default: 14034 MIPS_INVAL("special_r6 muldiv"); 14035 gen_reserved_instruction(ctx); 14036 break; 14037 } 14038 break; 14039 case OPC_SELEQZ: 14040 case OPC_SELNEZ: 14041 gen_cond_move(ctx, op1, rd, rs, rt); 14042 break; 14043 case R6_OPC_CLO: 14044 case R6_OPC_CLZ: 14045 if (rt == 0 && sa == 1) { 14046 /* 14047 * Major opcode and function field is shared with preR6 MFHI/MTHI. 14048 * We need additionally to check other fields. 14049 */ 14050 gen_cl(ctx, op1, rd, rs); 14051 } else { 14052 gen_reserved_instruction(ctx); 14053 } 14054 break; 14055 case R6_OPC_SDBBP: 14056 if (is_uhi(extract32(ctx->opcode, 6, 20))) { 14057 gen_helper_do_semihosting(cpu_env); 14058 } else { 14059 if (ctx->hflags & MIPS_HFLAG_SBRI) { 14060 gen_reserved_instruction(ctx); 14061 } else { 14062 generate_exception_end(ctx, EXCP_DBp); 14063 } 14064 } 14065 break; 14066 #if defined(TARGET_MIPS64) 14067 case R6_OPC_DCLO: 14068 case R6_OPC_DCLZ: 14069 if (rt == 0 && sa == 1) { 14070 /* 14071 * Major opcode and function field is shared with preR6 MFHI/MTHI. 14072 * We need additionally to check other fields. 14073 */ 14074 check_mips_64(ctx); 14075 gen_cl(ctx, op1, rd, rs); 14076 } else { 14077 gen_reserved_instruction(ctx); 14078 } 14079 break; 14080 case OPC_DMULT: 14081 case OPC_DMULTU: 14082 case OPC_DDIV: 14083 case OPC_DDIVU: 14084 14085 op2 = MASK_R6_MULDIV(ctx->opcode); 14086 switch (op2) { 14087 case R6_OPC_DMUL: 14088 case R6_OPC_DMUH: 14089 case R6_OPC_DMULU: 14090 case R6_OPC_DMUHU: 14091 case R6_OPC_DDIV: 14092 case R6_OPC_DMOD: 14093 case R6_OPC_DDIVU: 14094 case R6_OPC_DMODU: 14095 check_mips_64(ctx); 14096 gen_r6_muldiv(ctx, op2, rd, rs, rt); 14097 break; 14098 default: 14099 MIPS_INVAL("special_r6 muldiv"); 14100 gen_reserved_instruction(ctx); 14101 break; 14102 } 14103 break; 14104 #endif 14105 default: /* Invalid */ 14106 MIPS_INVAL("special_r6"); 14107 gen_reserved_instruction(ctx); 14108 break; 14109 } 14110 } 14111 14112 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) 14113 { 14114 int rs = extract32(ctx->opcode, 21, 5); 14115 int rt = extract32(ctx->opcode, 16, 5); 14116 int rd = extract32(ctx->opcode, 11, 5); 14117 uint32_t op1 = MASK_SPECIAL(ctx->opcode); 14118 14119 switch (op1) { 14120 case OPC_MOVN: /* Conditional move */ 14121 case OPC_MOVZ: 14122 gen_cond_move(ctx, op1, rd, rs, rt); 14123 break; 14124 case OPC_MFHI: /* Move from HI/LO */ 14125 case OPC_MFLO: 14126 gen_HILO(ctx, op1, 0, rd); 14127 break; 14128 case OPC_MTHI: 14129 case OPC_MTLO: /* Move to HI/LO */ 14130 gen_HILO(ctx, op1, 0, rs); 14131 break; 14132 case OPC_MULT: 14133 case OPC_MULTU: 14134 gen_mul_txx9(ctx, op1, rd, rs, rt); 14135 break; 14136 case OPC_DIV: 14137 case OPC_DIVU: 14138 gen_muldiv(ctx, op1, 0, rs, rt); 14139 break; 14140 #if defined(TARGET_MIPS64) 14141 case OPC_DMULT: 14142 case OPC_DMULTU: 14143 case OPC_DDIV: 14144 case OPC_DDIVU: 14145 check_insn_opc_user_only(ctx, INSN_R5900); 14146 gen_muldiv(ctx, op1, 0, rs, rt); 14147 break; 14148 #endif 14149 case OPC_JR: 14150 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 14151 break; 14152 default: /* Invalid */ 14153 MIPS_INVAL("special_tx79"); 14154 gen_reserved_instruction(ctx); 14155 break; 14156 } 14157 } 14158 14159 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) 14160 { 14161 int rs, rt, rd, sa; 14162 uint32_t op1; 14163 14164 rs = (ctx->opcode >> 21) & 0x1f; 14165 rt = (ctx->opcode >> 16) & 0x1f; 14166 rd = (ctx->opcode >> 11) & 0x1f; 14167 sa = (ctx->opcode >> 6) & 0x1f; 14168 14169 op1 = MASK_SPECIAL(ctx->opcode); 14170 switch (op1) { 14171 case OPC_MOVN: /* Conditional move */ 14172 case OPC_MOVZ: 14173 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | 14174 INSN_LOONGSON2E | INSN_LOONGSON2F); 14175 gen_cond_move(ctx, op1, rd, rs, rt); 14176 break; 14177 case OPC_MFHI: /* Move from HI/LO */ 14178 case OPC_MFLO: 14179 gen_HILO(ctx, op1, rs & 3, rd); 14180 break; 14181 case OPC_MTHI: 14182 case OPC_MTLO: /* Move to HI/LO */ 14183 gen_HILO(ctx, op1, rd & 3, rs); 14184 break; 14185 case OPC_MOVCI: 14186 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 14187 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 14188 check_cp1_enabled(ctx); 14189 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 14190 (ctx->opcode >> 16) & 1); 14191 } else { 14192 generate_exception_err(ctx, EXCP_CpU, 1); 14193 } 14194 break; 14195 case OPC_MULT: 14196 case OPC_MULTU: 14197 if (sa) { 14198 check_insn(ctx, INSN_VR54XX); 14199 op1 = MASK_MUL_VR54XX(ctx->opcode); 14200 gen_mul_vr54xx(ctx, op1, rd, rs, rt); 14201 } else { 14202 gen_muldiv(ctx, op1, rd & 3, rs, rt); 14203 } 14204 break; 14205 case OPC_DIV: 14206 case OPC_DIVU: 14207 gen_muldiv(ctx, op1, 0, rs, rt); 14208 break; 14209 #if defined(TARGET_MIPS64) 14210 case OPC_DMULT: 14211 case OPC_DMULTU: 14212 case OPC_DDIV: 14213 case OPC_DDIVU: 14214 check_insn(ctx, ISA_MIPS3); 14215 check_mips_64(ctx); 14216 gen_muldiv(ctx, op1, 0, rs, rt); 14217 break; 14218 #endif 14219 case OPC_JR: 14220 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 14221 break; 14222 case OPC_SPIM: 14223 #ifdef MIPS_STRICT_STANDARD 14224 MIPS_INVAL("SPIM"); 14225 gen_reserved_instruction(ctx); 14226 #else 14227 /* Implemented as RI exception for now. */ 14228 MIPS_INVAL("spim (unofficial)"); 14229 gen_reserved_instruction(ctx); 14230 #endif 14231 break; 14232 default: /* Invalid */ 14233 MIPS_INVAL("special_legacy"); 14234 gen_reserved_instruction(ctx); 14235 break; 14236 } 14237 } 14238 14239 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) 14240 { 14241 int rs, rt, rd, sa; 14242 uint32_t op1; 14243 14244 rs = (ctx->opcode >> 21) & 0x1f; 14245 rt = (ctx->opcode >> 16) & 0x1f; 14246 rd = (ctx->opcode >> 11) & 0x1f; 14247 sa = (ctx->opcode >> 6) & 0x1f; 14248 14249 op1 = MASK_SPECIAL(ctx->opcode); 14250 switch (op1) { 14251 case OPC_SLL: /* Shift with immediate */ 14252 if (sa == 5 && rd == 0 && 14253 rs == 0 && rt == 0) { /* PAUSE */ 14254 if ((ctx->insn_flags & ISA_MIPS_R6) && 14255 (ctx->hflags & MIPS_HFLAG_BMASK)) { 14256 gen_reserved_instruction(ctx); 14257 break; 14258 } 14259 } 14260 /* Fallthrough */ 14261 case OPC_SRA: 14262 gen_shift_imm(ctx, op1, rd, rt, sa); 14263 break; 14264 case OPC_SRL: 14265 switch ((ctx->opcode >> 21) & 0x1f) { 14266 case 1: 14267 /* rotr is decoded as srl on non-R2 CPUs */ 14268 if (ctx->insn_flags & ISA_MIPS_R2) { 14269 op1 = OPC_ROTR; 14270 } 14271 /* Fallthrough */ 14272 case 0: 14273 gen_shift_imm(ctx, op1, rd, rt, sa); 14274 break; 14275 default: 14276 gen_reserved_instruction(ctx); 14277 break; 14278 } 14279 break; 14280 case OPC_ADD: 14281 case OPC_ADDU: 14282 case OPC_SUB: 14283 case OPC_SUBU: 14284 gen_arith(ctx, op1, rd, rs, rt); 14285 break; 14286 case OPC_SLLV: /* Shifts */ 14287 case OPC_SRAV: 14288 gen_shift(ctx, op1, rd, rs, rt); 14289 break; 14290 case OPC_SRLV: 14291 switch ((ctx->opcode >> 6) & 0x1f) { 14292 case 1: 14293 /* rotrv is decoded as srlv on non-R2 CPUs */ 14294 if (ctx->insn_flags & ISA_MIPS_R2) { 14295 op1 = OPC_ROTRV; 14296 } 14297 /* Fallthrough */ 14298 case 0: 14299 gen_shift(ctx, op1, rd, rs, rt); 14300 break; 14301 default: 14302 gen_reserved_instruction(ctx); 14303 break; 14304 } 14305 break; 14306 case OPC_SLT: /* Set on less than */ 14307 case OPC_SLTU: 14308 gen_slt(ctx, op1, rd, rs, rt); 14309 break; 14310 case OPC_AND: /* Logic*/ 14311 case OPC_OR: 14312 case OPC_NOR: 14313 case OPC_XOR: 14314 gen_logic(ctx, op1, rd, rs, rt); 14315 break; 14316 case OPC_JALR: 14317 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 14318 break; 14319 case OPC_TGE: /* Traps */ 14320 case OPC_TGEU: 14321 case OPC_TLT: 14322 case OPC_TLTU: 14323 case OPC_TEQ: 14324 case OPC_TNE: 14325 check_insn(ctx, ISA_MIPS2); 14326 gen_trap(ctx, op1, rs, rt, -1); 14327 break; 14328 case OPC_PMON: 14329 /* Pmon entry point, also R4010 selsl */ 14330 #ifdef MIPS_STRICT_STANDARD 14331 MIPS_INVAL("PMON / selsl"); 14332 gen_reserved_instruction(ctx); 14333 #else 14334 gen_helper_0e0i(pmon, sa); 14335 #endif 14336 break; 14337 case OPC_SYSCALL: 14338 generate_exception_end(ctx, EXCP_SYSCALL); 14339 break; 14340 case OPC_BREAK: 14341 generate_exception_end(ctx, EXCP_BREAK); 14342 break; 14343 case OPC_SYNC: 14344 check_insn(ctx, ISA_MIPS2); 14345 gen_sync(extract32(ctx->opcode, 6, 5)); 14346 break; 14347 14348 #if defined(TARGET_MIPS64) 14349 /* MIPS64 specific opcodes */ 14350 case OPC_DSLL: 14351 case OPC_DSRA: 14352 case OPC_DSLL32: 14353 case OPC_DSRA32: 14354 check_insn(ctx, ISA_MIPS3); 14355 check_mips_64(ctx); 14356 gen_shift_imm(ctx, op1, rd, rt, sa); 14357 break; 14358 case OPC_DSRL: 14359 switch ((ctx->opcode >> 21) & 0x1f) { 14360 case 1: 14361 /* drotr is decoded as dsrl on non-R2 CPUs */ 14362 if (ctx->insn_flags & ISA_MIPS_R2) { 14363 op1 = OPC_DROTR; 14364 } 14365 /* Fallthrough */ 14366 case 0: 14367 check_insn(ctx, ISA_MIPS3); 14368 check_mips_64(ctx); 14369 gen_shift_imm(ctx, op1, rd, rt, sa); 14370 break; 14371 default: 14372 gen_reserved_instruction(ctx); 14373 break; 14374 } 14375 break; 14376 case OPC_DSRL32: 14377 switch ((ctx->opcode >> 21) & 0x1f) { 14378 case 1: 14379 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 14380 if (ctx->insn_flags & ISA_MIPS_R2) { 14381 op1 = OPC_DROTR32; 14382 } 14383 /* Fallthrough */ 14384 case 0: 14385 check_insn(ctx, ISA_MIPS3); 14386 check_mips_64(ctx); 14387 gen_shift_imm(ctx, op1, rd, rt, sa); 14388 break; 14389 default: 14390 gen_reserved_instruction(ctx); 14391 break; 14392 } 14393 break; 14394 case OPC_DADD: 14395 case OPC_DADDU: 14396 case OPC_DSUB: 14397 case OPC_DSUBU: 14398 check_insn(ctx, ISA_MIPS3); 14399 check_mips_64(ctx); 14400 gen_arith(ctx, op1, rd, rs, rt); 14401 break; 14402 case OPC_DSLLV: 14403 case OPC_DSRAV: 14404 check_insn(ctx, ISA_MIPS3); 14405 check_mips_64(ctx); 14406 gen_shift(ctx, op1, rd, rs, rt); 14407 break; 14408 case OPC_DSRLV: 14409 switch ((ctx->opcode >> 6) & 0x1f) { 14410 case 1: 14411 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 14412 if (ctx->insn_flags & ISA_MIPS_R2) { 14413 op1 = OPC_DROTRV; 14414 } 14415 /* Fallthrough */ 14416 case 0: 14417 check_insn(ctx, ISA_MIPS3); 14418 check_mips_64(ctx); 14419 gen_shift(ctx, op1, rd, rs, rt); 14420 break; 14421 default: 14422 gen_reserved_instruction(ctx); 14423 break; 14424 } 14425 break; 14426 #endif 14427 default: 14428 if (ctx->insn_flags & ISA_MIPS_R6) { 14429 decode_opc_special_r6(env, ctx); 14430 } else if (ctx->insn_flags & INSN_R5900) { 14431 decode_opc_special_tx79(env, ctx); 14432 } else { 14433 decode_opc_special_legacy(env, ctx); 14434 } 14435 } 14436 } 14437 14438 14439 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) 14440 { 14441 int rs, rt, rd; 14442 uint32_t op1; 14443 14444 rs = (ctx->opcode >> 21) & 0x1f; 14445 rt = (ctx->opcode >> 16) & 0x1f; 14446 rd = (ctx->opcode >> 11) & 0x1f; 14447 14448 op1 = MASK_SPECIAL2(ctx->opcode); 14449 switch (op1) { 14450 case OPC_MADD: /* Multiply and add/sub */ 14451 case OPC_MADDU: 14452 case OPC_MSUB: 14453 case OPC_MSUBU: 14454 check_insn(ctx, ISA_MIPS_R1); 14455 gen_muldiv(ctx, op1, rd & 3, rs, rt); 14456 break; 14457 case OPC_MUL: 14458 gen_arith(ctx, op1, rd, rs, rt); 14459 break; 14460 case OPC_DIV_G_2F: 14461 case OPC_DIVU_G_2F: 14462 case OPC_MULT_G_2F: 14463 case OPC_MULTU_G_2F: 14464 case OPC_MOD_G_2F: 14465 case OPC_MODU_G_2F: 14466 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 14467 gen_loongson_integer(ctx, op1, rd, rs, rt); 14468 break; 14469 case OPC_CLO: 14470 case OPC_CLZ: 14471 check_insn(ctx, ISA_MIPS_R1); 14472 gen_cl(ctx, op1, rd, rs); 14473 break; 14474 case OPC_SDBBP: 14475 if (is_uhi(extract32(ctx->opcode, 6, 20))) { 14476 gen_helper_do_semihosting(cpu_env); 14477 } else { 14478 /* 14479 * XXX: not clear which exception should be raised 14480 * when in debug mode... 14481 */ 14482 check_insn(ctx, ISA_MIPS_R1); 14483 generate_exception_end(ctx, EXCP_DBp); 14484 } 14485 break; 14486 #if defined(TARGET_MIPS64) 14487 case OPC_DCLO: 14488 case OPC_DCLZ: 14489 check_insn(ctx, ISA_MIPS_R1); 14490 check_mips_64(ctx); 14491 gen_cl(ctx, op1, rd, rs); 14492 break; 14493 case OPC_DMULT_G_2F: 14494 case OPC_DMULTU_G_2F: 14495 case OPC_DDIV_G_2F: 14496 case OPC_DDIVU_G_2F: 14497 case OPC_DMOD_G_2F: 14498 case OPC_DMODU_G_2F: 14499 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 14500 gen_loongson_integer(ctx, op1, rd, rs, rt); 14501 break; 14502 #endif 14503 default: /* Invalid */ 14504 MIPS_INVAL("special2_legacy"); 14505 gen_reserved_instruction(ctx); 14506 break; 14507 } 14508 } 14509 14510 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) 14511 { 14512 int rs, rt, rd, sa; 14513 uint32_t op1, op2; 14514 int16_t imm; 14515 14516 rs = (ctx->opcode >> 21) & 0x1f; 14517 rt = (ctx->opcode >> 16) & 0x1f; 14518 rd = (ctx->opcode >> 11) & 0x1f; 14519 sa = (ctx->opcode >> 6) & 0x1f; 14520 imm = (int16_t)ctx->opcode >> 7; 14521 14522 op1 = MASK_SPECIAL3(ctx->opcode); 14523 switch (op1) { 14524 case R6_OPC_PREF: 14525 if (rt >= 24) { 14526 /* hint codes 24-31 are reserved and signal RI */ 14527 gen_reserved_instruction(ctx); 14528 } 14529 /* Treat as NOP. */ 14530 break; 14531 case R6_OPC_CACHE: 14532 check_cp0_enabled(ctx); 14533 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14534 gen_cache_operation(ctx, rt, rs, imm); 14535 } 14536 break; 14537 case R6_OPC_SC: 14538 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); 14539 break; 14540 case R6_OPC_LL: 14541 gen_ld(ctx, op1, rt, rs, imm); 14542 break; 14543 case OPC_BSHFL: 14544 { 14545 if (rd == 0) { 14546 /* Treat as NOP. */ 14547 break; 14548 } 14549 op2 = MASK_BSHFL(ctx->opcode); 14550 switch (op2) { 14551 case OPC_ALIGN: 14552 case OPC_ALIGN_1: 14553 case OPC_ALIGN_2: 14554 case OPC_ALIGN_3: 14555 gen_align(ctx, 32, rd, rs, rt, sa & 3); 14556 break; 14557 case OPC_BITSWAP: 14558 gen_bitswap(ctx, op2, rd, rt); 14559 break; 14560 } 14561 } 14562 break; 14563 #ifndef CONFIG_USER_ONLY 14564 case OPC_GINV: 14565 if (unlikely(ctx->gi <= 1)) { 14566 gen_reserved_instruction(ctx); 14567 } 14568 check_cp0_enabled(ctx); 14569 switch ((ctx->opcode >> 6) & 3) { 14570 case 0: /* GINVI */ 14571 /* Treat as NOP. */ 14572 break; 14573 case 2: /* GINVT */ 14574 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); 14575 break; 14576 default: 14577 gen_reserved_instruction(ctx); 14578 break; 14579 } 14580 break; 14581 #endif 14582 #if defined(TARGET_MIPS64) 14583 case R6_OPC_SCD: 14584 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false); 14585 break; 14586 case R6_OPC_LLD: 14587 gen_ld(ctx, op1, rt, rs, imm); 14588 break; 14589 case OPC_DBSHFL: 14590 check_mips_64(ctx); 14591 { 14592 if (rd == 0) { 14593 /* Treat as NOP. */ 14594 break; 14595 } 14596 op2 = MASK_DBSHFL(ctx->opcode); 14597 switch (op2) { 14598 case OPC_DALIGN: 14599 case OPC_DALIGN_1: 14600 case OPC_DALIGN_2: 14601 case OPC_DALIGN_3: 14602 case OPC_DALIGN_4: 14603 case OPC_DALIGN_5: 14604 case OPC_DALIGN_6: 14605 case OPC_DALIGN_7: 14606 gen_align(ctx, 64, rd, rs, rt, sa & 7); 14607 break; 14608 case OPC_DBITSWAP: 14609 gen_bitswap(ctx, op2, rd, rt); 14610 break; 14611 } 14612 14613 } 14614 break; 14615 #endif 14616 default: /* Invalid */ 14617 MIPS_INVAL("special3_r6"); 14618 gen_reserved_instruction(ctx); 14619 break; 14620 } 14621 } 14622 14623 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) 14624 { 14625 int rs, rt, rd; 14626 uint32_t op1, op2; 14627 14628 rs = (ctx->opcode >> 21) & 0x1f; 14629 rt = (ctx->opcode >> 16) & 0x1f; 14630 rd = (ctx->opcode >> 11) & 0x1f; 14631 14632 op1 = MASK_SPECIAL3(ctx->opcode); 14633 switch (op1) { 14634 case OPC_DIV_G_2E: 14635 case OPC_DIVU_G_2E: 14636 case OPC_MOD_G_2E: 14637 case OPC_MODU_G_2E: 14638 case OPC_MULT_G_2E: 14639 case OPC_MULTU_G_2E: 14640 /* 14641 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 14642 * the same mask and op1. 14643 */ 14644 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) { 14645 op2 = MASK_ADDUH_QB(ctx->opcode); 14646 switch (op2) { 14647 case OPC_ADDUH_QB: 14648 case OPC_ADDUH_R_QB: 14649 case OPC_ADDQH_PH: 14650 case OPC_ADDQH_R_PH: 14651 case OPC_ADDQH_W: 14652 case OPC_ADDQH_R_W: 14653 case OPC_SUBUH_QB: 14654 case OPC_SUBUH_R_QB: 14655 case OPC_SUBQH_PH: 14656 case OPC_SUBQH_R_PH: 14657 case OPC_SUBQH_W: 14658 case OPC_SUBQH_R_W: 14659 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14660 break; 14661 case OPC_MUL_PH: 14662 case OPC_MUL_S_PH: 14663 case OPC_MULQ_S_W: 14664 case OPC_MULQ_RS_W: 14665 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14666 break; 14667 default: 14668 MIPS_INVAL("MASK ADDUH.QB"); 14669 gen_reserved_instruction(ctx); 14670 break; 14671 } 14672 } else if (ctx->insn_flags & INSN_LOONGSON2E) { 14673 gen_loongson_integer(ctx, op1, rd, rs, rt); 14674 } else { 14675 gen_reserved_instruction(ctx); 14676 } 14677 break; 14678 case OPC_LX_DSP: 14679 op2 = MASK_LX(ctx->opcode); 14680 switch (op2) { 14681 #if defined(TARGET_MIPS64) 14682 case OPC_LDX: 14683 #endif 14684 case OPC_LBUX: 14685 case OPC_LHX: 14686 case OPC_LWX: 14687 gen_mipsdsp_ld(ctx, op2, rd, rs, rt); 14688 break; 14689 default: /* Invalid */ 14690 MIPS_INVAL("MASK LX"); 14691 gen_reserved_instruction(ctx); 14692 break; 14693 } 14694 break; 14695 case OPC_ABSQ_S_PH_DSP: 14696 op2 = MASK_ABSQ_S_PH(ctx->opcode); 14697 switch (op2) { 14698 case OPC_ABSQ_S_QB: 14699 case OPC_ABSQ_S_PH: 14700 case OPC_ABSQ_S_W: 14701 case OPC_PRECEQ_W_PHL: 14702 case OPC_PRECEQ_W_PHR: 14703 case OPC_PRECEQU_PH_QBL: 14704 case OPC_PRECEQU_PH_QBR: 14705 case OPC_PRECEQU_PH_QBLA: 14706 case OPC_PRECEQU_PH_QBRA: 14707 case OPC_PRECEU_PH_QBL: 14708 case OPC_PRECEU_PH_QBR: 14709 case OPC_PRECEU_PH_QBLA: 14710 case OPC_PRECEU_PH_QBRA: 14711 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14712 break; 14713 case OPC_BITREV: 14714 case OPC_REPL_QB: 14715 case OPC_REPLV_QB: 14716 case OPC_REPL_PH: 14717 case OPC_REPLV_PH: 14718 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 14719 break; 14720 default: 14721 MIPS_INVAL("MASK ABSQ_S.PH"); 14722 gen_reserved_instruction(ctx); 14723 break; 14724 } 14725 break; 14726 case OPC_ADDU_QB_DSP: 14727 op2 = MASK_ADDU_QB(ctx->opcode); 14728 switch (op2) { 14729 case OPC_ADDQ_PH: 14730 case OPC_ADDQ_S_PH: 14731 case OPC_ADDQ_S_W: 14732 case OPC_ADDU_QB: 14733 case OPC_ADDU_S_QB: 14734 case OPC_ADDU_PH: 14735 case OPC_ADDU_S_PH: 14736 case OPC_SUBQ_PH: 14737 case OPC_SUBQ_S_PH: 14738 case OPC_SUBQ_S_W: 14739 case OPC_SUBU_QB: 14740 case OPC_SUBU_S_QB: 14741 case OPC_SUBU_PH: 14742 case OPC_SUBU_S_PH: 14743 case OPC_ADDSC: 14744 case OPC_ADDWC: 14745 case OPC_MODSUB: 14746 case OPC_RADDU_W_QB: 14747 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14748 break; 14749 case OPC_MULEU_S_PH_QBL: 14750 case OPC_MULEU_S_PH_QBR: 14751 case OPC_MULQ_RS_PH: 14752 case OPC_MULEQ_S_W_PHL: 14753 case OPC_MULEQ_S_W_PHR: 14754 case OPC_MULQ_S_PH: 14755 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14756 break; 14757 default: /* Invalid */ 14758 MIPS_INVAL("MASK ADDU.QB"); 14759 gen_reserved_instruction(ctx); 14760 break; 14761 14762 } 14763 break; 14764 case OPC_CMPU_EQ_QB_DSP: 14765 op2 = MASK_CMPU_EQ_QB(ctx->opcode); 14766 switch (op2) { 14767 case OPC_PRECR_SRA_PH_W: 14768 case OPC_PRECR_SRA_R_PH_W: 14769 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 14770 break; 14771 case OPC_PRECR_QB_PH: 14772 case OPC_PRECRQ_QB_PH: 14773 case OPC_PRECRQ_PH_W: 14774 case OPC_PRECRQ_RS_PH_W: 14775 case OPC_PRECRQU_S_QB_PH: 14776 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14777 break; 14778 case OPC_CMPU_EQ_QB: 14779 case OPC_CMPU_LT_QB: 14780 case OPC_CMPU_LE_QB: 14781 case OPC_CMP_EQ_PH: 14782 case OPC_CMP_LT_PH: 14783 case OPC_CMP_LE_PH: 14784 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 14785 break; 14786 case OPC_CMPGU_EQ_QB: 14787 case OPC_CMPGU_LT_QB: 14788 case OPC_CMPGU_LE_QB: 14789 case OPC_CMPGDU_EQ_QB: 14790 case OPC_CMPGDU_LT_QB: 14791 case OPC_CMPGDU_LE_QB: 14792 case OPC_PICK_QB: 14793 case OPC_PICK_PH: 14794 case OPC_PACKRL_PH: 14795 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 14796 break; 14797 default: /* Invalid */ 14798 MIPS_INVAL("MASK CMPU.EQ.QB"); 14799 gen_reserved_instruction(ctx); 14800 break; 14801 } 14802 break; 14803 case OPC_SHLL_QB_DSP: 14804 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14805 break; 14806 case OPC_DPA_W_PH_DSP: 14807 op2 = MASK_DPA_W_PH(ctx->opcode); 14808 switch (op2) { 14809 case OPC_DPAU_H_QBL: 14810 case OPC_DPAU_H_QBR: 14811 case OPC_DPSU_H_QBL: 14812 case OPC_DPSU_H_QBR: 14813 case OPC_DPA_W_PH: 14814 case OPC_DPAX_W_PH: 14815 case OPC_DPAQ_S_W_PH: 14816 case OPC_DPAQX_S_W_PH: 14817 case OPC_DPAQX_SA_W_PH: 14818 case OPC_DPS_W_PH: 14819 case OPC_DPSX_W_PH: 14820 case OPC_DPSQ_S_W_PH: 14821 case OPC_DPSQX_S_W_PH: 14822 case OPC_DPSQX_SA_W_PH: 14823 case OPC_MULSAQ_S_W_PH: 14824 case OPC_DPAQ_SA_L_W: 14825 case OPC_DPSQ_SA_L_W: 14826 case OPC_MAQ_S_W_PHL: 14827 case OPC_MAQ_S_W_PHR: 14828 case OPC_MAQ_SA_W_PHL: 14829 case OPC_MAQ_SA_W_PHR: 14830 case OPC_MULSA_W_PH: 14831 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14832 break; 14833 default: /* Invalid */ 14834 MIPS_INVAL("MASK DPAW.PH"); 14835 gen_reserved_instruction(ctx); 14836 break; 14837 } 14838 break; 14839 case OPC_INSV_DSP: 14840 op2 = MASK_INSV(ctx->opcode); 14841 switch (op2) { 14842 case OPC_INSV: 14843 check_dsp(ctx); 14844 { 14845 TCGv t0, t1; 14846 14847 if (rt == 0) { 14848 break; 14849 } 14850 14851 t0 = tcg_temp_new(); 14852 t1 = tcg_temp_new(); 14853 14854 gen_load_gpr(t0, rt); 14855 gen_load_gpr(t1, rs); 14856 14857 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0); 14858 14859 tcg_temp_free(t0); 14860 tcg_temp_free(t1); 14861 break; 14862 } 14863 default: /* Invalid */ 14864 MIPS_INVAL("MASK INSV"); 14865 gen_reserved_instruction(ctx); 14866 break; 14867 } 14868 break; 14869 case OPC_APPEND_DSP: 14870 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 14871 break; 14872 case OPC_EXTR_W_DSP: 14873 op2 = MASK_EXTR_W(ctx->opcode); 14874 switch (op2) { 14875 case OPC_EXTR_W: 14876 case OPC_EXTR_R_W: 14877 case OPC_EXTR_RS_W: 14878 case OPC_EXTR_S_H: 14879 case OPC_EXTRV_S_H: 14880 case OPC_EXTRV_W: 14881 case OPC_EXTRV_R_W: 14882 case OPC_EXTRV_RS_W: 14883 case OPC_EXTP: 14884 case OPC_EXTPV: 14885 case OPC_EXTPDP: 14886 case OPC_EXTPDPV: 14887 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 14888 break; 14889 case OPC_RDDSP: 14890 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1); 14891 break; 14892 case OPC_SHILO: 14893 case OPC_SHILOV: 14894 case OPC_MTHLIP: 14895 case OPC_WRDSP: 14896 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 14897 break; 14898 default: /* Invalid */ 14899 MIPS_INVAL("MASK EXTR.W"); 14900 gen_reserved_instruction(ctx); 14901 break; 14902 } 14903 break; 14904 #if defined(TARGET_MIPS64) 14905 case OPC_DDIV_G_2E: 14906 case OPC_DDIVU_G_2E: 14907 case OPC_DMULT_G_2E: 14908 case OPC_DMULTU_G_2E: 14909 case OPC_DMOD_G_2E: 14910 case OPC_DMODU_G_2E: 14911 check_insn(ctx, INSN_LOONGSON2E); 14912 gen_loongson_integer(ctx, op1, rd, rs, rt); 14913 break; 14914 case OPC_ABSQ_S_QH_DSP: 14915 op2 = MASK_ABSQ_S_QH(ctx->opcode); 14916 switch (op2) { 14917 case OPC_PRECEQ_L_PWL: 14918 case OPC_PRECEQ_L_PWR: 14919 case OPC_PRECEQ_PW_QHL: 14920 case OPC_PRECEQ_PW_QHR: 14921 case OPC_PRECEQ_PW_QHLA: 14922 case OPC_PRECEQ_PW_QHRA: 14923 case OPC_PRECEQU_QH_OBL: 14924 case OPC_PRECEQU_QH_OBR: 14925 case OPC_PRECEQU_QH_OBLA: 14926 case OPC_PRECEQU_QH_OBRA: 14927 case OPC_PRECEU_QH_OBL: 14928 case OPC_PRECEU_QH_OBR: 14929 case OPC_PRECEU_QH_OBLA: 14930 case OPC_PRECEU_QH_OBRA: 14931 case OPC_ABSQ_S_OB: 14932 case OPC_ABSQ_S_PW: 14933 case OPC_ABSQ_S_QH: 14934 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14935 break; 14936 case OPC_REPL_OB: 14937 case OPC_REPL_PW: 14938 case OPC_REPL_QH: 14939 case OPC_REPLV_OB: 14940 case OPC_REPLV_PW: 14941 case OPC_REPLV_QH: 14942 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 14943 break; 14944 default: /* Invalid */ 14945 MIPS_INVAL("MASK ABSQ_S.QH"); 14946 gen_reserved_instruction(ctx); 14947 break; 14948 } 14949 break; 14950 case OPC_ADDU_OB_DSP: 14951 op2 = MASK_ADDU_OB(ctx->opcode); 14952 switch (op2) { 14953 case OPC_RADDU_L_OB: 14954 case OPC_SUBQ_PW: 14955 case OPC_SUBQ_S_PW: 14956 case OPC_SUBQ_QH: 14957 case OPC_SUBQ_S_QH: 14958 case OPC_SUBU_OB: 14959 case OPC_SUBU_S_OB: 14960 case OPC_SUBU_QH: 14961 case OPC_SUBU_S_QH: 14962 case OPC_SUBUH_OB: 14963 case OPC_SUBUH_R_OB: 14964 case OPC_ADDQ_PW: 14965 case OPC_ADDQ_S_PW: 14966 case OPC_ADDQ_QH: 14967 case OPC_ADDQ_S_QH: 14968 case OPC_ADDU_OB: 14969 case OPC_ADDU_S_OB: 14970 case OPC_ADDU_QH: 14971 case OPC_ADDU_S_QH: 14972 case OPC_ADDUH_OB: 14973 case OPC_ADDUH_R_OB: 14974 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14975 break; 14976 case OPC_MULEQ_S_PW_QHL: 14977 case OPC_MULEQ_S_PW_QHR: 14978 case OPC_MULEU_S_QH_OBL: 14979 case OPC_MULEU_S_QH_OBR: 14980 case OPC_MULQ_RS_QH: 14981 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14982 break; 14983 default: /* Invalid */ 14984 MIPS_INVAL("MASK ADDU.OB"); 14985 gen_reserved_instruction(ctx); 14986 break; 14987 } 14988 break; 14989 case OPC_CMPU_EQ_OB_DSP: 14990 op2 = MASK_CMPU_EQ_OB(ctx->opcode); 14991 switch (op2) { 14992 case OPC_PRECR_SRA_QH_PW: 14993 case OPC_PRECR_SRA_R_QH_PW: 14994 /* Return value is rt. */ 14995 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 14996 break; 14997 case OPC_PRECR_OB_QH: 14998 case OPC_PRECRQ_OB_QH: 14999 case OPC_PRECRQ_PW_L: 15000 case OPC_PRECRQ_QH_PW: 15001 case OPC_PRECRQ_RS_QH_PW: 15002 case OPC_PRECRQU_S_OB_QH: 15003 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 15004 break; 15005 case OPC_CMPU_EQ_OB: 15006 case OPC_CMPU_LT_OB: 15007 case OPC_CMPU_LE_OB: 15008 case OPC_CMP_EQ_QH: 15009 case OPC_CMP_LT_QH: 15010 case OPC_CMP_LE_QH: 15011 case OPC_CMP_EQ_PW: 15012 case OPC_CMP_LT_PW: 15013 case OPC_CMP_LE_PW: 15014 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 15015 break; 15016 case OPC_CMPGDU_EQ_OB: 15017 case OPC_CMPGDU_LT_OB: 15018 case OPC_CMPGDU_LE_OB: 15019 case OPC_CMPGU_EQ_OB: 15020 case OPC_CMPGU_LT_OB: 15021 case OPC_CMPGU_LE_OB: 15022 case OPC_PACKRL_PW: 15023 case OPC_PICK_OB: 15024 case OPC_PICK_PW: 15025 case OPC_PICK_QH: 15026 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 15027 break; 15028 default: /* Invalid */ 15029 MIPS_INVAL("MASK CMPU_EQ.OB"); 15030 gen_reserved_instruction(ctx); 15031 break; 15032 } 15033 break; 15034 case OPC_DAPPEND_DSP: 15035 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 15036 break; 15037 case OPC_DEXTR_W_DSP: 15038 op2 = MASK_DEXTR_W(ctx->opcode); 15039 switch (op2) { 15040 case OPC_DEXTP: 15041 case OPC_DEXTPDP: 15042 case OPC_DEXTPDPV: 15043 case OPC_DEXTPV: 15044 case OPC_DEXTR_L: 15045 case OPC_DEXTR_R_L: 15046 case OPC_DEXTR_RS_L: 15047 case OPC_DEXTR_W: 15048 case OPC_DEXTR_R_W: 15049 case OPC_DEXTR_RS_W: 15050 case OPC_DEXTR_S_H: 15051 case OPC_DEXTRV_L: 15052 case OPC_DEXTRV_R_L: 15053 case OPC_DEXTRV_RS_L: 15054 case OPC_DEXTRV_S_H: 15055 case OPC_DEXTRV_W: 15056 case OPC_DEXTRV_R_W: 15057 case OPC_DEXTRV_RS_W: 15058 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 15059 break; 15060 case OPC_DMTHLIP: 15061 case OPC_DSHILO: 15062 case OPC_DSHILOV: 15063 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 15064 break; 15065 default: /* Invalid */ 15066 MIPS_INVAL("MASK EXTR.W"); 15067 gen_reserved_instruction(ctx); 15068 break; 15069 } 15070 break; 15071 case OPC_DPAQ_W_QH_DSP: 15072 op2 = MASK_DPAQ_W_QH(ctx->opcode); 15073 switch (op2) { 15074 case OPC_DPAU_H_OBL: 15075 case OPC_DPAU_H_OBR: 15076 case OPC_DPSU_H_OBL: 15077 case OPC_DPSU_H_OBR: 15078 case OPC_DPA_W_QH: 15079 case OPC_DPAQ_S_W_QH: 15080 case OPC_DPS_W_QH: 15081 case OPC_DPSQ_S_W_QH: 15082 case OPC_MULSAQ_S_W_QH: 15083 case OPC_DPAQ_SA_L_PW: 15084 case OPC_DPSQ_SA_L_PW: 15085 case OPC_MULSAQ_S_L_PW: 15086 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 15087 break; 15088 case OPC_MAQ_S_W_QHLL: 15089 case OPC_MAQ_S_W_QHLR: 15090 case OPC_MAQ_S_W_QHRL: 15091 case OPC_MAQ_S_W_QHRR: 15092 case OPC_MAQ_SA_W_QHLL: 15093 case OPC_MAQ_SA_W_QHLR: 15094 case OPC_MAQ_SA_W_QHRL: 15095 case OPC_MAQ_SA_W_QHRR: 15096 case OPC_MAQ_S_L_PWL: 15097 case OPC_MAQ_S_L_PWR: 15098 case OPC_DMADD: 15099 case OPC_DMADDU: 15100 case OPC_DMSUB: 15101 case OPC_DMSUBU: 15102 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 15103 break; 15104 default: /* Invalid */ 15105 MIPS_INVAL("MASK DPAQ.W.QH"); 15106 gen_reserved_instruction(ctx); 15107 break; 15108 } 15109 break; 15110 case OPC_DINSV_DSP: 15111 op2 = MASK_INSV(ctx->opcode); 15112 switch (op2) { 15113 case OPC_DINSV: 15114 { 15115 TCGv t0, t1; 15116 15117 check_dsp(ctx); 15118 15119 if (rt == 0) { 15120 break; 15121 } 15122 15123 t0 = tcg_temp_new(); 15124 t1 = tcg_temp_new(); 15125 15126 gen_load_gpr(t0, rt); 15127 gen_load_gpr(t1, rs); 15128 15129 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0); 15130 15131 tcg_temp_free(t0); 15132 tcg_temp_free(t1); 15133 break; 15134 } 15135 default: /* Invalid */ 15136 MIPS_INVAL("MASK DINSV"); 15137 gen_reserved_instruction(ctx); 15138 break; 15139 } 15140 break; 15141 case OPC_SHLL_OB_DSP: 15142 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 15143 break; 15144 #endif 15145 default: /* Invalid */ 15146 MIPS_INVAL("special3_legacy"); 15147 gen_reserved_instruction(ctx); 15148 break; 15149 } 15150 } 15151 15152 15153 #if defined(TARGET_MIPS64) 15154 15155 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) 15156 { 15157 uint32_t opc = MASK_MMI(ctx->opcode); 15158 int rs = extract32(ctx->opcode, 21, 5); 15159 int rt = extract32(ctx->opcode, 16, 5); 15160 int rd = extract32(ctx->opcode, 11, 5); 15161 15162 switch (opc) { 15163 case MMI_OPC_MULT1: 15164 case MMI_OPC_MULTU1: 15165 case MMI_OPC_MADD: 15166 case MMI_OPC_MADDU: 15167 case MMI_OPC_MADD1: 15168 case MMI_OPC_MADDU1: 15169 gen_mul_txx9(ctx, opc, rd, rs, rt); 15170 break; 15171 case MMI_OPC_DIV1: 15172 case MMI_OPC_DIVU1: 15173 gen_div1_tx79(ctx, opc, rs, rt); 15174 break; 15175 default: 15176 MIPS_INVAL("TX79 MMI class"); 15177 gen_reserved_instruction(ctx); 15178 break; 15179 } 15180 } 15181 15182 static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx) 15183 { 15184 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_LQ */ 15185 } 15186 15187 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset) 15188 { 15189 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */ 15190 } 15191 15192 /* 15193 * The TX79-specific instruction Store Quadword 15194 * 15195 * +--------+-------+-------+------------------------+ 15196 * | 011111 | base | rt | offset | SQ 15197 * +--------+-------+-------+------------------------+ 15198 * 6 5 5 16 15199 * 15200 * has the same opcode as the Read Hardware Register instruction 15201 * 15202 * +--------+-------+-------+-------+-------+--------+ 15203 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR 15204 * +--------+-------+-------+-------+-------+--------+ 15205 * 6 5 5 5 5 6 15206 * 15207 * that is required, trapped and emulated by the Linux kernel. However, all 15208 * RDHWR encodings yield address error exceptions on the TX79 since the SQ 15209 * offset is odd. Therefore all valid SQ instructions can execute normally. 15210 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish 15211 * between SQ and RDHWR, as the Linux kernel does. 15212 */ 15213 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx) 15214 { 15215 int base = extract32(ctx->opcode, 21, 5); 15216 int rt = extract32(ctx->opcode, 16, 5); 15217 int offset = extract32(ctx->opcode, 0, 16); 15218 15219 #ifdef CONFIG_USER_ONLY 15220 uint32_t op1 = MASK_SPECIAL3(ctx->opcode); 15221 uint32_t op2 = extract32(ctx->opcode, 6, 5); 15222 15223 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) { 15224 int rd = extract32(ctx->opcode, 11, 5); 15225 15226 gen_rdhwr(ctx, rt, rd, 0); 15227 return; 15228 } 15229 #endif 15230 15231 gen_mmi_sq(ctx, base, rt, offset); 15232 } 15233 15234 #endif 15235 15236 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) 15237 { 15238 int rs, rt, rd, sa; 15239 uint32_t op1, op2; 15240 int16_t imm; 15241 15242 rs = (ctx->opcode >> 21) & 0x1f; 15243 rt = (ctx->opcode >> 16) & 0x1f; 15244 rd = (ctx->opcode >> 11) & 0x1f; 15245 sa = (ctx->opcode >> 6) & 0x1f; 15246 imm = sextract32(ctx->opcode, 7, 9); 15247 15248 op1 = MASK_SPECIAL3(ctx->opcode); 15249 15250 /* 15251 * EVA loads and stores overlap Loongson 2E instructions decoded by 15252 * decode_opc_special3_legacy(), so be careful to allow their decoding when 15253 * EVA is absent. 15254 */ 15255 if (ctx->eva) { 15256 switch (op1) { 15257 case OPC_LWLE: 15258 case OPC_LWRE: 15259 case OPC_LBUE: 15260 case OPC_LHUE: 15261 case OPC_LBE: 15262 case OPC_LHE: 15263 case OPC_LLE: 15264 case OPC_LWE: 15265 check_cp0_enabled(ctx); 15266 gen_ld(ctx, op1, rt, rs, imm); 15267 return; 15268 case OPC_SWLE: 15269 case OPC_SWRE: 15270 case OPC_SBE: 15271 case OPC_SHE: 15272 case OPC_SWE: 15273 check_cp0_enabled(ctx); 15274 gen_st(ctx, op1, rt, rs, imm); 15275 return; 15276 case OPC_SCE: 15277 check_cp0_enabled(ctx); 15278 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true); 15279 return; 15280 case OPC_CACHEE: 15281 check_eva(ctx); 15282 check_cp0_enabled(ctx); 15283 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 15284 gen_cache_operation(ctx, rt, rs, imm); 15285 } 15286 return; 15287 case OPC_PREFE: 15288 check_cp0_enabled(ctx); 15289 /* Treat as NOP. */ 15290 return; 15291 } 15292 } 15293 15294 switch (op1) { 15295 case OPC_EXT: 15296 case OPC_INS: 15297 check_insn(ctx, ISA_MIPS_R2); 15298 gen_bitops(ctx, op1, rt, rs, sa, rd); 15299 break; 15300 case OPC_BSHFL: 15301 op2 = MASK_BSHFL(ctx->opcode); 15302 switch (op2) { 15303 case OPC_ALIGN: 15304 case OPC_ALIGN_1: 15305 case OPC_ALIGN_2: 15306 case OPC_ALIGN_3: 15307 case OPC_BITSWAP: 15308 check_insn(ctx, ISA_MIPS_R6); 15309 decode_opc_special3_r6(env, ctx); 15310 break; 15311 default: 15312 check_insn(ctx, ISA_MIPS_R2); 15313 gen_bshfl(ctx, op2, rt, rd); 15314 break; 15315 } 15316 break; 15317 #if defined(TARGET_MIPS64) 15318 case OPC_DEXTM: 15319 case OPC_DEXTU: 15320 case OPC_DEXT: 15321 case OPC_DINSM: 15322 case OPC_DINSU: 15323 case OPC_DINS: 15324 check_insn(ctx, ISA_MIPS_R2); 15325 check_mips_64(ctx); 15326 gen_bitops(ctx, op1, rt, rs, sa, rd); 15327 break; 15328 case OPC_DBSHFL: 15329 op2 = MASK_DBSHFL(ctx->opcode); 15330 switch (op2) { 15331 case OPC_DALIGN: 15332 case OPC_DALIGN_1: 15333 case OPC_DALIGN_2: 15334 case OPC_DALIGN_3: 15335 case OPC_DALIGN_4: 15336 case OPC_DALIGN_5: 15337 case OPC_DALIGN_6: 15338 case OPC_DALIGN_7: 15339 case OPC_DBITSWAP: 15340 check_insn(ctx, ISA_MIPS_R6); 15341 decode_opc_special3_r6(env, ctx); 15342 break; 15343 default: 15344 check_insn(ctx, ISA_MIPS_R2); 15345 check_mips_64(ctx); 15346 op2 = MASK_DBSHFL(ctx->opcode); 15347 gen_bshfl(ctx, op2, rt, rd); 15348 break; 15349 } 15350 break; 15351 #endif 15352 case OPC_RDHWR: 15353 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3)); 15354 break; 15355 case OPC_FORK: 15356 check_mt(ctx); 15357 { 15358 TCGv t0 = tcg_temp_new(); 15359 TCGv t1 = tcg_temp_new(); 15360 15361 gen_load_gpr(t0, rt); 15362 gen_load_gpr(t1, rs); 15363 gen_helper_fork(t0, t1); 15364 tcg_temp_free(t0); 15365 tcg_temp_free(t1); 15366 } 15367 break; 15368 case OPC_YIELD: 15369 check_mt(ctx); 15370 { 15371 TCGv t0 = tcg_temp_new(); 15372 15373 gen_load_gpr(t0, rs); 15374 gen_helper_yield(t0, cpu_env, t0); 15375 gen_store_gpr(t0, rd); 15376 tcg_temp_free(t0); 15377 } 15378 break; 15379 default: 15380 if (ctx->insn_flags & ISA_MIPS_R6) { 15381 decode_opc_special3_r6(env, ctx); 15382 } else { 15383 decode_opc_special3_legacy(env, ctx); 15384 } 15385 } 15386 } 15387 15388 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) 15389 { 15390 int32_t offset; 15391 int rs, rt, rd, sa; 15392 uint32_t op, op1; 15393 int16_t imm; 15394 15395 op = MASK_OP_MAJOR(ctx->opcode); 15396 rs = (ctx->opcode >> 21) & 0x1f; 15397 rt = (ctx->opcode >> 16) & 0x1f; 15398 rd = (ctx->opcode >> 11) & 0x1f; 15399 sa = (ctx->opcode >> 6) & 0x1f; 15400 imm = (int16_t)ctx->opcode; 15401 switch (op) { 15402 case OPC_SPECIAL: 15403 decode_opc_special(env, ctx); 15404 break; 15405 case OPC_SPECIAL2: 15406 #if defined(TARGET_MIPS64) 15407 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { 15408 decode_mmi(env, ctx); 15409 break; 15410 } 15411 #endif 15412 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) { 15413 if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) { 15414 gen_arith(ctx, OPC_MUL, rd, rs, rt); 15415 } else { 15416 decode_ase_mxu(ctx, ctx->opcode); 15417 } 15418 break; 15419 } 15420 decode_opc_special2_legacy(env, ctx); 15421 break; 15422 case OPC_SPECIAL3: 15423 #if defined(TARGET_MIPS64) 15424 if (ctx->insn_flags & INSN_R5900) { 15425 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ 15426 } else { 15427 decode_opc_special3(env, ctx); 15428 } 15429 #else 15430 decode_opc_special3(env, ctx); 15431 #endif 15432 break; 15433 case OPC_REGIMM: 15434 op1 = MASK_REGIMM(ctx->opcode); 15435 switch (op1) { 15436 case OPC_BLTZL: /* REGIMM branches */ 15437 case OPC_BGEZL: 15438 case OPC_BLTZALL: 15439 case OPC_BGEZALL: 15440 check_insn(ctx, ISA_MIPS2); 15441 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15442 /* Fallthrough */ 15443 case OPC_BLTZ: 15444 case OPC_BGEZ: 15445 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 15446 break; 15447 case OPC_BLTZAL: 15448 case OPC_BGEZAL: 15449 if (ctx->insn_flags & ISA_MIPS_R6) { 15450 if (rs == 0) { 15451 /* OPC_NAL, OPC_BAL */ 15452 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); 15453 } else { 15454 gen_reserved_instruction(ctx); 15455 } 15456 } else { 15457 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 15458 } 15459 break; 15460 case OPC_TGEI: /* REGIMM traps */ 15461 case OPC_TGEIU: 15462 case OPC_TLTI: 15463 case OPC_TLTIU: 15464 case OPC_TEQI: 15465 15466 case OPC_TNEI: 15467 check_insn(ctx, ISA_MIPS2); 15468 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15469 gen_trap(ctx, op1, rs, -1, imm); 15470 break; 15471 case OPC_SIGRIE: 15472 check_insn(ctx, ISA_MIPS_R6); 15473 gen_reserved_instruction(ctx); 15474 break; 15475 case OPC_SYNCI: 15476 check_insn(ctx, ISA_MIPS_R2); 15477 /* 15478 * Break the TB to be able to sync copied instructions 15479 * immediately. 15480 */ 15481 ctx->base.is_jmp = DISAS_STOP; 15482 break; 15483 case OPC_BPOSGE32: /* MIPS DSP branch */ 15484 #if defined(TARGET_MIPS64) 15485 case OPC_BPOSGE64: 15486 #endif 15487 check_dsp(ctx); 15488 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); 15489 break; 15490 #if defined(TARGET_MIPS64) 15491 case OPC_DAHI: 15492 check_insn(ctx, ISA_MIPS_R6); 15493 check_mips_64(ctx); 15494 if (rs != 0) { 15495 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); 15496 } 15497 break; 15498 case OPC_DATI: 15499 check_insn(ctx, ISA_MIPS_R6); 15500 check_mips_64(ctx); 15501 if (rs != 0) { 15502 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); 15503 } 15504 break; 15505 #endif 15506 default: /* Invalid */ 15507 MIPS_INVAL("regimm"); 15508 gen_reserved_instruction(ctx); 15509 break; 15510 } 15511 break; 15512 case OPC_CP0: 15513 check_cp0_enabled(ctx); 15514 op1 = MASK_CP0(ctx->opcode); 15515 switch (op1) { 15516 case OPC_MFC0: 15517 case OPC_MTC0: 15518 case OPC_MFTR: 15519 case OPC_MTTR: 15520 case OPC_MFHC0: 15521 case OPC_MTHC0: 15522 #if defined(TARGET_MIPS64) 15523 case OPC_DMFC0: 15524 case OPC_DMTC0: 15525 #endif 15526 #ifndef CONFIG_USER_ONLY 15527 gen_cp0(env, ctx, op1, rt, rd); 15528 #endif /* !CONFIG_USER_ONLY */ 15529 break; 15530 case OPC_C0: 15531 case OPC_C0_1: 15532 case OPC_C0_2: 15533 case OPC_C0_3: 15534 case OPC_C0_4: 15535 case OPC_C0_5: 15536 case OPC_C0_6: 15537 case OPC_C0_7: 15538 case OPC_C0_8: 15539 case OPC_C0_9: 15540 case OPC_C0_A: 15541 case OPC_C0_B: 15542 case OPC_C0_C: 15543 case OPC_C0_D: 15544 case OPC_C0_E: 15545 case OPC_C0_F: 15546 #ifndef CONFIG_USER_ONLY 15547 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 15548 #endif /* !CONFIG_USER_ONLY */ 15549 break; 15550 case OPC_MFMC0: 15551 #ifndef CONFIG_USER_ONLY 15552 { 15553 uint32_t op2; 15554 TCGv t0 = tcg_temp_new(); 15555 15556 op2 = MASK_MFMC0(ctx->opcode); 15557 switch (op2) { 15558 case OPC_DMT: 15559 check_cp0_mt(ctx); 15560 gen_helper_dmt(t0); 15561 gen_store_gpr(t0, rt); 15562 break; 15563 case OPC_EMT: 15564 check_cp0_mt(ctx); 15565 gen_helper_emt(t0); 15566 gen_store_gpr(t0, rt); 15567 break; 15568 case OPC_DVPE: 15569 check_cp0_mt(ctx); 15570 gen_helper_dvpe(t0, cpu_env); 15571 gen_store_gpr(t0, rt); 15572 break; 15573 case OPC_EVPE: 15574 check_cp0_mt(ctx); 15575 gen_helper_evpe(t0, cpu_env); 15576 gen_store_gpr(t0, rt); 15577 break; 15578 case OPC_DVP: 15579 check_insn(ctx, ISA_MIPS_R6); 15580 if (ctx->vp) { 15581 gen_helper_dvp(t0, cpu_env); 15582 gen_store_gpr(t0, rt); 15583 } 15584 break; 15585 case OPC_EVP: 15586 check_insn(ctx, ISA_MIPS_R6); 15587 if (ctx->vp) { 15588 gen_helper_evp(t0, cpu_env); 15589 gen_store_gpr(t0, rt); 15590 } 15591 break; 15592 case OPC_DI: 15593 check_insn(ctx, ISA_MIPS_R2); 15594 save_cpu_state(ctx, 1); 15595 gen_helper_di(t0, cpu_env); 15596 gen_store_gpr(t0, rt); 15597 /* 15598 * Stop translation as we may have switched 15599 * the execution mode. 15600 */ 15601 ctx->base.is_jmp = DISAS_STOP; 15602 break; 15603 case OPC_EI: 15604 check_insn(ctx, ISA_MIPS_R2); 15605 save_cpu_state(ctx, 1); 15606 gen_helper_ei(t0, cpu_env); 15607 gen_store_gpr(t0, rt); 15608 /* 15609 * DISAS_STOP isn't sufficient, we need to ensure we break 15610 * out of translated code to check for pending interrupts. 15611 */ 15612 gen_save_pc(ctx->base.pc_next + 4); 15613 ctx->base.is_jmp = DISAS_EXIT; 15614 break; 15615 default: /* Invalid */ 15616 MIPS_INVAL("mfmc0"); 15617 gen_reserved_instruction(ctx); 15618 break; 15619 } 15620 tcg_temp_free(t0); 15621 } 15622 #endif /* !CONFIG_USER_ONLY */ 15623 break; 15624 case OPC_RDPGPR: 15625 check_insn(ctx, ISA_MIPS_R2); 15626 gen_load_srsgpr(rt, rd); 15627 break; 15628 case OPC_WRPGPR: 15629 check_insn(ctx, ISA_MIPS_R2); 15630 gen_store_srsgpr(rt, rd); 15631 break; 15632 default: 15633 MIPS_INVAL("cp0"); 15634 gen_reserved_instruction(ctx); 15635 break; 15636 } 15637 break; 15638 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */ 15639 if (ctx->insn_flags & ISA_MIPS_R6) { 15640 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */ 15641 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15642 } else { 15643 /* OPC_ADDI */ 15644 /* Arithmetic with immediate opcode */ 15645 gen_arith_imm(ctx, op, rt, rs, imm); 15646 } 15647 break; 15648 case OPC_ADDIU: 15649 gen_arith_imm(ctx, op, rt, rs, imm); 15650 break; 15651 case OPC_SLTI: /* Set on less than with immediate opcode */ 15652 case OPC_SLTIU: 15653 gen_slt_imm(ctx, op, rt, rs, imm); 15654 break; 15655 case OPC_ANDI: /* Arithmetic with immediate opcode */ 15656 case OPC_LUI: /* OPC_AUI */ 15657 case OPC_ORI: 15658 case OPC_XORI: 15659 gen_logic_imm(ctx, op, rt, rs, imm); 15660 break; 15661 case OPC_J: /* Jump */ 15662 case OPC_JAL: 15663 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 15664 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 15665 break; 15666 /* Branch */ 15667 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ 15668 if (ctx->insn_flags & ISA_MIPS_R6) { 15669 if (rt == 0) { 15670 gen_reserved_instruction(ctx); 15671 break; 15672 } 15673 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */ 15674 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15675 } else { 15676 /* OPC_BLEZL */ 15677 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15678 } 15679 break; 15680 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ 15681 if (ctx->insn_flags & ISA_MIPS_R6) { 15682 if (rt == 0) { 15683 gen_reserved_instruction(ctx); 15684 break; 15685 } 15686 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */ 15687 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15688 } else { 15689 /* OPC_BGTZL */ 15690 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15691 } 15692 break; 15693 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */ 15694 if (rt == 0) { 15695 /* OPC_BLEZ */ 15696 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15697 } else { 15698 check_insn(ctx, ISA_MIPS_R6); 15699 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */ 15700 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15701 } 15702 break; 15703 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */ 15704 if (rt == 0) { 15705 /* OPC_BGTZ */ 15706 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15707 } else { 15708 check_insn(ctx, ISA_MIPS_R6); 15709 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */ 15710 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15711 } 15712 break; 15713 case OPC_BEQL: 15714 case OPC_BNEL: 15715 check_insn(ctx, ISA_MIPS2); 15716 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15717 /* Fallthrough */ 15718 case OPC_BEQ: 15719 case OPC_BNE: 15720 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15721 break; 15722 case OPC_LL: /* Load and stores */ 15723 check_insn(ctx, ISA_MIPS2); 15724 if (ctx->insn_flags & INSN_R5900) { 15725 check_insn_opc_user_only(ctx, INSN_R5900); 15726 } 15727 /* Fallthrough */ 15728 case OPC_LWL: 15729 case OPC_LWR: 15730 case OPC_LB: 15731 case OPC_LH: 15732 case OPC_LW: 15733 case OPC_LWPC: 15734 case OPC_LBU: 15735 case OPC_LHU: 15736 gen_ld(ctx, op, rt, rs, imm); 15737 break; 15738 case OPC_SWL: 15739 case OPC_SWR: 15740 case OPC_SB: 15741 case OPC_SH: 15742 case OPC_SW: 15743 gen_st(ctx, op, rt, rs, imm); 15744 break; 15745 case OPC_SC: 15746 check_insn(ctx, ISA_MIPS2); 15747 if (ctx->insn_flags & INSN_R5900) { 15748 check_insn_opc_user_only(ctx, INSN_R5900); 15749 } 15750 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); 15751 break; 15752 case OPC_CACHE: 15753 check_cp0_enabled(ctx); 15754 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 15755 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 15756 gen_cache_operation(ctx, rt, rs, imm); 15757 } 15758 /* Treat as NOP. */ 15759 break; 15760 case OPC_PREF: 15761 if (ctx->insn_flags & INSN_R5900) { 15762 /* Treat as NOP. */ 15763 } else { 15764 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 15765 /* Treat as NOP. */ 15766 } 15767 break; 15768 15769 /* Floating point (COP1). */ 15770 case OPC_LWC1: 15771 case OPC_LDC1: 15772 case OPC_SWC1: 15773 case OPC_SDC1: 15774 gen_cop1_ldst(ctx, op, rt, rs, imm); 15775 break; 15776 15777 case OPC_CP1: 15778 op1 = MASK_CP1(ctx->opcode); 15779 15780 switch (op1) { 15781 case OPC_MFHC1: 15782 case OPC_MTHC1: 15783 check_cp1_enabled(ctx); 15784 check_insn(ctx, ISA_MIPS_R2); 15785 /* fall through */ 15786 case OPC_MFC1: 15787 case OPC_CFC1: 15788 case OPC_MTC1: 15789 case OPC_CTC1: 15790 check_cp1_enabled(ctx); 15791 gen_cp1(ctx, op1, rt, rd); 15792 break; 15793 #if defined(TARGET_MIPS64) 15794 case OPC_DMFC1: 15795 case OPC_DMTC1: 15796 check_cp1_enabled(ctx); 15797 check_insn(ctx, ISA_MIPS3); 15798 check_mips_64(ctx); 15799 gen_cp1(ctx, op1, rt, rd); 15800 break; 15801 #endif 15802 case OPC_BC1EQZ: /* OPC_BC1ANY2 */ 15803 check_cp1_enabled(ctx); 15804 if (ctx->insn_flags & ISA_MIPS_R6) { 15805 /* OPC_BC1EQZ */ 15806 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 15807 rt, imm << 2, 4); 15808 } else { 15809 /* OPC_BC1ANY2 */ 15810 check_cop1x(ctx); 15811 check_insn(ctx, ASE_MIPS3D); 15812 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 15813 (rt >> 2) & 0x7, imm << 2); 15814 } 15815 break; 15816 case OPC_BC1NEZ: 15817 check_cp1_enabled(ctx); 15818 check_insn(ctx, ISA_MIPS_R6); 15819 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 15820 rt, imm << 2, 4); 15821 break; 15822 case OPC_BC1ANY4: 15823 check_cp1_enabled(ctx); 15824 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15825 check_cop1x(ctx); 15826 check_insn(ctx, ASE_MIPS3D); 15827 /* fall through */ 15828 case OPC_BC1: 15829 check_cp1_enabled(ctx); 15830 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15831 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 15832 (rt >> 2) & 0x7, imm << 2); 15833 break; 15834 case OPC_PS_FMT: 15835 check_ps(ctx); 15836 /* fall through */ 15837 case OPC_S_FMT: 15838 case OPC_D_FMT: 15839 check_cp1_enabled(ctx); 15840 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 15841 (imm >> 8) & 0x7); 15842 break; 15843 case OPC_W_FMT: 15844 case OPC_L_FMT: 15845 { 15846 int r6_op = ctx->opcode & FOP(0x3f, 0x1f); 15847 check_cp1_enabled(ctx); 15848 if (ctx->insn_flags & ISA_MIPS_R6) { 15849 switch (r6_op) { 15850 case R6_OPC_CMP_AF_S: 15851 case R6_OPC_CMP_UN_S: 15852 case R6_OPC_CMP_EQ_S: 15853 case R6_OPC_CMP_UEQ_S: 15854 case R6_OPC_CMP_LT_S: 15855 case R6_OPC_CMP_ULT_S: 15856 case R6_OPC_CMP_LE_S: 15857 case R6_OPC_CMP_ULE_S: 15858 case R6_OPC_CMP_SAF_S: 15859 case R6_OPC_CMP_SUN_S: 15860 case R6_OPC_CMP_SEQ_S: 15861 case R6_OPC_CMP_SEUQ_S: 15862 case R6_OPC_CMP_SLT_S: 15863 case R6_OPC_CMP_SULT_S: 15864 case R6_OPC_CMP_SLE_S: 15865 case R6_OPC_CMP_SULE_S: 15866 case R6_OPC_CMP_OR_S: 15867 case R6_OPC_CMP_UNE_S: 15868 case R6_OPC_CMP_NE_S: 15869 case R6_OPC_CMP_SOR_S: 15870 case R6_OPC_CMP_SUNE_S: 15871 case R6_OPC_CMP_SNE_S: 15872 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa); 15873 break; 15874 case R6_OPC_CMP_AF_D: 15875 case R6_OPC_CMP_UN_D: 15876 case R6_OPC_CMP_EQ_D: 15877 case R6_OPC_CMP_UEQ_D: 15878 case R6_OPC_CMP_LT_D: 15879 case R6_OPC_CMP_ULT_D: 15880 case R6_OPC_CMP_LE_D: 15881 case R6_OPC_CMP_ULE_D: 15882 case R6_OPC_CMP_SAF_D: 15883 case R6_OPC_CMP_SUN_D: 15884 case R6_OPC_CMP_SEQ_D: 15885 case R6_OPC_CMP_SEUQ_D: 15886 case R6_OPC_CMP_SLT_D: 15887 case R6_OPC_CMP_SULT_D: 15888 case R6_OPC_CMP_SLE_D: 15889 case R6_OPC_CMP_SULE_D: 15890 case R6_OPC_CMP_OR_D: 15891 case R6_OPC_CMP_UNE_D: 15892 case R6_OPC_CMP_NE_D: 15893 case R6_OPC_CMP_SOR_D: 15894 case R6_OPC_CMP_SUNE_D: 15895 case R6_OPC_CMP_SNE_D: 15896 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa); 15897 break; 15898 default: 15899 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), 15900 rt, rd, sa, (imm >> 8) & 0x7); 15901 15902 break; 15903 } 15904 } else { 15905 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 15906 (imm >> 8) & 0x7); 15907 } 15908 break; 15909 } 15910 default: 15911 MIPS_INVAL("cp1"); 15912 gen_reserved_instruction(ctx); 15913 break; 15914 } 15915 break; 15916 15917 /* Compact branches [R6] and COP2 [non-R6] */ 15918 case OPC_BC: /* OPC_LWC2 */ 15919 case OPC_BALC: /* OPC_SWC2 */ 15920 if (ctx->insn_flags & ISA_MIPS_R6) { 15921 /* OPC_BC, OPC_BALC */ 15922 gen_compute_compact_branch(ctx, op, 0, 0, 15923 sextract32(ctx->opcode << 2, 0, 28)); 15924 } else if (ctx->insn_flags & ASE_LEXT) { 15925 gen_loongson_lswc2(ctx, rt, rs, rd); 15926 } else { 15927 /* OPC_LWC2, OPC_SWC2 */ 15928 /* COP2: Not implemented. */ 15929 generate_exception_err(ctx, EXCP_CpU, 2); 15930 } 15931 break; 15932 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */ 15933 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */ 15934 if (ctx->insn_flags & ISA_MIPS_R6) { 15935 if (rs != 0) { 15936 /* OPC_BEQZC, OPC_BNEZC */ 15937 gen_compute_compact_branch(ctx, op, rs, 0, 15938 sextract32(ctx->opcode << 2, 0, 23)); 15939 } else { 15940 /* OPC_JIC, OPC_JIALC */ 15941 gen_compute_compact_branch(ctx, op, 0, rt, imm); 15942 } 15943 } else if (ctx->insn_flags & ASE_LEXT) { 15944 gen_loongson_lsdc2(ctx, rt, rs, rd); 15945 } else { 15946 /* OPC_LWC2, OPC_SWC2 */ 15947 /* COP2: Not implemented. */ 15948 generate_exception_err(ctx, EXCP_CpU, 2); 15949 } 15950 break; 15951 case OPC_CP2: 15952 check_insn(ctx, ASE_LMMI); 15953 /* Note that these instructions use different fields. */ 15954 gen_loongson_multimedia(ctx, sa, rd, rt); 15955 break; 15956 15957 case OPC_CP3: 15958 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 15959 check_cp1_enabled(ctx); 15960 op1 = MASK_CP3(ctx->opcode); 15961 switch (op1) { 15962 case OPC_LUXC1: 15963 case OPC_SUXC1: 15964 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 15965 /* Fallthrough */ 15966 case OPC_LWXC1: 15967 case OPC_LDXC1: 15968 case OPC_SWXC1: 15969 case OPC_SDXC1: 15970 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15971 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 15972 break; 15973 case OPC_PREFX: 15974 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15975 /* Treat as NOP. */ 15976 break; 15977 case OPC_ALNV_PS: 15978 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 15979 /* Fallthrough */ 15980 case OPC_MADD_S: 15981 case OPC_MADD_D: 15982 case OPC_MADD_PS: 15983 case OPC_MSUB_S: 15984 case OPC_MSUB_D: 15985 case OPC_MSUB_PS: 15986 case OPC_NMADD_S: 15987 case OPC_NMADD_D: 15988 case OPC_NMADD_PS: 15989 case OPC_NMSUB_S: 15990 case OPC_NMSUB_D: 15991 case OPC_NMSUB_PS: 15992 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15993 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 15994 break; 15995 default: 15996 MIPS_INVAL("cp3"); 15997 gen_reserved_instruction(ctx); 15998 break; 15999 } 16000 } else { 16001 generate_exception_err(ctx, EXCP_CpU, 1); 16002 } 16003 break; 16004 16005 #if defined(TARGET_MIPS64) 16006 /* MIPS64 opcodes */ 16007 case OPC_LLD: 16008 if (ctx->insn_flags & INSN_R5900) { 16009 check_insn_opc_user_only(ctx, INSN_R5900); 16010 } 16011 /* fall through */ 16012 case OPC_LDL: 16013 case OPC_LDR: 16014 case OPC_LWU: 16015 case OPC_LD: 16016 check_insn(ctx, ISA_MIPS3); 16017 check_mips_64(ctx); 16018 gen_ld(ctx, op, rt, rs, imm); 16019 break; 16020 case OPC_SDL: 16021 case OPC_SDR: 16022 case OPC_SD: 16023 check_insn(ctx, ISA_MIPS3); 16024 check_mips_64(ctx); 16025 gen_st(ctx, op, rt, rs, imm); 16026 break; 16027 case OPC_SCD: 16028 check_insn(ctx, ISA_MIPS3); 16029 if (ctx->insn_flags & INSN_R5900) { 16030 check_insn_opc_user_only(ctx, INSN_R5900); 16031 } 16032 check_mips_64(ctx); 16033 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false); 16034 break; 16035 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ 16036 if (ctx->insn_flags & ISA_MIPS_R6) { 16037 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */ 16038 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 16039 } else { 16040 /* OPC_DADDI */ 16041 check_insn(ctx, ISA_MIPS3); 16042 check_mips_64(ctx); 16043 gen_arith_imm(ctx, op, rt, rs, imm); 16044 } 16045 break; 16046 case OPC_DADDIU: 16047 check_insn(ctx, ISA_MIPS3); 16048 check_mips_64(ctx); 16049 gen_arith_imm(ctx, op, rt, rs, imm); 16050 break; 16051 #else 16052 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 16053 if (ctx->insn_flags & ISA_MIPS_R6) { 16054 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 16055 } else { 16056 MIPS_INVAL("major opcode"); 16057 gen_reserved_instruction(ctx); 16058 } 16059 break; 16060 #endif 16061 case OPC_DAUI: /* OPC_JALX */ 16062 if (ctx->insn_flags & ISA_MIPS_R6) { 16063 #if defined(TARGET_MIPS64) 16064 /* OPC_DAUI */ 16065 check_mips_64(ctx); 16066 if (rs == 0) { 16067 generate_exception(ctx, EXCP_RI); 16068 } else if (rt != 0) { 16069 TCGv t0 = tcg_temp_new(); 16070 gen_load_gpr(t0, rs); 16071 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16); 16072 tcg_temp_free(t0); 16073 } 16074 #else 16075 gen_reserved_instruction(ctx); 16076 MIPS_INVAL("major opcode"); 16077 #endif 16078 } else { 16079 /* OPC_JALX */ 16080 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS); 16081 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 16082 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 16083 } 16084 break; 16085 case OPC_MDMX: /* MMI_OPC_LQ */ 16086 if (ctx->insn_flags & INSN_R5900) { 16087 #if defined(TARGET_MIPS64) 16088 gen_mmi_lq(env, ctx); 16089 #endif 16090 } else { 16091 /* MDMX: Not implemented. */ 16092 } 16093 break; 16094 case OPC_PCREL: 16095 check_insn(ctx, ISA_MIPS_R6); 16096 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs); 16097 break; 16098 default: /* Invalid */ 16099 MIPS_INVAL("major opcode"); 16100 return false; 16101 } 16102 return true; 16103 } 16104 16105 static void decode_opc(CPUMIPSState *env, DisasContext *ctx) 16106 { 16107 /* make sure instructions are on a word boundary */ 16108 if (ctx->base.pc_next & 0x3) { 16109 env->CP0_BadVAddr = ctx->base.pc_next; 16110 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); 16111 return; 16112 } 16113 16114 /* Handle blikely not taken case */ 16115 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { 16116 TCGLabel *l1 = gen_new_label(); 16117 16118 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 16119 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 16120 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); 16121 gen_set_label(l1); 16122 } 16123 16124 /* Transition to the auto-generated decoder. */ 16125 16126 /* ISA extensions */ 16127 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) { 16128 return; 16129 } 16130 16131 /* ISA (from latest to oldest) */ 16132 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) { 16133 return; 16134 } 16135 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { 16136 return; 16137 } 16138 16139 if (decode_opc_legacy(env, ctx)) { 16140 return; 16141 } 16142 16143 gen_reserved_instruction(ctx); 16144 } 16145 16146 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 16147 { 16148 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16149 CPUMIPSState *env = cs->env_ptr; 16150 16151 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; 16152 ctx->saved_pc = -1; 16153 ctx->insn_flags = env->insn_flags; 16154 ctx->CP0_Config1 = env->CP0_Config1; 16155 ctx->CP0_Config2 = env->CP0_Config2; 16156 ctx->CP0_Config3 = env->CP0_Config3; 16157 ctx->CP0_Config5 = env->CP0_Config5; 16158 ctx->btarget = 0; 16159 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; 16160 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; 16161 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3; 16162 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1; 16163 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1; 16164 ctx->PAMask = env->PAMask; 16165 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; 16166 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; 16167 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1; 16168 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift; 16169 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; 16170 /* Restore delay slot state from the tb context. */ 16171 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ 16172 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; 16173 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || 16174 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); 16175 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1; 16176 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; 16177 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; 16178 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; 16179 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1; 16180 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3; 16181 restore_cpu_state(env, ctx); 16182 #ifdef CONFIG_USER_ONLY 16183 ctx->mem_idx = MIPS_HFLAG_UM; 16184 #else 16185 ctx->mem_idx = hflags_mmu_index(ctx->hflags); 16186 #endif 16187 ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 | 16188 INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN; 16189 16190 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, 16191 ctx->hflags); 16192 } 16193 16194 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) 16195 { 16196 } 16197 16198 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 16199 { 16200 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16201 16202 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, 16203 ctx->btarget); 16204 } 16205 16206 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, 16207 const CPUBreakpoint *bp) 16208 { 16209 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16210 16211 save_cpu_state(ctx, 1); 16212 ctx->base.is_jmp = DISAS_NORETURN; 16213 gen_helper_raise_exception_debug(cpu_env); 16214 /* 16215 * The address covered by the breakpoint must be included in 16216 * [tb->pc, tb->pc + tb->size) in order to for it to be 16217 * properly cleared -- thus we increment the PC here so that 16218 * the logic setting tb->size below does the right thing. 16219 */ 16220 ctx->base.pc_next += 4; 16221 return true; 16222 } 16223 16224 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 16225 { 16226 CPUMIPSState *env = cs->env_ptr; 16227 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16228 int insn_bytes; 16229 int is_slot; 16230 16231 is_slot = ctx->hflags & MIPS_HFLAG_BMASK; 16232 if (ctx->insn_flags & ISA_NANOMIPS32) { 16233 ctx->opcode = translator_lduw(env, ctx->base.pc_next); 16234 insn_bytes = decode_isa_nanomips(env, ctx); 16235 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) { 16236 ctx->opcode = translator_ldl(env, ctx->base.pc_next); 16237 insn_bytes = 4; 16238 decode_opc(env, ctx); 16239 } else if (ctx->insn_flags & ASE_MICROMIPS) { 16240 ctx->opcode = translator_lduw(env, ctx->base.pc_next); 16241 insn_bytes = decode_isa_micromips(env, ctx); 16242 } else if (ctx->insn_flags & ASE_MIPS16) { 16243 ctx->opcode = translator_lduw(env, ctx->base.pc_next); 16244 insn_bytes = decode_ase_mips16e(env, ctx); 16245 } else { 16246 gen_reserved_instruction(ctx); 16247 g_assert(ctx->base.is_jmp == DISAS_NORETURN); 16248 return; 16249 } 16250 16251 if (ctx->hflags & MIPS_HFLAG_BMASK) { 16252 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 | 16253 MIPS_HFLAG_FBNSLOT))) { 16254 /* 16255 * Force to generate branch as there is neither delay nor 16256 * forbidden slot. 16257 */ 16258 is_slot = 1; 16259 } 16260 if ((ctx->hflags & MIPS_HFLAG_M16) && 16261 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) { 16262 /* 16263 * Force to generate branch as microMIPS R6 doesn't restrict 16264 * branches in the forbidden slot. 16265 */ 16266 is_slot = 1; 16267 } 16268 } 16269 if (is_slot) { 16270 gen_branch(ctx, insn_bytes); 16271 } 16272 ctx->base.pc_next += insn_bytes; 16273 16274 if (ctx->base.is_jmp != DISAS_NEXT) { 16275 return; 16276 } 16277 /* 16278 * Execute a branch and its delay slot as a single instruction. 16279 * This is what GDB expects and is consistent with what the 16280 * hardware does (e.g. if a delay slot instruction faults, the 16281 * reported PC is the PC of the branch). 16282 */ 16283 if (ctx->base.singlestep_enabled && 16284 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) { 16285 ctx->base.is_jmp = DISAS_TOO_MANY; 16286 } 16287 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) { 16288 ctx->base.is_jmp = DISAS_TOO_MANY; 16289 } 16290 } 16291 16292 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 16293 { 16294 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16295 16296 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) { 16297 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT); 16298 gen_helper_raise_exception_debug(cpu_env); 16299 } else { 16300 switch (ctx->base.is_jmp) { 16301 case DISAS_STOP: 16302 gen_save_pc(ctx->base.pc_next); 16303 tcg_gen_lookup_and_goto_ptr(); 16304 break; 16305 case DISAS_NEXT: 16306 case DISAS_TOO_MANY: 16307 save_cpu_state(ctx, 0); 16308 gen_goto_tb(ctx, 0, ctx->base.pc_next); 16309 break; 16310 case DISAS_EXIT: 16311 tcg_gen_exit_tb(NULL, 0); 16312 break; 16313 case DISAS_NORETURN: 16314 break; 16315 default: 16316 g_assert_not_reached(); 16317 } 16318 } 16319 } 16320 16321 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs) 16322 { 16323 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); 16324 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size); 16325 } 16326 16327 static const TranslatorOps mips_tr_ops = { 16328 .init_disas_context = mips_tr_init_disas_context, 16329 .tb_start = mips_tr_tb_start, 16330 .insn_start = mips_tr_insn_start, 16331 .breakpoint_check = mips_tr_breakpoint_check, 16332 .translate_insn = mips_tr_translate_insn, 16333 .tb_stop = mips_tr_tb_stop, 16334 .disas_log = mips_tr_disas_log, 16335 }; 16336 16337 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) 16338 { 16339 DisasContext ctx; 16340 16341 translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns); 16342 } 16343 16344 void mips_tcg_init(void) 16345 { 16346 int i; 16347 16348 cpu_gpr[0] = NULL; 16349 for (i = 1; i < 32; i++) 16350 cpu_gpr[i] = tcg_global_mem_new(cpu_env, 16351 offsetof(CPUMIPSState, 16352 active_tc.gpr[i]), 16353 regnames[i]); 16354 #if defined(TARGET_MIPS64) 16355 cpu_gpr_hi[0] = NULL; 16356 16357 for (unsigned i = 1; i < 32; i++) { 16358 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]); 16359 16360 cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env, 16361 offsetof(CPUMIPSState, 16362 active_tc.gpr_hi[i]), 16363 rname); 16364 } 16365 #endif /* !TARGET_MIPS64 */ 16366 for (i = 0; i < 32; i++) { 16367 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); 16368 16369 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); 16370 } 16371 msa_translate_init(); 16372 cpu_PC = tcg_global_mem_new(cpu_env, 16373 offsetof(CPUMIPSState, active_tc.PC), "PC"); 16374 for (i = 0; i < MIPS_DSP_ACC; i++) { 16375 cpu_HI[i] = tcg_global_mem_new(cpu_env, 16376 offsetof(CPUMIPSState, active_tc.HI[i]), 16377 regnames_HI[i]); 16378 cpu_LO[i] = tcg_global_mem_new(cpu_env, 16379 offsetof(CPUMIPSState, active_tc.LO[i]), 16380 regnames_LO[i]); 16381 } 16382 cpu_dspctrl = tcg_global_mem_new(cpu_env, 16383 offsetof(CPUMIPSState, 16384 active_tc.DSPControl), 16385 "DSPControl"); 16386 bcond = tcg_global_mem_new(cpu_env, 16387 offsetof(CPUMIPSState, bcond), "bcond"); 16388 btarget = tcg_global_mem_new(cpu_env, 16389 offsetof(CPUMIPSState, btarget), "btarget"); 16390 hflags = tcg_global_mem_new_i32(cpu_env, 16391 offsetof(CPUMIPSState, hflags), "hflags"); 16392 16393 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env, 16394 offsetof(CPUMIPSState, active_fpu.fcr0), 16395 "fcr0"); 16396 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env, 16397 offsetof(CPUMIPSState, active_fpu.fcr31), 16398 "fcr31"); 16399 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr), 16400 "lladdr"); 16401 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval), 16402 "llval"); 16403 16404 if (TARGET_LONG_BITS == 32) { 16405 mxu_translate_init(); 16406 } 16407 } 16408 16409 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, 16410 target_ulong *data) 16411 { 16412 env->active_tc.PC = data[0]; 16413 env->hflags &= ~MIPS_HFLAG_BMASK; 16414 env->hflags |= data[1]; 16415 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) { 16416 case MIPS_HFLAG_BR: 16417 break; 16418 case MIPS_HFLAG_BC: 16419 case MIPS_HFLAG_BL: 16420 case MIPS_HFLAG_B: 16421 env->btarget = data[2]; 16422 break; 16423 } 16424 } 16425