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 "exec/translator.h" 36 #include "exec/log.h" 37 #include "qemu/qemu-print.h" 38 #include "fpu_helper.h" 39 #include "translate.h" 40 41 /* 42 * Many sysemu-only helpers are not reachable for user-only. 43 * Define stub generators here, so that we need not either sprinkle 44 * ifdefs through the translator, nor provide the helper function. 45 */ 46 #define STUB_HELPER(NAME, ...) \ 47 static inline void gen_helper_##NAME(__VA_ARGS__) \ 48 { g_assert_not_reached(); } 49 50 #ifdef CONFIG_USER_ONLY 51 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg) 52 #endif 53 54 enum { 55 /* indirect opcode tables */ 56 OPC_SPECIAL = (0x00 << 26), 57 OPC_REGIMM = (0x01 << 26), 58 OPC_CP0 = (0x10 << 26), 59 OPC_CP2 = (0x12 << 26), 60 OPC_CP3 = (0x13 << 26), 61 OPC_SPECIAL2 = (0x1C << 26), 62 OPC_SPECIAL3 = (0x1F << 26), 63 /* arithmetic with immediate */ 64 OPC_ADDI = (0x08 << 26), 65 OPC_ADDIU = (0x09 << 26), 66 OPC_SLTI = (0x0A << 26), 67 OPC_SLTIU = (0x0B << 26), 68 /* logic with immediate */ 69 OPC_ANDI = (0x0C << 26), 70 OPC_ORI = (0x0D << 26), 71 OPC_XORI = (0x0E << 26), 72 OPC_LUI = (0x0F << 26), 73 /* arithmetic with immediate */ 74 OPC_DADDI = (0x18 << 26), 75 OPC_DADDIU = (0x19 << 26), 76 /* Jump and branches */ 77 OPC_J = (0x02 << 26), 78 OPC_JAL = (0x03 << 26), 79 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */ 80 OPC_BEQL = (0x14 << 26), 81 OPC_BNE = (0x05 << 26), 82 OPC_BNEL = (0x15 << 26), 83 OPC_BLEZ = (0x06 << 26), 84 OPC_BLEZL = (0x16 << 26), 85 OPC_BGTZ = (0x07 << 26), 86 OPC_BGTZL = (0x17 << 26), 87 OPC_JALX = (0x1D << 26), 88 OPC_DAUI = (0x1D << 26), 89 /* Load and stores */ 90 OPC_LDL = (0x1A << 26), 91 OPC_LDR = (0x1B << 26), 92 OPC_LB = (0x20 << 26), 93 OPC_LH = (0x21 << 26), 94 OPC_LWL = (0x22 << 26), 95 OPC_LW = (0x23 << 26), 96 OPC_LWPC = OPC_LW | 0x5, 97 OPC_LBU = (0x24 << 26), 98 OPC_LHU = (0x25 << 26), 99 OPC_LWR = (0x26 << 26), 100 OPC_LWU = (0x27 << 26), 101 OPC_SB = (0x28 << 26), 102 OPC_SH = (0x29 << 26), 103 OPC_SWL = (0x2A << 26), 104 OPC_SW = (0x2B << 26), 105 OPC_SDL = (0x2C << 26), 106 OPC_SDR = (0x2D << 26), 107 OPC_SWR = (0x2E << 26), 108 OPC_LL = (0x30 << 26), 109 OPC_LLD = (0x34 << 26), 110 OPC_LD = (0x37 << 26), 111 OPC_LDPC = OPC_LD | 0x5, 112 OPC_SC = (0x38 << 26), 113 OPC_SCD = (0x3C << 26), 114 OPC_SD = (0x3F << 26), 115 /* Floating point load/store */ 116 OPC_LWC1 = (0x31 << 26), 117 OPC_LWC2 = (0x32 << 26), 118 OPC_LDC1 = (0x35 << 26), 119 OPC_LDC2 = (0x36 << 26), 120 OPC_SWC1 = (0x39 << 26), 121 OPC_SWC2 = (0x3A << 26), 122 OPC_SDC1 = (0x3D << 26), 123 OPC_SDC2 = (0x3E << 26), 124 /* Compact Branches */ 125 OPC_BLEZALC = (0x06 << 26), 126 OPC_BGEZALC = (0x06 << 26), 127 OPC_BGEUC = (0x06 << 26), 128 OPC_BGTZALC = (0x07 << 26), 129 OPC_BLTZALC = (0x07 << 26), 130 OPC_BLTUC = (0x07 << 26), 131 OPC_BOVC = (0x08 << 26), 132 OPC_BEQZALC = (0x08 << 26), 133 OPC_BEQC = (0x08 << 26), 134 OPC_BLEZC = (0x16 << 26), 135 OPC_BGEZC = (0x16 << 26), 136 OPC_BGEC = (0x16 << 26), 137 OPC_BGTZC = (0x17 << 26), 138 OPC_BLTZC = (0x17 << 26), 139 OPC_BLTC = (0x17 << 26), 140 OPC_BNVC = (0x18 << 26), 141 OPC_BNEZALC = (0x18 << 26), 142 OPC_BNEC = (0x18 << 26), 143 OPC_BC = (0x32 << 26), 144 OPC_BEQZC = (0x36 << 26), 145 OPC_JIC = (0x36 << 26), 146 OPC_BALC = (0x3A << 26), 147 OPC_BNEZC = (0x3E << 26), 148 OPC_JIALC = (0x3E << 26), 149 /* MDMX ASE specific */ 150 OPC_MDMX = (0x1E << 26), 151 /* Cache and prefetch */ 152 OPC_CACHE = (0x2F << 26), 153 OPC_PREF = (0x33 << 26), 154 /* PC-relative address computation / loads */ 155 OPC_PCREL = (0x3B << 26), 156 }; 157 158 /* PC-relative address computation / loads */ 159 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19))) 160 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16))) 161 enum { 162 /* Instructions determined by bits 19 and 20 */ 163 OPC_ADDIUPC = OPC_PCREL | (0 << 19), 164 R6_OPC_LWPC = OPC_PCREL | (1 << 19), 165 OPC_LWUPC = OPC_PCREL | (2 << 19), 166 167 /* Instructions determined by bits 16 ... 20 */ 168 OPC_AUIPC = OPC_PCREL | (0x1e << 16), 169 OPC_ALUIPC = OPC_PCREL | (0x1f << 16), 170 171 /* Other */ 172 R6_OPC_LDPC = OPC_PCREL | (6 << 18), 173 }; 174 175 /* MIPS special opcodes */ 176 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 177 178 enum { 179 /* Shifts */ 180 OPC_SLL = 0x00 | OPC_SPECIAL, 181 /* NOP is SLL r0, r0, 0 */ 182 /* SSNOP is SLL r0, r0, 1 */ 183 /* EHB is SLL r0, r0, 3 */ 184 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */ 185 OPC_ROTR = OPC_SRL | (1 << 21), 186 OPC_SRA = 0x03 | OPC_SPECIAL, 187 OPC_SLLV = 0x04 | OPC_SPECIAL, 188 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */ 189 OPC_ROTRV = OPC_SRLV | (1 << 6), 190 OPC_SRAV = 0x07 | OPC_SPECIAL, 191 OPC_DSLLV = 0x14 | OPC_SPECIAL, 192 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */ 193 OPC_DROTRV = OPC_DSRLV | (1 << 6), 194 OPC_DSRAV = 0x17 | OPC_SPECIAL, 195 OPC_DSLL = 0x38 | OPC_SPECIAL, 196 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */ 197 OPC_DROTR = OPC_DSRL | (1 << 21), 198 OPC_DSRA = 0x3B | OPC_SPECIAL, 199 OPC_DSLL32 = 0x3C | OPC_SPECIAL, 200 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */ 201 OPC_DROTR32 = OPC_DSRL32 | (1 << 21), 202 OPC_DSRA32 = 0x3F | OPC_SPECIAL, 203 /* Multiplication / division */ 204 OPC_MULT = 0x18 | OPC_SPECIAL, 205 OPC_MULTU = 0x19 | OPC_SPECIAL, 206 OPC_DIV = 0x1A | OPC_SPECIAL, 207 OPC_DIVU = 0x1B | OPC_SPECIAL, 208 OPC_DMULT = 0x1C | OPC_SPECIAL, 209 OPC_DMULTU = 0x1D | OPC_SPECIAL, 210 OPC_DDIV = 0x1E | OPC_SPECIAL, 211 OPC_DDIVU = 0x1F | OPC_SPECIAL, 212 213 /* 2 registers arithmetic / logic */ 214 OPC_ADD = 0x20 | OPC_SPECIAL, 215 OPC_ADDU = 0x21 | OPC_SPECIAL, 216 OPC_SUB = 0x22 | OPC_SPECIAL, 217 OPC_SUBU = 0x23 | OPC_SPECIAL, 218 OPC_AND = 0x24 | OPC_SPECIAL, 219 OPC_OR = 0x25 | OPC_SPECIAL, 220 OPC_XOR = 0x26 | OPC_SPECIAL, 221 OPC_NOR = 0x27 | OPC_SPECIAL, 222 OPC_SLT = 0x2A | OPC_SPECIAL, 223 OPC_SLTU = 0x2B | OPC_SPECIAL, 224 OPC_DADD = 0x2C | OPC_SPECIAL, 225 OPC_DADDU = 0x2D | OPC_SPECIAL, 226 OPC_DSUB = 0x2E | OPC_SPECIAL, 227 OPC_DSUBU = 0x2F | OPC_SPECIAL, 228 /* Jumps */ 229 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */ 230 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */ 231 /* Traps */ 232 OPC_TGE = 0x30 | OPC_SPECIAL, 233 OPC_TGEU = 0x31 | OPC_SPECIAL, 234 OPC_TLT = 0x32 | OPC_SPECIAL, 235 OPC_TLTU = 0x33 | OPC_SPECIAL, 236 OPC_TEQ = 0x34 | OPC_SPECIAL, 237 OPC_TNE = 0x36 | OPC_SPECIAL, 238 /* HI / LO registers load & stores */ 239 OPC_MFHI = 0x10 | OPC_SPECIAL, 240 OPC_MTHI = 0x11 | OPC_SPECIAL, 241 OPC_MFLO = 0x12 | OPC_SPECIAL, 242 OPC_MTLO = 0x13 | OPC_SPECIAL, 243 /* Conditional moves */ 244 OPC_MOVZ = 0x0A | OPC_SPECIAL, 245 OPC_MOVN = 0x0B | OPC_SPECIAL, 246 247 OPC_SELEQZ = 0x35 | OPC_SPECIAL, 248 OPC_SELNEZ = 0x37 | OPC_SPECIAL, 249 250 OPC_MOVCI = 0x01 | OPC_SPECIAL, 251 252 /* Special */ 253 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */ 254 OPC_SYSCALL = 0x0C | OPC_SPECIAL, 255 OPC_BREAK = 0x0D | OPC_SPECIAL, 256 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */ 257 OPC_SYNC = 0x0F | OPC_SPECIAL, 258 259 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, 260 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, 261 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, 262 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, 263 }; 264 265 /* 266 * R6 Multiply and Divide instructions have the same opcode 267 * and function field as legacy OPC_MULT[U]/OPC_DIV[U] 268 */ 269 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff))) 270 271 enum { 272 R6_OPC_MUL = OPC_MULT | (2 << 6), 273 R6_OPC_MUH = OPC_MULT | (3 << 6), 274 R6_OPC_MULU = OPC_MULTU | (2 << 6), 275 R6_OPC_MUHU = OPC_MULTU | (3 << 6), 276 R6_OPC_DIV = OPC_DIV | (2 << 6), 277 R6_OPC_MOD = OPC_DIV | (3 << 6), 278 R6_OPC_DIVU = OPC_DIVU | (2 << 6), 279 R6_OPC_MODU = OPC_DIVU | (3 << 6), 280 281 R6_OPC_DMUL = OPC_DMULT | (2 << 6), 282 R6_OPC_DMUH = OPC_DMULT | (3 << 6), 283 R6_OPC_DMULU = OPC_DMULTU | (2 << 6), 284 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6), 285 R6_OPC_DDIV = OPC_DDIV | (2 << 6), 286 R6_OPC_DMOD = OPC_DDIV | (3 << 6), 287 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6), 288 R6_OPC_DMODU = OPC_DDIVU | (3 << 6), 289 290 R6_OPC_CLZ = 0x10 | OPC_SPECIAL, 291 R6_OPC_CLO = 0x11 | OPC_SPECIAL, 292 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL, 293 R6_OPC_DCLO = 0x13 | OPC_SPECIAL, 294 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL, 295 }; 296 297 /* Multiplication variants of the vr54xx. */ 298 #define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6))) 299 300 enum { 301 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT, 302 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU, 303 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT, 304 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU, 305 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT, 306 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU, 307 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT, 308 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU, 309 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT, 310 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU, 311 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT, 312 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU, 313 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT, 314 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU, 315 }; 316 317 /* REGIMM (rt field) opcodes */ 318 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16))) 319 320 enum { 321 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM, 322 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM, 323 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM, 324 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM, 325 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM, 326 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM, 327 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM, 328 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM, 329 OPC_TGEI = (0x08 << 16) | OPC_REGIMM, 330 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM, 331 OPC_TLTI = (0x0A << 16) | OPC_REGIMM, 332 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM, 333 OPC_TEQI = (0x0C << 16) | OPC_REGIMM, 334 OPC_TNEI = (0x0E << 16) | OPC_REGIMM, 335 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM, 336 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM, 337 338 OPC_DAHI = (0x06 << 16) | OPC_REGIMM, 339 OPC_DATI = (0x1e << 16) | OPC_REGIMM, 340 }; 341 342 /* Special2 opcodes */ 343 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 344 345 enum { 346 /* Multiply & xxx operations */ 347 OPC_MADD = 0x00 | OPC_SPECIAL2, 348 OPC_MADDU = 0x01 | OPC_SPECIAL2, 349 OPC_MUL = 0x02 | OPC_SPECIAL2, 350 OPC_MSUB = 0x04 | OPC_SPECIAL2, 351 OPC_MSUBU = 0x05 | OPC_SPECIAL2, 352 /* Loongson 2F */ 353 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2, 354 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2, 355 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2, 356 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2, 357 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2, 358 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2, 359 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2, 360 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2, 361 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2, 362 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2, 363 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2, 364 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2, 365 /* Misc */ 366 OPC_CLZ = 0x20 | OPC_SPECIAL2, 367 OPC_CLO = 0x21 | OPC_SPECIAL2, 368 OPC_DCLZ = 0x24 | OPC_SPECIAL2, 369 OPC_DCLO = 0x25 | OPC_SPECIAL2, 370 /* Special */ 371 OPC_SDBBP = 0x3F | OPC_SPECIAL2, 372 }; 373 374 /* Special3 opcodes */ 375 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 376 377 enum { 378 OPC_EXT = 0x00 | OPC_SPECIAL3, 379 OPC_DEXTM = 0x01 | OPC_SPECIAL3, 380 OPC_DEXTU = 0x02 | OPC_SPECIAL3, 381 OPC_DEXT = 0x03 | OPC_SPECIAL3, 382 OPC_INS = 0x04 | OPC_SPECIAL3, 383 OPC_DINSM = 0x05 | OPC_SPECIAL3, 384 OPC_DINSU = 0x06 | OPC_SPECIAL3, 385 OPC_DINS = 0x07 | OPC_SPECIAL3, 386 OPC_FORK = 0x08 | OPC_SPECIAL3, 387 OPC_YIELD = 0x09 | OPC_SPECIAL3, 388 OPC_BSHFL = 0x20 | OPC_SPECIAL3, 389 OPC_DBSHFL = 0x24 | OPC_SPECIAL3, 390 OPC_RDHWR = 0x3B | OPC_SPECIAL3, 391 OPC_GINV = 0x3D | OPC_SPECIAL3, 392 393 /* Loongson 2E */ 394 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3, 395 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3, 396 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3, 397 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3, 398 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3, 399 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3, 400 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3, 401 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3, 402 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3, 403 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3, 404 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3, 405 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3, 406 407 /* MIPS DSP Load */ 408 OPC_LX_DSP = 0x0A | OPC_SPECIAL3, 409 /* MIPS DSP Arithmetic */ 410 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3, 411 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3, 412 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3, 413 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3, 414 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */ 415 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */ 416 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3, 417 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3, 418 /* MIPS DSP GPR-Based Shift Sub-class */ 419 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3, 420 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3, 421 /* MIPS DSP Multiply Sub-class insns */ 422 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */ 423 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */ 424 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3, 425 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3, 426 /* DSP Bit/Manipulation Sub-class */ 427 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, 428 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3, 429 /* MIPS DSP Append Sub-class */ 430 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3, 431 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3, 432 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 433 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, 434 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3, 435 436 /* EVA */ 437 OPC_LWLE = 0x19 | OPC_SPECIAL3, 438 OPC_LWRE = 0x1A | OPC_SPECIAL3, 439 OPC_CACHEE = 0x1B | OPC_SPECIAL3, 440 OPC_SBE = 0x1C | OPC_SPECIAL3, 441 OPC_SHE = 0x1D | OPC_SPECIAL3, 442 OPC_SCE = 0x1E | OPC_SPECIAL3, 443 OPC_SWE = 0x1F | OPC_SPECIAL3, 444 OPC_SWLE = 0x21 | OPC_SPECIAL3, 445 OPC_SWRE = 0x22 | OPC_SPECIAL3, 446 OPC_PREFE = 0x23 | OPC_SPECIAL3, 447 OPC_LBUE = 0x28 | OPC_SPECIAL3, 448 OPC_LHUE = 0x29 | OPC_SPECIAL3, 449 OPC_LBE = 0x2C | OPC_SPECIAL3, 450 OPC_LHE = 0x2D | OPC_SPECIAL3, 451 OPC_LLE = 0x2E | OPC_SPECIAL3, 452 OPC_LWE = 0x2F | OPC_SPECIAL3, 453 454 /* R6 */ 455 R6_OPC_PREF = 0x35 | OPC_SPECIAL3, 456 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, 457 R6_OPC_LL = 0x36 | OPC_SPECIAL3, 458 R6_OPC_SC = 0x26 | OPC_SPECIAL3, 459 R6_OPC_LLD = 0x37 | OPC_SPECIAL3, 460 R6_OPC_SCD = 0x27 | OPC_SPECIAL3, 461 }; 462 463 /* Loongson EXT load/store quad word opcodes */ 464 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020)) 465 enum { 466 OPC_GSLQ = 0x0020 | OPC_LWC2, 467 OPC_GSLQC1 = 0x8020 | OPC_LWC2, 468 OPC_GSSHFL = OPC_LWC2, 469 OPC_GSSQ = 0x0020 | OPC_SWC2, 470 OPC_GSSQC1 = 0x8020 | OPC_SWC2, 471 OPC_GSSHFS = OPC_SWC2, 472 }; 473 474 /* Loongson EXT shifted load/store opcodes */ 475 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f)) 476 enum { 477 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL, 478 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL, 479 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL, 480 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL, 481 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS, 482 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS, 483 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS, 484 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS, 485 }; 486 487 /* Loongson EXT LDC2/SDC2 opcodes */ 488 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7)) 489 490 enum { 491 OPC_GSLBX = 0x0 | OPC_LDC2, 492 OPC_GSLHX = 0x1 | OPC_LDC2, 493 OPC_GSLWX = 0x2 | OPC_LDC2, 494 OPC_GSLDX = 0x3 | OPC_LDC2, 495 OPC_GSLWXC1 = 0x6 | OPC_LDC2, 496 OPC_GSLDXC1 = 0x7 | OPC_LDC2, 497 OPC_GSSBX = 0x0 | OPC_SDC2, 498 OPC_GSSHX = 0x1 | OPC_SDC2, 499 OPC_GSSWX = 0x2 | OPC_SDC2, 500 OPC_GSSDX = 0x3 | OPC_SDC2, 501 OPC_GSSWXC1 = 0x6 | OPC_SDC2, 502 OPC_GSSDXC1 = 0x7 | OPC_SDC2, 503 }; 504 505 /* BSHFL opcodes */ 506 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 507 508 enum { 509 OPC_WSBH = (0x02 << 6) | OPC_BSHFL, 510 OPC_SEB = (0x10 << 6) | OPC_BSHFL, 511 OPC_SEH = (0x18 << 6) | OPC_BSHFL, 512 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */ 513 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL, 514 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL, 515 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL, 516 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */ 517 }; 518 519 /* DBSHFL opcodes */ 520 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 521 522 enum { 523 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, 524 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, 525 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */ 526 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL, 527 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL, 528 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL, 529 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL, 530 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL, 531 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL, 532 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL, 533 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */ 534 }; 535 536 /* MIPS DSP REGIMM opcodes */ 537 enum { 538 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM, 539 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM, 540 }; 541 542 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 543 /* MIPS DSP Load */ 544 enum { 545 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP, 546 OPC_LHX = (0x04 << 6) | OPC_LX_DSP, 547 OPC_LWX = (0x00 << 6) | OPC_LX_DSP, 548 OPC_LDX = (0x08 << 6) | OPC_LX_DSP, 549 }; 550 551 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 552 enum { 553 /* MIPS DSP Arithmetic Sub-class */ 554 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP, 555 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP, 556 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP, 557 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP, 558 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP, 559 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP, 560 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP, 561 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP, 562 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP, 563 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP, 564 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP, 565 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP, 566 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP, 567 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP, 568 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP, 569 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP, 570 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP, 571 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP, 572 /* MIPS DSP Multiply Sub-class insns */ 573 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP, 574 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP, 575 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP, 576 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP, 577 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP, 578 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP, 579 }; 580 581 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E 582 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 583 enum { 584 /* MIPS DSP Arithmetic Sub-class */ 585 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP, 586 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP, 587 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP, 588 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP, 589 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP, 590 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP, 591 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP, 592 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP, 593 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP, 594 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP, 595 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP, 596 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP, 597 /* MIPS DSP Multiply Sub-class insns */ 598 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP, 599 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP, 600 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP, 601 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP, 602 }; 603 604 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 605 enum { 606 /* MIPS DSP Arithmetic Sub-class */ 607 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP, 608 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP, 609 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP, 610 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP, 611 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP, 612 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP, 613 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP, 614 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP, 615 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP, 616 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP, 617 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP, 618 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP, 619 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP, 620 /* DSP Bit/Manipulation Sub-class */ 621 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP, 622 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP, 623 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP, 624 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP, 625 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP, 626 }; 627 628 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 629 enum { 630 /* MIPS DSP Arithmetic Sub-class */ 631 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP, 632 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP, 633 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP, 634 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP, 635 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP, 636 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP, 637 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP, 638 /* DSP Compare-Pick Sub-class */ 639 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP, 640 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP, 641 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP, 642 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP, 643 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP, 644 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP, 645 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP, 646 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP, 647 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP, 648 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP, 649 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP, 650 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP, 651 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP, 652 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP, 653 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP, 654 }; 655 656 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 657 enum { 658 /* MIPS DSP GPR-Based Shift Sub-class */ 659 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP, 660 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP, 661 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP, 662 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP, 663 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP, 664 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP, 665 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP, 666 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP, 667 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP, 668 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP, 669 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP, 670 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP, 671 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP, 672 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP, 673 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP, 674 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP, 675 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP, 676 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP, 677 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP, 678 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP, 679 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP, 680 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP, 681 }; 682 683 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 684 enum { 685 /* MIPS DSP Multiply Sub-class insns */ 686 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP, 687 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP, 688 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP, 689 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP, 690 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP, 691 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP, 692 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP, 693 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP, 694 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP, 695 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP, 696 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP, 697 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP, 698 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP, 699 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP, 700 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP, 701 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP, 702 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP, 703 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP, 704 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP, 705 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP, 706 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP, 707 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP, 708 }; 709 710 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 711 enum { 712 /* DSP Bit/Manipulation Sub-class */ 713 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP, 714 }; 715 716 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 717 enum { 718 /* MIPS DSP Append Sub-class */ 719 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP, 720 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP, 721 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP, 722 }; 723 724 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 725 enum { 726 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 727 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP, 728 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP, 729 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP, 730 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP, 731 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP, 732 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP, 733 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP, 734 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP, 735 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP, 736 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP, 737 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP, 738 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP, 739 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP, 740 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP, 741 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP, 742 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP, 743 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP, 744 }; 745 746 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 747 enum { 748 /* MIPS DSP Arithmetic Sub-class */ 749 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP, 750 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP, 751 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP, 752 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP, 753 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP, 754 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP, 755 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP, 756 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP, 757 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP, 758 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP, 759 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP, 760 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP, 761 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP, 762 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP, 763 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP, 764 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP, 765 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP, 766 /* DSP Bit/Manipulation Sub-class */ 767 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP, 768 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP, 769 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP, 770 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP, 771 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP, 772 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP, 773 }; 774 775 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 776 enum { 777 /* MIPS DSP Multiply Sub-class insns */ 778 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP, 779 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP, 780 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP, 781 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP, 782 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP, 783 /* MIPS DSP Arithmetic Sub-class */ 784 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP, 785 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP, 786 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP, 787 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP, 788 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP, 789 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP, 790 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP, 791 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP, 792 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP, 793 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP, 794 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP, 795 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP, 796 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP, 797 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP, 798 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP, 799 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP, 800 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP, 801 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP, 802 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP, 803 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP, 804 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP, 805 }; 806 807 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 808 enum { 809 /* DSP Compare-Pick Sub-class */ 810 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP, 811 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP, 812 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP, 813 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP, 814 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP, 815 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP, 816 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP, 817 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP, 818 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP, 819 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP, 820 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP, 821 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP, 822 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP, 823 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP, 824 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP, 825 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP, 826 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP, 827 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP, 828 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP, 829 /* MIPS DSP Arithmetic Sub-class */ 830 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP, 831 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP, 832 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP, 833 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP, 834 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP, 835 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP, 836 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP, 837 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP, 838 }; 839 840 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 841 enum { 842 /* DSP Append Sub-class */ 843 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP, 844 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP, 845 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP, 846 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP, 847 }; 848 849 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 850 enum { 851 /* MIPS DSP Accumulator and DSPControl Access Sub-class */ 852 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP, 853 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP, 854 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP, 855 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP, 856 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP, 857 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP, 858 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP, 859 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP, 860 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP, 861 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP, 862 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP, 863 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP, 864 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP, 865 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP, 866 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP, 867 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP, 868 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP, 869 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP, 870 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP, 871 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP, 872 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP, 873 }; 874 875 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 876 enum { 877 /* DSP Bit/Manipulation Sub-class */ 878 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP, 879 }; 880 881 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 882 enum { 883 /* MIPS DSP Multiply Sub-class insns */ 884 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP, 885 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP, 886 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP, 887 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP, 888 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP, 889 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP, 890 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP, 891 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP, 892 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP, 893 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP, 894 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP, 895 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP, 896 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP, 897 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP, 898 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP, 899 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP, 900 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP, 901 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP, 902 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP, 903 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP, 904 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP, 905 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP, 906 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP, 907 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP, 908 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP, 909 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP, 910 }; 911 912 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) 913 enum { 914 /* MIPS DSP GPR-Based Shift Sub-class */ 915 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP, 916 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP, 917 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP, 918 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP, 919 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP, 920 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP, 921 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP, 922 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP, 923 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP, 924 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP, 925 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP, 926 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP, 927 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP, 928 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP, 929 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP, 930 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP, 931 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP, 932 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP, 933 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP, 934 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP, 935 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP, 936 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP, 937 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP, 938 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP, 939 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP, 940 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP, 941 }; 942 943 /* Coprocessor 0 (rs field) */ 944 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 945 946 enum { 947 OPC_MFC0 = (0x00 << 21) | OPC_CP0, 948 OPC_DMFC0 = (0x01 << 21) | OPC_CP0, 949 OPC_MFHC0 = (0x02 << 21) | OPC_CP0, 950 OPC_MTC0 = (0x04 << 21) | OPC_CP0, 951 OPC_DMTC0 = (0x05 << 21) | OPC_CP0, 952 OPC_MTHC0 = (0x06 << 21) | OPC_CP0, 953 OPC_MFTR = (0x08 << 21) | OPC_CP0, 954 OPC_RDPGPR = (0x0A << 21) | OPC_CP0, 955 OPC_MFMC0 = (0x0B << 21) | OPC_CP0, 956 OPC_MTTR = (0x0C << 21) | OPC_CP0, 957 OPC_WRPGPR = (0x0E << 21) | OPC_CP0, 958 OPC_C0 = (0x10 << 21) | OPC_CP0, 959 OPC_C0_1 = (0x11 << 21) | OPC_CP0, 960 OPC_C0_2 = (0x12 << 21) | OPC_CP0, 961 OPC_C0_3 = (0x13 << 21) | OPC_CP0, 962 OPC_C0_4 = (0x14 << 21) | OPC_CP0, 963 OPC_C0_5 = (0x15 << 21) | OPC_CP0, 964 OPC_C0_6 = (0x16 << 21) | OPC_CP0, 965 OPC_C0_7 = (0x17 << 21) | OPC_CP0, 966 OPC_C0_8 = (0x18 << 21) | OPC_CP0, 967 OPC_C0_9 = (0x19 << 21) | OPC_CP0, 968 OPC_C0_A = (0x1A << 21) | OPC_CP0, 969 OPC_C0_B = (0x1B << 21) | OPC_CP0, 970 OPC_C0_C = (0x1C << 21) | OPC_CP0, 971 OPC_C0_D = (0x1D << 21) | OPC_CP0, 972 OPC_C0_E = (0x1E << 21) | OPC_CP0, 973 OPC_C0_F = (0x1F << 21) | OPC_CP0, 974 }; 975 976 /* MFMC0 opcodes */ 977 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF)) 978 979 enum { 980 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 981 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0, 982 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0, 983 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0, 984 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, 985 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0, 986 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0, 987 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0, 988 }; 989 990 /* Coprocessor 0 (with rs == C0) */ 991 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F)) 992 993 enum { 994 OPC_TLBR = 0x01 | OPC_C0, 995 OPC_TLBWI = 0x02 | OPC_C0, 996 OPC_TLBINV = 0x03 | OPC_C0, 997 OPC_TLBINVF = 0x04 | OPC_C0, 998 OPC_TLBWR = 0x06 | OPC_C0, 999 OPC_TLBP = 0x08 | OPC_C0, 1000 OPC_RFE = 0x10 | OPC_C0, 1001 OPC_ERET = 0x18 | OPC_C0, 1002 OPC_DERET = 0x1F | OPC_C0, 1003 OPC_WAIT = 0x20 | OPC_C0, 1004 }; 1005 1006 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21))) 1007 1008 enum { 1009 OPC_MFC2 = (0x00 << 21) | OPC_CP2, 1010 OPC_DMFC2 = (0x01 << 21) | OPC_CP2, 1011 OPC_CFC2 = (0x02 << 21) | OPC_CP2, 1012 OPC_MFHC2 = (0x03 << 21) | OPC_CP2, 1013 OPC_MTC2 = (0x04 << 21) | OPC_CP2, 1014 OPC_DMTC2 = (0x05 << 21) | OPC_CP2, 1015 OPC_CTC2 = (0x06 << 21) | OPC_CP2, 1016 OPC_MTHC2 = (0x07 << 21) | OPC_CP2, 1017 OPC_BC2 = (0x08 << 21) | OPC_CP2, 1018 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2, 1019 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2, 1020 }; 1021 1022 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F)) 1023 1024 enum { 1025 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2, 1026 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2, 1027 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2, 1028 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2, 1029 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2, 1030 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2, 1031 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2, 1032 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2, 1033 1034 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2, 1035 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2, 1036 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2, 1037 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2, 1038 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2, 1039 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2, 1040 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2, 1041 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2, 1042 1043 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2, 1044 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2, 1045 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2, 1046 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2, 1047 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2, 1048 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2, 1049 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2, 1050 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2, 1051 1052 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2, 1053 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2, 1054 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2, 1055 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2, 1056 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2, 1057 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2, 1058 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2, 1059 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2, 1060 1061 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2, 1062 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2, 1063 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2, 1064 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2, 1065 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2, 1066 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2, 1067 1068 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2, 1069 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2, 1070 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2, 1071 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2, 1072 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2, 1073 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2, 1074 1075 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2, 1076 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2, 1077 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2, 1078 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2, 1079 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2, 1080 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2, 1081 1082 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2, 1083 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2, 1084 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2, 1085 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2, 1086 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2, 1087 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2, 1088 1089 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2, 1090 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2, 1091 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2, 1092 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2, 1093 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2, 1094 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2, 1095 1096 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2, 1097 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2, 1098 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2, 1099 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2, 1100 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2, 1101 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2, 1102 1103 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2, 1104 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2, 1105 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2, 1106 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2, 1107 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2, 1108 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2, 1109 1110 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2, 1111 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2, 1112 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2, 1113 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2, 1114 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2, 1115 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2, 1116 }; 1117 1118 1119 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F)) 1120 1121 enum { 1122 OPC_LWXC1 = 0x00 | OPC_CP3, 1123 OPC_LDXC1 = 0x01 | OPC_CP3, 1124 OPC_LUXC1 = 0x05 | OPC_CP3, 1125 OPC_SWXC1 = 0x08 | OPC_CP3, 1126 OPC_SDXC1 = 0x09 | OPC_CP3, 1127 OPC_SUXC1 = 0x0D | OPC_CP3, 1128 OPC_PREFX = 0x0F | OPC_CP3, 1129 OPC_ALNV_PS = 0x1E | OPC_CP3, 1130 OPC_MADD_S = 0x20 | OPC_CP3, 1131 OPC_MADD_D = 0x21 | OPC_CP3, 1132 OPC_MADD_PS = 0x26 | OPC_CP3, 1133 OPC_MSUB_S = 0x28 | OPC_CP3, 1134 OPC_MSUB_D = 0x29 | OPC_CP3, 1135 OPC_MSUB_PS = 0x2E | OPC_CP3, 1136 OPC_NMADD_S = 0x30 | OPC_CP3, 1137 OPC_NMADD_D = 0x31 | OPC_CP3, 1138 OPC_NMADD_PS = 0x36 | OPC_CP3, 1139 OPC_NMSUB_S = 0x38 | OPC_CP3, 1140 OPC_NMSUB_D = 0x39 | OPC_CP3, 1141 OPC_NMSUB_PS = 0x3E | OPC_CP3, 1142 }; 1143 1144 /* 1145 * MMI (MultiMedia Instruction) encodings 1146 * ====================================== 1147 * 1148 * MMI instructions encoding table keys: 1149 * 1150 * * This code is reserved for future use. An attempt to execute it 1151 * causes a Reserved Instruction exception. 1152 * % This code indicates an instruction class. The instruction word 1153 * must be further decoded by examining additional tables that show 1154 * the values for other instruction fields. 1155 * # This code is reserved for the unsupported instructions DMULT, 1156 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt 1157 * to execute it causes a Reserved Instruction exception. 1158 * 1159 * MMI instructions encoded by opcode field (MMI, LQ, SQ): 1160 * 1161 * 31 26 0 1162 * +--------+----------------------------------------+ 1163 * | opcode | | 1164 * +--------+----------------------------------------+ 1165 * 1166 * opcode bits 28..26 1167 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1168 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1169 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1170 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ 1171 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI 1172 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL 1173 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ 1174 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU 1175 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE 1176 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD 1177 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD 1178 */ 1179 1180 enum { 1181 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */ 1182 MMI_OPC_LQ = 0x1E << 26, /* Same as OPC_MSA */ 1183 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */ 1184 }; 1185 1186 /* 1187 * MMI instructions with opcode field = MMI: 1188 * 1189 * 31 26 5 0 1190 * +--------+-------------------------------+--------+ 1191 * | MMI | |function| 1192 * +--------+-------------------------------+--------+ 1193 * 1194 * function bits 2..0 1195 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 1196 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 1197 * -------+-------+-------+-------+-------+-------+-------+-------+------- 1198 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | * 1199 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | * 1200 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | * 1201 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | * 1202 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | * 1203 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | * 1204 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH 1205 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW 1206 */ 1207 1208 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F)) 1209 enum { 1210 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */ 1211 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */ 1212 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */ 1213 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */ 1214 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */ 1215 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */ 1216 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI, 1217 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI, 1218 }; 1219 1220 /* global register indices */ 1221 TCGv cpu_gpr[32], cpu_PC; 1222 /* 1223 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[]) 1224 * and the upper halves in cpu_gpr_hi[]. 1225 */ 1226 TCGv_i64 cpu_gpr_hi[32]; 1227 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; 1228 static TCGv cpu_dspctrl, btarget; 1229 TCGv bcond; 1230 static TCGv cpu_lladdr, cpu_llval; 1231 static TCGv_i32 hflags; 1232 TCGv_i32 fpu_fcr0, fpu_fcr31; 1233 TCGv_i64 fpu_f64[32]; 1234 1235 #include "exec/gen-icount.h" 1236 1237 #define gen_helper_0e0i(name, arg) do { \ 1238 TCGv_i32 helper_tmp = tcg_const_i32(arg); \ 1239 gen_helper_##name(cpu_env, helper_tmp); \ 1240 tcg_temp_free_i32(helper_tmp); \ 1241 } while (0) 1242 1243 #define gen_helper_0e1i(name, arg1, arg2) do { \ 1244 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ 1245 gen_helper_##name(cpu_env, arg1, helper_tmp); \ 1246 tcg_temp_free_i32(helper_tmp); \ 1247 } while (0) 1248 1249 #define gen_helper_1e0i(name, ret, arg1) do { \ 1250 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \ 1251 gen_helper_##name(ret, cpu_env, helper_tmp); \ 1252 tcg_temp_free_i32(helper_tmp); \ 1253 } while (0) 1254 1255 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \ 1256 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ 1257 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \ 1258 tcg_temp_free_i32(helper_tmp); \ 1259 } while (0) 1260 1261 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \ 1262 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ 1263 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \ 1264 tcg_temp_free_i32(helper_tmp); \ 1265 } while (0) 1266 1267 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \ 1268 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ 1269 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \ 1270 tcg_temp_free_i32(helper_tmp); \ 1271 } while (0) 1272 1273 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \ 1274 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \ 1275 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \ 1276 tcg_temp_free_i32(helper_tmp); \ 1277 } while (0) 1278 1279 #define DISAS_STOP DISAS_TARGET_0 1280 #define DISAS_EXIT DISAS_TARGET_1 1281 1282 static const char regnames_HI[][4] = { 1283 "HI0", "HI1", "HI2", "HI3", 1284 }; 1285 1286 static const char regnames_LO[][4] = { 1287 "LO0", "LO1", "LO2", "LO3", 1288 }; 1289 1290 /* General purpose registers moves. */ 1291 void gen_load_gpr(TCGv t, int reg) 1292 { 1293 if (reg == 0) { 1294 tcg_gen_movi_tl(t, 0); 1295 } else { 1296 tcg_gen_mov_tl(t, cpu_gpr[reg]); 1297 } 1298 } 1299 1300 void gen_store_gpr(TCGv t, int reg) 1301 { 1302 if (reg != 0) { 1303 tcg_gen_mov_tl(cpu_gpr[reg], t); 1304 } 1305 } 1306 1307 #if defined(TARGET_MIPS64) 1308 void gen_load_gpr_hi(TCGv_i64 t, int reg) 1309 { 1310 if (reg == 0) { 1311 tcg_gen_movi_i64(t, 0); 1312 } else { 1313 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]); 1314 } 1315 } 1316 1317 void gen_store_gpr_hi(TCGv_i64 t, int reg) 1318 { 1319 if (reg != 0) { 1320 tcg_gen_mov_i64(cpu_gpr_hi[reg], t); 1321 } 1322 } 1323 #endif /* TARGET_MIPS64 */ 1324 1325 /* Moves to/from shadow registers. */ 1326 static inline void gen_load_srsgpr(int from, int to) 1327 { 1328 TCGv t0 = tcg_temp_new(); 1329 1330 if (from == 0) { 1331 tcg_gen_movi_tl(t0, 0); 1332 } else { 1333 TCGv_i32 t2 = tcg_temp_new_i32(); 1334 TCGv_ptr addr = tcg_temp_new_ptr(); 1335 1336 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1337 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1338 tcg_gen_andi_i32(t2, t2, 0xf); 1339 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1340 tcg_gen_ext_i32_ptr(addr, t2); 1341 tcg_gen_add_ptr(addr, cpu_env, addr); 1342 1343 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from); 1344 tcg_temp_free_ptr(addr); 1345 tcg_temp_free_i32(t2); 1346 } 1347 gen_store_gpr(t0, to); 1348 tcg_temp_free(t0); 1349 } 1350 1351 static inline void gen_store_srsgpr(int from, int to) 1352 { 1353 if (to != 0) { 1354 TCGv t0 = tcg_temp_new(); 1355 TCGv_i32 t2 = tcg_temp_new_i32(); 1356 TCGv_ptr addr = tcg_temp_new_ptr(); 1357 1358 gen_load_gpr(t0, from); 1359 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl)); 1360 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS); 1361 tcg_gen_andi_i32(t2, t2, 0xf); 1362 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32); 1363 tcg_gen_ext_i32_ptr(addr, t2); 1364 tcg_gen_add_ptr(addr, cpu_env, addr); 1365 1366 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to); 1367 tcg_temp_free_ptr(addr); 1368 tcg_temp_free_i32(t2); 1369 tcg_temp_free(t0); 1370 } 1371 } 1372 1373 /* Tests */ 1374 static inline void gen_save_pc(target_ulong pc) 1375 { 1376 tcg_gen_movi_tl(cpu_PC, pc); 1377 } 1378 1379 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) 1380 { 1381 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); 1382 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { 1383 gen_save_pc(ctx->base.pc_next); 1384 ctx->saved_pc = ctx->base.pc_next; 1385 } 1386 if (ctx->hflags != ctx->saved_hflags) { 1387 tcg_gen_movi_i32(hflags, ctx->hflags); 1388 ctx->saved_hflags = ctx->hflags; 1389 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1390 case MIPS_HFLAG_BR: 1391 break; 1392 case MIPS_HFLAG_BC: 1393 case MIPS_HFLAG_BL: 1394 case MIPS_HFLAG_B: 1395 tcg_gen_movi_tl(btarget, ctx->btarget); 1396 break; 1397 } 1398 } 1399 } 1400 1401 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) 1402 { 1403 ctx->saved_hflags = ctx->hflags; 1404 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) { 1405 case MIPS_HFLAG_BR: 1406 break; 1407 case MIPS_HFLAG_BC: 1408 case MIPS_HFLAG_BL: 1409 case MIPS_HFLAG_B: 1410 ctx->btarget = env->btarget; 1411 break; 1412 } 1413 } 1414 1415 void generate_exception_err(DisasContext *ctx, int excp, int err) 1416 { 1417 TCGv_i32 texcp = tcg_const_i32(excp); 1418 TCGv_i32 terr = tcg_const_i32(err); 1419 save_cpu_state(ctx, 1); 1420 gen_helper_raise_exception_err(cpu_env, texcp, terr); 1421 tcg_temp_free_i32(terr); 1422 tcg_temp_free_i32(texcp); 1423 ctx->base.is_jmp = DISAS_NORETURN; 1424 } 1425 1426 void generate_exception(DisasContext *ctx, int excp) 1427 { 1428 gen_helper_0e0i(raise_exception, excp); 1429 } 1430 1431 void generate_exception_end(DisasContext *ctx, int excp) 1432 { 1433 generate_exception_err(ctx, excp, 0); 1434 } 1435 1436 void gen_reserved_instruction(DisasContext *ctx) 1437 { 1438 generate_exception_end(ctx, EXCP_RI); 1439 } 1440 1441 /* Floating point register moves. */ 1442 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1443 { 1444 if (ctx->hflags & MIPS_HFLAG_FRE) { 1445 generate_exception(ctx, EXCP_RI); 1446 } 1447 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); 1448 } 1449 1450 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) 1451 { 1452 TCGv_i64 t64; 1453 if (ctx->hflags & MIPS_HFLAG_FRE) { 1454 generate_exception(ctx, EXCP_RI); 1455 } 1456 t64 = tcg_temp_new_i64(); 1457 tcg_gen_extu_i32_i64(t64, t); 1458 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); 1459 tcg_temp_free_i64(t64); 1460 } 1461 1462 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1463 { 1464 if (ctx->hflags & MIPS_HFLAG_F64) { 1465 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); 1466 } else { 1467 gen_load_fpr32(ctx, t, reg | 1); 1468 } 1469 } 1470 1471 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) 1472 { 1473 if (ctx->hflags & MIPS_HFLAG_F64) { 1474 TCGv_i64 t64 = tcg_temp_new_i64(); 1475 tcg_gen_extu_i32_i64(t64, t); 1476 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); 1477 tcg_temp_free_i64(t64); 1478 } else { 1479 gen_store_fpr32(ctx, t, reg | 1); 1480 } 1481 } 1482 1483 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1484 { 1485 if (ctx->hflags & MIPS_HFLAG_F64) { 1486 tcg_gen_mov_i64(t, fpu_f64[reg]); 1487 } else { 1488 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]); 1489 } 1490 } 1491 1492 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) 1493 { 1494 if (ctx->hflags & MIPS_HFLAG_F64) { 1495 tcg_gen_mov_i64(fpu_f64[reg], t); 1496 } else { 1497 TCGv_i64 t0; 1498 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32); 1499 t0 = tcg_temp_new_i64(); 1500 tcg_gen_shri_i64(t0, t, 32); 1501 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32); 1502 tcg_temp_free_i64(t0); 1503 } 1504 } 1505 1506 int get_fp_bit(int cc) 1507 { 1508 if (cc) { 1509 return 24 + cc; 1510 } else { 1511 return 23; 1512 } 1513 } 1514 1515 /* Addresses computation */ 1516 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1) 1517 { 1518 tcg_gen_add_tl(ret, arg0, arg1); 1519 1520 #if defined(TARGET_MIPS64) 1521 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1522 tcg_gen_ext32s_i64(ret, ret); 1523 } 1524 #endif 1525 } 1526 1527 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, 1528 target_long ofs) 1529 { 1530 tcg_gen_addi_tl(ret, base, ofs); 1531 1532 #if defined(TARGET_MIPS64) 1533 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1534 tcg_gen_ext32s_i64(ret, ret); 1535 } 1536 #endif 1537 } 1538 1539 /* Addresses computation (translation time) */ 1540 static target_long addr_add(DisasContext *ctx, target_long base, 1541 target_long offset) 1542 { 1543 target_long sum = base + offset; 1544 1545 #if defined(TARGET_MIPS64) 1546 if (ctx->hflags & MIPS_HFLAG_AWRAP) { 1547 sum = (int32_t)sum; 1548 } 1549 #endif 1550 return sum; 1551 } 1552 1553 /* Sign-extract the low 32-bits to a target_long. */ 1554 void gen_move_low32(TCGv ret, TCGv_i64 arg) 1555 { 1556 #if defined(TARGET_MIPS64) 1557 tcg_gen_ext32s_i64(ret, arg); 1558 #else 1559 tcg_gen_extrl_i64_i32(ret, arg); 1560 #endif 1561 } 1562 1563 /* Sign-extract the high 32-bits to a target_long. */ 1564 void gen_move_high32(TCGv ret, TCGv_i64 arg) 1565 { 1566 #if defined(TARGET_MIPS64) 1567 tcg_gen_sari_i64(ret, arg, 32); 1568 #else 1569 tcg_gen_extrh_i64_i32(ret, arg); 1570 #endif 1571 } 1572 1573 bool check_cp0_enabled(DisasContext *ctx) 1574 { 1575 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1576 generate_exception_end(ctx, EXCP_CpU); 1577 return false; 1578 } 1579 return true; 1580 } 1581 1582 void check_cp1_enabled(DisasContext *ctx) 1583 { 1584 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) { 1585 generate_exception_err(ctx, EXCP_CpU, 1); 1586 } 1587 } 1588 1589 /* 1590 * Verify that the processor is running with COP1X instructions enabled. 1591 * This is associated with the nabla symbol in the MIPS32 and MIPS64 1592 * opcode tables. 1593 */ 1594 void check_cop1x(DisasContext *ctx) 1595 { 1596 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) { 1597 gen_reserved_instruction(ctx); 1598 } 1599 } 1600 1601 /* 1602 * Verify that the processor is running with 64-bit floating-point 1603 * operations enabled. 1604 */ 1605 void check_cp1_64bitmode(DisasContext *ctx) 1606 { 1607 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) { 1608 gen_reserved_instruction(ctx); 1609 } 1610 } 1611 1612 /* 1613 * Verify if floating point register is valid; an operation is not defined 1614 * if bit 0 of any register specification is set and the FR bit in the 1615 * Status register equals zero, since the register numbers specify an 1616 * even-odd pair of adjacent coprocessor general registers. When the FR bit 1617 * in the Status register equals one, both even and odd register numbers 1618 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers. 1619 * 1620 * Multiple 64 bit wide registers can be checked by calling 1621 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN); 1622 */ 1623 void check_cp1_registers(DisasContext *ctx, int regs) 1624 { 1625 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) { 1626 gen_reserved_instruction(ctx); 1627 } 1628 } 1629 1630 /* 1631 * Verify that the processor is running with DSP instructions enabled. 1632 * This is enabled by CP0 Status register MX(24) bit. 1633 */ 1634 static inline void check_dsp(DisasContext *ctx) 1635 { 1636 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) { 1637 if (ctx->insn_flags & ASE_DSP) { 1638 generate_exception_end(ctx, EXCP_DSPDIS); 1639 } else { 1640 gen_reserved_instruction(ctx); 1641 } 1642 } 1643 } 1644 1645 static inline void check_dsp_r2(DisasContext *ctx) 1646 { 1647 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) { 1648 if (ctx->insn_flags & ASE_DSP) { 1649 generate_exception_end(ctx, EXCP_DSPDIS); 1650 } else { 1651 gen_reserved_instruction(ctx); 1652 } 1653 } 1654 } 1655 1656 static inline void check_dsp_r3(DisasContext *ctx) 1657 { 1658 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) { 1659 if (ctx->insn_flags & ASE_DSP) { 1660 generate_exception_end(ctx, EXCP_DSPDIS); 1661 } else { 1662 gen_reserved_instruction(ctx); 1663 } 1664 } 1665 } 1666 1667 /* 1668 * This code generates a "reserved instruction" exception if the 1669 * CPU does not support the instruction set corresponding to flags. 1670 */ 1671 void check_insn(DisasContext *ctx, uint64_t flags) 1672 { 1673 if (unlikely(!(ctx->insn_flags & flags))) { 1674 gen_reserved_instruction(ctx); 1675 } 1676 } 1677 1678 /* 1679 * This code generates a "reserved instruction" exception if the 1680 * CPU has corresponding flag set which indicates that the instruction 1681 * has been removed. 1682 */ 1683 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) 1684 { 1685 if (unlikely(ctx->insn_flags & flags)) { 1686 gen_reserved_instruction(ctx); 1687 } 1688 } 1689 1690 /* 1691 * The Linux kernel traps certain reserved instruction exceptions to 1692 * emulate the corresponding instructions. QEMU is the kernel in user 1693 * mode, so those traps are emulated by accepting the instructions. 1694 * 1695 * A reserved instruction exception is generated for flagged CPUs if 1696 * QEMU runs in system mode. 1697 */ 1698 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) 1699 { 1700 #ifndef CONFIG_USER_ONLY 1701 check_insn_opc_removed(ctx, flags); 1702 #endif 1703 } 1704 1705 /* 1706 * This code generates a "reserved instruction" exception if the 1707 * CPU does not support 64-bit paired-single (PS) floating point data type. 1708 */ 1709 static inline void check_ps(DisasContext *ctx) 1710 { 1711 if (unlikely(!ctx->ps)) { 1712 generate_exception(ctx, EXCP_RI); 1713 } 1714 check_cp1_64bitmode(ctx); 1715 } 1716 1717 /* 1718 * This code generates a "reserved instruction" exception if cpu is not 1719 * 64-bit or 64-bit instructions are not enabled. 1720 */ 1721 void check_mips_64(DisasContext *ctx) 1722 { 1723 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) { 1724 gen_reserved_instruction(ctx); 1725 } 1726 } 1727 1728 #ifndef CONFIG_USER_ONLY 1729 static inline void check_mvh(DisasContext *ctx) 1730 { 1731 if (unlikely(!ctx->mvh)) { 1732 generate_exception(ctx, EXCP_RI); 1733 } 1734 } 1735 #endif 1736 1737 /* 1738 * This code generates a "reserved instruction" exception if the 1739 * Config5 XNP bit is set. 1740 */ 1741 static inline void check_xnp(DisasContext *ctx) 1742 { 1743 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) { 1744 gen_reserved_instruction(ctx); 1745 } 1746 } 1747 1748 #ifndef CONFIG_USER_ONLY 1749 /* 1750 * This code generates a "reserved instruction" exception if the 1751 * Config3 PW bit is NOT set. 1752 */ 1753 static inline void check_pw(DisasContext *ctx) 1754 { 1755 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) { 1756 gen_reserved_instruction(ctx); 1757 } 1758 } 1759 #endif 1760 1761 /* 1762 * This code generates a "reserved instruction" exception if the 1763 * Config3 MT bit is NOT set. 1764 */ 1765 static inline void check_mt(DisasContext *ctx) 1766 { 1767 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1768 gen_reserved_instruction(ctx); 1769 } 1770 } 1771 1772 #ifndef CONFIG_USER_ONLY 1773 /* 1774 * This code generates a "coprocessor unusable" exception if CP0 is not 1775 * available, and, if that is not the case, generates a "reserved instruction" 1776 * exception if the Config5 MT bit is NOT set. This is needed for availability 1777 * control of some of MT ASE instructions. 1778 */ 1779 static inline void check_cp0_mt(DisasContext *ctx) 1780 { 1781 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) { 1782 generate_exception_end(ctx, EXCP_CpU); 1783 } else { 1784 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) { 1785 gen_reserved_instruction(ctx); 1786 } 1787 } 1788 } 1789 #endif 1790 1791 /* 1792 * This code generates a "reserved instruction" exception if the 1793 * Config5 NMS bit is set. 1794 */ 1795 static inline void check_nms(DisasContext *ctx) 1796 { 1797 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) { 1798 gen_reserved_instruction(ctx); 1799 } 1800 } 1801 1802 /* 1803 * This code generates a "reserved instruction" exception if the 1804 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, 1805 * Config2 TL, and Config5 L2C are unset. 1806 */ 1807 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) 1808 { 1809 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) && 1810 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) && 1811 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) && 1812 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && 1813 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && 1814 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) { 1815 gen_reserved_instruction(ctx); 1816 } 1817 } 1818 1819 /* 1820 * This code generates a "reserved instruction" exception if the 1821 * Config5 EVA bit is NOT set. 1822 */ 1823 static inline void check_eva(DisasContext *ctx) 1824 { 1825 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) { 1826 gen_reserved_instruction(ctx); 1827 } 1828 } 1829 1830 1831 /* 1832 * Define small wrappers for gen_load_fpr* so that we have a uniform 1833 * calling interface for 32 and 64-bit FPRs. No sense in changing 1834 * all callers for gen_load_fpr32 when we need the CTX parameter for 1835 * this one use. 1836 */ 1837 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) 1838 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) 1839 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \ 1840 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ 1841 int ft, int fs, int cc) \ 1842 { \ 1843 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ 1844 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ 1845 switch (ifmt) { \ 1846 case FMT_PS: \ 1847 check_ps(ctx); \ 1848 break; \ 1849 case FMT_D: \ 1850 if (abs) { \ 1851 check_cop1x(ctx); \ 1852 } \ 1853 check_cp1_registers(ctx, fs | ft); \ 1854 break; \ 1855 case FMT_S: \ 1856 if (abs) { \ 1857 check_cop1x(ctx); \ 1858 } \ 1859 break; \ 1860 } \ 1861 gen_ldcmp_fpr##bits(ctx, fp0, fs); \ 1862 gen_ldcmp_fpr##bits(ctx, fp1, ft); \ 1863 switch (n) { \ 1864 case 0: \ 1865 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \ 1866 break; \ 1867 case 1: \ 1868 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \ 1869 break; \ 1870 case 2: \ 1871 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \ 1872 break; \ 1873 case 3: \ 1874 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \ 1875 break; \ 1876 case 4: \ 1877 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \ 1878 break; \ 1879 case 5: \ 1880 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \ 1881 break; \ 1882 case 6: \ 1883 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \ 1884 break; \ 1885 case 7: \ 1886 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \ 1887 break; \ 1888 case 8: \ 1889 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \ 1890 break; \ 1891 case 9: \ 1892 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \ 1893 break; \ 1894 case 10: \ 1895 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \ 1896 break; \ 1897 case 11: \ 1898 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \ 1899 break; \ 1900 case 12: \ 1901 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \ 1902 break; \ 1903 case 13: \ 1904 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \ 1905 break; \ 1906 case 14: \ 1907 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \ 1908 break; \ 1909 case 15: \ 1910 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \ 1911 break; \ 1912 default: \ 1913 abort(); \ 1914 } \ 1915 tcg_temp_free_i##bits(fp0); \ 1916 tcg_temp_free_i##bits(fp1); \ 1917 } 1918 1919 FOP_CONDS(, 0, d, FMT_D, 64) 1920 FOP_CONDS(abs, 1, d, FMT_D, 64) 1921 FOP_CONDS(, 0, s, FMT_S, 32) 1922 FOP_CONDS(abs, 1, s, FMT_S, 32) 1923 FOP_CONDS(, 0, ps, FMT_PS, 64) 1924 FOP_CONDS(abs, 1, ps, FMT_PS, 64) 1925 #undef FOP_CONDS 1926 1927 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \ 1928 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \ 1929 int ft, int fs, int fd) \ 1930 { \ 1931 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \ 1932 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \ 1933 if (ifmt == FMT_D) { \ 1934 check_cp1_registers(ctx, fs | ft | fd); \ 1935 } \ 1936 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \ 1937 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \ 1938 switch (n) { \ 1939 case 0: \ 1940 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \ 1941 break; \ 1942 case 1: \ 1943 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \ 1944 break; \ 1945 case 2: \ 1946 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \ 1947 break; \ 1948 case 3: \ 1949 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \ 1950 break; \ 1951 case 4: \ 1952 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \ 1953 break; \ 1954 case 5: \ 1955 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \ 1956 break; \ 1957 case 6: \ 1958 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \ 1959 break; \ 1960 case 7: \ 1961 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \ 1962 break; \ 1963 case 8: \ 1964 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \ 1965 break; \ 1966 case 9: \ 1967 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \ 1968 break; \ 1969 case 10: \ 1970 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \ 1971 break; \ 1972 case 11: \ 1973 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \ 1974 break; \ 1975 case 12: \ 1976 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \ 1977 break; \ 1978 case 13: \ 1979 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \ 1980 break; \ 1981 case 14: \ 1982 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \ 1983 break; \ 1984 case 15: \ 1985 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \ 1986 break; \ 1987 case 17: \ 1988 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \ 1989 break; \ 1990 case 18: \ 1991 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \ 1992 break; \ 1993 case 19: \ 1994 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \ 1995 break; \ 1996 case 25: \ 1997 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \ 1998 break; \ 1999 case 26: \ 2000 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \ 2001 break; \ 2002 case 27: \ 2003 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \ 2004 break; \ 2005 default: \ 2006 abort(); \ 2007 } \ 2008 STORE; \ 2009 tcg_temp_free_i ## bits(fp0); \ 2010 tcg_temp_free_i ## bits(fp1); \ 2011 } 2012 2013 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) 2014 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd)) 2015 #undef FOP_CONDNS 2016 #undef gen_ldcmp_fpr32 2017 #undef gen_ldcmp_fpr64 2018 2019 /* load/store instructions. */ 2020 #ifdef CONFIG_USER_ONLY 2021 #define OP_LD_ATOMIC(insn, fname) \ 2022 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 2023 DisasContext *ctx) \ 2024 { \ 2025 TCGv t0 = tcg_temp_new(); \ 2026 tcg_gen_mov_tl(t0, arg1); \ 2027 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ 2028 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \ 2029 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \ 2030 tcg_temp_free(t0); \ 2031 } 2032 #else 2033 #define OP_LD_ATOMIC(insn, fname) \ 2034 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ 2035 DisasContext *ctx) \ 2036 { \ 2037 gen_helper_1e1i(insn, ret, arg1, mem_idx); \ 2038 } 2039 #endif 2040 OP_LD_ATOMIC(ll, ld32s); 2041 #if defined(TARGET_MIPS64) 2042 OP_LD_ATOMIC(lld, ld64); 2043 #endif 2044 #undef OP_LD_ATOMIC 2045 2046 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset) 2047 { 2048 if (base == 0) { 2049 tcg_gen_movi_tl(addr, offset); 2050 } else if (offset == 0) { 2051 gen_load_gpr(addr, base); 2052 } else { 2053 tcg_gen_movi_tl(addr, offset); 2054 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); 2055 } 2056 } 2057 2058 static target_ulong pc_relative_pc(DisasContext *ctx) 2059 { 2060 target_ulong pc = ctx->base.pc_next; 2061 2062 if (ctx->hflags & MIPS_HFLAG_BMASK) { 2063 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4; 2064 2065 pc -= branch_bytes; 2066 } 2067 2068 pc &= ~(target_ulong)3; 2069 return pc; 2070 } 2071 2072 /* Load */ 2073 static void gen_ld(DisasContext *ctx, uint32_t opc, 2074 int rt, int base, int offset) 2075 { 2076 TCGv t0, t1, t2; 2077 int mem_idx = ctx->mem_idx; 2078 2079 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F | 2080 INSN_LOONGSON3A)) { 2081 /* 2082 * Loongson CPU uses a load to zero register for prefetch. 2083 * We emulate it as a NOP. On other CPU we must perform the 2084 * actual memory access. 2085 */ 2086 return; 2087 } 2088 2089 t0 = tcg_temp_new(); 2090 gen_base_offset_addr(ctx, t0, base, offset); 2091 2092 switch (opc) { 2093 #if defined(TARGET_MIPS64) 2094 case OPC_LWU: 2095 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL | 2096 ctx->default_tcg_memop_mask); 2097 gen_store_gpr(t0, rt); 2098 break; 2099 case OPC_LD: 2100 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ | 2101 ctx->default_tcg_memop_mask); 2102 gen_store_gpr(t0, rt); 2103 break; 2104 case OPC_LLD: 2105 case R6_OPC_LLD: 2106 op_ld_lld(t0, t0, mem_idx, ctx); 2107 gen_store_gpr(t0, rt); 2108 break; 2109 case OPC_LDL: 2110 t1 = tcg_temp_new(); 2111 /* 2112 * Do a byte access to possibly trigger a page 2113 * fault with the unaligned address. 2114 */ 2115 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2116 tcg_gen_andi_tl(t1, t0, 7); 2117 #ifndef TARGET_WORDS_BIGENDIAN 2118 tcg_gen_xori_tl(t1, t1, 7); 2119 #endif 2120 tcg_gen_shli_tl(t1, t1, 3); 2121 tcg_gen_andi_tl(t0, t0, ~7); 2122 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); 2123 tcg_gen_shl_tl(t0, t0, t1); 2124 t2 = tcg_const_tl(-1); 2125 tcg_gen_shl_tl(t2, t2, t1); 2126 gen_load_gpr(t1, rt); 2127 tcg_gen_andc_tl(t1, t1, t2); 2128 tcg_temp_free(t2); 2129 tcg_gen_or_tl(t0, t0, t1); 2130 tcg_temp_free(t1); 2131 gen_store_gpr(t0, rt); 2132 break; 2133 case OPC_LDR: 2134 t1 = tcg_temp_new(); 2135 /* 2136 * Do a byte access to possibly trigger a page 2137 * fault with the unaligned address. 2138 */ 2139 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2140 tcg_gen_andi_tl(t1, t0, 7); 2141 #ifdef TARGET_WORDS_BIGENDIAN 2142 tcg_gen_xori_tl(t1, t1, 7); 2143 #endif 2144 tcg_gen_shli_tl(t1, t1, 3); 2145 tcg_gen_andi_tl(t0, t0, ~7); 2146 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); 2147 tcg_gen_shr_tl(t0, t0, t1); 2148 tcg_gen_xori_tl(t1, t1, 63); 2149 t2 = tcg_const_tl(0xfffffffffffffffeull); 2150 tcg_gen_shl_tl(t2, t2, t1); 2151 gen_load_gpr(t1, rt); 2152 tcg_gen_and_tl(t1, t1, t2); 2153 tcg_temp_free(t2); 2154 tcg_gen_or_tl(t0, t0, t1); 2155 tcg_temp_free(t1); 2156 gen_store_gpr(t0, rt); 2157 break; 2158 case OPC_LDPC: 2159 t1 = tcg_const_tl(pc_relative_pc(ctx)); 2160 gen_op_addr_add(ctx, t0, t0, t1); 2161 tcg_temp_free(t1); 2162 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); 2163 gen_store_gpr(t0, rt); 2164 break; 2165 #endif 2166 case OPC_LWPC: 2167 t1 = tcg_const_tl(pc_relative_pc(ctx)); 2168 gen_op_addr_add(ctx, t0, t0, t1); 2169 tcg_temp_free(t1); 2170 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL); 2171 gen_store_gpr(t0, rt); 2172 break; 2173 case OPC_LWE: 2174 mem_idx = MIPS_HFLAG_UM; 2175 /* fall through */ 2176 case OPC_LW: 2177 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL | 2178 ctx->default_tcg_memop_mask); 2179 gen_store_gpr(t0, rt); 2180 break; 2181 case OPC_LHE: 2182 mem_idx = MIPS_HFLAG_UM; 2183 /* fall through */ 2184 case OPC_LH: 2185 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW | 2186 ctx->default_tcg_memop_mask); 2187 gen_store_gpr(t0, rt); 2188 break; 2189 case OPC_LHUE: 2190 mem_idx = MIPS_HFLAG_UM; 2191 /* fall through */ 2192 case OPC_LHU: 2193 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW | 2194 ctx->default_tcg_memop_mask); 2195 gen_store_gpr(t0, rt); 2196 break; 2197 case OPC_LBE: 2198 mem_idx = MIPS_HFLAG_UM; 2199 /* fall through */ 2200 case OPC_LB: 2201 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); 2202 gen_store_gpr(t0, rt); 2203 break; 2204 case OPC_LBUE: 2205 mem_idx = MIPS_HFLAG_UM; 2206 /* fall through */ 2207 case OPC_LBU: 2208 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); 2209 gen_store_gpr(t0, rt); 2210 break; 2211 case OPC_LWLE: 2212 mem_idx = MIPS_HFLAG_UM; 2213 /* fall through */ 2214 case OPC_LWL: 2215 t1 = tcg_temp_new(); 2216 /* 2217 * Do a byte access to possibly trigger a page 2218 * fault with the unaligned address. 2219 */ 2220 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2221 tcg_gen_andi_tl(t1, t0, 3); 2222 #ifndef TARGET_WORDS_BIGENDIAN 2223 tcg_gen_xori_tl(t1, t1, 3); 2224 #endif 2225 tcg_gen_shli_tl(t1, t1, 3); 2226 tcg_gen_andi_tl(t0, t0, ~3); 2227 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); 2228 tcg_gen_shl_tl(t0, t0, t1); 2229 t2 = tcg_const_tl(-1); 2230 tcg_gen_shl_tl(t2, t2, t1); 2231 gen_load_gpr(t1, rt); 2232 tcg_gen_andc_tl(t1, t1, t2); 2233 tcg_temp_free(t2); 2234 tcg_gen_or_tl(t0, t0, t1); 2235 tcg_temp_free(t1); 2236 tcg_gen_ext32s_tl(t0, t0); 2237 gen_store_gpr(t0, rt); 2238 break; 2239 case OPC_LWRE: 2240 mem_idx = MIPS_HFLAG_UM; 2241 /* fall through */ 2242 case OPC_LWR: 2243 t1 = tcg_temp_new(); 2244 /* 2245 * Do a byte access to possibly trigger a page 2246 * fault with the unaligned address. 2247 */ 2248 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); 2249 tcg_gen_andi_tl(t1, t0, 3); 2250 #ifdef TARGET_WORDS_BIGENDIAN 2251 tcg_gen_xori_tl(t1, t1, 3); 2252 #endif 2253 tcg_gen_shli_tl(t1, t1, 3); 2254 tcg_gen_andi_tl(t0, t0, ~3); 2255 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); 2256 tcg_gen_shr_tl(t0, t0, t1); 2257 tcg_gen_xori_tl(t1, t1, 31); 2258 t2 = tcg_const_tl(0xfffffffeull); 2259 tcg_gen_shl_tl(t2, t2, t1); 2260 gen_load_gpr(t1, rt); 2261 tcg_gen_and_tl(t1, t1, t2); 2262 tcg_temp_free(t2); 2263 tcg_gen_or_tl(t0, t0, t1); 2264 tcg_temp_free(t1); 2265 tcg_gen_ext32s_tl(t0, t0); 2266 gen_store_gpr(t0, rt); 2267 break; 2268 case OPC_LLE: 2269 mem_idx = MIPS_HFLAG_UM; 2270 /* fall through */ 2271 case OPC_LL: 2272 case R6_OPC_LL: 2273 op_ld_ll(t0, t0, mem_idx, ctx); 2274 gen_store_gpr(t0, rt); 2275 break; 2276 } 2277 tcg_temp_free(t0); 2278 } 2279 2280 /* Store */ 2281 static void gen_st(DisasContext *ctx, uint32_t opc, int rt, 2282 int base, int offset) 2283 { 2284 TCGv t0 = tcg_temp_new(); 2285 TCGv t1 = tcg_temp_new(); 2286 int mem_idx = ctx->mem_idx; 2287 2288 gen_base_offset_addr(ctx, t0, base, offset); 2289 gen_load_gpr(t1, rt); 2290 switch (opc) { 2291 #if defined(TARGET_MIPS64) 2292 case OPC_SD: 2293 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ | 2294 ctx->default_tcg_memop_mask); 2295 break; 2296 case OPC_SDL: 2297 gen_helper_0e2i(sdl, t1, t0, mem_idx); 2298 break; 2299 case OPC_SDR: 2300 gen_helper_0e2i(sdr, t1, t0, mem_idx); 2301 break; 2302 #endif 2303 case OPC_SWE: 2304 mem_idx = MIPS_HFLAG_UM; 2305 /* fall through */ 2306 case OPC_SW: 2307 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | 2308 ctx->default_tcg_memop_mask); 2309 break; 2310 case OPC_SHE: 2311 mem_idx = MIPS_HFLAG_UM; 2312 /* fall through */ 2313 case OPC_SH: 2314 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | 2315 ctx->default_tcg_memop_mask); 2316 break; 2317 case OPC_SBE: 2318 mem_idx = MIPS_HFLAG_UM; 2319 /* fall through */ 2320 case OPC_SB: 2321 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); 2322 break; 2323 case OPC_SWLE: 2324 mem_idx = MIPS_HFLAG_UM; 2325 /* fall through */ 2326 case OPC_SWL: 2327 gen_helper_0e2i(swl, t1, t0, mem_idx); 2328 break; 2329 case OPC_SWRE: 2330 mem_idx = MIPS_HFLAG_UM; 2331 /* fall through */ 2332 case OPC_SWR: 2333 gen_helper_0e2i(swr, t1, t0, mem_idx); 2334 break; 2335 } 2336 tcg_temp_free(t0); 2337 tcg_temp_free(t1); 2338 } 2339 2340 2341 /* Store conditional */ 2342 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, 2343 MemOp tcg_mo, bool eva) 2344 { 2345 TCGv addr, t0, val; 2346 TCGLabel *l1 = gen_new_label(); 2347 TCGLabel *done = gen_new_label(); 2348 2349 t0 = tcg_temp_new(); 2350 addr = tcg_temp_new(); 2351 /* compare the address against that of the preceding LL */ 2352 gen_base_offset_addr(ctx, addr, base, offset); 2353 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); 2354 tcg_temp_free(addr); 2355 tcg_gen_movi_tl(t0, 0); 2356 gen_store_gpr(t0, rt); 2357 tcg_gen_br(done); 2358 2359 gen_set_label(l1); 2360 /* generate cmpxchg */ 2361 val = tcg_temp_new(); 2362 gen_load_gpr(val, rt); 2363 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, 2364 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo); 2365 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); 2366 gen_store_gpr(t0, rt); 2367 tcg_temp_free(val); 2368 2369 gen_set_label(done); 2370 tcg_temp_free(t0); 2371 } 2372 2373 /* Load and store */ 2374 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, 2375 TCGv t0) 2376 { 2377 /* 2378 * Don't do NOP if destination is zero: we must perform the actual 2379 * memory access. 2380 */ 2381 switch (opc) { 2382 case OPC_LWC1: 2383 { 2384 TCGv_i32 fp0 = tcg_temp_new_i32(); 2385 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | 2386 ctx->default_tcg_memop_mask); 2387 gen_store_fpr32(ctx, fp0, ft); 2388 tcg_temp_free_i32(fp0); 2389 } 2390 break; 2391 case OPC_SWC1: 2392 { 2393 TCGv_i32 fp0 = tcg_temp_new_i32(); 2394 gen_load_fpr32(ctx, fp0, ft); 2395 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | 2396 ctx->default_tcg_memop_mask); 2397 tcg_temp_free_i32(fp0); 2398 } 2399 break; 2400 case OPC_LDC1: 2401 { 2402 TCGv_i64 fp0 = tcg_temp_new_i64(); 2403 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ | 2404 ctx->default_tcg_memop_mask); 2405 gen_store_fpr64(ctx, fp0, ft); 2406 tcg_temp_free_i64(fp0); 2407 } 2408 break; 2409 case OPC_SDC1: 2410 { 2411 TCGv_i64 fp0 = tcg_temp_new_i64(); 2412 gen_load_fpr64(ctx, fp0, ft); 2413 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ | 2414 ctx->default_tcg_memop_mask); 2415 tcg_temp_free_i64(fp0); 2416 } 2417 break; 2418 default: 2419 MIPS_INVAL("flt_ldst"); 2420 gen_reserved_instruction(ctx); 2421 break; 2422 } 2423 } 2424 2425 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, 2426 int rs, int16_t imm) 2427 { 2428 TCGv t0 = tcg_temp_new(); 2429 2430 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2431 check_cp1_enabled(ctx); 2432 switch (op) { 2433 case OPC_LDC1: 2434 case OPC_SDC1: 2435 check_insn(ctx, ISA_MIPS2); 2436 /* Fallthrough */ 2437 default: 2438 gen_base_offset_addr(ctx, t0, rs, imm); 2439 gen_flt_ldst(ctx, op, rt, t0); 2440 } 2441 } else { 2442 generate_exception_err(ctx, EXCP_CpU, 1); 2443 } 2444 tcg_temp_free(t0); 2445 } 2446 2447 /* Arithmetic with immediate operand */ 2448 static void gen_arith_imm(DisasContext *ctx, uint32_t opc, 2449 int rt, int rs, int imm) 2450 { 2451 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2452 2453 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { 2454 /* 2455 * If no destination, treat it as a NOP. 2456 * For addi, we must generate the overflow exception when needed. 2457 */ 2458 return; 2459 } 2460 switch (opc) { 2461 case OPC_ADDI: 2462 { 2463 TCGv t0 = tcg_temp_local_new(); 2464 TCGv t1 = tcg_temp_new(); 2465 TCGv t2 = tcg_temp_new(); 2466 TCGLabel *l1 = gen_new_label(); 2467 2468 gen_load_gpr(t1, rs); 2469 tcg_gen_addi_tl(t0, t1, uimm); 2470 tcg_gen_ext32s_tl(t0, t0); 2471 2472 tcg_gen_xori_tl(t1, t1, ~uimm); 2473 tcg_gen_xori_tl(t2, t0, uimm); 2474 tcg_gen_and_tl(t1, t1, t2); 2475 tcg_temp_free(t2); 2476 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2477 tcg_temp_free(t1); 2478 /* operands of same sign, result different sign */ 2479 generate_exception(ctx, EXCP_OVERFLOW); 2480 gen_set_label(l1); 2481 tcg_gen_ext32s_tl(t0, t0); 2482 gen_store_gpr(t0, rt); 2483 tcg_temp_free(t0); 2484 } 2485 break; 2486 case OPC_ADDIU: 2487 if (rs != 0) { 2488 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2489 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2490 } else { 2491 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2492 } 2493 break; 2494 #if defined(TARGET_MIPS64) 2495 case OPC_DADDI: 2496 { 2497 TCGv t0 = tcg_temp_local_new(); 2498 TCGv t1 = tcg_temp_new(); 2499 TCGv t2 = tcg_temp_new(); 2500 TCGLabel *l1 = gen_new_label(); 2501 2502 gen_load_gpr(t1, rs); 2503 tcg_gen_addi_tl(t0, t1, uimm); 2504 2505 tcg_gen_xori_tl(t1, t1, ~uimm); 2506 tcg_gen_xori_tl(t2, t0, uimm); 2507 tcg_gen_and_tl(t1, t1, t2); 2508 tcg_temp_free(t2); 2509 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2510 tcg_temp_free(t1); 2511 /* operands of same sign, result different sign */ 2512 generate_exception(ctx, EXCP_OVERFLOW); 2513 gen_set_label(l1); 2514 gen_store_gpr(t0, rt); 2515 tcg_temp_free(t0); 2516 } 2517 break; 2518 case OPC_DADDIU: 2519 if (rs != 0) { 2520 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2521 } else { 2522 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2523 } 2524 break; 2525 #endif 2526 } 2527 } 2528 2529 /* Logic with immediate operand */ 2530 static void gen_logic_imm(DisasContext *ctx, uint32_t opc, 2531 int rt, int rs, int16_t imm) 2532 { 2533 target_ulong uimm; 2534 2535 if (rt == 0) { 2536 /* If no destination, treat it as a NOP. */ 2537 return; 2538 } 2539 uimm = (uint16_t)imm; 2540 switch (opc) { 2541 case OPC_ANDI: 2542 if (likely(rs != 0)) { 2543 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2544 } else { 2545 tcg_gen_movi_tl(cpu_gpr[rt], 0); 2546 } 2547 break; 2548 case OPC_ORI: 2549 if (rs != 0) { 2550 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2551 } else { 2552 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2553 } 2554 break; 2555 case OPC_XORI: 2556 if (likely(rs != 0)) { 2557 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); 2558 } else { 2559 tcg_gen_movi_tl(cpu_gpr[rt], uimm); 2560 } 2561 break; 2562 case OPC_LUI: 2563 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) { 2564 /* OPC_AUI */ 2565 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16); 2566 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 2567 } else { 2568 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16); 2569 } 2570 break; 2571 2572 default: 2573 break; 2574 } 2575 } 2576 2577 /* Set on less than with immediate operand */ 2578 static void gen_slt_imm(DisasContext *ctx, uint32_t opc, 2579 int rt, int rs, int16_t imm) 2580 { 2581 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ 2582 TCGv t0; 2583 2584 if (rt == 0) { 2585 /* If no destination, treat it as a NOP. */ 2586 return; 2587 } 2588 t0 = tcg_temp_new(); 2589 gen_load_gpr(t0, rs); 2590 switch (opc) { 2591 case OPC_SLTI: 2592 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); 2593 break; 2594 case OPC_SLTIU: 2595 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); 2596 break; 2597 } 2598 tcg_temp_free(t0); 2599 } 2600 2601 /* Shifts with immediate operand */ 2602 static void gen_shift_imm(DisasContext *ctx, uint32_t opc, 2603 int rt, int rs, int16_t imm) 2604 { 2605 target_ulong uimm = ((uint16_t)imm) & 0x1f; 2606 TCGv t0; 2607 2608 if (rt == 0) { 2609 /* If no destination, treat it as a NOP. */ 2610 return; 2611 } 2612 2613 t0 = tcg_temp_new(); 2614 gen_load_gpr(t0, rs); 2615 switch (opc) { 2616 case OPC_SLL: 2617 tcg_gen_shli_tl(t0, t0, uimm); 2618 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2619 break; 2620 case OPC_SRA: 2621 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2622 break; 2623 case OPC_SRL: 2624 if (uimm != 0) { 2625 tcg_gen_ext32u_tl(t0, t0); 2626 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2627 } else { 2628 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2629 } 2630 break; 2631 case OPC_ROTR: 2632 if (uimm != 0) { 2633 TCGv_i32 t1 = tcg_temp_new_i32(); 2634 2635 tcg_gen_trunc_tl_i32(t1, t0); 2636 tcg_gen_rotri_i32(t1, t1, uimm); 2637 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); 2638 tcg_temp_free_i32(t1); 2639 } else { 2640 tcg_gen_ext32s_tl(cpu_gpr[rt], t0); 2641 } 2642 break; 2643 #if defined(TARGET_MIPS64) 2644 case OPC_DSLL: 2645 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm); 2646 break; 2647 case OPC_DSRA: 2648 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); 2649 break; 2650 case OPC_DSRL: 2651 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); 2652 break; 2653 case OPC_DROTR: 2654 if (uimm != 0) { 2655 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm); 2656 } else { 2657 tcg_gen_mov_tl(cpu_gpr[rt], t0); 2658 } 2659 break; 2660 case OPC_DSLL32: 2661 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32); 2662 break; 2663 case OPC_DSRA32: 2664 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32); 2665 break; 2666 case OPC_DSRL32: 2667 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32); 2668 break; 2669 case OPC_DROTR32: 2670 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32); 2671 break; 2672 #endif 2673 } 2674 tcg_temp_free(t0); 2675 } 2676 2677 /* Arithmetic */ 2678 static void gen_arith(DisasContext *ctx, uint32_t opc, 2679 int rd, int rs, int rt) 2680 { 2681 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB 2682 && opc != OPC_DADD && opc != OPC_DSUB) { 2683 /* 2684 * If no destination, treat it as a NOP. 2685 * For add & sub, we must generate the overflow exception when needed. 2686 */ 2687 return; 2688 } 2689 2690 switch (opc) { 2691 case OPC_ADD: 2692 { 2693 TCGv t0 = tcg_temp_local_new(); 2694 TCGv t1 = tcg_temp_new(); 2695 TCGv t2 = tcg_temp_new(); 2696 TCGLabel *l1 = gen_new_label(); 2697 2698 gen_load_gpr(t1, rs); 2699 gen_load_gpr(t2, rt); 2700 tcg_gen_add_tl(t0, t1, t2); 2701 tcg_gen_ext32s_tl(t0, t0); 2702 tcg_gen_xor_tl(t1, t1, t2); 2703 tcg_gen_xor_tl(t2, t0, t2); 2704 tcg_gen_andc_tl(t1, t2, t1); 2705 tcg_temp_free(t2); 2706 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2707 tcg_temp_free(t1); 2708 /* operands of same sign, result different sign */ 2709 generate_exception(ctx, EXCP_OVERFLOW); 2710 gen_set_label(l1); 2711 gen_store_gpr(t0, rd); 2712 tcg_temp_free(t0); 2713 } 2714 break; 2715 case OPC_ADDU: 2716 if (rs != 0 && rt != 0) { 2717 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2718 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2719 } else if (rs == 0 && rt != 0) { 2720 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2721 } else if (rs != 0 && rt == 0) { 2722 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2723 } else { 2724 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2725 } 2726 break; 2727 case OPC_SUB: 2728 { 2729 TCGv t0 = tcg_temp_local_new(); 2730 TCGv t1 = tcg_temp_new(); 2731 TCGv t2 = tcg_temp_new(); 2732 TCGLabel *l1 = gen_new_label(); 2733 2734 gen_load_gpr(t1, rs); 2735 gen_load_gpr(t2, rt); 2736 tcg_gen_sub_tl(t0, t1, t2); 2737 tcg_gen_ext32s_tl(t0, t0); 2738 tcg_gen_xor_tl(t2, t1, t2); 2739 tcg_gen_xor_tl(t1, t0, t1); 2740 tcg_gen_and_tl(t1, t1, t2); 2741 tcg_temp_free(t2); 2742 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2743 tcg_temp_free(t1); 2744 /* 2745 * operands of different sign, first operand and the result 2746 * of different sign 2747 */ 2748 generate_exception(ctx, EXCP_OVERFLOW); 2749 gen_set_label(l1); 2750 gen_store_gpr(t0, rd); 2751 tcg_temp_free(t0); 2752 } 2753 break; 2754 case OPC_SUBU: 2755 if (rs != 0 && rt != 0) { 2756 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2757 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2758 } else if (rs == 0 && rt != 0) { 2759 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2760 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2761 } else if (rs != 0 && rt == 0) { 2762 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2763 } else { 2764 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2765 } 2766 break; 2767 #if defined(TARGET_MIPS64) 2768 case OPC_DADD: 2769 { 2770 TCGv t0 = tcg_temp_local_new(); 2771 TCGv t1 = tcg_temp_new(); 2772 TCGv t2 = tcg_temp_new(); 2773 TCGLabel *l1 = gen_new_label(); 2774 2775 gen_load_gpr(t1, rs); 2776 gen_load_gpr(t2, rt); 2777 tcg_gen_add_tl(t0, t1, t2); 2778 tcg_gen_xor_tl(t1, t1, t2); 2779 tcg_gen_xor_tl(t2, t0, t2); 2780 tcg_gen_andc_tl(t1, t2, t1); 2781 tcg_temp_free(t2); 2782 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2783 tcg_temp_free(t1); 2784 /* operands of same sign, result different sign */ 2785 generate_exception(ctx, EXCP_OVERFLOW); 2786 gen_set_label(l1); 2787 gen_store_gpr(t0, rd); 2788 tcg_temp_free(t0); 2789 } 2790 break; 2791 case OPC_DADDU: 2792 if (rs != 0 && rt != 0) { 2793 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2794 } else if (rs == 0 && rt != 0) { 2795 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2796 } else if (rs != 0 && rt == 0) { 2797 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2798 } else { 2799 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2800 } 2801 break; 2802 case OPC_DSUB: 2803 { 2804 TCGv t0 = tcg_temp_local_new(); 2805 TCGv t1 = tcg_temp_new(); 2806 TCGv t2 = tcg_temp_new(); 2807 TCGLabel *l1 = gen_new_label(); 2808 2809 gen_load_gpr(t1, rs); 2810 gen_load_gpr(t2, rt); 2811 tcg_gen_sub_tl(t0, t1, t2); 2812 tcg_gen_xor_tl(t2, t1, t2); 2813 tcg_gen_xor_tl(t1, t0, t1); 2814 tcg_gen_and_tl(t1, t1, t2); 2815 tcg_temp_free(t2); 2816 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 2817 tcg_temp_free(t1); 2818 /* 2819 * Operands of different sign, first operand and result different 2820 * sign. 2821 */ 2822 generate_exception(ctx, EXCP_OVERFLOW); 2823 gen_set_label(l1); 2824 gen_store_gpr(t0, rd); 2825 tcg_temp_free(t0); 2826 } 2827 break; 2828 case OPC_DSUBU: 2829 if (rs != 0 && rt != 0) { 2830 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2831 } else if (rs == 0 && rt != 0) { 2832 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); 2833 } else if (rs != 0 && rt == 0) { 2834 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2835 } else { 2836 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2837 } 2838 break; 2839 #endif 2840 case OPC_MUL: 2841 if (likely(rs != 0 && rt != 0)) { 2842 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2843 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 2844 } else { 2845 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2846 } 2847 break; 2848 } 2849 } 2850 2851 /* Conditional move */ 2852 static void gen_cond_move(DisasContext *ctx, uint32_t opc, 2853 int rd, int rs, int rt) 2854 { 2855 TCGv t0, t1, t2; 2856 2857 if (rd == 0) { 2858 /* If no destination, treat it as a NOP. */ 2859 return; 2860 } 2861 2862 t0 = tcg_temp_new(); 2863 gen_load_gpr(t0, rt); 2864 t1 = tcg_const_tl(0); 2865 t2 = tcg_temp_new(); 2866 gen_load_gpr(t2, rs); 2867 switch (opc) { 2868 case OPC_MOVN: 2869 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2870 break; 2871 case OPC_MOVZ: 2872 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); 2873 break; 2874 case OPC_SELNEZ: 2875 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); 2876 break; 2877 case OPC_SELEQZ: 2878 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); 2879 break; 2880 } 2881 tcg_temp_free(t2); 2882 tcg_temp_free(t1); 2883 tcg_temp_free(t0); 2884 } 2885 2886 /* Logic */ 2887 static void gen_logic(DisasContext *ctx, uint32_t opc, 2888 int rd, int rs, int rt) 2889 { 2890 if (rd == 0) { 2891 /* If no destination, treat it as a NOP. */ 2892 return; 2893 } 2894 2895 switch (opc) { 2896 case OPC_AND: 2897 if (likely(rs != 0 && rt != 0)) { 2898 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2899 } else { 2900 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2901 } 2902 break; 2903 case OPC_NOR: 2904 if (rs != 0 && rt != 0) { 2905 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2906 } else if (rs == 0 && rt != 0) { 2907 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); 2908 } else if (rs != 0 && rt == 0) { 2909 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); 2910 } else { 2911 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); 2912 } 2913 break; 2914 case OPC_OR: 2915 if (likely(rs != 0 && rt != 0)) { 2916 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2917 } else if (rs == 0 && rt != 0) { 2918 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2919 } else if (rs != 0 && rt == 0) { 2920 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2921 } else { 2922 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2923 } 2924 break; 2925 case OPC_XOR: 2926 if (likely(rs != 0 && rt != 0)) { 2927 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); 2928 } else if (rs == 0 && rt != 0) { 2929 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); 2930 } else if (rs != 0 && rt == 0) { 2931 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); 2932 } else { 2933 tcg_gen_movi_tl(cpu_gpr[rd], 0); 2934 } 2935 break; 2936 } 2937 } 2938 2939 /* Set on lower than */ 2940 static void gen_slt(DisasContext *ctx, uint32_t opc, 2941 int rd, int rs, int rt) 2942 { 2943 TCGv t0, t1; 2944 2945 if (rd == 0) { 2946 /* If no destination, treat it as a NOP. */ 2947 return; 2948 } 2949 2950 t0 = tcg_temp_new(); 2951 t1 = tcg_temp_new(); 2952 gen_load_gpr(t0, rs); 2953 gen_load_gpr(t1, rt); 2954 switch (opc) { 2955 case OPC_SLT: 2956 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); 2957 break; 2958 case OPC_SLTU: 2959 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); 2960 break; 2961 } 2962 tcg_temp_free(t0); 2963 tcg_temp_free(t1); 2964 } 2965 2966 /* Shifts */ 2967 static void gen_shift(DisasContext *ctx, uint32_t opc, 2968 int rd, int rs, int rt) 2969 { 2970 TCGv t0, t1; 2971 2972 if (rd == 0) { 2973 /* 2974 * If no destination, treat it as a NOP. 2975 * For add & sub, we must generate the overflow exception when needed. 2976 */ 2977 return; 2978 } 2979 2980 t0 = tcg_temp_new(); 2981 t1 = tcg_temp_new(); 2982 gen_load_gpr(t0, rs); 2983 gen_load_gpr(t1, rt); 2984 switch (opc) { 2985 case OPC_SLLV: 2986 tcg_gen_andi_tl(t0, t0, 0x1f); 2987 tcg_gen_shl_tl(t0, t1, t0); 2988 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2989 break; 2990 case OPC_SRAV: 2991 tcg_gen_andi_tl(t0, t0, 0x1f); 2992 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 2993 break; 2994 case OPC_SRLV: 2995 tcg_gen_ext32u_tl(t1, t1); 2996 tcg_gen_andi_tl(t0, t0, 0x1f); 2997 tcg_gen_shr_tl(t0, t1, t0); 2998 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 2999 break; 3000 case OPC_ROTRV: 3001 { 3002 TCGv_i32 t2 = tcg_temp_new_i32(); 3003 TCGv_i32 t3 = tcg_temp_new_i32(); 3004 3005 tcg_gen_trunc_tl_i32(t2, t0); 3006 tcg_gen_trunc_tl_i32(t3, t1); 3007 tcg_gen_andi_i32(t2, t2, 0x1f); 3008 tcg_gen_rotr_i32(t2, t3, t2); 3009 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3010 tcg_temp_free_i32(t2); 3011 tcg_temp_free_i32(t3); 3012 } 3013 break; 3014 #if defined(TARGET_MIPS64) 3015 case OPC_DSLLV: 3016 tcg_gen_andi_tl(t0, t0, 0x3f); 3017 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); 3018 break; 3019 case OPC_DSRAV: 3020 tcg_gen_andi_tl(t0, t0, 0x3f); 3021 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); 3022 break; 3023 case OPC_DSRLV: 3024 tcg_gen_andi_tl(t0, t0, 0x3f); 3025 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); 3026 break; 3027 case OPC_DROTRV: 3028 tcg_gen_andi_tl(t0, t0, 0x3f); 3029 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); 3030 break; 3031 #endif 3032 } 3033 tcg_temp_free(t0); 3034 tcg_temp_free(t1); 3035 } 3036 3037 /* Arithmetic on HI/LO registers */ 3038 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) 3039 { 3040 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 3041 /* Treat as NOP. */ 3042 return; 3043 } 3044 3045 if (acc != 0) { 3046 check_dsp(ctx); 3047 } 3048 3049 switch (opc) { 3050 case OPC_MFHI: 3051 #if defined(TARGET_MIPS64) 3052 if (acc != 0) { 3053 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]); 3054 } else 3055 #endif 3056 { 3057 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]); 3058 } 3059 break; 3060 case OPC_MFLO: 3061 #if defined(TARGET_MIPS64) 3062 if (acc != 0) { 3063 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]); 3064 } else 3065 #endif 3066 { 3067 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]); 3068 } 3069 break; 3070 case OPC_MTHI: 3071 if (reg != 0) { 3072 #if defined(TARGET_MIPS64) 3073 if (acc != 0) { 3074 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]); 3075 } else 3076 #endif 3077 { 3078 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]); 3079 } 3080 } else { 3081 tcg_gen_movi_tl(cpu_HI[acc], 0); 3082 } 3083 break; 3084 case OPC_MTLO: 3085 if (reg != 0) { 3086 #if defined(TARGET_MIPS64) 3087 if (acc != 0) { 3088 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]); 3089 } else 3090 #endif 3091 { 3092 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]); 3093 } 3094 } else { 3095 tcg_gen_movi_tl(cpu_LO[acc], 0); 3096 } 3097 break; 3098 } 3099 } 3100 3101 static inline void gen_r6_ld(target_long addr, int reg, int memidx, 3102 MemOp memop) 3103 { 3104 TCGv t0 = tcg_const_tl(addr); 3105 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop); 3106 gen_store_gpr(t0, reg); 3107 tcg_temp_free(t0); 3108 } 3109 3110 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc, 3111 int rs) 3112 { 3113 target_long offset; 3114 target_long addr; 3115 3116 switch (MASK_OPC_PCREL_TOP2BITS(opc)) { 3117 case OPC_ADDIUPC: 3118 if (rs != 0) { 3119 offset = sextract32(ctx->opcode << 2, 0, 21); 3120 addr = addr_add(ctx, pc, offset); 3121 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3122 } 3123 break; 3124 case R6_OPC_LWPC: 3125 offset = sextract32(ctx->opcode << 2, 0, 21); 3126 addr = addr_add(ctx, pc, offset); 3127 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL); 3128 break; 3129 #if defined(TARGET_MIPS64) 3130 case OPC_LWUPC: 3131 check_mips_64(ctx); 3132 offset = sextract32(ctx->opcode << 2, 0, 21); 3133 addr = addr_add(ctx, pc, offset); 3134 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL); 3135 break; 3136 #endif 3137 default: 3138 switch (MASK_OPC_PCREL_TOP5BITS(opc)) { 3139 case OPC_AUIPC: 3140 if (rs != 0) { 3141 offset = sextract32(ctx->opcode, 0, 16) << 16; 3142 addr = addr_add(ctx, pc, offset); 3143 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3144 } 3145 break; 3146 case OPC_ALUIPC: 3147 if (rs != 0) { 3148 offset = sextract32(ctx->opcode, 0, 16) << 16; 3149 addr = ~0xFFFF & addr_add(ctx, pc, offset); 3150 tcg_gen_movi_tl(cpu_gpr[rs], addr); 3151 } 3152 break; 3153 #if defined(TARGET_MIPS64) 3154 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */ 3155 case R6_OPC_LDPC + (1 << 16): 3156 case R6_OPC_LDPC + (2 << 16): 3157 case R6_OPC_LDPC + (3 << 16): 3158 check_mips_64(ctx); 3159 offset = sextract32(ctx->opcode << 3, 0, 21); 3160 addr = addr_add(ctx, (pc & ~0x7), offset); 3161 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ); 3162 break; 3163 #endif 3164 default: 3165 MIPS_INVAL("OPC_PCREL"); 3166 gen_reserved_instruction(ctx); 3167 break; 3168 } 3169 break; 3170 } 3171 } 3172 3173 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) 3174 { 3175 TCGv t0, t1; 3176 3177 if (rd == 0) { 3178 /* Treat as NOP. */ 3179 return; 3180 } 3181 3182 t0 = tcg_temp_new(); 3183 t1 = tcg_temp_new(); 3184 3185 gen_load_gpr(t0, rs); 3186 gen_load_gpr(t1, rt); 3187 3188 switch (opc) { 3189 case R6_OPC_DIV: 3190 { 3191 TCGv t2 = tcg_temp_new(); 3192 TCGv t3 = tcg_temp_new(); 3193 tcg_gen_ext32s_tl(t0, t0); 3194 tcg_gen_ext32s_tl(t1, t1); 3195 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3196 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3197 tcg_gen_and_tl(t2, t2, t3); 3198 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3199 tcg_gen_or_tl(t2, t2, t3); 3200 tcg_gen_movi_tl(t3, 0); 3201 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3202 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3203 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3204 tcg_temp_free(t3); 3205 tcg_temp_free(t2); 3206 } 3207 break; 3208 case R6_OPC_MOD: 3209 { 3210 TCGv t2 = tcg_temp_new(); 3211 TCGv t3 = tcg_temp_new(); 3212 tcg_gen_ext32s_tl(t0, t0); 3213 tcg_gen_ext32s_tl(t1, t1); 3214 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3215 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3216 tcg_gen_and_tl(t2, t2, t3); 3217 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3218 tcg_gen_or_tl(t2, t2, t3); 3219 tcg_gen_movi_tl(t3, 0); 3220 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3221 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3222 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3223 tcg_temp_free(t3); 3224 tcg_temp_free(t2); 3225 } 3226 break; 3227 case R6_OPC_DIVU: 3228 { 3229 TCGv t2 = tcg_const_tl(0); 3230 TCGv t3 = tcg_const_tl(1); 3231 tcg_gen_ext32u_tl(t0, t0); 3232 tcg_gen_ext32u_tl(t1, t1); 3233 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3234 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3235 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3236 tcg_temp_free(t3); 3237 tcg_temp_free(t2); 3238 } 3239 break; 3240 case R6_OPC_MODU: 3241 { 3242 TCGv t2 = tcg_const_tl(0); 3243 TCGv t3 = tcg_const_tl(1); 3244 tcg_gen_ext32u_tl(t0, t0); 3245 tcg_gen_ext32u_tl(t1, t1); 3246 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3247 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3248 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3249 tcg_temp_free(t3); 3250 tcg_temp_free(t2); 3251 } 3252 break; 3253 case R6_OPC_MUL: 3254 { 3255 TCGv_i32 t2 = tcg_temp_new_i32(); 3256 TCGv_i32 t3 = tcg_temp_new_i32(); 3257 tcg_gen_trunc_tl_i32(t2, t0); 3258 tcg_gen_trunc_tl_i32(t3, t1); 3259 tcg_gen_mul_i32(t2, t2, t3); 3260 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3261 tcg_temp_free_i32(t2); 3262 tcg_temp_free_i32(t3); 3263 } 3264 break; 3265 case R6_OPC_MUH: 3266 { 3267 TCGv_i32 t2 = tcg_temp_new_i32(); 3268 TCGv_i32 t3 = tcg_temp_new_i32(); 3269 tcg_gen_trunc_tl_i32(t2, t0); 3270 tcg_gen_trunc_tl_i32(t3, t1); 3271 tcg_gen_muls2_i32(t2, t3, t2, t3); 3272 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3273 tcg_temp_free_i32(t2); 3274 tcg_temp_free_i32(t3); 3275 } 3276 break; 3277 case R6_OPC_MULU: 3278 { 3279 TCGv_i32 t2 = tcg_temp_new_i32(); 3280 TCGv_i32 t3 = tcg_temp_new_i32(); 3281 tcg_gen_trunc_tl_i32(t2, t0); 3282 tcg_gen_trunc_tl_i32(t3, t1); 3283 tcg_gen_mul_i32(t2, t2, t3); 3284 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3285 tcg_temp_free_i32(t2); 3286 tcg_temp_free_i32(t3); 3287 } 3288 break; 3289 case R6_OPC_MUHU: 3290 { 3291 TCGv_i32 t2 = tcg_temp_new_i32(); 3292 TCGv_i32 t3 = tcg_temp_new_i32(); 3293 tcg_gen_trunc_tl_i32(t2, t0); 3294 tcg_gen_trunc_tl_i32(t3, t1); 3295 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3296 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); 3297 tcg_temp_free_i32(t2); 3298 tcg_temp_free_i32(t3); 3299 } 3300 break; 3301 #if defined(TARGET_MIPS64) 3302 case R6_OPC_DDIV: 3303 { 3304 TCGv t2 = tcg_temp_new(); 3305 TCGv t3 = tcg_temp_new(); 3306 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3307 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3308 tcg_gen_and_tl(t2, t2, t3); 3309 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3310 tcg_gen_or_tl(t2, t2, t3); 3311 tcg_gen_movi_tl(t3, 0); 3312 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3313 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3314 tcg_temp_free(t3); 3315 tcg_temp_free(t2); 3316 } 3317 break; 3318 case R6_OPC_DMOD: 3319 { 3320 TCGv t2 = tcg_temp_new(); 3321 TCGv t3 = tcg_temp_new(); 3322 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3323 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3324 tcg_gen_and_tl(t2, t2, t3); 3325 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3326 tcg_gen_or_tl(t2, t2, t3); 3327 tcg_gen_movi_tl(t3, 0); 3328 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3329 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3330 tcg_temp_free(t3); 3331 tcg_temp_free(t2); 3332 } 3333 break; 3334 case R6_OPC_DDIVU: 3335 { 3336 TCGv t2 = tcg_const_tl(0); 3337 TCGv t3 = tcg_const_tl(1); 3338 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3339 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); 3340 tcg_temp_free(t3); 3341 tcg_temp_free(t2); 3342 } 3343 break; 3344 case R6_OPC_DMODU: 3345 { 3346 TCGv t2 = tcg_const_tl(0); 3347 TCGv t3 = tcg_const_tl(1); 3348 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3349 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); 3350 tcg_temp_free(t3); 3351 tcg_temp_free(t2); 3352 } 3353 break; 3354 case R6_OPC_DMUL: 3355 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3356 break; 3357 case R6_OPC_DMUH: 3358 { 3359 TCGv t2 = tcg_temp_new(); 3360 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); 3361 tcg_temp_free(t2); 3362 } 3363 break; 3364 case R6_OPC_DMULU: 3365 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); 3366 break; 3367 case R6_OPC_DMUHU: 3368 { 3369 TCGv t2 = tcg_temp_new(); 3370 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); 3371 tcg_temp_free(t2); 3372 } 3373 break; 3374 #endif 3375 default: 3376 MIPS_INVAL("r6 mul/div"); 3377 gen_reserved_instruction(ctx); 3378 goto out; 3379 } 3380 out: 3381 tcg_temp_free(t0); 3382 tcg_temp_free(t1); 3383 } 3384 3385 #if defined(TARGET_MIPS64) 3386 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt) 3387 { 3388 TCGv t0, t1; 3389 3390 t0 = tcg_temp_new(); 3391 t1 = tcg_temp_new(); 3392 3393 gen_load_gpr(t0, rs); 3394 gen_load_gpr(t1, rt); 3395 3396 switch (opc) { 3397 case MMI_OPC_DIV1: 3398 { 3399 TCGv t2 = tcg_temp_new(); 3400 TCGv t3 = tcg_temp_new(); 3401 tcg_gen_ext32s_tl(t0, t0); 3402 tcg_gen_ext32s_tl(t1, t1); 3403 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3404 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3405 tcg_gen_and_tl(t2, t2, t3); 3406 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3407 tcg_gen_or_tl(t2, t2, t3); 3408 tcg_gen_movi_tl(t3, 0); 3409 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3410 tcg_gen_div_tl(cpu_LO[1], t0, t1); 3411 tcg_gen_rem_tl(cpu_HI[1], t0, t1); 3412 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3413 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3414 tcg_temp_free(t3); 3415 tcg_temp_free(t2); 3416 } 3417 break; 3418 case MMI_OPC_DIVU1: 3419 { 3420 TCGv t2 = tcg_const_tl(0); 3421 TCGv t3 = tcg_const_tl(1); 3422 tcg_gen_ext32u_tl(t0, t0); 3423 tcg_gen_ext32u_tl(t1, t1); 3424 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3425 tcg_gen_divu_tl(cpu_LO[1], t0, t1); 3426 tcg_gen_remu_tl(cpu_HI[1], t0, t1); 3427 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]); 3428 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]); 3429 tcg_temp_free(t3); 3430 tcg_temp_free(t2); 3431 } 3432 break; 3433 default: 3434 MIPS_INVAL("div1 TX79"); 3435 gen_reserved_instruction(ctx); 3436 goto out; 3437 } 3438 out: 3439 tcg_temp_free(t0); 3440 tcg_temp_free(t1); 3441 } 3442 #endif 3443 3444 static void gen_muldiv(DisasContext *ctx, uint32_t opc, 3445 int acc, int rs, int rt) 3446 { 3447 TCGv t0, t1; 3448 3449 t0 = tcg_temp_new(); 3450 t1 = tcg_temp_new(); 3451 3452 gen_load_gpr(t0, rs); 3453 gen_load_gpr(t1, rt); 3454 3455 if (acc != 0) { 3456 check_dsp(ctx); 3457 } 3458 3459 switch (opc) { 3460 case OPC_DIV: 3461 { 3462 TCGv t2 = tcg_temp_new(); 3463 TCGv t3 = tcg_temp_new(); 3464 tcg_gen_ext32s_tl(t0, t0); 3465 tcg_gen_ext32s_tl(t1, t1); 3466 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); 3467 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); 3468 tcg_gen_and_tl(t2, t2, t3); 3469 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3470 tcg_gen_or_tl(t2, t2, t3); 3471 tcg_gen_movi_tl(t3, 0); 3472 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3473 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3474 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3475 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3476 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3477 tcg_temp_free(t3); 3478 tcg_temp_free(t2); 3479 } 3480 break; 3481 case OPC_DIVU: 3482 { 3483 TCGv t2 = tcg_const_tl(0); 3484 TCGv t3 = tcg_const_tl(1); 3485 tcg_gen_ext32u_tl(t0, t0); 3486 tcg_gen_ext32u_tl(t1, t1); 3487 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3488 tcg_gen_divu_tl(cpu_LO[acc], t0, t1); 3489 tcg_gen_remu_tl(cpu_HI[acc], t0, t1); 3490 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]); 3491 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]); 3492 tcg_temp_free(t3); 3493 tcg_temp_free(t2); 3494 } 3495 break; 3496 case OPC_MULT: 3497 { 3498 TCGv_i32 t2 = tcg_temp_new_i32(); 3499 TCGv_i32 t3 = tcg_temp_new_i32(); 3500 tcg_gen_trunc_tl_i32(t2, t0); 3501 tcg_gen_trunc_tl_i32(t3, t1); 3502 tcg_gen_muls2_i32(t2, t3, t2, t3); 3503 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3504 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3505 tcg_temp_free_i32(t2); 3506 tcg_temp_free_i32(t3); 3507 } 3508 break; 3509 case OPC_MULTU: 3510 { 3511 TCGv_i32 t2 = tcg_temp_new_i32(); 3512 TCGv_i32 t3 = tcg_temp_new_i32(); 3513 tcg_gen_trunc_tl_i32(t2, t0); 3514 tcg_gen_trunc_tl_i32(t3, t1); 3515 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3516 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3517 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3518 tcg_temp_free_i32(t2); 3519 tcg_temp_free_i32(t3); 3520 } 3521 break; 3522 #if defined(TARGET_MIPS64) 3523 case OPC_DDIV: 3524 { 3525 TCGv t2 = tcg_temp_new(); 3526 TCGv t3 = tcg_temp_new(); 3527 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); 3528 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); 3529 tcg_gen_and_tl(t2, t2, t3); 3530 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); 3531 tcg_gen_or_tl(t2, t2, t3); 3532 tcg_gen_movi_tl(t3, 0); 3533 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); 3534 tcg_gen_div_tl(cpu_LO[acc], t0, t1); 3535 tcg_gen_rem_tl(cpu_HI[acc], t0, t1); 3536 tcg_temp_free(t3); 3537 tcg_temp_free(t2); 3538 } 3539 break; 3540 case OPC_DDIVU: 3541 { 3542 TCGv t2 = tcg_const_tl(0); 3543 TCGv t3 = tcg_const_tl(1); 3544 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); 3545 tcg_gen_divu_i64(cpu_LO[acc], t0, t1); 3546 tcg_gen_remu_i64(cpu_HI[acc], t0, t1); 3547 tcg_temp_free(t3); 3548 tcg_temp_free(t2); 3549 } 3550 break; 3551 case OPC_DMULT: 3552 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3553 break; 3554 case OPC_DMULTU: 3555 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1); 3556 break; 3557 #endif 3558 case OPC_MADD: 3559 { 3560 TCGv_i64 t2 = tcg_temp_new_i64(); 3561 TCGv_i64 t3 = tcg_temp_new_i64(); 3562 3563 tcg_gen_ext_tl_i64(t2, t0); 3564 tcg_gen_ext_tl_i64(t3, t1); 3565 tcg_gen_mul_i64(t2, t2, t3); 3566 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3567 tcg_gen_add_i64(t2, t2, t3); 3568 tcg_temp_free_i64(t3); 3569 gen_move_low32(cpu_LO[acc], t2); 3570 gen_move_high32(cpu_HI[acc], t2); 3571 tcg_temp_free_i64(t2); 3572 } 3573 break; 3574 case OPC_MADDU: 3575 { 3576 TCGv_i64 t2 = tcg_temp_new_i64(); 3577 TCGv_i64 t3 = tcg_temp_new_i64(); 3578 3579 tcg_gen_ext32u_tl(t0, t0); 3580 tcg_gen_ext32u_tl(t1, t1); 3581 tcg_gen_extu_tl_i64(t2, t0); 3582 tcg_gen_extu_tl_i64(t3, t1); 3583 tcg_gen_mul_i64(t2, t2, t3); 3584 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3585 tcg_gen_add_i64(t2, t2, t3); 3586 tcg_temp_free_i64(t3); 3587 gen_move_low32(cpu_LO[acc], t2); 3588 gen_move_high32(cpu_HI[acc], t2); 3589 tcg_temp_free_i64(t2); 3590 } 3591 break; 3592 case OPC_MSUB: 3593 { 3594 TCGv_i64 t2 = tcg_temp_new_i64(); 3595 TCGv_i64 t3 = tcg_temp_new_i64(); 3596 3597 tcg_gen_ext_tl_i64(t2, t0); 3598 tcg_gen_ext_tl_i64(t3, t1); 3599 tcg_gen_mul_i64(t2, t2, t3); 3600 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3601 tcg_gen_sub_i64(t2, t3, t2); 3602 tcg_temp_free_i64(t3); 3603 gen_move_low32(cpu_LO[acc], t2); 3604 gen_move_high32(cpu_HI[acc], t2); 3605 tcg_temp_free_i64(t2); 3606 } 3607 break; 3608 case OPC_MSUBU: 3609 { 3610 TCGv_i64 t2 = tcg_temp_new_i64(); 3611 TCGv_i64 t3 = tcg_temp_new_i64(); 3612 3613 tcg_gen_ext32u_tl(t0, t0); 3614 tcg_gen_ext32u_tl(t1, t1); 3615 tcg_gen_extu_tl_i64(t2, t0); 3616 tcg_gen_extu_tl_i64(t3, t1); 3617 tcg_gen_mul_i64(t2, t2, t3); 3618 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3619 tcg_gen_sub_i64(t2, t3, t2); 3620 tcg_temp_free_i64(t3); 3621 gen_move_low32(cpu_LO[acc], t2); 3622 gen_move_high32(cpu_HI[acc], t2); 3623 tcg_temp_free_i64(t2); 3624 } 3625 break; 3626 default: 3627 MIPS_INVAL("mul/div"); 3628 gen_reserved_instruction(ctx); 3629 goto out; 3630 } 3631 out: 3632 tcg_temp_free(t0); 3633 tcg_temp_free(t1); 3634 } 3635 3636 /* 3637 * These MULT[U] and MADD[U] instructions implemented in for example 3638 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core 3639 * architectures are special three-operand variants with the syntax 3640 * 3641 * MULT[U][1] rd, rs, rt 3642 * 3643 * such that 3644 * 3645 * (rd, LO, HI) <- rs * rt 3646 * 3647 * and 3648 * 3649 * MADD[U][1] rd, rs, rt 3650 * 3651 * such that 3652 * 3653 * (rd, LO, HI) <- (LO, HI) + rs * rt 3654 * 3655 * where the low-order 32-bits of the result is placed into both the 3656 * GPR rd and the special register LO. The high-order 32-bits of the 3657 * result is placed into the special register HI. 3658 * 3659 * If the GPR rd is omitted in assembly language, it is taken to be 0, 3660 * which is the zero register that always reads as 0. 3661 */ 3662 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, 3663 int rd, int rs, int rt) 3664 { 3665 TCGv t0 = tcg_temp_new(); 3666 TCGv t1 = tcg_temp_new(); 3667 int acc = 0; 3668 3669 gen_load_gpr(t0, rs); 3670 gen_load_gpr(t1, rt); 3671 3672 switch (opc) { 3673 case MMI_OPC_MULT1: 3674 acc = 1; 3675 /* Fall through */ 3676 case OPC_MULT: 3677 { 3678 TCGv_i32 t2 = tcg_temp_new_i32(); 3679 TCGv_i32 t3 = tcg_temp_new_i32(); 3680 tcg_gen_trunc_tl_i32(t2, t0); 3681 tcg_gen_trunc_tl_i32(t3, t1); 3682 tcg_gen_muls2_i32(t2, t3, t2, t3); 3683 if (rd) { 3684 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3685 } 3686 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3687 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3688 tcg_temp_free_i32(t2); 3689 tcg_temp_free_i32(t3); 3690 } 3691 break; 3692 case MMI_OPC_MULTU1: 3693 acc = 1; 3694 /* Fall through */ 3695 case OPC_MULTU: 3696 { 3697 TCGv_i32 t2 = tcg_temp_new_i32(); 3698 TCGv_i32 t3 = tcg_temp_new_i32(); 3699 tcg_gen_trunc_tl_i32(t2, t0); 3700 tcg_gen_trunc_tl_i32(t3, t1); 3701 tcg_gen_mulu2_i32(t2, t3, t2, t3); 3702 if (rd) { 3703 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); 3704 } 3705 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 3706 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 3707 tcg_temp_free_i32(t2); 3708 tcg_temp_free_i32(t3); 3709 } 3710 break; 3711 case MMI_OPC_MADD1: 3712 acc = 1; 3713 /* Fall through */ 3714 case MMI_OPC_MADD: 3715 { 3716 TCGv_i64 t2 = tcg_temp_new_i64(); 3717 TCGv_i64 t3 = tcg_temp_new_i64(); 3718 3719 tcg_gen_ext_tl_i64(t2, t0); 3720 tcg_gen_ext_tl_i64(t3, t1); 3721 tcg_gen_mul_i64(t2, t2, t3); 3722 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3723 tcg_gen_add_i64(t2, t2, t3); 3724 tcg_temp_free_i64(t3); 3725 gen_move_low32(cpu_LO[acc], t2); 3726 gen_move_high32(cpu_HI[acc], t2); 3727 if (rd) { 3728 gen_move_low32(cpu_gpr[rd], t2); 3729 } 3730 tcg_temp_free_i64(t2); 3731 } 3732 break; 3733 case MMI_OPC_MADDU1: 3734 acc = 1; 3735 /* Fall through */ 3736 case MMI_OPC_MADDU: 3737 { 3738 TCGv_i64 t2 = tcg_temp_new_i64(); 3739 TCGv_i64 t3 = tcg_temp_new_i64(); 3740 3741 tcg_gen_ext32u_tl(t0, t0); 3742 tcg_gen_ext32u_tl(t1, t1); 3743 tcg_gen_extu_tl_i64(t2, t0); 3744 tcg_gen_extu_tl_i64(t3, t1); 3745 tcg_gen_mul_i64(t2, t2, t3); 3746 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 3747 tcg_gen_add_i64(t2, t2, t3); 3748 tcg_temp_free_i64(t3); 3749 gen_move_low32(cpu_LO[acc], t2); 3750 gen_move_high32(cpu_HI[acc], t2); 3751 if (rd) { 3752 gen_move_low32(cpu_gpr[rd], t2); 3753 } 3754 tcg_temp_free_i64(t2); 3755 } 3756 break; 3757 default: 3758 MIPS_INVAL("mul/madd TXx9"); 3759 gen_reserved_instruction(ctx); 3760 goto out; 3761 } 3762 3763 out: 3764 tcg_temp_free(t0); 3765 tcg_temp_free(t1); 3766 } 3767 3768 static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc, 3769 int rd, int rs, int rt) 3770 { 3771 TCGv t0 = tcg_temp_new(); 3772 TCGv t1 = tcg_temp_new(); 3773 3774 gen_load_gpr(t0, rs); 3775 gen_load_gpr(t1, rt); 3776 3777 switch (opc) { 3778 case OPC_VR54XX_MULS: 3779 gen_helper_muls(t0, cpu_env, t0, t1); 3780 break; 3781 case OPC_VR54XX_MULSU: 3782 gen_helper_mulsu(t0, cpu_env, t0, t1); 3783 break; 3784 case OPC_VR54XX_MACC: 3785 gen_helper_macc(t0, cpu_env, t0, t1); 3786 break; 3787 case OPC_VR54XX_MACCU: 3788 gen_helper_maccu(t0, cpu_env, t0, t1); 3789 break; 3790 case OPC_VR54XX_MSAC: 3791 gen_helper_msac(t0, cpu_env, t0, t1); 3792 break; 3793 case OPC_VR54XX_MSACU: 3794 gen_helper_msacu(t0, cpu_env, t0, t1); 3795 break; 3796 case OPC_VR54XX_MULHI: 3797 gen_helper_mulhi(t0, cpu_env, t0, t1); 3798 break; 3799 case OPC_VR54XX_MULHIU: 3800 gen_helper_mulhiu(t0, cpu_env, t0, t1); 3801 break; 3802 case OPC_VR54XX_MULSHI: 3803 gen_helper_mulshi(t0, cpu_env, t0, t1); 3804 break; 3805 case OPC_VR54XX_MULSHIU: 3806 gen_helper_mulshiu(t0, cpu_env, t0, t1); 3807 break; 3808 case OPC_VR54XX_MACCHI: 3809 gen_helper_macchi(t0, cpu_env, t0, t1); 3810 break; 3811 case OPC_VR54XX_MACCHIU: 3812 gen_helper_macchiu(t0, cpu_env, t0, t1); 3813 break; 3814 case OPC_VR54XX_MSACHI: 3815 gen_helper_msachi(t0, cpu_env, t0, t1); 3816 break; 3817 case OPC_VR54XX_MSACHIU: 3818 gen_helper_msachiu(t0, cpu_env, t0, t1); 3819 break; 3820 default: 3821 MIPS_INVAL("mul vr54xx"); 3822 gen_reserved_instruction(ctx); 3823 goto out; 3824 } 3825 gen_store_gpr(t0, rd); 3826 3827 out: 3828 tcg_temp_free(t0); 3829 tcg_temp_free(t1); 3830 } 3831 3832 static void gen_cl(DisasContext *ctx, uint32_t opc, 3833 int rd, int rs) 3834 { 3835 TCGv t0; 3836 3837 if (rd == 0) { 3838 /* Treat as NOP. */ 3839 return; 3840 } 3841 t0 = cpu_gpr[rd]; 3842 gen_load_gpr(t0, rs); 3843 3844 switch (opc) { 3845 case OPC_CLO: 3846 case R6_OPC_CLO: 3847 #if defined(TARGET_MIPS64) 3848 case OPC_DCLO: 3849 case R6_OPC_DCLO: 3850 #endif 3851 tcg_gen_not_tl(t0, t0); 3852 break; 3853 } 3854 3855 switch (opc) { 3856 case OPC_CLO: 3857 case R6_OPC_CLO: 3858 case OPC_CLZ: 3859 case R6_OPC_CLZ: 3860 tcg_gen_ext32u_tl(t0, t0); 3861 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); 3862 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); 3863 break; 3864 #if defined(TARGET_MIPS64) 3865 case OPC_DCLO: 3866 case R6_OPC_DCLO: 3867 case OPC_DCLZ: 3868 case R6_OPC_DCLZ: 3869 tcg_gen_clzi_i64(t0, t0, 64); 3870 break; 3871 #endif 3872 } 3873 } 3874 3875 /* Godson integer instructions */ 3876 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc, 3877 int rd, int rs, int rt) 3878 { 3879 TCGv t0, t1; 3880 3881 if (rd == 0) { 3882 /* Treat as NOP. */ 3883 return; 3884 } 3885 3886 switch (opc) { 3887 case OPC_MULT_G_2E: 3888 case OPC_MULT_G_2F: 3889 case OPC_MULTU_G_2E: 3890 case OPC_MULTU_G_2F: 3891 #if defined(TARGET_MIPS64) 3892 case OPC_DMULT_G_2E: 3893 case OPC_DMULT_G_2F: 3894 case OPC_DMULTU_G_2E: 3895 case OPC_DMULTU_G_2F: 3896 #endif 3897 t0 = tcg_temp_new(); 3898 t1 = tcg_temp_new(); 3899 break; 3900 default: 3901 t0 = tcg_temp_local_new(); 3902 t1 = tcg_temp_local_new(); 3903 break; 3904 } 3905 3906 gen_load_gpr(t0, rs); 3907 gen_load_gpr(t1, rt); 3908 3909 switch (opc) { 3910 case OPC_MULT_G_2E: 3911 case OPC_MULT_G_2F: 3912 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3913 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3914 break; 3915 case OPC_MULTU_G_2E: 3916 case OPC_MULTU_G_2F: 3917 tcg_gen_ext32u_tl(t0, t0); 3918 tcg_gen_ext32u_tl(t1, t1); 3919 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 3920 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3921 break; 3922 case OPC_DIV_G_2E: 3923 case OPC_DIV_G_2F: 3924 { 3925 TCGLabel *l1 = gen_new_label(); 3926 TCGLabel *l2 = gen_new_label(); 3927 TCGLabel *l3 = gen_new_label(); 3928 tcg_gen_ext32s_tl(t0, t0); 3929 tcg_gen_ext32s_tl(t1, t1); 3930 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3931 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3932 tcg_gen_br(l3); 3933 gen_set_label(l1); 3934 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 3935 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 3936 tcg_gen_mov_tl(cpu_gpr[rd], t0); 3937 tcg_gen_br(l3); 3938 gen_set_label(l2); 3939 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 3940 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3941 gen_set_label(l3); 3942 } 3943 break; 3944 case OPC_DIVU_G_2E: 3945 case OPC_DIVU_G_2F: 3946 { 3947 TCGLabel *l1 = gen_new_label(); 3948 TCGLabel *l2 = gen_new_label(); 3949 tcg_gen_ext32u_tl(t0, t0); 3950 tcg_gen_ext32u_tl(t1, t1); 3951 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3952 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3953 tcg_gen_br(l2); 3954 gen_set_label(l1); 3955 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 3956 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3957 gen_set_label(l2); 3958 } 3959 break; 3960 case OPC_MOD_G_2E: 3961 case OPC_MOD_G_2F: 3962 { 3963 TCGLabel *l1 = gen_new_label(); 3964 TCGLabel *l2 = gen_new_label(); 3965 TCGLabel *l3 = gen_new_label(); 3966 tcg_gen_ext32u_tl(t0, t0); 3967 tcg_gen_ext32u_tl(t1, t1); 3968 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 3969 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2); 3970 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2); 3971 gen_set_label(l1); 3972 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3973 tcg_gen_br(l3); 3974 gen_set_label(l2); 3975 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 3976 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3977 gen_set_label(l3); 3978 } 3979 break; 3980 case OPC_MODU_G_2E: 3981 case OPC_MODU_G_2F: 3982 { 3983 TCGLabel *l1 = gen_new_label(); 3984 TCGLabel *l2 = gen_new_label(); 3985 tcg_gen_ext32u_tl(t0, t0); 3986 tcg_gen_ext32u_tl(t1, t1); 3987 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 3988 tcg_gen_movi_tl(cpu_gpr[rd], 0); 3989 tcg_gen_br(l2); 3990 gen_set_label(l1); 3991 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 3992 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); 3993 gen_set_label(l2); 3994 } 3995 break; 3996 #if defined(TARGET_MIPS64) 3997 case OPC_DMULT_G_2E: 3998 case OPC_DMULT_G_2F: 3999 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 4000 break; 4001 case OPC_DMULTU_G_2E: 4002 case OPC_DMULTU_G_2F: 4003 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); 4004 break; 4005 case OPC_DDIV_G_2E: 4006 case OPC_DDIV_G_2F: 4007 { 4008 TCGLabel *l1 = gen_new_label(); 4009 TCGLabel *l2 = gen_new_label(); 4010 TCGLabel *l3 = gen_new_label(); 4011 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4012 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4013 tcg_gen_br(l3); 4014 gen_set_label(l1); 4015 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 4016 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 4017 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4018 tcg_gen_br(l3); 4019 gen_set_label(l2); 4020 tcg_gen_div_tl(cpu_gpr[rd], t0, t1); 4021 gen_set_label(l3); 4022 } 4023 break; 4024 case OPC_DDIVU_G_2E: 4025 case OPC_DDIVU_G_2F: 4026 { 4027 TCGLabel *l1 = gen_new_label(); 4028 TCGLabel *l2 = gen_new_label(); 4029 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4030 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4031 tcg_gen_br(l2); 4032 gen_set_label(l1); 4033 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); 4034 gen_set_label(l2); 4035 } 4036 break; 4037 case OPC_DMOD_G_2E: 4038 case OPC_DMOD_G_2F: 4039 { 4040 TCGLabel *l1 = gen_new_label(); 4041 TCGLabel *l2 = gen_new_label(); 4042 TCGLabel *l3 = gen_new_label(); 4043 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 4044 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); 4045 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); 4046 gen_set_label(l1); 4047 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4048 tcg_gen_br(l3); 4049 gen_set_label(l2); 4050 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); 4051 gen_set_label(l3); 4052 } 4053 break; 4054 case OPC_DMODU_G_2E: 4055 case OPC_DMODU_G_2F: 4056 { 4057 TCGLabel *l1 = gen_new_label(); 4058 TCGLabel *l2 = gen_new_label(); 4059 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 4060 tcg_gen_movi_tl(cpu_gpr[rd], 0); 4061 tcg_gen_br(l2); 4062 gen_set_label(l1); 4063 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); 4064 gen_set_label(l2); 4065 } 4066 break; 4067 #endif 4068 } 4069 4070 tcg_temp_free(t0); 4071 tcg_temp_free(t1); 4072 } 4073 4074 /* Loongson multimedia instructions */ 4075 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) 4076 { 4077 uint32_t opc, shift_max; 4078 TCGv_i64 t0, t1; 4079 TCGCond cond; 4080 4081 opc = MASK_LMMI(ctx->opcode); 4082 switch (opc) { 4083 case OPC_ADD_CP2: 4084 case OPC_SUB_CP2: 4085 case OPC_DADD_CP2: 4086 case OPC_DSUB_CP2: 4087 t0 = tcg_temp_local_new_i64(); 4088 t1 = tcg_temp_local_new_i64(); 4089 break; 4090 default: 4091 t0 = tcg_temp_new_i64(); 4092 t1 = tcg_temp_new_i64(); 4093 break; 4094 } 4095 4096 check_cp1_enabled(ctx); 4097 gen_load_fpr64(ctx, t0, rs); 4098 gen_load_fpr64(ctx, t1, rt); 4099 4100 switch (opc) { 4101 case OPC_PADDSH: 4102 gen_helper_paddsh(t0, t0, t1); 4103 break; 4104 case OPC_PADDUSH: 4105 gen_helper_paddush(t0, t0, t1); 4106 break; 4107 case OPC_PADDH: 4108 gen_helper_paddh(t0, t0, t1); 4109 break; 4110 case OPC_PADDW: 4111 gen_helper_paddw(t0, t0, t1); 4112 break; 4113 case OPC_PADDSB: 4114 gen_helper_paddsb(t0, t0, t1); 4115 break; 4116 case OPC_PADDUSB: 4117 gen_helper_paddusb(t0, t0, t1); 4118 break; 4119 case OPC_PADDB: 4120 gen_helper_paddb(t0, t0, t1); 4121 break; 4122 4123 case OPC_PSUBSH: 4124 gen_helper_psubsh(t0, t0, t1); 4125 break; 4126 case OPC_PSUBUSH: 4127 gen_helper_psubush(t0, t0, t1); 4128 break; 4129 case OPC_PSUBH: 4130 gen_helper_psubh(t0, t0, t1); 4131 break; 4132 case OPC_PSUBW: 4133 gen_helper_psubw(t0, t0, t1); 4134 break; 4135 case OPC_PSUBSB: 4136 gen_helper_psubsb(t0, t0, t1); 4137 break; 4138 case OPC_PSUBUSB: 4139 gen_helper_psubusb(t0, t0, t1); 4140 break; 4141 case OPC_PSUBB: 4142 gen_helper_psubb(t0, t0, t1); 4143 break; 4144 4145 case OPC_PSHUFH: 4146 gen_helper_pshufh(t0, t0, t1); 4147 break; 4148 case OPC_PACKSSWH: 4149 gen_helper_packsswh(t0, t0, t1); 4150 break; 4151 case OPC_PACKSSHB: 4152 gen_helper_packsshb(t0, t0, t1); 4153 break; 4154 case OPC_PACKUSHB: 4155 gen_helper_packushb(t0, t0, t1); 4156 break; 4157 4158 case OPC_PUNPCKLHW: 4159 gen_helper_punpcklhw(t0, t0, t1); 4160 break; 4161 case OPC_PUNPCKHHW: 4162 gen_helper_punpckhhw(t0, t0, t1); 4163 break; 4164 case OPC_PUNPCKLBH: 4165 gen_helper_punpcklbh(t0, t0, t1); 4166 break; 4167 case OPC_PUNPCKHBH: 4168 gen_helper_punpckhbh(t0, t0, t1); 4169 break; 4170 case OPC_PUNPCKLWD: 4171 gen_helper_punpcklwd(t0, t0, t1); 4172 break; 4173 case OPC_PUNPCKHWD: 4174 gen_helper_punpckhwd(t0, t0, t1); 4175 break; 4176 4177 case OPC_PAVGH: 4178 gen_helper_pavgh(t0, t0, t1); 4179 break; 4180 case OPC_PAVGB: 4181 gen_helper_pavgb(t0, t0, t1); 4182 break; 4183 case OPC_PMAXSH: 4184 gen_helper_pmaxsh(t0, t0, t1); 4185 break; 4186 case OPC_PMINSH: 4187 gen_helper_pminsh(t0, t0, t1); 4188 break; 4189 case OPC_PMAXUB: 4190 gen_helper_pmaxub(t0, t0, t1); 4191 break; 4192 case OPC_PMINUB: 4193 gen_helper_pminub(t0, t0, t1); 4194 break; 4195 4196 case OPC_PCMPEQW: 4197 gen_helper_pcmpeqw(t0, t0, t1); 4198 break; 4199 case OPC_PCMPGTW: 4200 gen_helper_pcmpgtw(t0, t0, t1); 4201 break; 4202 case OPC_PCMPEQH: 4203 gen_helper_pcmpeqh(t0, t0, t1); 4204 break; 4205 case OPC_PCMPGTH: 4206 gen_helper_pcmpgth(t0, t0, t1); 4207 break; 4208 case OPC_PCMPEQB: 4209 gen_helper_pcmpeqb(t0, t0, t1); 4210 break; 4211 case OPC_PCMPGTB: 4212 gen_helper_pcmpgtb(t0, t0, t1); 4213 break; 4214 4215 case OPC_PSLLW: 4216 gen_helper_psllw(t0, t0, t1); 4217 break; 4218 case OPC_PSLLH: 4219 gen_helper_psllh(t0, t0, t1); 4220 break; 4221 case OPC_PSRLW: 4222 gen_helper_psrlw(t0, t0, t1); 4223 break; 4224 case OPC_PSRLH: 4225 gen_helper_psrlh(t0, t0, t1); 4226 break; 4227 case OPC_PSRAW: 4228 gen_helper_psraw(t0, t0, t1); 4229 break; 4230 case OPC_PSRAH: 4231 gen_helper_psrah(t0, t0, t1); 4232 break; 4233 4234 case OPC_PMULLH: 4235 gen_helper_pmullh(t0, t0, t1); 4236 break; 4237 case OPC_PMULHH: 4238 gen_helper_pmulhh(t0, t0, t1); 4239 break; 4240 case OPC_PMULHUH: 4241 gen_helper_pmulhuh(t0, t0, t1); 4242 break; 4243 case OPC_PMADDHW: 4244 gen_helper_pmaddhw(t0, t0, t1); 4245 break; 4246 4247 case OPC_PASUBUB: 4248 gen_helper_pasubub(t0, t0, t1); 4249 break; 4250 case OPC_BIADD: 4251 gen_helper_biadd(t0, t0); 4252 break; 4253 case OPC_PMOVMSKB: 4254 gen_helper_pmovmskb(t0, t0); 4255 break; 4256 4257 case OPC_PADDD: 4258 tcg_gen_add_i64(t0, t0, t1); 4259 break; 4260 case OPC_PSUBD: 4261 tcg_gen_sub_i64(t0, t0, t1); 4262 break; 4263 case OPC_XOR_CP2: 4264 tcg_gen_xor_i64(t0, t0, t1); 4265 break; 4266 case OPC_NOR_CP2: 4267 tcg_gen_nor_i64(t0, t0, t1); 4268 break; 4269 case OPC_AND_CP2: 4270 tcg_gen_and_i64(t0, t0, t1); 4271 break; 4272 case OPC_OR_CP2: 4273 tcg_gen_or_i64(t0, t0, t1); 4274 break; 4275 4276 case OPC_PANDN: 4277 tcg_gen_andc_i64(t0, t1, t0); 4278 break; 4279 4280 case OPC_PINSRH_0: 4281 tcg_gen_deposit_i64(t0, t0, t1, 0, 16); 4282 break; 4283 case OPC_PINSRH_1: 4284 tcg_gen_deposit_i64(t0, t0, t1, 16, 16); 4285 break; 4286 case OPC_PINSRH_2: 4287 tcg_gen_deposit_i64(t0, t0, t1, 32, 16); 4288 break; 4289 case OPC_PINSRH_3: 4290 tcg_gen_deposit_i64(t0, t0, t1, 48, 16); 4291 break; 4292 4293 case OPC_PEXTRH: 4294 tcg_gen_andi_i64(t1, t1, 3); 4295 tcg_gen_shli_i64(t1, t1, 4); 4296 tcg_gen_shr_i64(t0, t0, t1); 4297 tcg_gen_ext16u_i64(t0, t0); 4298 break; 4299 4300 case OPC_ADDU_CP2: 4301 tcg_gen_add_i64(t0, t0, t1); 4302 tcg_gen_ext32s_i64(t0, t0); 4303 break; 4304 case OPC_SUBU_CP2: 4305 tcg_gen_sub_i64(t0, t0, t1); 4306 tcg_gen_ext32s_i64(t0, t0); 4307 break; 4308 4309 case OPC_SLL_CP2: 4310 shift_max = 32; 4311 goto do_shift; 4312 case OPC_SRL_CP2: 4313 shift_max = 32; 4314 goto do_shift; 4315 case OPC_SRA_CP2: 4316 shift_max = 32; 4317 goto do_shift; 4318 case OPC_DSLL_CP2: 4319 shift_max = 64; 4320 goto do_shift; 4321 case OPC_DSRL_CP2: 4322 shift_max = 64; 4323 goto do_shift; 4324 case OPC_DSRA_CP2: 4325 shift_max = 64; 4326 goto do_shift; 4327 do_shift: 4328 /* Make sure shift count isn't TCG undefined behaviour. */ 4329 tcg_gen_andi_i64(t1, t1, shift_max - 1); 4330 4331 switch (opc) { 4332 case OPC_SLL_CP2: 4333 case OPC_DSLL_CP2: 4334 tcg_gen_shl_i64(t0, t0, t1); 4335 break; 4336 case OPC_SRA_CP2: 4337 case OPC_DSRA_CP2: 4338 /* 4339 * Since SRA is UndefinedResult without sign-extended inputs, 4340 * we can treat SRA and DSRA the same. 4341 */ 4342 tcg_gen_sar_i64(t0, t0, t1); 4343 break; 4344 case OPC_SRL_CP2: 4345 /* We want to shift in zeros for SRL; zero-extend first. */ 4346 tcg_gen_ext32u_i64(t0, t0); 4347 /* FALLTHRU */ 4348 case OPC_DSRL_CP2: 4349 tcg_gen_shr_i64(t0, t0, t1); 4350 break; 4351 } 4352 4353 if (shift_max == 32) { 4354 tcg_gen_ext32s_i64(t0, t0); 4355 } 4356 4357 /* Shifts larger than MAX produce zero. */ 4358 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max); 4359 tcg_gen_neg_i64(t1, t1); 4360 tcg_gen_and_i64(t0, t0, t1); 4361 break; 4362 4363 case OPC_ADD_CP2: 4364 case OPC_DADD_CP2: 4365 { 4366 TCGv_i64 t2 = tcg_temp_new_i64(); 4367 TCGLabel *lab = gen_new_label(); 4368 4369 tcg_gen_mov_i64(t2, t0); 4370 tcg_gen_add_i64(t0, t1, t2); 4371 if (opc == OPC_ADD_CP2) { 4372 tcg_gen_ext32s_i64(t0, t0); 4373 } 4374 tcg_gen_xor_i64(t1, t1, t2); 4375 tcg_gen_xor_i64(t2, t2, t0); 4376 tcg_gen_andc_i64(t1, t2, t1); 4377 tcg_temp_free_i64(t2); 4378 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4379 generate_exception(ctx, EXCP_OVERFLOW); 4380 gen_set_label(lab); 4381 break; 4382 } 4383 4384 case OPC_SUB_CP2: 4385 case OPC_DSUB_CP2: 4386 { 4387 TCGv_i64 t2 = tcg_temp_new_i64(); 4388 TCGLabel *lab = gen_new_label(); 4389 4390 tcg_gen_mov_i64(t2, t0); 4391 tcg_gen_sub_i64(t0, t1, t2); 4392 if (opc == OPC_SUB_CP2) { 4393 tcg_gen_ext32s_i64(t0, t0); 4394 } 4395 tcg_gen_xor_i64(t1, t1, t2); 4396 tcg_gen_xor_i64(t2, t2, t0); 4397 tcg_gen_and_i64(t1, t1, t2); 4398 tcg_temp_free_i64(t2); 4399 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); 4400 generate_exception(ctx, EXCP_OVERFLOW); 4401 gen_set_label(lab); 4402 break; 4403 } 4404 4405 case OPC_PMULUW: 4406 tcg_gen_ext32u_i64(t0, t0); 4407 tcg_gen_ext32u_i64(t1, t1); 4408 tcg_gen_mul_i64(t0, t0, t1); 4409 break; 4410 4411 case OPC_SEQU_CP2: 4412 case OPC_SEQ_CP2: 4413 cond = TCG_COND_EQ; 4414 goto do_cc_cond; 4415 break; 4416 case OPC_SLTU_CP2: 4417 cond = TCG_COND_LTU; 4418 goto do_cc_cond; 4419 break; 4420 case OPC_SLT_CP2: 4421 cond = TCG_COND_LT; 4422 goto do_cc_cond; 4423 break; 4424 case OPC_SLEU_CP2: 4425 cond = TCG_COND_LEU; 4426 goto do_cc_cond; 4427 break; 4428 case OPC_SLE_CP2: 4429 cond = TCG_COND_LE; 4430 do_cc_cond: 4431 { 4432 int cc = (ctx->opcode >> 8) & 0x7; 4433 TCGv_i64 t64 = tcg_temp_new_i64(); 4434 TCGv_i32 t32 = tcg_temp_new_i32(); 4435 4436 tcg_gen_setcond_i64(cond, t64, t0, t1); 4437 tcg_gen_extrl_i64_i32(t32, t64); 4438 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32, 4439 get_fp_bit(cc), 1); 4440 4441 tcg_temp_free_i32(t32); 4442 tcg_temp_free_i64(t64); 4443 } 4444 goto no_rd; 4445 break; 4446 default: 4447 MIPS_INVAL("loongson_cp2"); 4448 gen_reserved_instruction(ctx); 4449 return; 4450 } 4451 4452 gen_store_fpr64(ctx, t0, rd); 4453 4454 no_rd: 4455 tcg_temp_free_i64(t0); 4456 tcg_temp_free_i64(t1); 4457 } 4458 4459 static void gen_loongson_lswc2(DisasContext *ctx, int rt, 4460 int rs, int rd) 4461 { 4462 TCGv t0, t1, t2; 4463 TCGv_i32 fp0; 4464 #if defined(TARGET_MIPS64) 4465 int lsq_rt1 = ctx->opcode & 0x1f; 4466 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4; 4467 #endif 4468 int shf_offset = sextract32(ctx->opcode, 6, 8); 4469 4470 t0 = tcg_temp_new(); 4471 4472 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) { 4473 #if defined(TARGET_MIPS64) 4474 case OPC_GSLQ: 4475 t1 = tcg_temp_new(); 4476 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4477 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4478 ctx->default_tcg_memop_mask); 4479 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4480 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4481 ctx->default_tcg_memop_mask); 4482 gen_store_gpr(t1, rt); 4483 gen_store_gpr(t0, lsq_rt1); 4484 tcg_temp_free(t1); 4485 break; 4486 case OPC_GSLQC1: 4487 check_cp1_enabled(ctx); 4488 t1 = tcg_temp_new(); 4489 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4490 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4491 ctx->default_tcg_memop_mask); 4492 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4493 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4494 ctx->default_tcg_memop_mask); 4495 gen_store_fpr64(ctx, t1, rt); 4496 gen_store_fpr64(ctx, t0, lsq_rt1); 4497 tcg_temp_free(t1); 4498 break; 4499 case OPC_GSSQ: 4500 t1 = tcg_temp_new(); 4501 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4502 gen_load_gpr(t1, rt); 4503 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4504 ctx->default_tcg_memop_mask); 4505 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4506 gen_load_gpr(t1, lsq_rt1); 4507 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4508 ctx->default_tcg_memop_mask); 4509 tcg_temp_free(t1); 4510 break; 4511 case OPC_GSSQC1: 4512 check_cp1_enabled(ctx); 4513 t1 = tcg_temp_new(); 4514 gen_base_offset_addr(ctx, t0, rs, lsq_offset); 4515 gen_load_fpr64(ctx, t1, rt); 4516 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4517 ctx->default_tcg_memop_mask); 4518 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8); 4519 gen_load_fpr64(ctx, t1, lsq_rt1); 4520 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4521 ctx->default_tcg_memop_mask); 4522 tcg_temp_free(t1); 4523 break; 4524 #endif 4525 case OPC_GSSHFL: 4526 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4527 case OPC_GSLWLC1: 4528 check_cp1_enabled(ctx); 4529 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4530 t1 = tcg_temp_new(); 4531 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4532 tcg_gen_andi_tl(t1, t0, 3); 4533 #ifndef TARGET_WORDS_BIGENDIAN 4534 tcg_gen_xori_tl(t1, t1, 3); 4535 #endif 4536 tcg_gen_shli_tl(t1, t1, 3); 4537 tcg_gen_andi_tl(t0, t0, ~3); 4538 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); 4539 tcg_gen_shl_tl(t0, t0, t1); 4540 t2 = tcg_const_tl(-1); 4541 tcg_gen_shl_tl(t2, t2, t1); 4542 fp0 = tcg_temp_new_i32(); 4543 gen_load_fpr32(ctx, fp0, rt); 4544 tcg_gen_ext_i32_tl(t1, fp0); 4545 tcg_gen_andc_tl(t1, t1, t2); 4546 tcg_temp_free(t2); 4547 tcg_gen_or_tl(t0, t0, t1); 4548 tcg_temp_free(t1); 4549 #if defined(TARGET_MIPS64) 4550 tcg_gen_extrl_i64_i32(fp0, t0); 4551 #else 4552 tcg_gen_ext32s_tl(fp0, t0); 4553 #endif 4554 gen_store_fpr32(ctx, fp0, rt); 4555 tcg_temp_free_i32(fp0); 4556 break; 4557 case OPC_GSLWRC1: 4558 check_cp1_enabled(ctx); 4559 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4560 t1 = tcg_temp_new(); 4561 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4562 tcg_gen_andi_tl(t1, t0, 3); 4563 #ifdef TARGET_WORDS_BIGENDIAN 4564 tcg_gen_xori_tl(t1, t1, 3); 4565 #endif 4566 tcg_gen_shli_tl(t1, t1, 3); 4567 tcg_gen_andi_tl(t0, t0, ~3); 4568 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); 4569 tcg_gen_shr_tl(t0, t0, t1); 4570 tcg_gen_xori_tl(t1, t1, 31); 4571 t2 = tcg_const_tl(0xfffffffeull); 4572 tcg_gen_shl_tl(t2, t2, t1); 4573 fp0 = tcg_temp_new_i32(); 4574 gen_load_fpr32(ctx, fp0, rt); 4575 tcg_gen_ext_i32_tl(t1, fp0); 4576 tcg_gen_and_tl(t1, t1, t2); 4577 tcg_temp_free(t2); 4578 tcg_gen_or_tl(t0, t0, t1); 4579 tcg_temp_free(t1); 4580 #if defined(TARGET_MIPS64) 4581 tcg_gen_extrl_i64_i32(fp0, t0); 4582 #else 4583 tcg_gen_ext32s_tl(fp0, t0); 4584 #endif 4585 gen_store_fpr32(ctx, fp0, rt); 4586 tcg_temp_free_i32(fp0); 4587 break; 4588 #if defined(TARGET_MIPS64) 4589 case OPC_GSLDLC1: 4590 check_cp1_enabled(ctx); 4591 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4592 t1 = tcg_temp_new(); 4593 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4594 tcg_gen_andi_tl(t1, t0, 7); 4595 #ifndef TARGET_WORDS_BIGENDIAN 4596 tcg_gen_xori_tl(t1, t1, 7); 4597 #endif 4598 tcg_gen_shli_tl(t1, t1, 3); 4599 tcg_gen_andi_tl(t0, t0, ~7); 4600 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); 4601 tcg_gen_shl_tl(t0, t0, t1); 4602 t2 = tcg_const_tl(-1); 4603 tcg_gen_shl_tl(t2, t2, t1); 4604 gen_load_fpr64(ctx, t1, rt); 4605 tcg_gen_andc_tl(t1, t1, t2); 4606 tcg_temp_free(t2); 4607 tcg_gen_or_tl(t0, t0, t1); 4608 tcg_temp_free(t1); 4609 gen_store_fpr64(ctx, t0, rt); 4610 break; 4611 case OPC_GSLDRC1: 4612 check_cp1_enabled(ctx); 4613 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4614 t1 = tcg_temp_new(); 4615 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); 4616 tcg_gen_andi_tl(t1, t0, 7); 4617 #ifdef TARGET_WORDS_BIGENDIAN 4618 tcg_gen_xori_tl(t1, t1, 7); 4619 #endif 4620 tcg_gen_shli_tl(t1, t1, 3); 4621 tcg_gen_andi_tl(t0, t0, ~7); 4622 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); 4623 tcg_gen_shr_tl(t0, t0, t1); 4624 tcg_gen_xori_tl(t1, t1, 63); 4625 t2 = tcg_const_tl(0xfffffffffffffffeull); 4626 tcg_gen_shl_tl(t2, t2, t1); 4627 gen_load_fpr64(ctx, t1, rt); 4628 tcg_gen_and_tl(t1, t1, t2); 4629 tcg_temp_free(t2); 4630 tcg_gen_or_tl(t0, t0, t1); 4631 tcg_temp_free(t1); 4632 gen_store_fpr64(ctx, t0, rt); 4633 break; 4634 #endif 4635 default: 4636 MIPS_INVAL("loongson_gsshfl"); 4637 gen_reserved_instruction(ctx); 4638 break; 4639 } 4640 break; 4641 case OPC_GSSHFS: 4642 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) { 4643 case OPC_GSSWLC1: 4644 check_cp1_enabled(ctx); 4645 t1 = tcg_temp_new(); 4646 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4647 fp0 = tcg_temp_new_i32(); 4648 gen_load_fpr32(ctx, fp0, rt); 4649 tcg_gen_ext_i32_tl(t1, fp0); 4650 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx); 4651 tcg_temp_free_i32(fp0); 4652 tcg_temp_free(t1); 4653 break; 4654 case OPC_GSSWRC1: 4655 check_cp1_enabled(ctx); 4656 t1 = tcg_temp_new(); 4657 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4658 fp0 = tcg_temp_new_i32(); 4659 gen_load_fpr32(ctx, fp0, rt); 4660 tcg_gen_ext_i32_tl(t1, fp0); 4661 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx); 4662 tcg_temp_free_i32(fp0); 4663 tcg_temp_free(t1); 4664 break; 4665 #if defined(TARGET_MIPS64) 4666 case OPC_GSSDLC1: 4667 check_cp1_enabled(ctx); 4668 t1 = tcg_temp_new(); 4669 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4670 gen_load_fpr64(ctx, t1, rt); 4671 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx); 4672 tcg_temp_free(t1); 4673 break; 4674 case OPC_GSSDRC1: 4675 check_cp1_enabled(ctx); 4676 t1 = tcg_temp_new(); 4677 gen_base_offset_addr(ctx, t0, rs, shf_offset); 4678 gen_load_fpr64(ctx, t1, rt); 4679 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx); 4680 tcg_temp_free(t1); 4681 break; 4682 #endif 4683 default: 4684 MIPS_INVAL("loongson_gsshfs"); 4685 gen_reserved_instruction(ctx); 4686 break; 4687 } 4688 break; 4689 default: 4690 MIPS_INVAL("loongson_gslsq"); 4691 gen_reserved_instruction(ctx); 4692 break; 4693 } 4694 tcg_temp_free(t0); 4695 } 4696 4697 /* Loongson EXT LDC2/SDC2 */ 4698 static void gen_loongson_lsdc2(DisasContext *ctx, int rt, 4699 int rs, int rd) 4700 { 4701 int offset = sextract32(ctx->opcode, 3, 8); 4702 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode); 4703 TCGv t0, t1; 4704 TCGv_i32 fp0; 4705 4706 /* Pre-conditions */ 4707 switch (opc) { 4708 case OPC_GSLBX: 4709 case OPC_GSLHX: 4710 case OPC_GSLWX: 4711 case OPC_GSLDX: 4712 /* prefetch, implement as NOP */ 4713 if (rt == 0) { 4714 return; 4715 } 4716 break; 4717 case OPC_GSSBX: 4718 case OPC_GSSHX: 4719 case OPC_GSSWX: 4720 case OPC_GSSDX: 4721 break; 4722 case OPC_GSLWXC1: 4723 #if defined(TARGET_MIPS64) 4724 case OPC_GSLDXC1: 4725 #endif 4726 check_cp1_enabled(ctx); 4727 /* prefetch, implement as NOP */ 4728 if (rt == 0) { 4729 return; 4730 } 4731 break; 4732 case OPC_GSSWXC1: 4733 #if defined(TARGET_MIPS64) 4734 case OPC_GSSDXC1: 4735 #endif 4736 check_cp1_enabled(ctx); 4737 break; 4738 default: 4739 MIPS_INVAL("loongson_lsdc2"); 4740 gen_reserved_instruction(ctx); 4741 return; 4742 break; 4743 } 4744 4745 t0 = tcg_temp_new(); 4746 4747 gen_base_offset_addr(ctx, t0, rs, offset); 4748 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4749 4750 switch (opc) { 4751 case OPC_GSLBX: 4752 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); 4753 gen_store_gpr(t0, rt); 4754 break; 4755 case OPC_GSLHX: 4756 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW | 4757 ctx->default_tcg_memop_mask); 4758 gen_store_gpr(t0, rt); 4759 break; 4760 case OPC_GSLWX: 4761 gen_base_offset_addr(ctx, t0, rs, offset); 4762 if (rd) { 4763 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4764 } 4765 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL | 4766 ctx->default_tcg_memop_mask); 4767 gen_store_gpr(t0, rt); 4768 break; 4769 #if defined(TARGET_MIPS64) 4770 case OPC_GSLDX: 4771 gen_base_offset_addr(ctx, t0, rs, offset); 4772 if (rd) { 4773 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4774 } 4775 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4776 ctx->default_tcg_memop_mask); 4777 gen_store_gpr(t0, rt); 4778 break; 4779 #endif 4780 case OPC_GSLWXC1: 4781 check_cp1_enabled(ctx); 4782 gen_base_offset_addr(ctx, t0, rs, offset); 4783 if (rd) { 4784 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4785 } 4786 fp0 = tcg_temp_new_i32(); 4787 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL | 4788 ctx->default_tcg_memop_mask); 4789 gen_store_fpr32(ctx, fp0, rt); 4790 tcg_temp_free_i32(fp0); 4791 break; 4792 #if defined(TARGET_MIPS64) 4793 case OPC_GSLDXC1: 4794 check_cp1_enabled(ctx); 4795 gen_base_offset_addr(ctx, t0, rs, offset); 4796 if (rd) { 4797 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); 4798 } 4799 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ | 4800 ctx->default_tcg_memop_mask); 4801 gen_store_fpr64(ctx, t0, rt); 4802 break; 4803 #endif 4804 case OPC_GSSBX: 4805 t1 = tcg_temp_new(); 4806 gen_load_gpr(t1, rt); 4807 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB); 4808 tcg_temp_free(t1); 4809 break; 4810 case OPC_GSSHX: 4811 t1 = tcg_temp_new(); 4812 gen_load_gpr(t1, rt); 4813 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW | 4814 ctx->default_tcg_memop_mask); 4815 tcg_temp_free(t1); 4816 break; 4817 case OPC_GSSWX: 4818 t1 = tcg_temp_new(); 4819 gen_load_gpr(t1, rt); 4820 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL | 4821 ctx->default_tcg_memop_mask); 4822 tcg_temp_free(t1); 4823 break; 4824 #if defined(TARGET_MIPS64) 4825 case OPC_GSSDX: 4826 t1 = tcg_temp_new(); 4827 gen_load_gpr(t1, rt); 4828 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ | 4829 ctx->default_tcg_memop_mask); 4830 tcg_temp_free(t1); 4831 break; 4832 #endif 4833 case OPC_GSSWXC1: 4834 fp0 = tcg_temp_new_i32(); 4835 gen_load_fpr32(ctx, fp0, rt); 4836 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL | 4837 ctx->default_tcg_memop_mask); 4838 tcg_temp_free_i32(fp0); 4839 break; 4840 #if defined(TARGET_MIPS64) 4841 case OPC_GSSDXC1: 4842 t1 = tcg_temp_new(); 4843 gen_load_fpr64(ctx, t1, rt); 4844 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ | 4845 ctx->default_tcg_memop_mask); 4846 tcg_temp_free(t1); 4847 break; 4848 #endif 4849 default: 4850 break; 4851 } 4852 4853 tcg_temp_free(t0); 4854 } 4855 4856 /* Traps */ 4857 static void gen_trap(DisasContext *ctx, uint32_t opc, 4858 int rs, int rt, int16_t imm) 4859 { 4860 int cond; 4861 TCGv t0 = tcg_temp_new(); 4862 TCGv t1 = tcg_temp_new(); 4863 4864 cond = 0; 4865 /* Load needed operands */ 4866 switch (opc) { 4867 case OPC_TEQ: 4868 case OPC_TGE: 4869 case OPC_TGEU: 4870 case OPC_TLT: 4871 case OPC_TLTU: 4872 case OPC_TNE: 4873 /* Compare two registers */ 4874 if (rs != rt) { 4875 gen_load_gpr(t0, rs); 4876 gen_load_gpr(t1, rt); 4877 cond = 1; 4878 } 4879 break; 4880 case OPC_TEQI: 4881 case OPC_TGEI: 4882 case OPC_TGEIU: 4883 case OPC_TLTI: 4884 case OPC_TLTIU: 4885 case OPC_TNEI: 4886 /* Compare register to immediate */ 4887 if (rs != 0 || imm != 0) { 4888 gen_load_gpr(t0, rs); 4889 tcg_gen_movi_tl(t1, (int32_t)imm); 4890 cond = 1; 4891 } 4892 break; 4893 } 4894 if (cond == 0) { 4895 switch (opc) { 4896 case OPC_TEQ: /* rs == rs */ 4897 case OPC_TEQI: /* r0 == 0 */ 4898 case OPC_TGE: /* rs >= rs */ 4899 case OPC_TGEI: /* r0 >= 0 */ 4900 case OPC_TGEU: /* rs >= rs unsigned */ 4901 case OPC_TGEIU: /* r0 >= 0 unsigned */ 4902 /* Always trap */ 4903 generate_exception_end(ctx, EXCP_TRAP); 4904 break; 4905 case OPC_TLT: /* rs < rs */ 4906 case OPC_TLTI: /* r0 < 0 */ 4907 case OPC_TLTU: /* rs < rs unsigned */ 4908 case OPC_TLTIU: /* r0 < 0 unsigned */ 4909 case OPC_TNE: /* rs != rs */ 4910 case OPC_TNEI: /* r0 != 0 */ 4911 /* Never trap: treat as NOP. */ 4912 break; 4913 } 4914 } else { 4915 TCGLabel *l1 = gen_new_label(); 4916 4917 switch (opc) { 4918 case OPC_TEQ: 4919 case OPC_TEQI: 4920 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1); 4921 break; 4922 case OPC_TGE: 4923 case OPC_TGEI: 4924 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1); 4925 break; 4926 case OPC_TGEU: 4927 case OPC_TGEIU: 4928 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1); 4929 break; 4930 case OPC_TLT: 4931 case OPC_TLTI: 4932 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 4933 break; 4934 case OPC_TLTU: 4935 case OPC_TLTIU: 4936 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 4937 break; 4938 case OPC_TNE: 4939 case OPC_TNEI: 4940 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); 4941 break; 4942 } 4943 generate_exception(ctx, EXCP_TRAP); 4944 gen_set_label(l1); 4945 } 4946 tcg_temp_free(t0); 4947 tcg_temp_free(t1); 4948 } 4949 4950 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 4951 { 4952 if (translator_use_goto_tb(&ctx->base, dest)) { 4953 tcg_gen_goto_tb(n); 4954 gen_save_pc(dest); 4955 tcg_gen_exit_tb(ctx->base.tb, n); 4956 } else { 4957 gen_save_pc(dest); 4958 if (ctx->base.singlestep_enabled) { 4959 save_cpu_state(ctx, 0); 4960 gen_helper_raise_exception_debug(cpu_env); 4961 } else { 4962 tcg_gen_lookup_and_goto_ptr(); 4963 } 4964 } 4965 } 4966 4967 /* Branches (before delay slot) */ 4968 static void gen_compute_branch(DisasContext *ctx, uint32_t opc, 4969 int insn_bytes, 4970 int rs, int rt, int32_t offset, 4971 int delayslot_size) 4972 { 4973 target_ulong btgt = -1; 4974 int blink = 0; 4975 int bcond_compute = 0; 4976 TCGv t0 = tcg_temp_new(); 4977 TCGv t1 = tcg_temp_new(); 4978 4979 if (ctx->hflags & MIPS_HFLAG_BMASK) { 4980 #ifdef MIPS_DEBUG_DISAS 4981 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" 4982 TARGET_FMT_lx "\n", ctx->base.pc_next); 4983 #endif 4984 gen_reserved_instruction(ctx); 4985 goto out; 4986 } 4987 4988 /* Load needed operands */ 4989 switch (opc) { 4990 case OPC_BEQ: 4991 case OPC_BEQL: 4992 case OPC_BNE: 4993 case OPC_BNEL: 4994 /* Compare two registers */ 4995 if (rs != rt) { 4996 gen_load_gpr(t0, rs); 4997 gen_load_gpr(t1, rt); 4998 bcond_compute = 1; 4999 } 5000 btgt = ctx->base.pc_next + insn_bytes + offset; 5001 break; 5002 case OPC_BGEZ: 5003 case OPC_BGEZAL: 5004 case OPC_BGEZALL: 5005 case OPC_BGEZL: 5006 case OPC_BGTZ: 5007 case OPC_BGTZL: 5008 case OPC_BLEZ: 5009 case OPC_BLEZL: 5010 case OPC_BLTZ: 5011 case OPC_BLTZAL: 5012 case OPC_BLTZALL: 5013 case OPC_BLTZL: 5014 /* Compare to zero */ 5015 if (rs != 0) { 5016 gen_load_gpr(t0, rs); 5017 bcond_compute = 1; 5018 } 5019 btgt = ctx->base.pc_next + insn_bytes + offset; 5020 break; 5021 case OPC_BPOSGE32: 5022 #if defined(TARGET_MIPS64) 5023 case OPC_BPOSGE64: 5024 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F); 5025 #else 5026 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 5027 #endif 5028 bcond_compute = 1; 5029 btgt = ctx->base.pc_next + insn_bytes + offset; 5030 break; 5031 case OPC_J: 5032 case OPC_JAL: 5033 case OPC_JALX: 5034 /* Jump to immediate */ 5035 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) | 5036 (uint32_t)offset; 5037 break; 5038 case OPC_JR: 5039 case OPC_JALR: 5040 /* Jump to register */ 5041 if (offset != 0 && offset != 16) { 5042 /* 5043 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 5044 * others are reserved. 5045 */ 5046 MIPS_INVAL("jump hint"); 5047 gen_reserved_instruction(ctx); 5048 goto out; 5049 } 5050 gen_load_gpr(btarget, rs); 5051 break; 5052 default: 5053 MIPS_INVAL("branch/jump"); 5054 gen_reserved_instruction(ctx); 5055 goto out; 5056 } 5057 if (bcond_compute == 0) { 5058 /* No condition to be computed */ 5059 switch (opc) { 5060 case OPC_BEQ: /* rx == rx */ 5061 case OPC_BEQL: /* rx == rx likely */ 5062 case OPC_BGEZ: /* 0 >= 0 */ 5063 case OPC_BGEZL: /* 0 >= 0 likely */ 5064 case OPC_BLEZ: /* 0 <= 0 */ 5065 case OPC_BLEZL: /* 0 <= 0 likely */ 5066 /* Always take */ 5067 ctx->hflags |= MIPS_HFLAG_B; 5068 break; 5069 case OPC_BGEZAL: /* 0 >= 0 */ 5070 case OPC_BGEZALL: /* 0 >= 0 likely */ 5071 /* Always take and link */ 5072 blink = 31; 5073 ctx->hflags |= MIPS_HFLAG_B; 5074 break; 5075 case OPC_BNE: /* rx != rx */ 5076 case OPC_BGTZ: /* 0 > 0 */ 5077 case OPC_BLTZ: /* 0 < 0 */ 5078 /* Treat as NOP. */ 5079 goto out; 5080 case OPC_BLTZAL: /* 0 < 0 */ 5081 /* 5082 * Handle as an unconditional branch to get correct delay 5083 * slot checking. 5084 */ 5085 blink = 31; 5086 btgt = ctx->base.pc_next + insn_bytes + delayslot_size; 5087 ctx->hflags |= MIPS_HFLAG_B; 5088 break; 5089 case OPC_BLTZALL: /* 0 < 0 likely */ 5090 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 5091 /* Skip the instruction in the delay slot */ 5092 ctx->base.pc_next += 4; 5093 goto out; 5094 case OPC_BNEL: /* rx != rx likely */ 5095 case OPC_BGTZL: /* 0 > 0 likely */ 5096 case OPC_BLTZL: /* 0 < 0 likely */ 5097 /* Skip the instruction in the delay slot */ 5098 ctx->base.pc_next += 4; 5099 goto out; 5100 case OPC_J: 5101 ctx->hflags |= MIPS_HFLAG_B; 5102 break; 5103 case OPC_JALX: 5104 ctx->hflags |= MIPS_HFLAG_BX; 5105 /* Fallthrough */ 5106 case OPC_JAL: 5107 blink = 31; 5108 ctx->hflags |= MIPS_HFLAG_B; 5109 break; 5110 case OPC_JR: 5111 ctx->hflags |= MIPS_HFLAG_BR; 5112 break; 5113 case OPC_JALR: 5114 blink = rt; 5115 ctx->hflags |= MIPS_HFLAG_BR; 5116 break; 5117 default: 5118 MIPS_INVAL("branch/jump"); 5119 gen_reserved_instruction(ctx); 5120 goto out; 5121 } 5122 } else { 5123 switch (opc) { 5124 case OPC_BEQ: 5125 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 5126 goto not_likely; 5127 case OPC_BEQL: 5128 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 5129 goto likely; 5130 case OPC_BNE: 5131 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 5132 goto not_likely; 5133 case OPC_BNEL: 5134 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 5135 goto likely; 5136 case OPC_BGEZ: 5137 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5138 goto not_likely; 5139 case OPC_BGEZL: 5140 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5141 goto likely; 5142 case OPC_BGEZAL: 5143 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5144 blink = 31; 5145 goto not_likely; 5146 case OPC_BGEZALL: 5147 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 5148 blink = 31; 5149 goto likely; 5150 case OPC_BGTZ: 5151 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 5152 goto not_likely; 5153 case OPC_BGTZL: 5154 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0); 5155 goto likely; 5156 case OPC_BLEZ: 5157 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 5158 goto not_likely; 5159 case OPC_BLEZL: 5160 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0); 5161 goto likely; 5162 case OPC_BLTZ: 5163 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5164 goto not_likely; 5165 case OPC_BLTZL: 5166 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5167 goto likely; 5168 case OPC_BPOSGE32: 5169 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 5170 goto not_likely; 5171 #if defined(TARGET_MIPS64) 5172 case OPC_BPOSGE64: 5173 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64); 5174 goto not_likely; 5175 #endif 5176 case OPC_BLTZAL: 5177 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5178 blink = 31; 5179 not_likely: 5180 ctx->hflags |= MIPS_HFLAG_BC; 5181 break; 5182 case OPC_BLTZALL: 5183 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0); 5184 blink = 31; 5185 likely: 5186 ctx->hflags |= MIPS_HFLAG_BL; 5187 break; 5188 default: 5189 MIPS_INVAL("conditional branch/jump"); 5190 gen_reserved_instruction(ctx); 5191 goto out; 5192 } 5193 } 5194 5195 ctx->btarget = btgt; 5196 5197 switch (delayslot_size) { 5198 case 2: 5199 ctx->hflags |= MIPS_HFLAG_BDS16; 5200 break; 5201 case 4: 5202 ctx->hflags |= MIPS_HFLAG_BDS32; 5203 break; 5204 } 5205 5206 if (blink > 0) { 5207 int post_delay = insn_bytes + delayslot_size; 5208 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16); 5209 5210 tcg_gen_movi_tl(cpu_gpr[blink], 5211 ctx->base.pc_next + post_delay + lowbit); 5212 } 5213 5214 out: 5215 if (insn_bytes == 2) { 5216 ctx->hflags |= MIPS_HFLAG_B16; 5217 } 5218 tcg_temp_free(t0); 5219 tcg_temp_free(t1); 5220 } 5221 5222 5223 /* special3 bitfield operations */ 5224 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, 5225 int rs, int lsb, int msb) 5226 { 5227 TCGv t0 = tcg_temp_new(); 5228 TCGv t1 = tcg_temp_new(); 5229 5230 gen_load_gpr(t1, rs); 5231 switch (opc) { 5232 case OPC_EXT: 5233 if (lsb + msb > 31) { 5234 goto fail; 5235 } 5236 if (msb != 31) { 5237 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 5238 } else { 5239 /* 5240 * The two checks together imply that lsb == 0, 5241 * so this is a simple sign-extension. 5242 */ 5243 tcg_gen_ext32s_tl(t0, t1); 5244 } 5245 break; 5246 #if defined(TARGET_MIPS64) 5247 case OPC_DEXTU: 5248 lsb += 32; 5249 goto do_dext; 5250 case OPC_DEXTM: 5251 msb += 32; 5252 goto do_dext; 5253 case OPC_DEXT: 5254 do_dext: 5255 if (lsb + msb > 63) { 5256 goto fail; 5257 } 5258 tcg_gen_extract_tl(t0, t1, lsb, msb + 1); 5259 break; 5260 #endif 5261 case OPC_INS: 5262 if (lsb > msb) { 5263 goto fail; 5264 } 5265 gen_load_gpr(t0, rt); 5266 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 5267 tcg_gen_ext32s_tl(t0, t0); 5268 break; 5269 #if defined(TARGET_MIPS64) 5270 case OPC_DINSU: 5271 lsb += 32; 5272 /* FALLTHRU */ 5273 case OPC_DINSM: 5274 msb += 32; 5275 /* FALLTHRU */ 5276 case OPC_DINS: 5277 if (lsb > msb) { 5278 goto fail; 5279 } 5280 gen_load_gpr(t0, rt); 5281 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); 5282 break; 5283 #endif 5284 default: 5285 fail: 5286 MIPS_INVAL("bitops"); 5287 gen_reserved_instruction(ctx); 5288 tcg_temp_free(t0); 5289 tcg_temp_free(t1); 5290 return; 5291 } 5292 gen_store_gpr(t0, rt); 5293 tcg_temp_free(t0); 5294 tcg_temp_free(t1); 5295 } 5296 5297 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) 5298 { 5299 TCGv t0; 5300 5301 if (rd == 0) { 5302 /* If no destination, treat it as a NOP. */ 5303 return; 5304 } 5305 5306 t0 = tcg_temp_new(); 5307 gen_load_gpr(t0, rt); 5308 switch (op2) { 5309 case OPC_WSBH: 5310 { 5311 TCGv t1 = tcg_temp_new(); 5312 TCGv t2 = tcg_const_tl(0x00FF00FF); 5313 5314 tcg_gen_shri_tl(t1, t0, 8); 5315 tcg_gen_and_tl(t1, t1, t2); 5316 tcg_gen_and_tl(t0, t0, t2); 5317 tcg_gen_shli_tl(t0, t0, 8); 5318 tcg_gen_or_tl(t0, t0, t1); 5319 tcg_temp_free(t2); 5320 tcg_temp_free(t1); 5321 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 5322 } 5323 break; 5324 case OPC_SEB: 5325 tcg_gen_ext8s_tl(cpu_gpr[rd], t0); 5326 break; 5327 case OPC_SEH: 5328 tcg_gen_ext16s_tl(cpu_gpr[rd], t0); 5329 break; 5330 #if defined(TARGET_MIPS64) 5331 case OPC_DSBH: 5332 { 5333 TCGv t1 = tcg_temp_new(); 5334 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL); 5335 5336 tcg_gen_shri_tl(t1, t0, 8); 5337 tcg_gen_and_tl(t1, t1, t2); 5338 tcg_gen_and_tl(t0, t0, t2); 5339 tcg_gen_shli_tl(t0, t0, 8); 5340 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 5341 tcg_temp_free(t2); 5342 tcg_temp_free(t1); 5343 } 5344 break; 5345 case OPC_DSHD: 5346 { 5347 TCGv t1 = tcg_temp_new(); 5348 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL); 5349 5350 tcg_gen_shri_tl(t1, t0, 16); 5351 tcg_gen_and_tl(t1, t1, t2); 5352 tcg_gen_and_tl(t0, t0, t2); 5353 tcg_gen_shli_tl(t0, t0, 16); 5354 tcg_gen_or_tl(t0, t0, t1); 5355 tcg_gen_shri_tl(t1, t0, 32); 5356 tcg_gen_shli_tl(t0, t0, 32); 5357 tcg_gen_or_tl(cpu_gpr[rd], t0, t1); 5358 tcg_temp_free(t2); 5359 tcg_temp_free(t1); 5360 } 5361 break; 5362 #endif 5363 default: 5364 MIPS_INVAL("bsfhl"); 5365 gen_reserved_instruction(ctx); 5366 tcg_temp_free(t0); 5367 return; 5368 } 5369 tcg_temp_free(t0); 5370 } 5371 5372 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, 5373 int rt, int bits) 5374 { 5375 TCGv t0; 5376 if (rd == 0) { 5377 /* Treat as NOP. */ 5378 return; 5379 } 5380 t0 = tcg_temp_new(); 5381 if (bits == 0 || bits == wordsz) { 5382 if (bits == 0) { 5383 gen_load_gpr(t0, rt); 5384 } else { 5385 gen_load_gpr(t0, rs); 5386 } 5387 switch (wordsz) { 5388 case 32: 5389 tcg_gen_ext32s_tl(cpu_gpr[rd], t0); 5390 break; 5391 #if defined(TARGET_MIPS64) 5392 case 64: 5393 tcg_gen_mov_tl(cpu_gpr[rd], t0); 5394 break; 5395 #endif 5396 } 5397 } else { 5398 TCGv t1 = tcg_temp_new(); 5399 gen_load_gpr(t0, rt); 5400 gen_load_gpr(t1, rs); 5401 switch (wordsz) { 5402 case 32: 5403 { 5404 TCGv_i64 t2 = tcg_temp_new_i64(); 5405 tcg_gen_concat_tl_i64(t2, t1, t0); 5406 tcg_gen_shri_i64(t2, t2, 32 - bits); 5407 gen_move_low32(cpu_gpr[rd], t2); 5408 tcg_temp_free_i64(t2); 5409 } 5410 break; 5411 #if defined(TARGET_MIPS64) 5412 case 64: 5413 tcg_gen_shli_tl(t0, t0, bits); 5414 tcg_gen_shri_tl(t1, t1, 64 - bits); 5415 tcg_gen_or_tl(cpu_gpr[rd], t1, t0); 5416 break; 5417 #endif 5418 } 5419 tcg_temp_free(t1); 5420 } 5421 5422 tcg_temp_free(t0); 5423 } 5424 5425 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp) 5426 { 5427 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); 5428 } 5429 5430 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) 5431 { 5432 TCGv t0; 5433 if (rd == 0) { 5434 /* Treat as NOP. */ 5435 return; 5436 } 5437 t0 = tcg_temp_new(); 5438 gen_load_gpr(t0, rt); 5439 switch (opc) { 5440 case OPC_BITSWAP: 5441 gen_helper_bitswap(cpu_gpr[rd], t0); 5442 break; 5443 #if defined(TARGET_MIPS64) 5444 case OPC_DBITSWAP: 5445 gen_helper_dbitswap(cpu_gpr[rd], t0); 5446 break; 5447 #endif 5448 } 5449 tcg_temp_free(t0); 5450 } 5451 5452 #ifndef CONFIG_USER_ONLY 5453 /* CP0 (MMU and control) */ 5454 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off) 5455 { 5456 TCGv_i64 t0 = tcg_temp_new_i64(); 5457 TCGv_i64 t1 = tcg_temp_new_i64(); 5458 5459 tcg_gen_ext_tl_i64(t0, arg); 5460 tcg_gen_ld_i64(t1, cpu_env, off); 5461 #if defined(TARGET_MIPS64) 5462 tcg_gen_deposit_i64(t1, t1, t0, 30, 32); 5463 #else 5464 tcg_gen_concat32_i64(t1, t1, t0); 5465 #endif 5466 tcg_gen_st_i64(t1, cpu_env, off); 5467 tcg_temp_free_i64(t1); 5468 tcg_temp_free_i64(t0); 5469 } 5470 5471 static inline void gen_mthc0_store64(TCGv arg, target_ulong off) 5472 { 5473 TCGv_i64 t0 = tcg_temp_new_i64(); 5474 TCGv_i64 t1 = tcg_temp_new_i64(); 5475 5476 tcg_gen_ext_tl_i64(t0, arg); 5477 tcg_gen_ld_i64(t1, cpu_env, off); 5478 tcg_gen_concat32_i64(t1, t1, t0); 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_mfhc0_entrylo(TCGv arg, target_ulong off) 5485 { 5486 TCGv_i64 t0 = tcg_temp_new_i64(); 5487 5488 tcg_gen_ld_i64(t0, cpu_env, off); 5489 #if defined(TARGET_MIPS64) 5490 tcg_gen_shri_i64(t0, t0, 30); 5491 #else 5492 tcg_gen_shri_i64(t0, t0, 32); 5493 #endif 5494 gen_move_low32(arg, t0); 5495 tcg_temp_free_i64(t0); 5496 } 5497 5498 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift) 5499 { 5500 TCGv_i64 t0 = tcg_temp_new_i64(); 5501 5502 tcg_gen_ld_i64(t0, cpu_env, off); 5503 tcg_gen_shri_i64(t0, t0, 32 + shift); 5504 gen_move_low32(arg, t0); 5505 tcg_temp_free_i64(t0); 5506 } 5507 5508 static inline void gen_mfc0_load32(TCGv arg, target_ulong off) 5509 { 5510 TCGv_i32 t0 = tcg_temp_new_i32(); 5511 5512 tcg_gen_ld_i32(t0, cpu_env, off); 5513 tcg_gen_ext_i32_tl(arg, t0); 5514 tcg_temp_free_i32(t0); 5515 } 5516 5517 static inline void gen_mfc0_load64(TCGv arg, target_ulong off) 5518 { 5519 tcg_gen_ld_tl(arg, cpu_env, off); 5520 tcg_gen_ext32s_tl(arg, arg); 5521 } 5522 5523 static inline void gen_mtc0_store32(TCGv arg, target_ulong off) 5524 { 5525 TCGv_i32 t0 = tcg_temp_new_i32(); 5526 5527 tcg_gen_trunc_tl_i32(t0, arg); 5528 tcg_gen_st_i32(t0, cpu_env, off); 5529 tcg_temp_free_i32(t0); 5530 } 5531 5532 #define CP0_CHECK(c) \ 5533 do { \ 5534 if (!(c)) { \ 5535 goto cp0_unimplemented; \ 5536 } \ 5537 } while (0) 5538 5539 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5540 { 5541 const char *register_name = "invalid"; 5542 5543 switch (reg) { 5544 case CP0_REGISTER_02: 5545 switch (sel) { 5546 case 0: 5547 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5548 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5549 register_name = "EntryLo0"; 5550 break; 5551 default: 5552 goto cp0_unimplemented; 5553 } 5554 break; 5555 case CP0_REGISTER_03: 5556 switch (sel) { 5557 case CP0_REG03__ENTRYLO1: 5558 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5559 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5560 register_name = "EntryLo1"; 5561 break; 5562 default: 5563 goto cp0_unimplemented; 5564 } 5565 break; 5566 case CP0_REGISTER_09: 5567 switch (sel) { 5568 case CP0_REG09__SAAR: 5569 CP0_CHECK(ctx->saar); 5570 gen_helper_mfhc0_saar(arg, cpu_env); 5571 register_name = "SAAR"; 5572 break; 5573 default: 5574 goto cp0_unimplemented; 5575 } 5576 break; 5577 case CP0_REGISTER_17: 5578 switch (sel) { 5579 case CP0_REG17__LLADDR: 5580 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr), 5581 ctx->CP0_LLAddr_shift); 5582 register_name = "LLAddr"; 5583 break; 5584 case CP0_REG17__MAAR: 5585 CP0_CHECK(ctx->mrp); 5586 gen_helper_mfhc0_maar(arg, cpu_env); 5587 register_name = "MAAR"; 5588 break; 5589 default: 5590 goto cp0_unimplemented; 5591 } 5592 break; 5593 case CP0_REGISTER_19: 5594 switch (sel) { 5595 case CP0_REG19__WATCHHI0: 5596 case CP0_REG19__WATCHHI1: 5597 case CP0_REG19__WATCHHI2: 5598 case CP0_REG19__WATCHHI3: 5599 case CP0_REG19__WATCHHI4: 5600 case CP0_REG19__WATCHHI5: 5601 case CP0_REG19__WATCHHI6: 5602 case CP0_REG19__WATCHHI7: 5603 /* upper 32 bits are only available when Config5MI != 0 */ 5604 CP0_CHECK(ctx->mi); 5605 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0); 5606 register_name = "WatchHi"; 5607 break; 5608 default: 5609 goto cp0_unimplemented; 5610 } 5611 break; 5612 case CP0_REGISTER_28: 5613 switch (sel) { 5614 case 0: 5615 case 2: 5616 case 4: 5617 case 6: 5618 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0); 5619 register_name = "TagLo"; 5620 break; 5621 default: 5622 goto cp0_unimplemented; 5623 } 5624 break; 5625 default: 5626 goto cp0_unimplemented; 5627 } 5628 trace_mips_translate_c0("mfhc0", register_name, reg, sel); 5629 return; 5630 5631 cp0_unimplemented: 5632 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", 5633 register_name, reg, sel); 5634 tcg_gen_movi_tl(arg, 0); 5635 } 5636 5637 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5638 { 5639 const char *register_name = "invalid"; 5640 uint64_t mask = ctx->PAMask >> 36; 5641 5642 switch (reg) { 5643 case CP0_REGISTER_02: 5644 switch (sel) { 5645 case 0: 5646 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5647 tcg_gen_andi_tl(arg, arg, mask); 5648 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0)); 5649 register_name = "EntryLo0"; 5650 break; 5651 default: 5652 goto cp0_unimplemented; 5653 } 5654 break; 5655 case CP0_REGISTER_03: 5656 switch (sel) { 5657 case CP0_REG03__ENTRYLO1: 5658 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA); 5659 tcg_gen_andi_tl(arg, arg, mask); 5660 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1)); 5661 register_name = "EntryLo1"; 5662 break; 5663 default: 5664 goto cp0_unimplemented; 5665 } 5666 break; 5667 case CP0_REGISTER_09: 5668 switch (sel) { 5669 case CP0_REG09__SAAR: 5670 CP0_CHECK(ctx->saar); 5671 gen_helper_mthc0_saar(cpu_env, arg); 5672 register_name = "SAAR"; 5673 break; 5674 default: 5675 goto cp0_unimplemented; 5676 } 5677 break; 5678 case CP0_REGISTER_17: 5679 switch (sel) { 5680 case CP0_REG17__LLADDR: 5681 /* 5682 * LLAddr is read-only (the only exception is bit 0 if LLB is 5683 * supported); the CP0_LLAddr_rw_bitmask does not seem to be 5684 * relevant for modern MIPS cores supporting MTHC0, therefore 5685 * treating MTHC0 to LLAddr as NOP. 5686 */ 5687 register_name = "LLAddr"; 5688 break; 5689 case CP0_REG17__MAAR: 5690 CP0_CHECK(ctx->mrp); 5691 gen_helper_mthc0_maar(cpu_env, arg); 5692 register_name = "MAAR"; 5693 break; 5694 default: 5695 goto cp0_unimplemented; 5696 } 5697 break; 5698 case CP0_REGISTER_19: 5699 switch (sel) { 5700 case CP0_REG19__WATCHHI0: 5701 case CP0_REG19__WATCHHI1: 5702 case CP0_REG19__WATCHHI2: 5703 case CP0_REG19__WATCHHI3: 5704 case CP0_REG19__WATCHHI4: 5705 case CP0_REG19__WATCHHI5: 5706 case CP0_REG19__WATCHHI6: 5707 case CP0_REG19__WATCHHI7: 5708 /* upper 32 bits are only available when Config5MI != 0 */ 5709 CP0_CHECK(ctx->mi); 5710 gen_helper_0e1i(mthc0_watchhi, arg, sel); 5711 register_name = "WatchHi"; 5712 break; 5713 default: 5714 goto cp0_unimplemented; 5715 } 5716 break; 5717 case CP0_REGISTER_28: 5718 switch (sel) { 5719 case 0: 5720 case 2: 5721 case 4: 5722 case 6: 5723 tcg_gen_andi_tl(arg, arg, mask); 5724 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo)); 5725 register_name = "TagLo"; 5726 break; 5727 default: 5728 goto cp0_unimplemented; 5729 } 5730 break; 5731 default: 5732 goto cp0_unimplemented; 5733 } 5734 trace_mips_translate_c0("mthc0", register_name, reg, sel); 5735 return; 5736 5737 cp0_unimplemented: 5738 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", 5739 register_name, reg, sel); 5740 } 5741 5742 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg) 5743 { 5744 if (ctx->insn_flags & ISA_MIPS_R6) { 5745 tcg_gen_movi_tl(arg, 0); 5746 } else { 5747 tcg_gen_movi_tl(arg, ~0); 5748 } 5749 } 5750 5751 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 5752 { 5753 const char *register_name = "invalid"; 5754 5755 if (sel != 0) { 5756 check_insn(ctx, ISA_MIPS_R1); 5757 } 5758 5759 switch (reg) { 5760 case CP0_REGISTER_00: 5761 switch (sel) { 5762 case CP0_REG00__INDEX: 5763 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 5764 register_name = "Index"; 5765 break; 5766 case CP0_REG00__MVPCONTROL: 5767 CP0_CHECK(ctx->insn_flags & ASE_MT); 5768 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 5769 register_name = "MVPControl"; 5770 break; 5771 case CP0_REG00__MVPCONF0: 5772 CP0_CHECK(ctx->insn_flags & ASE_MT); 5773 gen_helper_mfc0_mvpconf0(arg, cpu_env); 5774 register_name = "MVPConf0"; 5775 break; 5776 case CP0_REG00__MVPCONF1: 5777 CP0_CHECK(ctx->insn_flags & ASE_MT); 5778 gen_helper_mfc0_mvpconf1(arg, cpu_env); 5779 register_name = "MVPConf1"; 5780 break; 5781 case CP0_REG00__VPCONTROL: 5782 CP0_CHECK(ctx->vp); 5783 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 5784 register_name = "VPControl"; 5785 break; 5786 default: 5787 goto cp0_unimplemented; 5788 } 5789 break; 5790 case CP0_REGISTER_01: 5791 switch (sel) { 5792 case CP0_REG01__RANDOM: 5793 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 5794 gen_helper_mfc0_random(arg, cpu_env); 5795 register_name = "Random"; 5796 break; 5797 case CP0_REG01__VPECONTROL: 5798 CP0_CHECK(ctx->insn_flags & ASE_MT); 5799 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 5800 register_name = "VPEControl"; 5801 break; 5802 case CP0_REG01__VPECONF0: 5803 CP0_CHECK(ctx->insn_flags & ASE_MT); 5804 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 5805 register_name = "VPEConf0"; 5806 break; 5807 case CP0_REG01__VPECONF1: 5808 CP0_CHECK(ctx->insn_flags & ASE_MT); 5809 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 5810 register_name = "VPEConf1"; 5811 break; 5812 case CP0_REG01__YQMASK: 5813 CP0_CHECK(ctx->insn_flags & ASE_MT); 5814 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask)); 5815 register_name = "YQMask"; 5816 break; 5817 case CP0_REG01__VPESCHEDULE: 5818 CP0_CHECK(ctx->insn_flags & ASE_MT); 5819 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule)); 5820 register_name = "VPESchedule"; 5821 break; 5822 case CP0_REG01__VPESCHEFBACK: 5823 CP0_CHECK(ctx->insn_flags & ASE_MT); 5824 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack)); 5825 register_name = "VPEScheFBack"; 5826 break; 5827 case CP0_REG01__VPEOPT: 5828 CP0_CHECK(ctx->insn_flags & ASE_MT); 5829 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 5830 register_name = "VPEOpt"; 5831 break; 5832 default: 5833 goto cp0_unimplemented; 5834 } 5835 break; 5836 case CP0_REGISTER_02: 5837 switch (sel) { 5838 case CP0_REG02__ENTRYLO0: 5839 { 5840 TCGv_i64 tmp = tcg_temp_new_i64(); 5841 tcg_gen_ld_i64(tmp, cpu_env, 5842 offsetof(CPUMIPSState, CP0_EntryLo0)); 5843 #if defined(TARGET_MIPS64) 5844 if (ctx->rxi) { 5845 /* Move RI/XI fields to bits 31:30 */ 5846 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5847 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5848 } 5849 #endif 5850 gen_move_low32(arg, tmp); 5851 tcg_temp_free_i64(tmp); 5852 } 5853 register_name = "EntryLo0"; 5854 break; 5855 case CP0_REG02__TCSTATUS: 5856 CP0_CHECK(ctx->insn_flags & ASE_MT); 5857 gen_helper_mfc0_tcstatus(arg, cpu_env); 5858 register_name = "TCStatus"; 5859 break; 5860 case CP0_REG02__TCBIND: 5861 CP0_CHECK(ctx->insn_flags & ASE_MT); 5862 gen_helper_mfc0_tcbind(arg, cpu_env); 5863 register_name = "TCBind"; 5864 break; 5865 case CP0_REG02__TCRESTART: 5866 CP0_CHECK(ctx->insn_flags & ASE_MT); 5867 gen_helper_mfc0_tcrestart(arg, cpu_env); 5868 register_name = "TCRestart"; 5869 break; 5870 case CP0_REG02__TCHALT: 5871 CP0_CHECK(ctx->insn_flags & ASE_MT); 5872 gen_helper_mfc0_tchalt(arg, cpu_env); 5873 register_name = "TCHalt"; 5874 break; 5875 case CP0_REG02__TCCONTEXT: 5876 CP0_CHECK(ctx->insn_flags & ASE_MT); 5877 gen_helper_mfc0_tccontext(arg, cpu_env); 5878 register_name = "TCContext"; 5879 break; 5880 case CP0_REG02__TCSCHEDULE: 5881 CP0_CHECK(ctx->insn_flags & ASE_MT); 5882 gen_helper_mfc0_tcschedule(arg, cpu_env); 5883 register_name = "TCSchedule"; 5884 break; 5885 case CP0_REG02__TCSCHEFBACK: 5886 CP0_CHECK(ctx->insn_flags & ASE_MT); 5887 gen_helper_mfc0_tcschefback(arg, cpu_env); 5888 register_name = "TCScheFBack"; 5889 break; 5890 default: 5891 goto cp0_unimplemented; 5892 } 5893 break; 5894 case CP0_REGISTER_03: 5895 switch (sel) { 5896 case CP0_REG03__ENTRYLO1: 5897 { 5898 TCGv_i64 tmp = tcg_temp_new_i64(); 5899 tcg_gen_ld_i64(tmp, cpu_env, 5900 offsetof(CPUMIPSState, CP0_EntryLo1)); 5901 #if defined(TARGET_MIPS64) 5902 if (ctx->rxi) { 5903 /* Move RI/XI fields to bits 31:30 */ 5904 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); 5905 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); 5906 } 5907 #endif 5908 gen_move_low32(arg, tmp); 5909 tcg_temp_free_i64(tmp); 5910 } 5911 register_name = "EntryLo1"; 5912 break; 5913 case CP0_REG03__GLOBALNUM: 5914 CP0_CHECK(ctx->vp); 5915 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 5916 register_name = "GlobalNumber"; 5917 break; 5918 default: 5919 goto cp0_unimplemented; 5920 } 5921 break; 5922 case CP0_REGISTER_04: 5923 switch (sel) { 5924 case CP0_REG04__CONTEXT: 5925 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 5926 tcg_gen_ext32s_tl(arg, arg); 5927 register_name = "Context"; 5928 break; 5929 case CP0_REG04__CONTEXTCONFIG: 5930 /* SmartMIPS ASE */ 5931 /* gen_helper_mfc0_contextconfig(arg); */ 5932 register_name = "ContextConfig"; 5933 goto cp0_unimplemented; 5934 case CP0_REG04__USERLOCAL: 5935 CP0_CHECK(ctx->ulri); 5936 tcg_gen_ld_tl(arg, cpu_env, 5937 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 5938 tcg_gen_ext32s_tl(arg, arg); 5939 register_name = "UserLocal"; 5940 break; 5941 case CP0_REG04__MMID: 5942 CP0_CHECK(ctx->mi); 5943 gen_helper_mtc0_memorymapid(cpu_env, arg); 5944 register_name = "MMID"; 5945 break; 5946 default: 5947 goto cp0_unimplemented; 5948 } 5949 break; 5950 case CP0_REGISTER_05: 5951 switch (sel) { 5952 case CP0_REG05__PAGEMASK: 5953 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 5954 register_name = "PageMask"; 5955 break; 5956 case CP0_REG05__PAGEGRAIN: 5957 check_insn(ctx, ISA_MIPS_R2); 5958 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 5959 register_name = "PageGrain"; 5960 break; 5961 case CP0_REG05__SEGCTL0: 5962 CP0_CHECK(ctx->sc); 5963 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 5964 tcg_gen_ext32s_tl(arg, arg); 5965 register_name = "SegCtl0"; 5966 break; 5967 case CP0_REG05__SEGCTL1: 5968 CP0_CHECK(ctx->sc); 5969 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 5970 tcg_gen_ext32s_tl(arg, arg); 5971 register_name = "SegCtl1"; 5972 break; 5973 case CP0_REG05__SEGCTL2: 5974 CP0_CHECK(ctx->sc); 5975 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 5976 tcg_gen_ext32s_tl(arg, arg); 5977 register_name = "SegCtl2"; 5978 break; 5979 case CP0_REG05__PWBASE: 5980 check_pw(ctx); 5981 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 5982 register_name = "PWBase"; 5983 break; 5984 case CP0_REG05__PWFIELD: 5985 check_pw(ctx); 5986 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField)); 5987 register_name = "PWField"; 5988 break; 5989 case CP0_REG05__PWSIZE: 5990 check_pw(ctx); 5991 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize)); 5992 register_name = "PWSize"; 5993 break; 5994 default: 5995 goto cp0_unimplemented; 5996 } 5997 break; 5998 case CP0_REGISTER_06: 5999 switch (sel) { 6000 case CP0_REG06__WIRED: 6001 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 6002 register_name = "Wired"; 6003 break; 6004 case CP0_REG06__SRSCONF0: 6005 check_insn(ctx, ISA_MIPS_R2); 6006 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 6007 register_name = "SRSConf0"; 6008 break; 6009 case CP0_REG06__SRSCONF1: 6010 check_insn(ctx, ISA_MIPS_R2); 6011 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 6012 register_name = "SRSConf1"; 6013 break; 6014 case CP0_REG06__SRSCONF2: 6015 check_insn(ctx, ISA_MIPS_R2); 6016 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 6017 register_name = "SRSConf2"; 6018 break; 6019 case CP0_REG06__SRSCONF3: 6020 check_insn(ctx, ISA_MIPS_R2); 6021 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 6022 register_name = "SRSConf3"; 6023 break; 6024 case CP0_REG06__SRSCONF4: 6025 check_insn(ctx, ISA_MIPS_R2); 6026 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 6027 register_name = "SRSConf4"; 6028 break; 6029 case CP0_REG06__PWCTL: 6030 check_pw(ctx); 6031 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 6032 register_name = "PWCtl"; 6033 break; 6034 default: 6035 goto cp0_unimplemented; 6036 } 6037 break; 6038 case CP0_REGISTER_07: 6039 switch (sel) { 6040 case CP0_REG07__HWRENA: 6041 check_insn(ctx, ISA_MIPS_R2); 6042 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 6043 register_name = "HWREna"; 6044 break; 6045 default: 6046 goto cp0_unimplemented; 6047 } 6048 break; 6049 case CP0_REGISTER_08: 6050 switch (sel) { 6051 case CP0_REG08__BADVADDR: 6052 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 6053 tcg_gen_ext32s_tl(arg, arg); 6054 register_name = "BadVAddr"; 6055 break; 6056 case CP0_REG08__BADINSTR: 6057 CP0_CHECK(ctx->bi); 6058 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 6059 register_name = "BadInstr"; 6060 break; 6061 case CP0_REG08__BADINSTRP: 6062 CP0_CHECK(ctx->bp); 6063 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 6064 register_name = "BadInstrP"; 6065 break; 6066 case CP0_REG08__BADINSTRX: 6067 CP0_CHECK(ctx->bi); 6068 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 6069 tcg_gen_andi_tl(arg, arg, ~0xffff); 6070 register_name = "BadInstrX"; 6071 break; 6072 default: 6073 goto cp0_unimplemented; 6074 } 6075 break; 6076 case CP0_REGISTER_09: 6077 switch (sel) { 6078 case CP0_REG09__COUNT: 6079 /* Mark as an IO operation because we read the time. */ 6080 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 6081 gen_io_start(); 6082 } 6083 gen_helper_mfc0_count(arg, cpu_env); 6084 /* 6085 * Break the TB to be able to take timer interrupts immediately 6086 * after reading count. DISAS_STOP isn't sufficient, we need to 6087 * ensure we break completely out of translated code. 6088 */ 6089 gen_save_pc(ctx->base.pc_next + 4); 6090 ctx->base.is_jmp = DISAS_EXIT; 6091 register_name = "Count"; 6092 break; 6093 case CP0_REG09__SAARI: 6094 CP0_CHECK(ctx->saar); 6095 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); 6096 register_name = "SAARI"; 6097 break; 6098 case CP0_REG09__SAAR: 6099 CP0_CHECK(ctx->saar); 6100 gen_helper_mfc0_saar(arg, cpu_env); 6101 register_name = "SAAR"; 6102 break; 6103 default: 6104 goto cp0_unimplemented; 6105 } 6106 break; 6107 case CP0_REGISTER_10: 6108 switch (sel) { 6109 case CP0_REG10__ENTRYHI: 6110 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 6111 tcg_gen_ext32s_tl(arg, arg); 6112 register_name = "EntryHi"; 6113 break; 6114 default: 6115 goto cp0_unimplemented; 6116 } 6117 break; 6118 case CP0_REGISTER_11: 6119 switch (sel) { 6120 case CP0_REG11__COMPARE: 6121 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 6122 register_name = "Compare"; 6123 break; 6124 /* 6,7 are implementation dependent */ 6125 default: 6126 goto cp0_unimplemented; 6127 } 6128 break; 6129 case CP0_REGISTER_12: 6130 switch (sel) { 6131 case CP0_REG12__STATUS: 6132 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 6133 register_name = "Status"; 6134 break; 6135 case CP0_REG12__INTCTL: 6136 check_insn(ctx, ISA_MIPS_R2); 6137 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 6138 register_name = "IntCtl"; 6139 break; 6140 case CP0_REG12__SRSCTL: 6141 check_insn(ctx, ISA_MIPS_R2); 6142 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 6143 register_name = "SRSCtl"; 6144 break; 6145 case CP0_REG12__SRSMAP: 6146 check_insn(ctx, ISA_MIPS_R2); 6147 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6148 register_name = "SRSMap"; 6149 break; 6150 default: 6151 goto cp0_unimplemented; 6152 } 6153 break; 6154 case CP0_REGISTER_13: 6155 switch (sel) { 6156 case CP0_REG13__CAUSE: 6157 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 6158 register_name = "Cause"; 6159 break; 6160 default: 6161 goto cp0_unimplemented; 6162 } 6163 break; 6164 case CP0_REGISTER_14: 6165 switch (sel) { 6166 case CP0_REG14__EPC: 6167 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 6168 tcg_gen_ext32s_tl(arg, arg); 6169 register_name = "EPC"; 6170 break; 6171 default: 6172 goto cp0_unimplemented; 6173 } 6174 break; 6175 case CP0_REGISTER_15: 6176 switch (sel) { 6177 case CP0_REG15__PRID: 6178 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 6179 register_name = "PRid"; 6180 break; 6181 case CP0_REG15__EBASE: 6182 check_insn(ctx, ISA_MIPS_R2); 6183 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); 6184 tcg_gen_ext32s_tl(arg, arg); 6185 register_name = "EBase"; 6186 break; 6187 case CP0_REG15__CMGCRBASE: 6188 check_insn(ctx, ISA_MIPS_R2); 6189 CP0_CHECK(ctx->cmgcr); 6190 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 6191 tcg_gen_ext32s_tl(arg, arg); 6192 register_name = "CMGCRBase"; 6193 break; 6194 default: 6195 goto cp0_unimplemented; 6196 } 6197 break; 6198 case CP0_REGISTER_16: 6199 switch (sel) { 6200 case CP0_REG16__CONFIG: 6201 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 6202 register_name = "Config"; 6203 break; 6204 case CP0_REG16__CONFIG1: 6205 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 6206 register_name = "Config1"; 6207 break; 6208 case CP0_REG16__CONFIG2: 6209 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 6210 register_name = "Config2"; 6211 break; 6212 case CP0_REG16__CONFIG3: 6213 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 6214 register_name = "Config3"; 6215 break; 6216 case CP0_REG16__CONFIG4: 6217 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 6218 register_name = "Config4"; 6219 break; 6220 case CP0_REG16__CONFIG5: 6221 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 6222 register_name = "Config5"; 6223 break; 6224 /* 6,7 are implementation dependent */ 6225 case CP0_REG16__CONFIG6: 6226 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 6227 register_name = "Config6"; 6228 break; 6229 case CP0_REG16__CONFIG7: 6230 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 6231 register_name = "Config7"; 6232 break; 6233 default: 6234 goto cp0_unimplemented; 6235 } 6236 break; 6237 case CP0_REGISTER_17: 6238 switch (sel) { 6239 case CP0_REG17__LLADDR: 6240 gen_helper_mfc0_lladdr(arg, cpu_env); 6241 register_name = "LLAddr"; 6242 break; 6243 case CP0_REG17__MAAR: 6244 CP0_CHECK(ctx->mrp); 6245 gen_helper_mfc0_maar(arg, cpu_env); 6246 register_name = "MAAR"; 6247 break; 6248 case CP0_REG17__MAARI: 6249 CP0_CHECK(ctx->mrp); 6250 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 6251 register_name = "MAARI"; 6252 break; 6253 default: 6254 goto cp0_unimplemented; 6255 } 6256 break; 6257 case CP0_REGISTER_18: 6258 switch (sel) { 6259 case CP0_REG18__WATCHLO0: 6260 case CP0_REG18__WATCHLO1: 6261 case CP0_REG18__WATCHLO2: 6262 case CP0_REG18__WATCHLO3: 6263 case CP0_REG18__WATCHLO4: 6264 case CP0_REG18__WATCHLO5: 6265 case CP0_REG18__WATCHLO6: 6266 case CP0_REG18__WATCHLO7: 6267 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6268 gen_helper_1e0i(mfc0_watchlo, arg, sel); 6269 register_name = "WatchLo"; 6270 break; 6271 default: 6272 goto cp0_unimplemented; 6273 } 6274 break; 6275 case CP0_REGISTER_19: 6276 switch (sel) { 6277 case CP0_REG19__WATCHHI0: 6278 case CP0_REG19__WATCHHI1: 6279 case CP0_REG19__WATCHHI2: 6280 case CP0_REG19__WATCHHI3: 6281 case CP0_REG19__WATCHHI4: 6282 case CP0_REG19__WATCHHI5: 6283 case CP0_REG19__WATCHHI6: 6284 case CP0_REG19__WATCHHI7: 6285 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 6286 gen_helper_1e0i(mfc0_watchhi, arg, sel); 6287 register_name = "WatchHi"; 6288 break; 6289 default: 6290 goto cp0_unimplemented; 6291 } 6292 break; 6293 case CP0_REGISTER_20: 6294 switch (sel) { 6295 case CP0_REG20__XCONTEXT: 6296 #if defined(TARGET_MIPS64) 6297 check_insn(ctx, ISA_MIPS3); 6298 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 6299 tcg_gen_ext32s_tl(arg, arg); 6300 register_name = "XContext"; 6301 break; 6302 #endif 6303 default: 6304 goto cp0_unimplemented; 6305 } 6306 break; 6307 case CP0_REGISTER_21: 6308 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 6309 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 6310 switch (sel) { 6311 case 0: 6312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 6313 register_name = "Framemask"; 6314 break; 6315 default: 6316 goto cp0_unimplemented; 6317 } 6318 break; 6319 case CP0_REGISTER_22: 6320 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 6321 register_name = "'Diagnostic"; /* implementation dependent */ 6322 break; 6323 case CP0_REGISTER_23: 6324 switch (sel) { 6325 case CP0_REG23__DEBUG: 6326 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 6327 register_name = "Debug"; 6328 break; 6329 case CP0_REG23__TRACECONTROL: 6330 /* PDtrace support */ 6331 /* gen_helper_mfc0_tracecontrol(arg); */ 6332 register_name = "TraceControl"; 6333 goto cp0_unimplemented; 6334 case CP0_REG23__TRACECONTROL2: 6335 /* PDtrace support */ 6336 /* gen_helper_mfc0_tracecontrol2(arg); */ 6337 register_name = "TraceControl2"; 6338 goto cp0_unimplemented; 6339 case CP0_REG23__USERTRACEDATA1: 6340 /* PDtrace support */ 6341 /* gen_helper_mfc0_usertracedata1(arg);*/ 6342 register_name = "UserTraceData1"; 6343 goto cp0_unimplemented; 6344 case CP0_REG23__TRACEIBPC: 6345 /* PDtrace support */ 6346 /* gen_helper_mfc0_traceibpc(arg); */ 6347 register_name = "TraceIBPC"; 6348 goto cp0_unimplemented; 6349 case CP0_REG23__TRACEDBPC: 6350 /* PDtrace support */ 6351 /* gen_helper_mfc0_tracedbpc(arg); */ 6352 register_name = "TraceDBPC"; 6353 goto cp0_unimplemented; 6354 default: 6355 goto cp0_unimplemented; 6356 } 6357 break; 6358 case CP0_REGISTER_24: 6359 switch (sel) { 6360 case CP0_REG24__DEPC: 6361 /* EJTAG support */ 6362 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 6363 tcg_gen_ext32s_tl(arg, arg); 6364 register_name = "DEPC"; 6365 break; 6366 default: 6367 goto cp0_unimplemented; 6368 } 6369 break; 6370 case CP0_REGISTER_25: 6371 switch (sel) { 6372 case CP0_REG25__PERFCTL0: 6373 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 6374 register_name = "Performance0"; 6375 break; 6376 case CP0_REG25__PERFCNT0: 6377 /* gen_helper_mfc0_performance1(arg); */ 6378 register_name = "Performance1"; 6379 goto cp0_unimplemented; 6380 case CP0_REG25__PERFCTL1: 6381 /* gen_helper_mfc0_performance2(arg); */ 6382 register_name = "Performance2"; 6383 goto cp0_unimplemented; 6384 case CP0_REG25__PERFCNT1: 6385 /* gen_helper_mfc0_performance3(arg); */ 6386 register_name = "Performance3"; 6387 goto cp0_unimplemented; 6388 case CP0_REG25__PERFCTL2: 6389 /* gen_helper_mfc0_performance4(arg); */ 6390 register_name = "Performance4"; 6391 goto cp0_unimplemented; 6392 case CP0_REG25__PERFCNT2: 6393 /* gen_helper_mfc0_performance5(arg); */ 6394 register_name = "Performance5"; 6395 goto cp0_unimplemented; 6396 case CP0_REG25__PERFCTL3: 6397 /* gen_helper_mfc0_performance6(arg); */ 6398 register_name = "Performance6"; 6399 goto cp0_unimplemented; 6400 case CP0_REG25__PERFCNT3: 6401 /* gen_helper_mfc0_performance7(arg); */ 6402 register_name = "Performance7"; 6403 goto cp0_unimplemented; 6404 default: 6405 goto cp0_unimplemented; 6406 } 6407 break; 6408 case CP0_REGISTER_26: 6409 switch (sel) { 6410 case CP0_REG26__ERRCTL: 6411 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 6412 register_name = "ErrCtl"; 6413 break; 6414 default: 6415 goto cp0_unimplemented; 6416 } 6417 break; 6418 case CP0_REGISTER_27: 6419 switch (sel) { 6420 case CP0_REG27__CACHERR: 6421 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 6422 register_name = "CacheErr"; 6423 break; 6424 default: 6425 goto cp0_unimplemented; 6426 } 6427 break; 6428 case CP0_REGISTER_28: 6429 switch (sel) { 6430 case CP0_REG28__TAGLO: 6431 case CP0_REG28__TAGLO1: 6432 case CP0_REG28__TAGLO2: 6433 case CP0_REG28__TAGLO3: 6434 { 6435 TCGv_i64 tmp = tcg_temp_new_i64(); 6436 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo)); 6437 gen_move_low32(arg, tmp); 6438 tcg_temp_free_i64(tmp); 6439 } 6440 register_name = "TagLo"; 6441 break; 6442 case CP0_REG28__DATALO: 6443 case CP0_REG28__DATALO1: 6444 case CP0_REG28__DATALO2: 6445 case CP0_REG28__DATALO3: 6446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 6447 register_name = "DataLo"; 6448 break; 6449 default: 6450 goto cp0_unimplemented; 6451 } 6452 break; 6453 case CP0_REGISTER_29: 6454 switch (sel) { 6455 case CP0_REG29__TAGHI: 6456 case CP0_REG29__TAGHI1: 6457 case CP0_REG29__TAGHI2: 6458 case CP0_REG29__TAGHI3: 6459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 6460 register_name = "TagHi"; 6461 break; 6462 case CP0_REG29__DATAHI: 6463 case CP0_REG29__DATAHI1: 6464 case CP0_REG29__DATAHI2: 6465 case CP0_REG29__DATAHI3: 6466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 6467 register_name = "DataHi"; 6468 break; 6469 default: 6470 goto cp0_unimplemented; 6471 } 6472 break; 6473 case CP0_REGISTER_30: 6474 switch (sel) { 6475 case CP0_REG30__ERROREPC: 6476 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 6477 tcg_gen_ext32s_tl(arg, arg); 6478 register_name = "ErrorEPC"; 6479 break; 6480 default: 6481 goto cp0_unimplemented; 6482 } 6483 break; 6484 case CP0_REGISTER_31: 6485 switch (sel) { 6486 case CP0_REG31__DESAVE: 6487 /* EJTAG support */ 6488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 6489 register_name = "DESAVE"; 6490 break; 6491 case CP0_REG31__KSCRATCH1: 6492 case CP0_REG31__KSCRATCH2: 6493 case CP0_REG31__KSCRATCH3: 6494 case CP0_REG31__KSCRATCH4: 6495 case CP0_REG31__KSCRATCH5: 6496 case CP0_REG31__KSCRATCH6: 6497 CP0_CHECK(ctx->kscrexist & (1 << sel)); 6498 tcg_gen_ld_tl(arg, cpu_env, 6499 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 6500 tcg_gen_ext32s_tl(arg, arg); 6501 register_name = "KScratch"; 6502 break; 6503 default: 6504 goto cp0_unimplemented; 6505 } 6506 break; 6507 default: 6508 goto cp0_unimplemented; 6509 } 6510 trace_mips_translate_c0("mfc0", register_name, reg, sel); 6511 return; 6512 6513 cp0_unimplemented: 6514 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", 6515 register_name, reg, sel); 6516 gen_mfc0_unimplemented(ctx, arg); 6517 } 6518 6519 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 6520 { 6521 const char *register_name = "invalid"; 6522 6523 if (sel != 0) { 6524 check_insn(ctx, ISA_MIPS_R1); 6525 } 6526 6527 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 6528 gen_io_start(); 6529 } 6530 6531 switch (reg) { 6532 case CP0_REGISTER_00: 6533 switch (sel) { 6534 case CP0_REG00__INDEX: 6535 gen_helper_mtc0_index(cpu_env, arg); 6536 register_name = "Index"; 6537 break; 6538 case CP0_REG00__MVPCONTROL: 6539 CP0_CHECK(ctx->insn_flags & ASE_MT); 6540 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 6541 register_name = "MVPControl"; 6542 break; 6543 case CP0_REG00__MVPCONF0: 6544 CP0_CHECK(ctx->insn_flags & ASE_MT); 6545 /* ignored */ 6546 register_name = "MVPConf0"; 6547 break; 6548 case CP0_REG00__MVPCONF1: 6549 CP0_CHECK(ctx->insn_flags & ASE_MT); 6550 /* ignored */ 6551 register_name = "MVPConf1"; 6552 break; 6553 case CP0_REG00__VPCONTROL: 6554 CP0_CHECK(ctx->vp); 6555 /* ignored */ 6556 register_name = "VPControl"; 6557 break; 6558 default: 6559 goto cp0_unimplemented; 6560 } 6561 break; 6562 case CP0_REGISTER_01: 6563 switch (sel) { 6564 case CP0_REG01__RANDOM: 6565 /* ignored */ 6566 register_name = "Random"; 6567 break; 6568 case CP0_REG01__VPECONTROL: 6569 CP0_CHECK(ctx->insn_flags & ASE_MT); 6570 gen_helper_mtc0_vpecontrol(cpu_env, arg); 6571 register_name = "VPEControl"; 6572 break; 6573 case CP0_REG01__VPECONF0: 6574 CP0_CHECK(ctx->insn_flags & ASE_MT); 6575 gen_helper_mtc0_vpeconf0(cpu_env, arg); 6576 register_name = "VPEConf0"; 6577 break; 6578 case CP0_REG01__VPECONF1: 6579 CP0_CHECK(ctx->insn_flags & ASE_MT); 6580 gen_helper_mtc0_vpeconf1(cpu_env, arg); 6581 register_name = "VPEConf1"; 6582 break; 6583 case CP0_REG01__YQMASK: 6584 CP0_CHECK(ctx->insn_flags & ASE_MT); 6585 gen_helper_mtc0_yqmask(cpu_env, arg); 6586 register_name = "YQMask"; 6587 break; 6588 case CP0_REG01__VPESCHEDULE: 6589 CP0_CHECK(ctx->insn_flags & ASE_MT); 6590 tcg_gen_st_tl(arg, cpu_env, 6591 offsetof(CPUMIPSState, CP0_VPESchedule)); 6592 register_name = "VPESchedule"; 6593 break; 6594 case CP0_REG01__VPESCHEFBACK: 6595 CP0_CHECK(ctx->insn_flags & ASE_MT); 6596 tcg_gen_st_tl(arg, cpu_env, 6597 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 6598 register_name = "VPEScheFBack"; 6599 break; 6600 case CP0_REG01__VPEOPT: 6601 CP0_CHECK(ctx->insn_flags & ASE_MT); 6602 gen_helper_mtc0_vpeopt(cpu_env, arg); 6603 register_name = "VPEOpt"; 6604 break; 6605 default: 6606 goto cp0_unimplemented; 6607 } 6608 break; 6609 case CP0_REGISTER_02: 6610 switch (sel) { 6611 case CP0_REG02__ENTRYLO0: 6612 gen_helper_mtc0_entrylo0(cpu_env, arg); 6613 register_name = "EntryLo0"; 6614 break; 6615 case CP0_REG02__TCSTATUS: 6616 CP0_CHECK(ctx->insn_flags & ASE_MT); 6617 gen_helper_mtc0_tcstatus(cpu_env, arg); 6618 register_name = "TCStatus"; 6619 break; 6620 case CP0_REG02__TCBIND: 6621 CP0_CHECK(ctx->insn_flags & ASE_MT); 6622 gen_helper_mtc0_tcbind(cpu_env, arg); 6623 register_name = "TCBind"; 6624 break; 6625 case CP0_REG02__TCRESTART: 6626 CP0_CHECK(ctx->insn_flags & ASE_MT); 6627 gen_helper_mtc0_tcrestart(cpu_env, arg); 6628 register_name = "TCRestart"; 6629 break; 6630 case CP0_REG02__TCHALT: 6631 CP0_CHECK(ctx->insn_flags & ASE_MT); 6632 gen_helper_mtc0_tchalt(cpu_env, arg); 6633 register_name = "TCHalt"; 6634 break; 6635 case CP0_REG02__TCCONTEXT: 6636 CP0_CHECK(ctx->insn_flags & ASE_MT); 6637 gen_helper_mtc0_tccontext(cpu_env, arg); 6638 register_name = "TCContext"; 6639 break; 6640 case CP0_REG02__TCSCHEDULE: 6641 CP0_CHECK(ctx->insn_flags & ASE_MT); 6642 gen_helper_mtc0_tcschedule(cpu_env, arg); 6643 register_name = "TCSchedule"; 6644 break; 6645 case CP0_REG02__TCSCHEFBACK: 6646 CP0_CHECK(ctx->insn_flags & ASE_MT); 6647 gen_helper_mtc0_tcschefback(cpu_env, arg); 6648 register_name = "TCScheFBack"; 6649 break; 6650 default: 6651 goto cp0_unimplemented; 6652 } 6653 break; 6654 case CP0_REGISTER_03: 6655 switch (sel) { 6656 case CP0_REG03__ENTRYLO1: 6657 gen_helper_mtc0_entrylo1(cpu_env, arg); 6658 register_name = "EntryLo1"; 6659 break; 6660 case CP0_REG03__GLOBALNUM: 6661 CP0_CHECK(ctx->vp); 6662 /* ignored */ 6663 register_name = "GlobalNumber"; 6664 break; 6665 default: 6666 goto cp0_unimplemented; 6667 } 6668 break; 6669 case CP0_REGISTER_04: 6670 switch (sel) { 6671 case CP0_REG04__CONTEXT: 6672 gen_helper_mtc0_context(cpu_env, arg); 6673 register_name = "Context"; 6674 break; 6675 case CP0_REG04__CONTEXTCONFIG: 6676 /* SmartMIPS ASE */ 6677 /* gen_helper_mtc0_contextconfig(arg); */ 6678 register_name = "ContextConfig"; 6679 goto cp0_unimplemented; 6680 case CP0_REG04__USERLOCAL: 6681 CP0_CHECK(ctx->ulri); 6682 tcg_gen_st_tl(arg, cpu_env, 6683 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 6684 register_name = "UserLocal"; 6685 break; 6686 case CP0_REG04__MMID: 6687 CP0_CHECK(ctx->mi); 6688 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 6689 register_name = "MMID"; 6690 break; 6691 default: 6692 goto cp0_unimplemented; 6693 } 6694 break; 6695 case CP0_REGISTER_05: 6696 switch (sel) { 6697 case CP0_REG05__PAGEMASK: 6698 gen_helper_mtc0_pagemask(cpu_env, arg); 6699 register_name = "PageMask"; 6700 break; 6701 case CP0_REG05__PAGEGRAIN: 6702 check_insn(ctx, ISA_MIPS_R2); 6703 gen_helper_mtc0_pagegrain(cpu_env, arg); 6704 register_name = "PageGrain"; 6705 ctx->base.is_jmp = DISAS_STOP; 6706 break; 6707 case CP0_REG05__SEGCTL0: 6708 CP0_CHECK(ctx->sc); 6709 gen_helper_mtc0_segctl0(cpu_env, arg); 6710 register_name = "SegCtl0"; 6711 break; 6712 case CP0_REG05__SEGCTL1: 6713 CP0_CHECK(ctx->sc); 6714 gen_helper_mtc0_segctl1(cpu_env, arg); 6715 register_name = "SegCtl1"; 6716 break; 6717 case CP0_REG05__SEGCTL2: 6718 CP0_CHECK(ctx->sc); 6719 gen_helper_mtc0_segctl2(cpu_env, arg); 6720 register_name = "SegCtl2"; 6721 break; 6722 case CP0_REG05__PWBASE: 6723 check_pw(ctx); 6724 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase)); 6725 register_name = "PWBase"; 6726 break; 6727 case CP0_REG05__PWFIELD: 6728 check_pw(ctx); 6729 gen_helper_mtc0_pwfield(cpu_env, arg); 6730 register_name = "PWField"; 6731 break; 6732 case CP0_REG05__PWSIZE: 6733 check_pw(ctx); 6734 gen_helper_mtc0_pwsize(cpu_env, arg); 6735 register_name = "PWSize"; 6736 break; 6737 default: 6738 goto cp0_unimplemented; 6739 } 6740 break; 6741 case CP0_REGISTER_06: 6742 switch (sel) { 6743 case CP0_REG06__WIRED: 6744 gen_helper_mtc0_wired(cpu_env, arg); 6745 register_name = "Wired"; 6746 break; 6747 case CP0_REG06__SRSCONF0: 6748 check_insn(ctx, ISA_MIPS_R2); 6749 gen_helper_mtc0_srsconf0(cpu_env, arg); 6750 register_name = "SRSConf0"; 6751 break; 6752 case CP0_REG06__SRSCONF1: 6753 check_insn(ctx, ISA_MIPS_R2); 6754 gen_helper_mtc0_srsconf1(cpu_env, arg); 6755 register_name = "SRSConf1"; 6756 break; 6757 case CP0_REG06__SRSCONF2: 6758 check_insn(ctx, ISA_MIPS_R2); 6759 gen_helper_mtc0_srsconf2(cpu_env, arg); 6760 register_name = "SRSConf2"; 6761 break; 6762 case CP0_REG06__SRSCONF3: 6763 check_insn(ctx, ISA_MIPS_R2); 6764 gen_helper_mtc0_srsconf3(cpu_env, arg); 6765 register_name = "SRSConf3"; 6766 break; 6767 case CP0_REG06__SRSCONF4: 6768 check_insn(ctx, ISA_MIPS_R2); 6769 gen_helper_mtc0_srsconf4(cpu_env, arg); 6770 register_name = "SRSConf4"; 6771 break; 6772 case CP0_REG06__PWCTL: 6773 check_pw(ctx); 6774 gen_helper_mtc0_pwctl(cpu_env, arg); 6775 register_name = "PWCtl"; 6776 break; 6777 default: 6778 goto cp0_unimplemented; 6779 } 6780 break; 6781 case CP0_REGISTER_07: 6782 switch (sel) { 6783 case CP0_REG07__HWRENA: 6784 check_insn(ctx, ISA_MIPS_R2); 6785 gen_helper_mtc0_hwrena(cpu_env, arg); 6786 ctx->base.is_jmp = DISAS_STOP; 6787 register_name = "HWREna"; 6788 break; 6789 default: 6790 goto cp0_unimplemented; 6791 } 6792 break; 6793 case CP0_REGISTER_08: 6794 switch (sel) { 6795 case CP0_REG08__BADVADDR: 6796 /* ignored */ 6797 register_name = "BadVAddr"; 6798 break; 6799 case CP0_REG08__BADINSTR: 6800 /* ignored */ 6801 register_name = "BadInstr"; 6802 break; 6803 case CP0_REG08__BADINSTRP: 6804 /* ignored */ 6805 register_name = "BadInstrP"; 6806 break; 6807 case CP0_REG08__BADINSTRX: 6808 /* ignored */ 6809 register_name = "BadInstrX"; 6810 break; 6811 default: 6812 goto cp0_unimplemented; 6813 } 6814 break; 6815 case CP0_REGISTER_09: 6816 switch (sel) { 6817 case CP0_REG09__COUNT: 6818 gen_helper_mtc0_count(cpu_env, arg); 6819 register_name = "Count"; 6820 break; 6821 case CP0_REG09__SAARI: 6822 CP0_CHECK(ctx->saar); 6823 gen_helper_mtc0_saari(cpu_env, arg); 6824 register_name = "SAARI"; 6825 break; 6826 case CP0_REG09__SAAR: 6827 CP0_CHECK(ctx->saar); 6828 gen_helper_mtc0_saar(cpu_env, arg); 6829 register_name = "SAAR"; 6830 break; 6831 default: 6832 goto cp0_unimplemented; 6833 } 6834 break; 6835 case CP0_REGISTER_10: 6836 switch (sel) { 6837 case CP0_REG10__ENTRYHI: 6838 gen_helper_mtc0_entryhi(cpu_env, arg); 6839 register_name = "EntryHi"; 6840 break; 6841 default: 6842 goto cp0_unimplemented; 6843 } 6844 break; 6845 case CP0_REGISTER_11: 6846 switch (sel) { 6847 case CP0_REG11__COMPARE: 6848 gen_helper_mtc0_compare(cpu_env, arg); 6849 register_name = "Compare"; 6850 break; 6851 /* 6,7 are implementation dependent */ 6852 default: 6853 goto cp0_unimplemented; 6854 } 6855 break; 6856 case CP0_REGISTER_12: 6857 switch (sel) { 6858 case CP0_REG12__STATUS: 6859 save_cpu_state(ctx, 1); 6860 gen_helper_mtc0_status(cpu_env, arg); 6861 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 6862 gen_save_pc(ctx->base.pc_next + 4); 6863 ctx->base.is_jmp = DISAS_EXIT; 6864 register_name = "Status"; 6865 break; 6866 case CP0_REG12__INTCTL: 6867 check_insn(ctx, ISA_MIPS_R2); 6868 gen_helper_mtc0_intctl(cpu_env, arg); 6869 /* Stop translation as we may have switched the execution mode */ 6870 ctx->base.is_jmp = DISAS_STOP; 6871 register_name = "IntCtl"; 6872 break; 6873 case CP0_REG12__SRSCTL: 6874 check_insn(ctx, ISA_MIPS_R2); 6875 gen_helper_mtc0_srsctl(cpu_env, arg); 6876 /* Stop translation as we may have switched the execution mode */ 6877 ctx->base.is_jmp = DISAS_STOP; 6878 register_name = "SRSCtl"; 6879 break; 6880 case CP0_REG12__SRSMAP: 6881 check_insn(ctx, ISA_MIPS_R2); 6882 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 6883 /* Stop translation as we may have switched the execution mode */ 6884 ctx->base.is_jmp = DISAS_STOP; 6885 register_name = "SRSMap"; 6886 break; 6887 default: 6888 goto cp0_unimplemented; 6889 } 6890 break; 6891 case CP0_REGISTER_13: 6892 switch (sel) { 6893 case CP0_REG13__CAUSE: 6894 save_cpu_state(ctx, 1); 6895 gen_helper_mtc0_cause(cpu_env, arg); 6896 /* 6897 * Stop translation as we may have triggered an interrupt. 6898 * DISAS_STOP isn't sufficient, we need to ensure we break out of 6899 * translated code to check for pending interrupts. 6900 */ 6901 gen_save_pc(ctx->base.pc_next + 4); 6902 ctx->base.is_jmp = DISAS_EXIT; 6903 register_name = "Cause"; 6904 break; 6905 default: 6906 goto cp0_unimplemented; 6907 } 6908 break; 6909 case CP0_REGISTER_14: 6910 switch (sel) { 6911 case CP0_REG14__EPC: 6912 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 6913 register_name = "EPC"; 6914 break; 6915 default: 6916 goto cp0_unimplemented; 6917 } 6918 break; 6919 case CP0_REGISTER_15: 6920 switch (sel) { 6921 case CP0_REG15__PRID: 6922 /* ignored */ 6923 register_name = "PRid"; 6924 break; 6925 case CP0_REG15__EBASE: 6926 check_insn(ctx, ISA_MIPS_R2); 6927 gen_helper_mtc0_ebase(cpu_env, arg); 6928 register_name = "EBase"; 6929 break; 6930 default: 6931 goto cp0_unimplemented; 6932 } 6933 break; 6934 case CP0_REGISTER_16: 6935 switch (sel) { 6936 case CP0_REG16__CONFIG: 6937 gen_helper_mtc0_config0(cpu_env, arg); 6938 register_name = "Config"; 6939 /* Stop translation as we may have switched the execution mode */ 6940 ctx->base.is_jmp = DISAS_STOP; 6941 break; 6942 case CP0_REG16__CONFIG1: 6943 /* ignored, read only */ 6944 register_name = "Config1"; 6945 break; 6946 case CP0_REG16__CONFIG2: 6947 gen_helper_mtc0_config2(cpu_env, arg); 6948 register_name = "Config2"; 6949 /* Stop translation as we may have switched the execution mode */ 6950 ctx->base.is_jmp = DISAS_STOP; 6951 break; 6952 case CP0_REG16__CONFIG3: 6953 gen_helper_mtc0_config3(cpu_env, arg); 6954 register_name = "Config3"; 6955 /* Stop translation as we may have switched the execution mode */ 6956 ctx->base.is_jmp = DISAS_STOP; 6957 break; 6958 case CP0_REG16__CONFIG4: 6959 gen_helper_mtc0_config4(cpu_env, arg); 6960 register_name = "Config4"; 6961 ctx->base.is_jmp = DISAS_STOP; 6962 break; 6963 case CP0_REG16__CONFIG5: 6964 gen_helper_mtc0_config5(cpu_env, arg); 6965 register_name = "Config5"; 6966 /* Stop translation as we may have switched the execution mode */ 6967 ctx->base.is_jmp = DISAS_STOP; 6968 break; 6969 /* 6,7 are implementation dependent */ 6970 case CP0_REG16__CONFIG6: 6971 /* ignored */ 6972 register_name = "Config6"; 6973 break; 6974 case CP0_REG16__CONFIG7: 6975 /* ignored */ 6976 register_name = "Config7"; 6977 break; 6978 default: 6979 register_name = "Invalid config selector"; 6980 goto cp0_unimplemented; 6981 } 6982 break; 6983 case CP0_REGISTER_17: 6984 switch (sel) { 6985 case CP0_REG17__LLADDR: 6986 gen_helper_mtc0_lladdr(cpu_env, arg); 6987 register_name = "LLAddr"; 6988 break; 6989 case CP0_REG17__MAAR: 6990 CP0_CHECK(ctx->mrp); 6991 gen_helper_mtc0_maar(cpu_env, arg); 6992 register_name = "MAAR"; 6993 break; 6994 case CP0_REG17__MAARI: 6995 CP0_CHECK(ctx->mrp); 6996 gen_helper_mtc0_maari(cpu_env, arg); 6997 register_name = "MAARI"; 6998 break; 6999 default: 7000 goto cp0_unimplemented; 7001 } 7002 break; 7003 case CP0_REGISTER_18: 7004 switch (sel) { 7005 case CP0_REG18__WATCHLO0: 7006 case CP0_REG18__WATCHLO1: 7007 case CP0_REG18__WATCHLO2: 7008 case CP0_REG18__WATCHLO3: 7009 case CP0_REG18__WATCHLO4: 7010 case CP0_REG18__WATCHLO5: 7011 case CP0_REG18__WATCHLO6: 7012 case CP0_REG18__WATCHLO7: 7013 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7014 gen_helper_0e1i(mtc0_watchlo, arg, sel); 7015 register_name = "WatchLo"; 7016 break; 7017 default: 7018 goto cp0_unimplemented; 7019 } 7020 break; 7021 case CP0_REGISTER_19: 7022 switch (sel) { 7023 case CP0_REG19__WATCHHI0: 7024 case CP0_REG19__WATCHHI1: 7025 case CP0_REG19__WATCHHI2: 7026 case CP0_REG19__WATCHHI3: 7027 case CP0_REG19__WATCHHI4: 7028 case CP0_REG19__WATCHHI5: 7029 case CP0_REG19__WATCHHI6: 7030 case CP0_REG19__WATCHHI7: 7031 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7032 gen_helper_0e1i(mtc0_watchhi, arg, sel); 7033 register_name = "WatchHi"; 7034 break; 7035 default: 7036 goto cp0_unimplemented; 7037 } 7038 break; 7039 case CP0_REGISTER_20: 7040 switch (sel) { 7041 case CP0_REG20__XCONTEXT: 7042 #if defined(TARGET_MIPS64) 7043 check_insn(ctx, ISA_MIPS3); 7044 gen_helper_mtc0_xcontext(cpu_env, arg); 7045 register_name = "XContext"; 7046 break; 7047 #endif 7048 default: 7049 goto cp0_unimplemented; 7050 } 7051 break; 7052 case CP0_REGISTER_21: 7053 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7054 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7055 switch (sel) { 7056 case 0: 7057 gen_helper_mtc0_framemask(cpu_env, arg); 7058 register_name = "Framemask"; 7059 break; 7060 default: 7061 goto cp0_unimplemented; 7062 } 7063 break; 7064 case CP0_REGISTER_22: 7065 /* ignored */ 7066 register_name = "Diagnostic"; /* implementation dependent */ 7067 break; 7068 case CP0_REGISTER_23: 7069 switch (sel) { 7070 case CP0_REG23__DEBUG: 7071 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 7072 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 7073 gen_save_pc(ctx->base.pc_next + 4); 7074 ctx->base.is_jmp = DISAS_EXIT; 7075 register_name = "Debug"; 7076 break; 7077 case CP0_REG23__TRACECONTROL: 7078 /* PDtrace support */ 7079 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ 7080 register_name = "TraceControl"; 7081 /* Stop translation as we may have switched the execution mode */ 7082 ctx->base.is_jmp = DISAS_STOP; 7083 goto cp0_unimplemented; 7084 case CP0_REG23__TRACECONTROL2: 7085 /* PDtrace support */ 7086 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ 7087 register_name = "TraceControl2"; 7088 /* Stop translation as we may have switched the execution mode */ 7089 ctx->base.is_jmp = DISAS_STOP; 7090 goto cp0_unimplemented; 7091 case CP0_REG23__USERTRACEDATA1: 7092 /* Stop translation as we may have switched the execution mode */ 7093 ctx->base.is_jmp = DISAS_STOP; 7094 /* PDtrace support */ 7095 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ 7096 register_name = "UserTraceData"; 7097 /* Stop translation as we may have switched the execution mode */ 7098 ctx->base.is_jmp = DISAS_STOP; 7099 goto cp0_unimplemented; 7100 case CP0_REG23__TRACEIBPC: 7101 /* PDtrace support */ 7102 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ 7103 /* Stop translation as we may have switched the execution mode */ 7104 ctx->base.is_jmp = DISAS_STOP; 7105 register_name = "TraceIBPC"; 7106 goto cp0_unimplemented; 7107 case CP0_REG23__TRACEDBPC: 7108 /* PDtrace support */ 7109 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ 7110 /* Stop translation as we may have switched the execution mode */ 7111 ctx->base.is_jmp = DISAS_STOP; 7112 register_name = "TraceDBPC"; 7113 goto cp0_unimplemented; 7114 default: 7115 goto cp0_unimplemented; 7116 } 7117 break; 7118 case CP0_REGISTER_24: 7119 switch (sel) { 7120 case CP0_REG24__DEPC: 7121 /* EJTAG support */ 7122 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 7123 register_name = "DEPC"; 7124 break; 7125 default: 7126 goto cp0_unimplemented; 7127 } 7128 break; 7129 case CP0_REGISTER_25: 7130 switch (sel) { 7131 case CP0_REG25__PERFCTL0: 7132 gen_helper_mtc0_performance0(cpu_env, arg); 7133 register_name = "Performance0"; 7134 break; 7135 case CP0_REG25__PERFCNT0: 7136 /* gen_helper_mtc0_performance1(arg); */ 7137 register_name = "Performance1"; 7138 goto cp0_unimplemented; 7139 case CP0_REG25__PERFCTL1: 7140 /* gen_helper_mtc0_performance2(arg); */ 7141 register_name = "Performance2"; 7142 goto cp0_unimplemented; 7143 case CP0_REG25__PERFCNT1: 7144 /* gen_helper_mtc0_performance3(arg); */ 7145 register_name = "Performance3"; 7146 goto cp0_unimplemented; 7147 case CP0_REG25__PERFCTL2: 7148 /* gen_helper_mtc0_performance4(arg); */ 7149 register_name = "Performance4"; 7150 goto cp0_unimplemented; 7151 case CP0_REG25__PERFCNT2: 7152 /* gen_helper_mtc0_performance5(arg); */ 7153 register_name = "Performance5"; 7154 goto cp0_unimplemented; 7155 case CP0_REG25__PERFCTL3: 7156 /* gen_helper_mtc0_performance6(arg); */ 7157 register_name = "Performance6"; 7158 goto cp0_unimplemented; 7159 case CP0_REG25__PERFCNT3: 7160 /* gen_helper_mtc0_performance7(arg); */ 7161 register_name = "Performance7"; 7162 goto cp0_unimplemented; 7163 default: 7164 goto cp0_unimplemented; 7165 } 7166 break; 7167 case CP0_REGISTER_26: 7168 switch (sel) { 7169 case CP0_REG26__ERRCTL: 7170 gen_helper_mtc0_errctl(cpu_env, arg); 7171 ctx->base.is_jmp = DISAS_STOP; 7172 register_name = "ErrCtl"; 7173 break; 7174 default: 7175 goto cp0_unimplemented; 7176 } 7177 break; 7178 case CP0_REGISTER_27: 7179 switch (sel) { 7180 case CP0_REG27__CACHERR: 7181 /* ignored */ 7182 register_name = "CacheErr"; 7183 break; 7184 default: 7185 goto cp0_unimplemented; 7186 } 7187 break; 7188 case CP0_REGISTER_28: 7189 switch (sel) { 7190 case CP0_REG28__TAGLO: 7191 case CP0_REG28__TAGLO1: 7192 case CP0_REG28__TAGLO2: 7193 case CP0_REG28__TAGLO3: 7194 gen_helper_mtc0_taglo(cpu_env, arg); 7195 register_name = "TagLo"; 7196 break; 7197 case CP0_REG28__DATALO: 7198 case CP0_REG28__DATALO1: 7199 case CP0_REG28__DATALO2: 7200 case CP0_REG28__DATALO3: 7201 gen_helper_mtc0_datalo(cpu_env, arg); 7202 register_name = "DataLo"; 7203 break; 7204 default: 7205 goto cp0_unimplemented; 7206 } 7207 break; 7208 case CP0_REGISTER_29: 7209 switch (sel) { 7210 case CP0_REG29__TAGHI: 7211 case CP0_REG29__TAGHI1: 7212 case CP0_REG29__TAGHI2: 7213 case CP0_REG29__TAGHI3: 7214 gen_helper_mtc0_taghi(cpu_env, arg); 7215 register_name = "TagHi"; 7216 break; 7217 case CP0_REG29__DATAHI: 7218 case CP0_REG29__DATAHI1: 7219 case CP0_REG29__DATAHI2: 7220 case CP0_REG29__DATAHI3: 7221 gen_helper_mtc0_datahi(cpu_env, arg); 7222 register_name = "DataHi"; 7223 break; 7224 default: 7225 register_name = "invalid sel"; 7226 goto cp0_unimplemented; 7227 } 7228 break; 7229 case CP0_REGISTER_30: 7230 switch (sel) { 7231 case CP0_REG30__ERROREPC: 7232 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7233 register_name = "ErrorEPC"; 7234 break; 7235 default: 7236 goto cp0_unimplemented; 7237 } 7238 break; 7239 case CP0_REGISTER_31: 7240 switch (sel) { 7241 case CP0_REG31__DESAVE: 7242 /* EJTAG support */ 7243 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7244 register_name = "DESAVE"; 7245 break; 7246 case CP0_REG31__KSCRATCH1: 7247 case CP0_REG31__KSCRATCH2: 7248 case CP0_REG31__KSCRATCH3: 7249 case CP0_REG31__KSCRATCH4: 7250 case CP0_REG31__KSCRATCH5: 7251 case CP0_REG31__KSCRATCH6: 7252 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7253 tcg_gen_st_tl(arg, cpu_env, 7254 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7255 register_name = "KScratch"; 7256 break; 7257 default: 7258 goto cp0_unimplemented; 7259 } 7260 break; 7261 default: 7262 goto cp0_unimplemented; 7263 } 7264 trace_mips_translate_c0("mtc0", register_name, reg, sel); 7265 7266 /* For simplicity assume that all writes can cause interrupts. */ 7267 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7268 /* 7269 * DISAS_STOP isn't sufficient, we need to ensure we break out of 7270 * translated code to check for pending interrupts. 7271 */ 7272 gen_save_pc(ctx->base.pc_next + 4); 7273 ctx->base.is_jmp = DISAS_EXIT; 7274 } 7275 return; 7276 7277 cp0_unimplemented: 7278 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", 7279 register_name, reg, sel); 7280 } 7281 7282 #if defined(TARGET_MIPS64) 7283 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) 7284 { 7285 const char *register_name = "invalid"; 7286 7287 if (sel != 0) { 7288 check_insn(ctx, ISA_MIPS_R1); 7289 } 7290 7291 switch (reg) { 7292 case CP0_REGISTER_00: 7293 switch (sel) { 7294 case CP0_REG00__INDEX: 7295 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index)); 7296 register_name = "Index"; 7297 break; 7298 case CP0_REG00__MVPCONTROL: 7299 CP0_CHECK(ctx->insn_flags & ASE_MT); 7300 gen_helper_mfc0_mvpcontrol(arg, cpu_env); 7301 register_name = "MVPControl"; 7302 break; 7303 case CP0_REG00__MVPCONF0: 7304 CP0_CHECK(ctx->insn_flags & ASE_MT); 7305 gen_helper_mfc0_mvpconf0(arg, cpu_env); 7306 register_name = "MVPConf0"; 7307 break; 7308 case CP0_REG00__MVPCONF1: 7309 CP0_CHECK(ctx->insn_flags & ASE_MT); 7310 gen_helper_mfc0_mvpconf1(arg, cpu_env); 7311 register_name = "MVPConf1"; 7312 break; 7313 case CP0_REG00__VPCONTROL: 7314 CP0_CHECK(ctx->vp); 7315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl)); 7316 register_name = "VPControl"; 7317 break; 7318 default: 7319 goto cp0_unimplemented; 7320 } 7321 break; 7322 case CP0_REGISTER_01: 7323 switch (sel) { 7324 case CP0_REG01__RANDOM: 7325 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7326 gen_helper_mfc0_random(arg, cpu_env); 7327 register_name = "Random"; 7328 break; 7329 case CP0_REG01__VPECONTROL: 7330 CP0_CHECK(ctx->insn_flags & ASE_MT); 7331 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl)); 7332 register_name = "VPEControl"; 7333 break; 7334 case CP0_REG01__VPECONF0: 7335 CP0_CHECK(ctx->insn_flags & ASE_MT); 7336 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0)); 7337 register_name = "VPEConf0"; 7338 break; 7339 case CP0_REG01__VPECONF1: 7340 CP0_CHECK(ctx->insn_flags & ASE_MT); 7341 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1)); 7342 register_name = "VPEConf1"; 7343 break; 7344 case CP0_REG01__YQMASK: 7345 CP0_CHECK(ctx->insn_flags & ASE_MT); 7346 tcg_gen_ld_tl(arg, cpu_env, 7347 offsetof(CPUMIPSState, CP0_YQMask)); 7348 register_name = "YQMask"; 7349 break; 7350 case CP0_REG01__VPESCHEDULE: 7351 CP0_CHECK(ctx->insn_flags & ASE_MT); 7352 tcg_gen_ld_tl(arg, cpu_env, 7353 offsetof(CPUMIPSState, CP0_VPESchedule)); 7354 register_name = "VPESchedule"; 7355 break; 7356 case CP0_REG01__VPESCHEFBACK: 7357 CP0_CHECK(ctx->insn_flags & ASE_MT); 7358 tcg_gen_ld_tl(arg, cpu_env, 7359 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 7360 register_name = "VPEScheFBack"; 7361 break; 7362 case CP0_REG01__VPEOPT: 7363 CP0_CHECK(ctx->insn_flags & ASE_MT); 7364 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt)); 7365 register_name = "VPEOpt"; 7366 break; 7367 default: 7368 goto cp0_unimplemented; 7369 } 7370 break; 7371 case CP0_REGISTER_02: 7372 switch (sel) { 7373 case CP0_REG02__ENTRYLO0: 7374 tcg_gen_ld_tl(arg, cpu_env, 7375 offsetof(CPUMIPSState, CP0_EntryLo0)); 7376 register_name = "EntryLo0"; 7377 break; 7378 case CP0_REG02__TCSTATUS: 7379 CP0_CHECK(ctx->insn_flags & ASE_MT); 7380 gen_helper_mfc0_tcstatus(arg, cpu_env); 7381 register_name = "TCStatus"; 7382 break; 7383 case CP0_REG02__TCBIND: 7384 CP0_CHECK(ctx->insn_flags & ASE_MT); 7385 gen_helper_mfc0_tcbind(arg, cpu_env); 7386 register_name = "TCBind"; 7387 break; 7388 case CP0_REG02__TCRESTART: 7389 CP0_CHECK(ctx->insn_flags & ASE_MT); 7390 gen_helper_dmfc0_tcrestart(arg, cpu_env); 7391 register_name = "TCRestart"; 7392 break; 7393 case CP0_REG02__TCHALT: 7394 CP0_CHECK(ctx->insn_flags & ASE_MT); 7395 gen_helper_dmfc0_tchalt(arg, cpu_env); 7396 register_name = "TCHalt"; 7397 break; 7398 case CP0_REG02__TCCONTEXT: 7399 CP0_CHECK(ctx->insn_flags & ASE_MT); 7400 gen_helper_dmfc0_tccontext(arg, cpu_env); 7401 register_name = "TCContext"; 7402 break; 7403 case CP0_REG02__TCSCHEDULE: 7404 CP0_CHECK(ctx->insn_flags & ASE_MT); 7405 gen_helper_dmfc0_tcschedule(arg, cpu_env); 7406 register_name = "TCSchedule"; 7407 break; 7408 case CP0_REG02__TCSCHEFBACK: 7409 CP0_CHECK(ctx->insn_flags & ASE_MT); 7410 gen_helper_dmfc0_tcschefback(arg, cpu_env); 7411 register_name = "TCScheFBack"; 7412 break; 7413 default: 7414 goto cp0_unimplemented; 7415 } 7416 break; 7417 case CP0_REGISTER_03: 7418 switch (sel) { 7419 case CP0_REG03__ENTRYLO1: 7420 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1)); 7421 register_name = "EntryLo1"; 7422 break; 7423 case CP0_REG03__GLOBALNUM: 7424 CP0_CHECK(ctx->vp); 7425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber)); 7426 register_name = "GlobalNumber"; 7427 break; 7428 default: 7429 goto cp0_unimplemented; 7430 } 7431 break; 7432 case CP0_REGISTER_04: 7433 switch (sel) { 7434 case CP0_REG04__CONTEXT: 7435 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context)); 7436 register_name = "Context"; 7437 break; 7438 case CP0_REG04__CONTEXTCONFIG: 7439 /* SmartMIPS ASE */ 7440 /* gen_helper_dmfc0_contextconfig(arg); */ 7441 register_name = "ContextConfig"; 7442 goto cp0_unimplemented; 7443 case CP0_REG04__USERLOCAL: 7444 CP0_CHECK(ctx->ulri); 7445 tcg_gen_ld_tl(arg, cpu_env, 7446 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 7447 register_name = "UserLocal"; 7448 break; 7449 case CP0_REG04__MMID: 7450 CP0_CHECK(ctx->mi); 7451 gen_helper_mtc0_memorymapid(cpu_env, arg); 7452 register_name = "MMID"; 7453 break; 7454 default: 7455 goto cp0_unimplemented; 7456 } 7457 break; 7458 case CP0_REGISTER_05: 7459 switch (sel) { 7460 case CP0_REG05__PAGEMASK: 7461 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask)); 7462 register_name = "PageMask"; 7463 break; 7464 case CP0_REG05__PAGEGRAIN: 7465 check_insn(ctx, ISA_MIPS_R2); 7466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain)); 7467 register_name = "PageGrain"; 7468 break; 7469 case CP0_REG05__SEGCTL0: 7470 CP0_CHECK(ctx->sc); 7471 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0)); 7472 register_name = "SegCtl0"; 7473 break; 7474 case CP0_REG05__SEGCTL1: 7475 CP0_CHECK(ctx->sc); 7476 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1)); 7477 register_name = "SegCtl1"; 7478 break; 7479 case CP0_REG05__SEGCTL2: 7480 CP0_CHECK(ctx->sc); 7481 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2)); 7482 register_name = "SegCtl2"; 7483 break; 7484 case CP0_REG05__PWBASE: 7485 check_pw(ctx); 7486 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); 7487 register_name = "PWBase"; 7488 break; 7489 case CP0_REG05__PWFIELD: 7490 check_pw(ctx); 7491 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField)); 7492 register_name = "PWField"; 7493 break; 7494 case CP0_REG05__PWSIZE: 7495 check_pw(ctx); 7496 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize)); 7497 register_name = "PWSize"; 7498 break; 7499 default: 7500 goto cp0_unimplemented; 7501 } 7502 break; 7503 case CP0_REGISTER_06: 7504 switch (sel) { 7505 case CP0_REG06__WIRED: 7506 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired)); 7507 register_name = "Wired"; 7508 break; 7509 case CP0_REG06__SRSCONF0: 7510 check_insn(ctx, ISA_MIPS_R2); 7511 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0)); 7512 register_name = "SRSConf0"; 7513 break; 7514 case CP0_REG06__SRSCONF1: 7515 check_insn(ctx, ISA_MIPS_R2); 7516 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1)); 7517 register_name = "SRSConf1"; 7518 break; 7519 case CP0_REG06__SRSCONF2: 7520 check_insn(ctx, ISA_MIPS_R2); 7521 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2)); 7522 register_name = "SRSConf2"; 7523 break; 7524 case CP0_REG06__SRSCONF3: 7525 check_insn(ctx, ISA_MIPS_R2); 7526 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3)); 7527 register_name = "SRSConf3"; 7528 break; 7529 case CP0_REG06__SRSCONF4: 7530 check_insn(ctx, ISA_MIPS_R2); 7531 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4)); 7532 register_name = "SRSConf4"; 7533 break; 7534 case CP0_REG06__PWCTL: 7535 check_pw(ctx); 7536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl)); 7537 register_name = "PWCtl"; 7538 break; 7539 default: 7540 goto cp0_unimplemented; 7541 } 7542 break; 7543 case CP0_REGISTER_07: 7544 switch (sel) { 7545 case CP0_REG07__HWRENA: 7546 check_insn(ctx, ISA_MIPS_R2); 7547 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna)); 7548 register_name = "HWREna"; 7549 break; 7550 default: 7551 goto cp0_unimplemented; 7552 } 7553 break; 7554 case CP0_REGISTER_08: 7555 switch (sel) { 7556 case CP0_REG08__BADVADDR: 7557 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 7558 register_name = "BadVAddr"; 7559 break; 7560 case CP0_REG08__BADINSTR: 7561 CP0_CHECK(ctx->bi); 7562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr)); 7563 register_name = "BadInstr"; 7564 break; 7565 case CP0_REG08__BADINSTRP: 7566 CP0_CHECK(ctx->bp); 7567 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP)); 7568 register_name = "BadInstrP"; 7569 break; 7570 case CP0_REG08__BADINSTRX: 7571 CP0_CHECK(ctx->bi); 7572 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX)); 7573 tcg_gen_andi_tl(arg, arg, ~0xffff); 7574 register_name = "BadInstrX"; 7575 break; 7576 default: 7577 goto cp0_unimplemented; 7578 } 7579 break; 7580 case CP0_REGISTER_09: 7581 switch (sel) { 7582 case CP0_REG09__COUNT: 7583 /* Mark as an IO operation because we read the time. */ 7584 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 7585 gen_io_start(); 7586 } 7587 gen_helper_mfc0_count(arg, cpu_env); 7588 /* 7589 * Break the TB to be able to take timer interrupts immediately 7590 * after reading count. DISAS_STOP isn't sufficient, we need to 7591 * ensure we break completely out of translated code. 7592 */ 7593 gen_save_pc(ctx->base.pc_next + 4); 7594 ctx->base.is_jmp = DISAS_EXIT; 7595 register_name = "Count"; 7596 break; 7597 case CP0_REG09__SAARI: 7598 CP0_CHECK(ctx->saar); 7599 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI)); 7600 register_name = "SAARI"; 7601 break; 7602 case CP0_REG09__SAAR: 7603 CP0_CHECK(ctx->saar); 7604 gen_helper_dmfc0_saar(arg, cpu_env); 7605 register_name = "SAAR"; 7606 break; 7607 default: 7608 goto cp0_unimplemented; 7609 } 7610 break; 7611 case CP0_REGISTER_10: 7612 switch (sel) { 7613 case CP0_REG10__ENTRYHI: 7614 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi)); 7615 register_name = "EntryHi"; 7616 break; 7617 default: 7618 goto cp0_unimplemented; 7619 } 7620 break; 7621 case CP0_REGISTER_11: 7622 switch (sel) { 7623 case CP0_REG11__COMPARE: 7624 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare)); 7625 register_name = "Compare"; 7626 break; 7627 /* 6,7 are implementation dependent */ 7628 default: 7629 goto cp0_unimplemented; 7630 } 7631 break; 7632 case CP0_REGISTER_12: 7633 switch (sel) { 7634 case CP0_REG12__STATUS: 7635 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status)); 7636 register_name = "Status"; 7637 break; 7638 case CP0_REG12__INTCTL: 7639 check_insn(ctx, ISA_MIPS_R2); 7640 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl)); 7641 register_name = "IntCtl"; 7642 break; 7643 case CP0_REG12__SRSCTL: 7644 check_insn(ctx, ISA_MIPS_R2); 7645 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl)); 7646 register_name = "SRSCtl"; 7647 break; 7648 case CP0_REG12__SRSMAP: 7649 check_insn(ctx, ISA_MIPS_R2); 7650 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 7651 register_name = "SRSMap"; 7652 break; 7653 default: 7654 goto cp0_unimplemented; 7655 } 7656 break; 7657 case CP0_REGISTER_13: 7658 switch (sel) { 7659 case CP0_REG13__CAUSE: 7660 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause)); 7661 register_name = "Cause"; 7662 break; 7663 default: 7664 goto cp0_unimplemented; 7665 } 7666 break; 7667 case CP0_REGISTER_14: 7668 switch (sel) { 7669 case CP0_REG14__EPC: 7670 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 7671 register_name = "EPC"; 7672 break; 7673 default: 7674 goto cp0_unimplemented; 7675 } 7676 break; 7677 case CP0_REGISTER_15: 7678 switch (sel) { 7679 case CP0_REG15__PRID: 7680 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid)); 7681 register_name = "PRid"; 7682 break; 7683 case CP0_REG15__EBASE: 7684 check_insn(ctx, ISA_MIPS_R2); 7685 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase)); 7686 register_name = "EBase"; 7687 break; 7688 case CP0_REG15__CMGCRBASE: 7689 check_insn(ctx, ISA_MIPS_R2); 7690 CP0_CHECK(ctx->cmgcr); 7691 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase)); 7692 register_name = "CMGCRBase"; 7693 break; 7694 default: 7695 goto cp0_unimplemented; 7696 } 7697 break; 7698 case CP0_REGISTER_16: 7699 switch (sel) { 7700 case CP0_REG16__CONFIG: 7701 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0)); 7702 register_name = "Config"; 7703 break; 7704 case CP0_REG16__CONFIG1: 7705 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1)); 7706 register_name = "Config1"; 7707 break; 7708 case CP0_REG16__CONFIG2: 7709 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2)); 7710 register_name = "Config2"; 7711 break; 7712 case CP0_REG16__CONFIG3: 7713 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); 7714 register_name = "Config3"; 7715 break; 7716 case CP0_REG16__CONFIG4: 7717 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); 7718 register_name = "Config4"; 7719 break; 7720 case CP0_REG16__CONFIG5: 7721 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); 7722 register_name = "Config5"; 7723 break; 7724 /* 6,7 are implementation dependent */ 7725 case CP0_REG16__CONFIG6: 7726 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); 7727 register_name = "Config6"; 7728 break; 7729 case CP0_REG16__CONFIG7: 7730 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7)); 7731 register_name = "Config7"; 7732 break; 7733 default: 7734 goto cp0_unimplemented; 7735 } 7736 break; 7737 case CP0_REGISTER_17: 7738 switch (sel) { 7739 case CP0_REG17__LLADDR: 7740 gen_helper_dmfc0_lladdr(arg, cpu_env); 7741 register_name = "LLAddr"; 7742 break; 7743 case CP0_REG17__MAAR: 7744 CP0_CHECK(ctx->mrp); 7745 gen_helper_dmfc0_maar(arg, cpu_env); 7746 register_name = "MAAR"; 7747 break; 7748 case CP0_REG17__MAARI: 7749 CP0_CHECK(ctx->mrp); 7750 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI)); 7751 register_name = "MAARI"; 7752 break; 7753 default: 7754 goto cp0_unimplemented; 7755 } 7756 break; 7757 case CP0_REGISTER_18: 7758 switch (sel) { 7759 case CP0_REG18__WATCHLO0: 7760 case CP0_REG18__WATCHLO1: 7761 case CP0_REG18__WATCHLO2: 7762 case CP0_REG18__WATCHLO3: 7763 case CP0_REG18__WATCHLO4: 7764 case CP0_REG18__WATCHLO5: 7765 case CP0_REG18__WATCHLO6: 7766 case CP0_REG18__WATCHLO7: 7767 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7768 gen_helper_1e0i(dmfc0_watchlo, arg, sel); 7769 register_name = "WatchLo"; 7770 break; 7771 default: 7772 goto cp0_unimplemented; 7773 } 7774 break; 7775 case CP0_REGISTER_19: 7776 switch (sel) { 7777 case CP0_REG19__WATCHHI0: 7778 case CP0_REG19__WATCHHI1: 7779 case CP0_REG19__WATCHHI2: 7780 case CP0_REG19__WATCHHI3: 7781 case CP0_REG19__WATCHHI4: 7782 case CP0_REG19__WATCHHI5: 7783 case CP0_REG19__WATCHHI6: 7784 case CP0_REG19__WATCHHI7: 7785 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 7786 gen_helper_1e0i(dmfc0_watchhi, arg, sel); 7787 register_name = "WatchHi"; 7788 break; 7789 default: 7790 goto cp0_unimplemented; 7791 } 7792 break; 7793 case CP0_REGISTER_20: 7794 switch (sel) { 7795 case CP0_REG20__XCONTEXT: 7796 check_insn(ctx, ISA_MIPS3); 7797 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext)); 7798 register_name = "XContext"; 7799 break; 7800 default: 7801 goto cp0_unimplemented; 7802 } 7803 break; 7804 case CP0_REGISTER_21: 7805 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 7806 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 7807 switch (sel) { 7808 case 0: 7809 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask)); 7810 register_name = "Framemask"; 7811 break; 7812 default: 7813 goto cp0_unimplemented; 7814 } 7815 break; 7816 case CP0_REGISTER_22: 7817 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7818 register_name = "'Diagnostic"; /* implementation dependent */ 7819 break; 7820 case CP0_REGISTER_23: 7821 switch (sel) { 7822 case CP0_REG23__DEBUG: 7823 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */ 7824 register_name = "Debug"; 7825 break; 7826 case CP0_REG23__TRACECONTROL: 7827 /* PDtrace support */ 7828 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */ 7829 register_name = "TraceControl"; 7830 goto cp0_unimplemented; 7831 case CP0_REG23__TRACECONTROL2: 7832 /* PDtrace support */ 7833 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */ 7834 register_name = "TraceControl2"; 7835 goto cp0_unimplemented; 7836 case CP0_REG23__USERTRACEDATA1: 7837 /* PDtrace support */ 7838 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/ 7839 register_name = "UserTraceData1"; 7840 goto cp0_unimplemented; 7841 case CP0_REG23__TRACEIBPC: 7842 /* PDtrace support */ 7843 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */ 7844 register_name = "TraceIBPC"; 7845 goto cp0_unimplemented; 7846 case CP0_REG23__TRACEDBPC: 7847 /* PDtrace support */ 7848 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */ 7849 register_name = "TraceDBPC"; 7850 goto cp0_unimplemented; 7851 default: 7852 goto cp0_unimplemented; 7853 } 7854 break; 7855 case CP0_REGISTER_24: 7856 switch (sel) { 7857 case CP0_REG24__DEPC: 7858 /* EJTAG support */ 7859 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 7860 register_name = "DEPC"; 7861 break; 7862 default: 7863 goto cp0_unimplemented; 7864 } 7865 break; 7866 case CP0_REGISTER_25: 7867 switch (sel) { 7868 case CP0_REG25__PERFCTL0: 7869 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0)); 7870 register_name = "Performance0"; 7871 break; 7872 case CP0_REG25__PERFCNT0: 7873 /* gen_helper_dmfc0_performance1(arg); */ 7874 register_name = "Performance1"; 7875 goto cp0_unimplemented; 7876 case CP0_REG25__PERFCTL1: 7877 /* gen_helper_dmfc0_performance2(arg); */ 7878 register_name = "Performance2"; 7879 goto cp0_unimplemented; 7880 case CP0_REG25__PERFCNT1: 7881 /* gen_helper_dmfc0_performance3(arg); */ 7882 register_name = "Performance3"; 7883 goto cp0_unimplemented; 7884 case CP0_REG25__PERFCTL2: 7885 /* gen_helper_dmfc0_performance4(arg); */ 7886 register_name = "Performance4"; 7887 goto cp0_unimplemented; 7888 case CP0_REG25__PERFCNT2: 7889 /* gen_helper_dmfc0_performance5(arg); */ 7890 register_name = "Performance5"; 7891 goto cp0_unimplemented; 7892 case CP0_REG25__PERFCTL3: 7893 /* gen_helper_dmfc0_performance6(arg); */ 7894 register_name = "Performance6"; 7895 goto cp0_unimplemented; 7896 case CP0_REG25__PERFCNT3: 7897 /* gen_helper_dmfc0_performance7(arg); */ 7898 register_name = "Performance7"; 7899 goto cp0_unimplemented; 7900 default: 7901 goto cp0_unimplemented; 7902 } 7903 break; 7904 case CP0_REGISTER_26: 7905 switch (sel) { 7906 case CP0_REG26__ERRCTL: 7907 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); 7908 register_name = "ErrCtl"; 7909 break; 7910 default: 7911 goto cp0_unimplemented; 7912 } 7913 break; 7914 case CP0_REGISTER_27: 7915 switch (sel) { 7916 /* ignored */ 7917 case CP0_REG27__CACHERR: 7918 tcg_gen_movi_tl(arg, 0); /* unimplemented */ 7919 register_name = "CacheErr"; 7920 break; 7921 default: 7922 goto cp0_unimplemented; 7923 } 7924 break; 7925 case CP0_REGISTER_28: 7926 switch (sel) { 7927 case CP0_REG28__TAGLO: 7928 case CP0_REG28__TAGLO1: 7929 case CP0_REG28__TAGLO2: 7930 case CP0_REG28__TAGLO3: 7931 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); 7932 register_name = "TagLo"; 7933 break; 7934 case CP0_REG28__DATALO: 7935 case CP0_REG28__DATALO1: 7936 case CP0_REG28__DATALO2: 7937 case CP0_REG28__DATALO3: 7938 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo)); 7939 register_name = "DataLo"; 7940 break; 7941 default: 7942 goto cp0_unimplemented; 7943 } 7944 break; 7945 case CP0_REGISTER_29: 7946 switch (sel) { 7947 case CP0_REG29__TAGHI: 7948 case CP0_REG29__TAGHI1: 7949 case CP0_REG29__TAGHI2: 7950 case CP0_REG29__TAGHI3: 7951 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi)); 7952 register_name = "TagHi"; 7953 break; 7954 case CP0_REG29__DATAHI: 7955 case CP0_REG29__DATAHI1: 7956 case CP0_REG29__DATAHI2: 7957 case CP0_REG29__DATAHI3: 7958 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi)); 7959 register_name = "DataHi"; 7960 break; 7961 default: 7962 goto cp0_unimplemented; 7963 } 7964 break; 7965 case CP0_REGISTER_30: 7966 switch (sel) { 7967 case CP0_REG30__ERROREPC: 7968 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 7969 register_name = "ErrorEPC"; 7970 break; 7971 default: 7972 goto cp0_unimplemented; 7973 } 7974 break; 7975 case CP0_REGISTER_31: 7976 switch (sel) { 7977 case CP0_REG31__DESAVE: 7978 /* EJTAG support */ 7979 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 7980 register_name = "DESAVE"; 7981 break; 7982 case CP0_REG31__KSCRATCH1: 7983 case CP0_REG31__KSCRATCH2: 7984 case CP0_REG31__KSCRATCH3: 7985 case CP0_REG31__KSCRATCH4: 7986 case CP0_REG31__KSCRATCH5: 7987 case CP0_REG31__KSCRATCH6: 7988 CP0_CHECK(ctx->kscrexist & (1 << sel)); 7989 tcg_gen_ld_tl(arg, cpu_env, 7990 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 7991 register_name = "KScratch"; 7992 break; 7993 default: 7994 goto cp0_unimplemented; 7995 } 7996 break; 7997 default: 7998 goto cp0_unimplemented; 7999 } 8000 trace_mips_translate_c0("dmfc0", register_name, reg, sel); 8001 return; 8002 8003 cp0_unimplemented: 8004 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", 8005 register_name, reg, sel); 8006 gen_mfc0_unimplemented(ctx, arg); 8007 } 8008 8009 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) 8010 { 8011 const char *register_name = "invalid"; 8012 8013 if (sel != 0) { 8014 check_insn(ctx, ISA_MIPS_R1); 8015 } 8016 8017 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 8018 gen_io_start(); 8019 } 8020 8021 switch (reg) { 8022 case CP0_REGISTER_00: 8023 switch (sel) { 8024 case CP0_REG00__INDEX: 8025 gen_helper_mtc0_index(cpu_env, arg); 8026 register_name = "Index"; 8027 break; 8028 case CP0_REG00__MVPCONTROL: 8029 CP0_CHECK(ctx->insn_flags & ASE_MT); 8030 gen_helper_mtc0_mvpcontrol(cpu_env, arg); 8031 register_name = "MVPControl"; 8032 break; 8033 case CP0_REG00__MVPCONF0: 8034 CP0_CHECK(ctx->insn_flags & ASE_MT); 8035 /* ignored */ 8036 register_name = "MVPConf0"; 8037 break; 8038 case CP0_REG00__MVPCONF1: 8039 CP0_CHECK(ctx->insn_flags & ASE_MT); 8040 /* ignored */ 8041 register_name = "MVPConf1"; 8042 break; 8043 case CP0_REG00__VPCONTROL: 8044 CP0_CHECK(ctx->vp); 8045 /* ignored */ 8046 register_name = "VPControl"; 8047 break; 8048 default: 8049 goto cp0_unimplemented; 8050 } 8051 break; 8052 case CP0_REGISTER_01: 8053 switch (sel) { 8054 case CP0_REG01__RANDOM: 8055 /* ignored */ 8056 register_name = "Random"; 8057 break; 8058 case CP0_REG01__VPECONTROL: 8059 CP0_CHECK(ctx->insn_flags & ASE_MT); 8060 gen_helper_mtc0_vpecontrol(cpu_env, arg); 8061 register_name = "VPEControl"; 8062 break; 8063 case CP0_REG01__VPECONF0: 8064 CP0_CHECK(ctx->insn_flags & ASE_MT); 8065 gen_helper_mtc0_vpeconf0(cpu_env, arg); 8066 register_name = "VPEConf0"; 8067 break; 8068 case CP0_REG01__VPECONF1: 8069 CP0_CHECK(ctx->insn_flags & ASE_MT); 8070 gen_helper_mtc0_vpeconf1(cpu_env, arg); 8071 register_name = "VPEConf1"; 8072 break; 8073 case CP0_REG01__YQMASK: 8074 CP0_CHECK(ctx->insn_flags & ASE_MT); 8075 gen_helper_mtc0_yqmask(cpu_env, arg); 8076 register_name = "YQMask"; 8077 break; 8078 case CP0_REG01__VPESCHEDULE: 8079 CP0_CHECK(ctx->insn_flags & ASE_MT); 8080 tcg_gen_st_tl(arg, cpu_env, 8081 offsetof(CPUMIPSState, CP0_VPESchedule)); 8082 register_name = "VPESchedule"; 8083 break; 8084 case CP0_REG01__VPESCHEFBACK: 8085 CP0_CHECK(ctx->insn_flags & ASE_MT); 8086 tcg_gen_st_tl(arg, cpu_env, 8087 offsetof(CPUMIPSState, CP0_VPEScheFBack)); 8088 register_name = "VPEScheFBack"; 8089 break; 8090 case CP0_REG01__VPEOPT: 8091 CP0_CHECK(ctx->insn_flags & ASE_MT); 8092 gen_helper_mtc0_vpeopt(cpu_env, arg); 8093 register_name = "VPEOpt"; 8094 break; 8095 default: 8096 goto cp0_unimplemented; 8097 } 8098 break; 8099 case CP0_REGISTER_02: 8100 switch (sel) { 8101 case CP0_REG02__ENTRYLO0: 8102 gen_helper_dmtc0_entrylo0(cpu_env, arg); 8103 register_name = "EntryLo0"; 8104 break; 8105 case CP0_REG02__TCSTATUS: 8106 CP0_CHECK(ctx->insn_flags & ASE_MT); 8107 gen_helper_mtc0_tcstatus(cpu_env, arg); 8108 register_name = "TCStatus"; 8109 break; 8110 case CP0_REG02__TCBIND: 8111 CP0_CHECK(ctx->insn_flags & ASE_MT); 8112 gen_helper_mtc0_tcbind(cpu_env, arg); 8113 register_name = "TCBind"; 8114 break; 8115 case CP0_REG02__TCRESTART: 8116 CP0_CHECK(ctx->insn_flags & ASE_MT); 8117 gen_helper_mtc0_tcrestart(cpu_env, arg); 8118 register_name = "TCRestart"; 8119 break; 8120 case CP0_REG02__TCHALT: 8121 CP0_CHECK(ctx->insn_flags & ASE_MT); 8122 gen_helper_mtc0_tchalt(cpu_env, arg); 8123 register_name = "TCHalt"; 8124 break; 8125 case CP0_REG02__TCCONTEXT: 8126 CP0_CHECK(ctx->insn_flags & ASE_MT); 8127 gen_helper_mtc0_tccontext(cpu_env, arg); 8128 register_name = "TCContext"; 8129 break; 8130 case CP0_REG02__TCSCHEDULE: 8131 CP0_CHECK(ctx->insn_flags & ASE_MT); 8132 gen_helper_mtc0_tcschedule(cpu_env, arg); 8133 register_name = "TCSchedule"; 8134 break; 8135 case CP0_REG02__TCSCHEFBACK: 8136 CP0_CHECK(ctx->insn_flags & ASE_MT); 8137 gen_helper_mtc0_tcschefback(cpu_env, arg); 8138 register_name = "TCScheFBack"; 8139 break; 8140 default: 8141 goto cp0_unimplemented; 8142 } 8143 break; 8144 case CP0_REGISTER_03: 8145 switch (sel) { 8146 case CP0_REG03__ENTRYLO1: 8147 gen_helper_dmtc0_entrylo1(cpu_env, arg); 8148 register_name = "EntryLo1"; 8149 break; 8150 case CP0_REG03__GLOBALNUM: 8151 CP0_CHECK(ctx->vp); 8152 /* ignored */ 8153 register_name = "GlobalNumber"; 8154 break; 8155 default: 8156 goto cp0_unimplemented; 8157 } 8158 break; 8159 case CP0_REGISTER_04: 8160 switch (sel) { 8161 case CP0_REG04__CONTEXT: 8162 gen_helper_mtc0_context(cpu_env, arg); 8163 register_name = "Context"; 8164 break; 8165 case CP0_REG04__CONTEXTCONFIG: 8166 /* SmartMIPS ASE */ 8167 /* gen_helper_dmtc0_contextconfig(arg); */ 8168 register_name = "ContextConfig"; 8169 goto cp0_unimplemented; 8170 case CP0_REG04__USERLOCAL: 8171 CP0_CHECK(ctx->ulri); 8172 tcg_gen_st_tl(arg, cpu_env, 8173 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 8174 register_name = "UserLocal"; 8175 break; 8176 case CP0_REG04__MMID: 8177 CP0_CHECK(ctx->mi); 8178 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); 8179 register_name = "MMID"; 8180 break; 8181 default: 8182 goto cp0_unimplemented; 8183 } 8184 break; 8185 case CP0_REGISTER_05: 8186 switch (sel) { 8187 case CP0_REG05__PAGEMASK: 8188 gen_helper_mtc0_pagemask(cpu_env, arg); 8189 register_name = "PageMask"; 8190 break; 8191 case CP0_REG05__PAGEGRAIN: 8192 check_insn(ctx, ISA_MIPS_R2); 8193 gen_helper_mtc0_pagegrain(cpu_env, arg); 8194 register_name = "PageGrain"; 8195 break; 8196 case CP0_REG05__SEGCTL0: 8197 CP0_CHECK(ctx->sc); 8198 gen_helper_mtc0_segctl0(cpu_env, arg); 8199 register_name = "SegCtl0"; 8200 break; 8201 case CP0_REG05__SEGCTL1: 8202 CP0_CHECK(ctx->sc); 8203 gen_helper_mtc0_segctl1(cpu_env, arg); 8204 register_name = "SegCtl1"; 8205 break; 8206 case CP0_REG05__SEGCTL2: 8207 CP0_CHECK(ctx->sc); 8208 gen_helper_mtc0_segctl2(cpu_env, arg); 8209 register_name = "SegCtl2"; 8210 break; 8211 case CP0_REG05__PWBASE: 8212 check_pw(ctx); 8213 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase)); 8214 register_name = "PWBase"; 8215 break; 8216 case CP0_REG05__PWFIELD: 8217 check_pw(ctx); 8218 gen_helper_mtc0_pwfield(cpu_env, arg); 8219 register_name = "PWField"; 8220 break; 8221 case CP0_REG05__PWSIZE: 8222 check_pw(ctx); 8223 gen_helper_mtc0_pwsize(cpu_env, arg); 8224 register_name = "PWSize"; 8225 break; 8226 default: 8227 goto cp0_unimplemented; 8228 } 8229 break; 8230 case CP0_REGISTER_06: 8231 switch (sel) { 8232 case CP0_REG06__WIRED: 8233 gen_helper_mtc0_wired(cpu_env, arg); 8234 register_name = "Wired"; 8235 break; 8236 case CP0_REG06__SRSCONF0: 8237 check_insn(ctx, ISA_MIPS_R2); 8238 gen_helper_mtc0_srsconf0(cpu_env, arg); 8239 register_name = "SRSConf0"; 8240 break; 8241 case CP0_REG06__SRSCONF1: 8242 check_insn(ctx, ISA_MIPS_R2); 8243 gen_helper_mtc0_srsconf1(cpu_env, arg); 8244 register_name = "SRSConf1"; 8245 break; 8246 case CP0_REG06__SRSCONF2: 8247 check_insn(ctx, ISA_MIPS_R2); 8248 gen_helper_mtc0_srsconf2(cpu_env, arg); 8249 register_name = "SRSConf2"; 8250 break; 8251 case CP0_REG06__SRSCONF3: 8252 check_insn(ctx, ISA_MIPS_R2); 8253 gen_helper_mtc0_srsconf3(cpu_env, arg); 8254 register_name = "SRSConf3"; 8255 break; 8256 case CP0_REG06__SRSCONF4: 8257 check_insn(ctx, ISA_MIPS_R2); 8258 gen_helper_mtc0_srsconf4(cpu_env, arg); 8259 register_name = "SRSConf4"; 8260 break; 8261 case CP0_REG06__PWCTL: 8262 check_pw(ctx); 8263 gen_helper_mtc0_pwctl(cpu_env, arg); 8264 register_name = "PWCtl"; 8265 break; 8266 default: 8267 goto cp0_unimplemented; 8268 } 8269 break; 8270 case CP0_REGISTER_07: 8271 switch (sel) { 8272 case CP0_REG07__HWRENA: 8273 check_insn(ctx, ISA_MIPS_R2); 8274 gen_helper_mtc0_hwrena(cpu_env, arg); 8275 ctx->base.is_jmp = DISAS_STOP; 8276 register_name = "HWREna"; 8277 break; 8278 default: 8279 goto cp0_unimplemented; 8280 } 8281 break; 8282 case CP0_REGISTER_08: 8283 switch (sel) { 8284 case CP0_REG08__BADVADDR: 8285 /* ignored */ 8286 register_name = "BadVAddr"; 8287 break; 8288 case CP0_REG08__BADINSTR: 8289 /* ignored */ 8290 register_name = "BadInstr"; 8291 break; 8292 case CP0_REG08__BADINSTRP: 8293 /* ignored */ 8294 register_name = "BadInstrP"; 8295 break; 8296 case CP0_REG08__BADINSTRX: 8297 /* ignored */ 8298 register_name = "BadInstrX"; 8299 break; 8300 default: 8301 goto cp0_unimplemented; 8302 } 8303 break; 8304 case CP0_REGISTER_09: 8305 switch (sel) { 8306 case CP0_REG09__COUNT: 8307 gen_helper_mtc0_count(cpu_env, arg); 8308 register_name = "Count"; 8309 break; 8310 case CP0_REG09__SAARI: 8311 CP0_CHECK(ctx->saar); 8312 gen_helper_mtc0_saari(cpu_env, arg); 8313 register_name = "SAARI"; 8314 break; 8315 case CP0_REG09__SAAR: 8316 CP0_CHECK(ctx->saar); 8317 gen_helper_mtc0_saar(cpu_env, arg); 8318 register_name = "SAAR"; 8319 break; 8320 default: 8321 goto cp0_unimplemented; 8322 } 8323 /* Stop translation as we may have switched the execution mode */ 8324 ctx->base.is_jmp = DISAS_STOP; 8325 break; 8326 case CP0_REGISTER_10: 8327 switch (sel) { 8328 case CP0_REG10__ENTRYHI: 8329 gen_helper_mtc0_entryhi(cpu_env, arg); 8330 register_name = "EntryHi"; 8331 break; 8332 default: 8333 goto cp0_unimplemented; 8334 } 8335 break; 8336 case CP0_REGISTER_11: 8337 switch (sel) { 8338 case CP0_REG11__COMPARE: 8339 gen_helper_mtc0_compare(cpu_env, arg); 8340 register_name = "Compare"; 8341 break; 8342 /* 6,7 are implementation dependent */ 8343 default: 8344 goto cp0_unimplemented; 8345 } 8346 /* Stop translation as we may have switched the execution mode */ 8347 ctx->base.is_jmp = DISAS_STOP; 8348 break; 8349 case CP0_REGISTER_12: 8350 switch (sel) { 8351 case CP0_REG12__STATUS: 8352 save_cpu_state(ctx, 1); 8353 gen_helper_mtc0_status(cpu_env, arg); 8354 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 8355 gen_save_pc(ctx->base.pc_next + 4); 8356 ctx->base.is_jmp = DISAS_EXIT; 8357 register_name = "Status"; 8358 break; 8359 case CP0_REG12__INTCTL: 8360 check_insn(ctx, ISA_MIPS_R2); 8361 gen_helper_mtc0_intctl(cpu_env, arg); 8362 /* Stop translation as we may have switched the execution mode */ 8363 ctx->base.is_jmp = DISAS_STOP; 8364 register_name = "IntCtl"; 8365 break; 8366 case CP0_REG12__SRSCTL: 8367 check_insn(ctx, ISA_MIPS_R2); 8368 gen_helper_mtc0_srsctl(cpu_env, arg); 8369 /* Stop translation as we may have switched the execution mode */ 8370 ctx->base.is_jmp = DISAS_STOP; 8371 register_name = "SRSCtl"; 8372 break; 8373 case CP0_REG12__SRSMAP: 8374 check_insn(ctx, ISA_MIPS_R2); 8375 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap)); 8376 /* Stop translation as we may have switched the execution mode */ 8377 ctx->base.is_jmp = DISAS_STOP; 8378 register_name = "SRSMap"; 8379 break; 8380 default: 8381 goto cp0_unimplemented; 8382 } 8383 break; 8384 case CP0_REGISTER_13: 8385 switch (sel) { 8386 case CP0_REG13__CAUSE: 8387 save_cpu_state(ctx, 1); 8388 gen_helper_mtc0_cause(cpu_env, arg); 8389 /* 8390 * Stop translation as we may have triggered an interrupt. 8391 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8392 * translated code to check for pending interrupts. 8393 */ 8394 gen_save_pc(ctx->base.pc_next + 4); 8395 ctx->base.is_jmp = DISAS_EXIT; 8396 register_name = "Cause"; 8397 break; 8398 default: 8399 goto cp0_unimplemented; 8400 } 8401 break; 8402 case CP0_REGISTER_14: 8403 switch (sel) { 8404 case CP0_REG14__EPC: 8405 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC)); 8406 register_name = "EPC"; 8407 break; 8408 default: 8409 goto cp0_unimplemented; 8410 } 8411 break; 8412 case CP0_REGISTER_15: 8413 switch (sel) { 8414 case CP0_REG15__PRID: 8415 /* ignored */ 8416 register_name = "PRid"; 8417 break; 8418 case CP0_REG15__EBASE: 8419 check_insn(ctx, ISA_MIPS_R2); 8420 gen_helper_mtc0_ebase(cpu_env, arg); 8421 register_name = "EBase"; 8422 break; 8423 default: 8424 goto cp0_unimplemented; 8425 } 8426 break; 8427 case CP0_REGISTER_16: 8428 switch (sel) { 8429 case CP0_REG16__CONFIG: 8430 gen_helper_mtc0_config0(cpu_env, arg); 8431 register_name = "Config"; 8432 /* Stop translation as we may have switched the execution mode */ 8433 ctx->base.is_jmp = DISAS_STOP; 8434 break; 8435 case CP0_REG16__CONFIG1: 8436 /* ignored, read only */ 8437 register_name = "Config1"; 8438 break; 8439 case CP0_REG16__CONFIG2: 8440 gen_helper_mtc0_config2(cpu_env, arg); 8441 register_name = "Config2"; 8442 /* Stop translation as we may have switched the execution mode */ 8443 ctx->base.is_jmp = DISAS_STOP; 8444 break; 8445 case CP0_REG16__CONFIG3: 8446 gen_helper_mtc0_config3(cpu_env, arg); 8447 register_name = "Config3"; 8448 /* Stop translation as we may have switched the execution mode */ 8449 ctx->base.is_jmp = DISAS_STOP; 8450 break; 8451 case CP0_REG16__CONFIG4: 8452 /* currently ignored */ 8453 register_name = "Config4"; 8454 break; 8455 case CP0_REG16__CONFIG5: 8456 gen_helper_mtc0_config5(cpu_env, arg); 8457 register_name = "Config5"; 8458 /* Stop translation as we may have switched the execution mode */ 8459 ctx->base.is_jmp = DISAS_STOP; 8460 break; 8461 /* 6,7 are implementation dependent */ 8462 default: 8463 register_name = "Invalid config selector"; 8464 goto cp0_unimplemented; 8465 } 8466 break; 8467 case CP0_REGISTER_17: 8468 switch (sel) { 8469 case CP0_REG17__LLADDR: 8470 gen_helper_mtc0_lladdr(cpu_env, arg); 8471 register_name = "LLAddr"; 8472 break; 8473 case CP0_REG17__MAAR: 8474 CP0_CHECK(ctx->mrp); 8475 gen_helper_mtc0_maar(cpu_env, arg); 8476 register_name = "MAAR"; 8477 break; 8478 case CP0_REG17__MAARI: 8479 CP0_CHECK(ctx->mrp); 8480 gen_helper_mtc0_maari(cpu_env, arg); 8481 register_name = "MAARI"; 8482 break; 8483 default: 8484 goto cp0_unimplemented; 8485 } 8486 break; 8487 case CP0_REGISTER_18: 8488 switch (sel) { 8489 case CP0_REG18__WATCHLO0: 8490 case CP0_REG18__WATCHLO1: 8491 case CP0_REG18__WATCHLO2: 8492 case CP0_REG18__WATCHLO3: 8493 case CP0_REG18__WATCHLO4: 8494 case CP0_REG18__WATCHLO5: 8495 case CP0_REG18__WATCHLO6: 8496 case CP0_REG18__WATCHLO7: 8497 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8498 gen_helper_0e1i(mtc0_watchlo, arg, sel); 8499 register_name = "WatchLo"; 8500 break; 8501 default: 8502 goto cp0_unimplemented; 8503 } 8504 break; 8505 case CP0_REGISTER_19: 8506 switch (sel) { 8507 case CP0_REG19__WATCHHI0: 8508 case CP0_REG19__WATCHHI1: 8509 case CP0_REG19__WATCHHI2: 8510 case CP0_REG19__WATCHHI3: 8511 case CP0_REG19__WATCHHI4: 8512 case CP0_REG19__WATCHHI5: 8513 case CP0_REG19__WATCHHI6: 8514 case CP0_REG19__WATCHHI7: 8515 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR)); 8516 gen_helper_0e1i(mtc0_watchhi, arg, sel); 8517 register_name = "WatchHi"; 8518 break; 8519 default: 8520 goto cp0_unimplemented; 8521 } 8522 break; 8523 case CP0_REGISTER_20: 8524 switch (sel) { 8525 case CP0_REG20__XCONTEXT: 8526 check_insn(ctx, ISA_MIPS3); 8527 gen_helper_mtc0_xcontext(cpu_env, arg); 8528 register_name = "XContext"; 8529 break; 8530 default: 8531 goto cp0_unimplemented; 8532 } 8533 break; 8534 case CP0_REGISTER_21: 8535 /* Officially reserved, but sel 0 is used for R1x000 framemask */ 8536 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6)); 8537 switch (sel) { 8538 case 0: 8539 gen_helper_mtc0_framemask(cpu_env, arg); 8540 register_name = "Framemask"; 8541 break; 8542 default: 8543 goto cp0_unimplemented; 8544 } 8545 break; 8546 case CP0_REGISTER_22: 8547 /* ignored */ 8548 register_name = "Diagnostic"; /* implementation dependent */ 8549 break; 8550 case CP0_REGISTER_23: 8551 switch (sel) { 8552 case CP0_REG23__DEBUG: 8553 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */ 8554 /* DISAS_STOP isn't good enough here, hflags may have changed. */ 8555 gen_save_pc(ctx->base.pc_next + 4); 8556 ctx->base.is_jmp = DISAS_EXIT; 8557 register_name = "Debug"; 8558 break; 8559 case CP0_REG23__TRACECONTROL: 8560 /* PDtrace support */ 8561 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */ 8562 /* Stop translation as we may have switched the execution mode */ 8563 ctx->base.is_jmp = DISAS_STOP; 8564 register_name = "TraceControl"; 8565 goto cp0_unimplemented; 8566 case CP0_REG23__TRACECONTROL2: 8567 /* PDtrace support */ 8568 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */ 8569 /* Stop translation as we may have switched the execution mode */ 8570 ctx->base.is_jmp = DISAS_STOP; 8571 register_name = "TraceControl2"; 8572 goto cp0_unimplemented; 8573 case CP0_REG23__USERTRACEDATA1: 8574 /* PDtrace support */ 8575 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/ 8576 /* Stop translation as we may have switched the execution mode */ 8577 ctx->base.is_jmp = DISAS_STOP; 8578 register_name = "UserTraceData1"; 8579 goto cp0_unimplemented; 8580 case CP0_REG23__TRACEIBPC: 8581 /* PDtrace support */ 8582 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */ 8583 /* Stop translation as we may have switched the execution mode */ 8584 ctx->base.is_jmp = DISAS_STOP; 8585 register_name = "TraceIBPC"; 8586 goto cp0_unimplemented; 8587 case CP0_REG23__TRACEDBPC: 8588 /* PDtrace support */ 8589 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */ 8590 /* Stop translation as we may have switched the execution mode */ 8591 ctx->base.is_jmp = DISAS_STOP; 8592 register_name = "TraceDBPC"; 8593 goto cp0_unimplemented; 8594 default: 8595 goto cp0_unimplemented; 8596 } 8597 break; 8598 case CP0_REGISTER_24: 8599 switch (sel) { 8600 case CP0_REG24__DEPC: 8601 /* EJTAG support */ 8602 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC)); 8603 register_name = "DEPC"; 8604 break; 8605 default: 8606 goto cp0_unimplemented; 8607 } 8608 break; 8609 case CP0_REGISTER_25: 8610 switch (sel) { 8611 case CP0_REG25__PERFCTL0: 8612 gen_helper_mtc0_performance0(cpu_env, arg); 8613 register_name = "Performance0"; 8614 break; 8615 case CP0_REG25__PERFCNT0: 8616 /* gen_helper_mtc0_performance1(cpu_env, arg); */ 8617 register_name = "Performance1"; 8618 goto cp0_unimplemented; 8619 case CP0_REG25__PERFCTL1: 8620 /* gen_helper_mtc0_performance2(cpu_env, arg); */ 8621 register_name = "Performance2"; 8622 goto cp0_unimplemented; 8623 case CP0_REG25__PERFCNT1: 8624 /* gen_helper_mtc0_performance3(cpu_env, arg); */ 8625 register_name = "Performance3"; 8626 goto cp0_unimplemented; 8627 case CP0_REG25__PERFCTL2: 8628 /* gen_helper_mtc0_performance4(cpu_env, arg); */ 8629 register_name = "Performance4"; 8630 goto cp0_unimplemented; 8631 case CP0_REG25__PERFCNT2: 8632 /* gen_helper_mtc0_performance5(cpu_env, arg); */ 8633 register_name = "Performance5"; 8634 goto cp0_unimplemented; 8635 case CP0_REG25__PERFCTL3: 8636 /* gen_helper_mtc0_performance6(cpu_env, arg); */ 8637 register_name = "Performance6"; 8638 goto cp0_unimplemented; 8639 case CP0_REG25__PERFCNT3: 8640 /* gen_helper_mtc0_performance7(cpu_env, arg); */ 8641 register_name = "Performance7"; 8642 goto cp0_unimplemented; 8643 default: 8644 goto cp0_unimplemented; 8645 } 8646 break; 8647 case CP0_REGISTER_26: 8648 switch (sel) { 8649 case CP0_REG26__ERRCTL: 8650 gen_helper_mtc0_errctl(cpu_env, arg); 8651 ctx->base.is_jmp = DISAS_STOP; 8652 register_name = "ErrCtl"; 8653 break; 8654 default: 8655 goto cp0_unimplemented; 8656 } 8657 break; 8658 case CP0_REGISTER_27: 8659 switch (sel) { 8660 case CP0_REG27__CACHERR: 8661 /* ignored */ 8662 register_name = "CacheErr"; 8663 break; 8664 default: 8665 goto cp0_unimplemented; 8666 } 8667 break; 8668 case CP0_REGISTER_28: 8669 switch (sel) { 8670 case CP0_REG28__TAGLO: 8671 case CP0_REG28__TAGLO1: 8672 case CP0_REG28__TAGLO2: 8673 case CP0_REG28__TAGLO3: 8674 gen_helper_mtc0_taglo(cpu_env, arg); 8675 register_name = "TagLo"; 8676 break; 8677 case CP0_REG28__DATALO: 8678 case CP0_REG28__DATALO1: 8679 case CP0_REG28__DATALO2: 8680 case CP0_REG28__DATALO3: 8681 gen_helper_mtc0_datalo(cpu_env, arg); 8682 register_name = "DataLo"; 8683 break; 8684 default: 8685 goto cp0_unimplemented; 8686 } 8687 break; 8688 case CP0_REGISTER_29: 8689 switch (sel) { 8690 case CP0_REG29__TAGHI: 8691 case CP0_REG29__TAGHI1: 8692 case CP0_REG29__TAGHI2: 8693 case CP0_REG29__TAGHI3: 8694 gen_helper_mtc0_taghi(cpu_env, arg); 8695 register_name = "TagHi"; 8696 break; 8697 case CP0_REG29__DATAHI: 8698 case CP0_REG29__DATAHI1: 8699 case CP0_REG29__DATAHI2: 8700 case CP0_REG29__DATAHI3: 8701 gen_helper_mtc0_datahi(cpu_env, arg); 8702 register_name = "DataHi"; 8703 break; 8704 default: 8705 register_name = "invalid sel"; 8706 goto cp0_unimplemented; 8707 } 8708 break; 8709 case CP0_REGISTER_30: 8710 switch (sel) { 8711 case CP0_REG30__ERROREPC: 8712 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC)); 8713 register_name = "ErrorEPC"; 8714 break; 8715 default: 8716 goto cp0_unimplemented; 8717 } 8718 break; 8719 case CP0_REGISTER_31: 8720 switch (sel) { 8721 case CP0_REG31__DESAVE: 8722 /* EJTAG support */ 8723 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE)); 8724 register_name = "DESAVE"; 8725 break; 8726 case CP0_REG31__KSCRATCH1: 8727 case CP0_REG31__KSCRATCH2: 8728 case CP0_REG31__KSCRATCH3: 8729 case CP0_REG31__KSCRATCH4: 8730 case CP0_REG31__KSCRATCH5: 8731 case CP0_REG31__KSCRATCH6: 8732 CP0_CHECK(ctx->kscrexist & (1 << sel)); 8733 tcg_gen_st_tl(arg, cpu_env, 8734 offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); 8735 register_name = "KScratch"; 8736 break; 8737 default: 8738 goto cp0_unimplemented; 8739 } 8740 break; 8741 default: 8742 goto cp0_unimplemented; 8743 } 8744 trace_mips_translate_c0("dmtc0", register_name, reg, sel); 8745 8746 /* For simplicity assume that all writes can cause interrupts. */ 8747 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 8748 /* 8749 * DISAS_STOP isn't sufficient, we need to ensure we break out of 8750 * translated code to check for pending interrupts. 8751 */ 8752 gen_save_pc(ctx->base.pc_next + 4); 8753 ctx->base.is_jmp = DISAS_EXIT; 8754 } 8755 return; 8756 8757 cp0_unimplemented: 8758 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", 8759 register_name, reg, sel); 8760 } 8761 #endif /* TARGET_MIPS64 */ 8762 8763 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd, 8764 int u, int sel, int h) 8765 { 8766 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8767 TCGv t0 = tcg_temp_local_new(); 8768 8769 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8770 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 8771 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 8772 tcg_gen_movi_tl(t0, -1); 8773 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 8774 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 8775 tcg_gen_movi_tl(t0, -1); 8776 } else if (u == 0) { 8777 switch (rt) { 8778 case 1: 8779 switch (sel) { 8780 case 1: 8781 gen_helper_mftc0_vpecontrol(t0, cpu_env); 8782 break; 8783 case 2: 8784 gen_helper_mftc0_vpeconf0(t0, cpu_env); 8785 break; 8786 default: 8787 goto die; 8788 break; 8789 } 8790 break; 8791 case 2: 8792 switch (sel) { 8793 case 1: 8794 gen_helper_mftc0_tcstatus(t0, cpu_env); 8795 break; 8796 case 2: 8797 gen_helper_mftc0_tcbind(t0, cpu_env); 8798 break; 8799 case 3: 8800 gen_helper_mftc0_tcrestart(t0, cpu_env); 8801 break; 8802 case 4: 8803 gen_helper_mftc0_tchalt(t0, cpu_env); 8804 break; 8805 case 5: 8806 gen_helper_mftc0_tccontext(t0, cpu_env); 8807 break; 8808 case 6: 8809 gen_helper_mftc0_tcschedule(t0, cpu_env); 8810 break; 8811 case 7: 8812 gen_helper_mftc0_tcschefback(t0, cpu_env); 8813 break; 8814 default: 8815 gen_mfc0(ctx, t0, rt, sel); 8816 break; 8817 } 8818 break; 8819 case 10: 8820 switch (sel) { 8821 case 0: 8822 gen_helper_mftc0_entryhi(t0, cpu_env); 8823 break; 8824 default: 8825 gen_mfc0(ctx, t0, rt, sel); 8826 break; 8827 } 8828 break; 8829 case 12: 8830 switch (sel) { 8831 case 0: 8832 gen_helper_mftc0_status(t0, cpu_env); 8833 break; 8834 default: 8835 gen_mfc0(ctx, t0, rt, sel); 8836 break; 8837 } 8838 break; 8839 case 13: 8840 switch (sel) { 8841 case 0: 8842 gen_helper_mftc0_cause(t0, cpu_env); 8843 break; 8844 default: 8845 goto die; 8846 break; 8847 } 8848 break; 8849 case 14: 8850 switch (sel) { 8851 case 0: 8852 gen_helper_mftc0_epc(t0, cpu_env); 8853 break; 8854 default: 8855 goto die; 8856 break; 8857 } 8858 break; 8859 case 15: 8860 switch (sel) { 8861 case 1: 8862 gen_helper_mftc0_ebase(t0, cpu_env); 8863 break; 8864 default: 8865 goto die; 8866 break; 8867 } 8868 break; 8869 case 16: 8870 switch (sel) { 8871 case 0: 8872 case 1: 8873 case 2: 8874 case 3: 8875 case 4: 8876 case 5: 8877 case 6: 8878 case 7: 8879 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel)); 8880 break; 8881 default: 8882 goto die; 8883 break; 8884 } 8885 break; 8886 case 23: 8887 switch (sel) { 8888 case 0: 8889 gen_helper_mftc0_debug(t0, cpu_env); 8890 break; 8891 default: 8892 gen_mfc0(ctx, t0, rt, sel); 8893 break; 8894 } 8895 break; 8896 default: 8897 gen_mfc0(ctx, t0, rt, sel); 8898 } 8899 } else { 8900 switch (sel) { 8901 /* GPR registers. */ 8902 case 0: 8903 gen_helper_1e0i(mftgpr, t0, rt); 8904 break; 8905 /* Auxiliary CPU registers */ 8906 case 1: 8907 switch (rt) { 8908 case 0: 8909 gen_helper_1e0i(mftlo, t0, 0); 8910 break; 8911 case 1: 8912 gen_helper_1e0i(mfthi, t0, 0); 8913 break; 8914 case 2: 8915 gen_helper_1e0i(mftacx, t0, 0); 8916 break; 8917 case 4: 8918 gen_helper_1e0i(mftlo, t0, 1); 8919 break; 8920 case 5: 8921 gen_helper_1e0i(mfthi, t0, 1); 8922 break; 8923 case 6: 8924 gen_helper_1e0i(mftacx, t0, 1); 8925 break; 8926 case 8: 8927 gen_helper_1e0i(mftlo, t0, 2); 8928 break; 8929 case 9: 8930 gen_helper_1e0i(mfthi, t0, 2); 8931 break; 8932 case 10: 8933 gen_helper_1e0i(mftacx, t0, 2); 8934 break; 8935 case 12: 8936 gen_helper_1e0i(mftlo, t0, 3); 8937 break; 8938 case 13: 8939 gen_helper_1e0i(mfthi, t0, 3); 8940 break; 8941 case 14: 8942 gen_helper_1e0i(mftacx, t0, 3); 8943 break; 8944 case 16: 8945 gen_helper_mftdsp(t0, cpu_env); 8946 break; 8947 default: 8948 goto die; 8949 } 8950 break; 8951 /* Floating point (COP1). */ 8952 case 2: 8953 /* XXX: For now we support only a single FPU context. */ 8954 if (h == 0) { 8955 TCGv_i32 fp0 = tcg_temp_new_i32(); 8956 8957 gen_load_fpr32(ctx, fp0, rt); 8958 tcg_gen_ext_i32_tl(t0, fp0); 8959 tcg_temp_free_i32(fp0); 8960 } else { 8961 TCGv_i32 fp0 = tcg_temp_new_i32(); 8962 8963 gen_load_fpr32h(ctx, fp0, rt); 8964 tcg_gen_ext_i32_tl(t0, fp0); 8965 tcg_temp_free_i32(fp0); 8966 } 8967 break; 8968 case 3: 8969 /* XXX: For now we support only a single FPU context. */ 8970 gen_helper_1e0i(cfc1, t0, rt); 8971 break; 8972 /* COP2: Not implemented. */ 8973 case 4: 8974 case 5: 8975 /* fall through */ 8976 default: 8977 goto die; 8978 } 8979 } 8980 trace_mips_translate_tr("mftr", rt, u, sel, h); 8981 gen_store_gpr(t0, rd); 8982 tcg_temp_free(t0); 8983 return; 8984 8985 die: 8986 tcg_temp_free(t0); 8987 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h); 8988 gen_reserved_instruction(ctx); 8989 } 8990 8991 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, 8992 int u, int sel, int h) 8993 { 8994 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); 8995 TCGv t0 = tcg_temp_local_new(); 8996 8997 gen_load_gpr(t0, rt); 8998 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && 8999 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) != 9000 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) { 9001 /* NOP */ 9002 ; 9003 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > 9004 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) { 9005 /* NOP */ 9006 ; 9007 } else if (u == 0) { 9008 switch (rd) { 9009 case 1: 9010 switch (sel) { 9011 case 1: 9012 gen_helper_mttc0_vpecontrol(cpu_env, t0); 9013 break; 9014 case 2: 9015 gen_helper_mttc0_vpeconf0(cpu_env, t0); 9016 break; 9017 default: 9018 goto die; 9019 break; 9020 } 9021 break; 9022 case 2: 9023 switch (sel) { 9024 case 1: 9025 gen_helper_mttc0_tcstatus(cpu_env, t0); 9026 break; 9027 case 2: 9028 gen_helper_mttc0_tcbind(cpu_env, t0); 9029 break; 9030 case 3: 9031 gen_helper_mttc0_tcrestart(cpu_env, t0); 9032 break; 9033 case 4: 9034 gen_helper_mttc0_tchalt(cpu_env, t0); 9035 break; 9036 case 5: 9037 gen_helper_mttc0_tccontext(cpu_env, t0); 9038 break; 9039 case 6: 9040 gen_helper_mttc0_tcschedule(cpu_env, t0); 9041 break; 9042 case 7: 9043 gen_helper_mttc0_tcschefback(cpu_env, t0); 9044 break; 9045 default: 9046 gen_mtc0(ctx, t0, rd, sel); 9047 break; 9048 } 9049 break; 9050 case 10: 9051 switch (sel) { 9052 case 0: 9053 gen_helper_mttc0_entryhi(cpu_env, t0); 9054 break; 9055 default: 9056 gen_mtc0(ctx, t0, rd, sel); 9057 break; 9058 } 9059 break; 9060 case 12: 9061 switch (sel) { 9062 case 0: 9063 gen_helper_mttc0_status(cpu_env, t0); 9064 break; 9065 default: 9066 gen_mtc0(ctx, t0, rd, sel); 9067 break; 9068 } 9069 break; 9070 case 13: 9071 switch (sel) { 9072 case 0: 9073 gen_helper_mttc0_cause(cpu_env, t0); 9074 break; 9075 default: 9076 goto die; 9077 break; 9078 } 9079 break; 9080 case 15: 9081 switch (sel) { 9082 case 1: 9083 gen_helper_mttc0_ebase(cpu_env, t0); 9084 break; 9085 default: 9086 goto die; 9087 break; 9088 } 9089 break; 9090 case 23: 9091 switch (sel) { 9092 case 0: 9093 gen_helper_mttc0_debug(cpu_env, t0); 9094 break; 9095 default: 9096 gen_mtc0(ctx, t0, rd, sel); 9097 break; 9098 } 9099 break; 9100 default: 9101 gen_mtc0(ctx, t0, rd, sel); 9102 } 9103 } else { 9104 switch (sel) { 9105 /* GPR registers. */ 9106 case 0: 9107 gen_helper_0e1i(mttgpr, t0, rd); 9108 break; 9109 /* Auxiliary CPU registers */ 9110 case 1: 9111 switch (rd) { 9112 case 0: 9113 gen_helper_0e1i(mttlo, t0, 0); 9114 break; 9115 case 1: 9116 gen_helper_0e1i(mtthi, t0, 0); 9117 break; 9118 case 2: 9119 gen_helper_0e1i(mttacx, t0, 0); 9120 break; 9121 case 4: 9122 gen_helper_0e1i(mttlo, t0, 1); 9123 break; 9124 case 5: 9125 gen_helper_0e1i(mtthi, t0, 1); 9126 break; 9127 case 6: 9128 gen_helper_0e1i(mttacx, t0, 1); 9129 break; 9130 case 8: 9131 gen_helper_0e1i(mttlo, t0, 2); 9132 break; 9133 case 9: 9134 gen_helper_0e1i(mtthi, t0, 2); 9135 break; 9136 case 10: 9137 gen_helper_0e1i(mttacx, t0, 2); 9138 break; 9139 case 12: 9140 gen_helper_0e1i(mttlo, t0, 3); 9141 break; 9142 case 13: 9143 gen_helper_0e1i(mtthi, t0, 3); 9144 break; 9145 case 14: 9146 gen_helper_0e1i(mttacx, t0, 3); 9147 break; 9148 case 16: 9149 gen_helper_mttdsp(cpu_env, t0); 9150 break; 9151 default: 9152 goto die; 9153 } 9154 break; 9155 /* Floating point (COP1). */ 9156 case 2: 9157 /* XXX: For now we support only a single FPU context. */ 9158 if (h == 0) { 9159 TCGv_i32 fp0 = tcg_temp_new_i32(); 9160 9161 tcg_gen_trunc_tl_i32(fp0, t0); 9162 gen_store_fpr32(ctx, fp0, rd); 9163 tcg_temp_free_i32(fp0); 9164 } else { 9165 TCGv_i32 fp0 = tcg_temp_new_i32(); 9166 9167 tcg_gen_trunc_tl_i32(fp0, t0); 9168 gen_store_fpr32h(ctx, fp0, rd); 9169 tcg_temp_free_i32(fp0); 9170 } 9171 break; 9172 case 3: 9173 /* XXX: For now we support only a single FPU context. */ 9174 { 9175 TCGv_i32 fs_tmp = tcg_const_i32(rd); 9176 9177 gen_helper_0e2i(ctc1, t0, fs_tmp, rt); 9178 tcg_temp_free_i32(fs_tmp); 9179 } 9180 /* Stop translation as we may have changed hflags */ 9181 ctx->base.is_jmp = DISAS_STOP; 9182 break; 9183 /* COP2: Not implemented. */ 9184 case 4: 9185 case 5: 9186 /* fall through */ 9187 default: 9188 goto die; 9189 } 9190 } 9191 trace_mips_translate_tr("mttr", rd, u, sel, h); 9192 tcg_temp_free(t0); 9193 return; 9194 9195 die: 9196 tcg_temp_free(t0); 9197 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h); 9198 gen_reserved_instruction(ctx); 9199 } 9200 9201 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc, 9202 int rt, int rd) 9203 { 9204 const char *opn = "ldst"; 9205 9206 check_cp0_enabled(ctx); 9207 switch (opc) { 9208 case OPC_MFC0: 9209 if (rt == 0) { 9210 /* Treat as NOP. */ 9211 return; 9212 } 9213 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9214 opn = "mfc0"; 9215 break; 9216 case OPC_MTC0: 9217 { 9218 TCGv t0 = tcg_temp_new(); 9219 9220 gen_load_gpr(t0, rt); 9221 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7); 9222 tcg_temp_free(t0); 9223 } 9224 opn = "mtc0"; 9225 break; 9226 #if defined(TARGET_MIPS64) 9227 case OPC_DMFC0: 9228 check_insn(ctx, ISA_MIPS3); 9229 if (rt == 0) { 9230 /* Treat as NOP. */ 9231 return; 9232 } 9233 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9234 opn = "dmfc0"; 9235 break; 9236 case OPC_DMTC0: 9237 check_insn(ctx, ISA_MIPS3); 9238 { 9239 TCGv t0 = tcg_temp_new(); 9240 9241 gen_load_gpr(t0, rt); 9242 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7); 9243 tcg_temp_free(t0); 9244 } 9245 opn = "dmtc0"; 9246 break; 9247 #endif 9248 case OPC_MFHC0: 9249 check_mvh(ctx); 9250 if (rt == 0) { 9251 /* Treat as NOP. */ 9252 return; 9253 } 9254 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7); 9255 opn = "mfhc0"; 9256 break; 9257 case OPC_MTHC0: 9258 check_mvh(ctx); 9259 { 9260 TCGv t0 = tcg_temp_new(); 9261 gen_load_gpr(t0, rt); 9262 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7); 9263 tcg_temp_free(t0); 9264 } 9265 opn = "mthc0"; 9266 break; 9267 case OPC_MFTR: 9268 check_cp0_enabled(ctx); 9269 if (rd == 0) { 9270 /* Treat as NOP. */ 9271 return; 9272 } 9273 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, 9274 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 9275 opn = "mftr"; 9276 break; 9277 case OPC_MTTR: 9278 check_cp0_enabled(ctx); 9279 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, 9280 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); 9281 opn = "mttr"; 9282 break; 9283 case OPC_TLBWI: 9284 opn = "tlbwi"; 9285 if (!env->tlb->helper_tlbwi) { 9286 goto die; 9287 } 9288 gen_helper_tlbwi(cpu_env); 9289 break; 9290 case OPC_TLBINV: 9291 opn = "tlbinv"; 9292 if (ctx->ie >= 2) { 9293 if (!env->tlb->helper_tlbinv) { 9294 goto die; 9295 } 9296 gen_helper_tlbinv(cpu_env); 9297 } /* treat as nop if TLBINV not supported */ 9298 break; 9299 case OPC_TLBINVF: 9300 opn = "tlbinvf"; 9301 if (ctx->ie >= 2) { 9302 if (!env->tlb->helper_tlbinvf) { 9303 goto die; 9304 } 9305 gen_helper_tlbinvf(cpu_env); 9306 } /* treat as nop if TLBINV not supported */ 9307 break; 9308 case OPC_TLBWR: 9309 opn = "tlbwr"; 9310 if (!env->tlb->helper_tlbwr) { 9311 goto die; 9312 } 9313 gen_helper_tlbwr(cpu_env); 9314 break; 9315 case OPC_TLBP: 9316 opn = "tlbp"; 9317 if (!env->tlb->helper_tlbp) { 9318 goto die; 9319 } 9320 gen_helper_tlbp(cpu_env); 9321 break; 9322 case OPC_TLBR: 9323 opn = "tlbr"; 9324 if (!env->tlb->helper_tlbr) { 9325 goto die; 9326 } 9327 gen_helper_tlbr(cpu_env); 9328 break; 9329 case OPC_ERET: /* OPC_ERETNC */ 9330 if ((ctx->insn_flags & ISA_MIPS_R6) && 9331 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9332 goto die; 9333 } else { 9334 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6; 9335 if (ctx->opcode & (1 << bit_shift)) { 9336 /* OPC_ERETNC */ 9337 opn = "eretnc"; 9338 check_insn(ctx, ISA_MIPS_R5); 9339 gen_helper_eretnc(cpu_env); 9340 } else { 9341 /* OPC_ERET */ 9342 opn = "eret"; 9343 check_insn(ctx, ISA_MIPS2); 9344 gen_helper_eret(cpu_env); 9345 } 9346 ctx->base.is_jmp = DISAS_EXIT; 9347 } 9348 break; 9349 case OPC_DERET: 9350 opn = "deret"; 9351 check_insn(ctx, ISA_MIPS_R1); 9352 if ((ctx->insn_flags & ISA_MIPS_R6) && 9353 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9354 goto die; 9355 } 9356 if (!(ctx->hflags & MIPS_HFLAG_DM)) { 9357 MIPS_INVAL(opn); 9358 gen_reserved_instruction(ctx); 9359 } else { 9360 gen_helper_deret(cpu_env); 9361 ctx->base.is_jmp = DISAS_EXIT; 9362 } 9363 break; 9364 case OPC_WAIT: 9365 opn = "wait"; 9366 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 9367 if ((ctx->insn_flags & ISA_MIPS_R6) && 9368 (ctx->hflags & MIPS_HFLAG_BMASK)) { 9369 goto die; 9370 } 9371 /* If we get an exception, we want to restart at next instruction */ 9372 ctx->base.pc_next += 4; 9373 save_cpu_state(ctx, 1); 9374 ctx->base.pc_next -= 4; 9375 gen_helper_wait(cpu_env); 9376 ctx->base.is_jmp = DISAS_NORETURN; 9377 break; 9378 default: 9379 die: 9380 MIPS_INVAL(opn); 9381 gen_reserved_instruction(ctx); 9382 return; 9383 } 9384 (void)opn; /* avoid a compiler warning */ 9385 } 9386 #endif /* !CONFIG_USER_ONLY */ 9387 9388 /* CP1 Branches (before delay slot) */ 9389 static void gen_compute_branch1(DisasContext *ctx, uint32_t op, 9390 int32_t cc, int32_t offset) 9391 { 9392 target_ulong btarget; 9393 TCGv_i32 t0 = tcg_temp_new_i32(); 9394 9395 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) { 9396 gen_reserved_instruction(ctx); 9397 goto out; 9398 } 9399 9400 if (cc != 0) { 9401 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 9402 } 9403 9404 btarget = ctx->base.pc_next + 4 + offset; 9405 9406 switch (op) { 9407 case OPC_BC1F: 9408 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9409 tcg_gen_not_i32(t0, t0); 9410 tcg_gen_andi_i32(t0, t0, 1); 9411 tcg_gen_extu_i32_tl(bcond, t0); 9412 goto not_likely; 9413 case OPC_BC1FL: 9414 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9415 tcg_gen_not_i32(t0, t0); 9416 tcg_gen_andi_i32(t0, t0, 1); 9417 tcg_gen_extu_i32_tl(bcond, t0); 9418 goto likely; 9419 case OPC_BC1T: 9420 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9421 tcg_gen_andi_i32(t0, t0, 1); 9422 tcg_gen_extu_i32_tl(bcond, t0); 9423 goto not_likely; 9424 case OPC_BC1TL: 9425 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9426 tcg_gen_andi_i32(t0, t0, 1); 9427 tcg_gen_extu_i32_tl(bcond, t0); 9428 likely: 9429 ctx->hflags |= MIPS_HFLAG_BL; 9430 break; 9431 case OPC_BC1FANY2: 9432 { 9433 TCGv_i32 t1 = tcg_temp_new_i32(); 9434 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9435 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9436 tcg_gen_nand_i32(t0, t0, t1); 9437 tcg_temp_free_i32(t1); 9438 tcg_gen_andi_i32(t0, t0, 1); 9439 tcg_gen_extu_i32_tl(bcond, t0); 9440 } 9441 goto not_likely; 9442 case OPC_BC1TANY2: 9443 { 9444 TCGv_i32 t1 = tcg_temp_new_i32(); 9445 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9446 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9447 tcg_gen_or_i32(t0, t0, t1); 9448 tcg_temp_free_i32(t1); 9449 tcg_gen_andi_i32(t0, t0, 1); 9450 tcg_gen_extu_i32_tl(bcond, t0); 9451 } 9452 goto not_likely; 9453 case OPC_BC1FANY4: 9454 { 9455 TCGv_i32 t1 = tcg_temp_new_i32(); 9456 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9457 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9458 tcg_gen_and_i32(t0, t0, t1); 9459 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 9460 tcg_gen_and_i32(t0, t0, t1); 9461 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 9462 tcg_gen_nand_i32(t0, t0, t1); 9463 tcg_temp_free_i32(t1); 9464 tcg_gen_andi_i32(t0, t0, 1); 9465 tcg_gen_extu_i32_tl(bcond, t0); 9466 } 9467 goto not_likely; 9468 case OPC_BC1TANY4: 9469 { 9470 TCGv_i32 t1 = tcg_temp_new_i32(); 9471 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); 9472 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1)); 9473 tcg_gen_or_i32(t0, t0, t1); 9474 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2)); 9475 tcg_gen_or_i32(t0, t0, t1); 9476 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3)); 9477 tcg_gen_or_i32(t0, t0, t1); 9478 tcg_temp_free_i32(t1); 9479 tcg_gen_andi_i32(t0, t0, 1); 9480 tcg_gen_extu_i32_tl(bcond, t0); 9481 } 9482 not_likely: 9483 ctx->hflags |= MIPS_HFLAG_BC; 9484 break; 9485 default: 9486 MIPS_INVAL("cp1 cond branch"); 9487 gen_reserved_instruction(ctx); 9488 goto out; 9489 } 9490 ctx->btarget = btarget; 9491 ctx->hflags |= MIPS_HFLAG_BDS32; 9492 out: 9493 tcg_temp_free_i32(t0); 9494 } 9495 9496 /* R6 CP1 Branches */ 9497 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op, 9498 int32_t ft, int32_t offset, 9499 int delayslot_size) 9500 { 9501 target_ulong btarget; 9502 TCGv_i64 t0 = tcg_temp_new_i64(); 9503 9504 if (ctx->hflags & MIPS_HFLAG_BMASK) { 9505 #ifdef MIPS_DEBUG_DISAS 9506 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx 9507 "\n", ctx->base.pc_next); 9508 #endif 9509 gen_reserved_instruction(ctx); 9510 goto out; 9511 } 9512 9513 gen_load_fpr64(ctx, t0, ft); 9514 tcg_gen_andi_i64(t0, t0, 1); 9515 9516 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 9517 9518 switch (op) { 9519 case OPC_BC1EQZ: 9520 tcg_gen_xori_i64(t0, t0, 1); 9521 ctx->hflags |= MIPS_HFLAG_BC; 9522 break; 9523 case OPC_BC1NEZ: 9524 /* t0 already set */ 9525 ctx->hflags |= MIPS_HFLAG_BC; 9526 break; 9527 default: 9528 MIPS_INVAL("cp1 cond branch"); 9529 gen_reserved_instruction(ctx); 9530 goto out; 9531 } 9532 9533 tcg_gen_trunc_i64_tl(bcond, t0); 9534 9535 ctx->btarget = btarget; 9536 9537 switch (delayslot_size) { 9538 case 2: 9539 ctx->hflags |= MIPS_HFLAG_BDS16; 9540 break; 9541 case 4: 9542 ctx->hflags |= MIPS_HFLAG_BDS32; 9543 break; 9544 } 9545 9546 out: 9547 tcg_temp_free_i64(t0); 9548 } 9549 9550 /* Coprocessor 1 (FPU) */ 9551 9552 #define FOP(func, fmt) (((fmt) << 21) | (func)) 9553 9554 enum fopcode { 9555 OPC_ADD_S = FOP(0, FMT_S), 9556 OPC_SUB_S = FOP(1, FMT_S), 9557 OPC_MUL_S = FOP(2, FMT_S), 9558 OPC_DIV_S = FOP(3, FMT_S), 9559 OPC_SQRT_S = FOP(4, FMT_S), 9560 OPC_ABS_S = FOP(5, FMT_S), 9561 OPC_MOV_S = FOP(6, FMT_S), 9562 OPC_NEG_S = FOP(7, FMT_S), 9563 OPC_ROUND_L_S = FOP(8, FMT_S), 9564 OPC_TRUNC_L_S = FOP(9, FMT_S), 9565 OPC_CEIL_L_S = FOP(10, FMT_S), 9566 OPC_FLOOR_L_S = FOP(11, FMT_S), 9567 OPC_ROUND_W_S = FOP(12, FMT_S), 9568 OPC_TRUNC_W_S = FOP(13, FMT_S), 9569 OPC_CEIL_W_S = FOP(14, FMT_S), 9570 OPC_FLOOR_W_S = FOP(15, FMT_S), 9571 OPC_SEL_S = FOP(16, FMT_S), 9572 OPC_MOVCF_S = FOP(17, FMT_S), 9573 OPC_MOVZ_S = FOP(18, FMT_S), 9574 OPC_MOVN_S = FOP(19, FMT_S), 9575 OPC_SELEQZ_S = FOP(20, FMT_S), 9576 OPC_RECIP_S = FOP(21, FMT_S), 9577 OPC_RSQRT_S = FOP(22, FMT_S), 9578 OPC_SELNEZ_S = FOP(23, FMT_S), 9579 OPC_MADDF_S = FOP(24, FMT_S), 9580 OPC_MSUBF_S = FOP(25, FMT_S), 9581 OPC_RINT_S = FOP(26, FMT_S), 9582 OPC_CLASS_S = FOP(27, FMT_S), 9583 OPC_MIN_S = FOP(28, FMT_S), 9584 OPC_RECIP2_S = FOP(28, FMT_S), 9585 OPC_MINA_S = FOP(29, FMT_S), 9586 OPC_RECIP1_S = FOP(29, FMT_S), 9587 OPC_MAX_S = FOP(30, FMT_S), 9588 OPC_RSQRT1_S = FOP(30, FMT_S), 9589 OPC_MAXA_S = FOP(31, FMT_S), 9590 OPC_RSQRT2_S = FOP(31, FMT_S), 9591 OPC_CVT_D_S = FOP(33, FMT_S), 9592 OPC_CVT_W_S = FOP(36, FMT_S), 9593 OPC_CVT_L_S = FOP(37, FMT_S), 9594 OPC_CVT_PS_S = FOP(38, FMT_S), 9595 OPC_CMP_F_S = FOP(48, FMT_S), 9596 OPC_CMP_UN_S = FOP(49, FMT_S), 9597 OPC_CMP_EQ_S = FOP(50, FMT_S), 9598 OPC_CMP_UEQ_S = FOP(51, FMT_S), 9599 OPC_CMP_OLT_S = FOP(52, FMT_S), 9600 OPC_CMP_ULT_S = FOP(53, FMT_S), 9601 OPC_CMP_OLE_S = FOP(54, FMT_S), 9602 OPC_CMP_ULE_S = FOP(55, FMT_S), 9603 OPC_CMP_SF_S = FOP(56, FMT_S), 9604 OPC_CMP_NGLE_S = FOP(57, FMT_S), 9605 OPC_CMP_SEQ_S = FOP(58, FMT_S), 9606 OPC_CMP_NGL_S = FOP(59, FMT_S), 9607 OPC_CMP_LT_S = FOP(60, FMT_S), 9608 OPC_CMP_NGE_S = FOP(61, FMT_S), 9609 OPC_CMP_LE_S = FOP(62, FMT_S), 9610 OPC_CMP_NGT_S = FOP(63, FMT_S), 9611 9612 OPC_ADD_D = FOP(0, FMT_D), 9613 OPC_SUB_D = FOP(1, FMT_D), 9614 OPC_MUL_D = FOP(2, FMT_D), 9615 OPC_DIV_D = FOP(3, FMT_D), 9616 OPC_SQRT_D = FOP(4, FMT_D), 9617 OPC_ABS_D = FOP(5, FMT_D), 9618 OPC_MOV_D = FOP(6, FMT_D), 9619 OPC_NEG_D = FOP(7, FMT_D), 9620 OPC_ROUND_L_D = FOP(8, FMT_D), 9621 OPC_TRUNC_L_D = FOP(9, FMT_D), 9622 OPC_CEIL_L_D = FOP(10, FMT_D), 9623 OPC_FLOOR_L_D = FOP(11, FMT_D), 9624 OPC_ROUND_W_D = FOP(12, FMT_D), 9625 OPC_TRUNC_W_D = FOP(13, FMT_D), 9626 OPC_CEIL_W_D = FOP(14, FMT_D), 9627 OPC_FLOOR_W_D = FOP(15, FMT_D), 9628 OPC_SEL_D = FOP(16, FMT_D), 9629 OPC_MOVCF_D = FOP(17, FMT_D), 9630 OPC_MOVZ_D = FOP(18, FMT_D), 9631 OPC_MOVN_D = FOP(19, FMT_D), 9632 OPC_SELEQZ_D = FOP(20, FMT_D), 9633 OPC_RECIP_D = FOP(21, FMT_D), 9634 OPC_RSQRT_D = FOP(22, FMT_D), 9635 OPC_SELNEZ_D = FOP(23, FMT_D), 9636 OPC_MADDF_D = FOP(24, FMT_D), 9637 OPC_MSUBF_D = FOP(25, FMT_D), 9638 OPC_RINT_D = FOP(26, FMT_D), 9639 OPC_CLASS_D = FOP(27, FMT_D), 9640 OPC_MIN_D = FOP(28, FMT_D), 9641 OPC_RECIP2_D = FOP(28, FMT_D), 9642 OPC_MINA_D = FOP(29, FMT_D), 9643 OPC_RECIP1_D = FOP(29, FMT_D), 9644 OPC_MAX_D = FOP(30, FMT_D), 9645 OPC_RSQRT1_D = FOP(30, FMT_D), 9646 OPC_MAXA_D = FOP(31, FMT_D), 9647 OPC_RSQRT2_D = FOP(31, FMT_D), 9648 OPC_CVT_S_D = FOP(32, FMT_D), 9649 OPC_CVT_W_D = FOP(36, FMT_D), 9650 OPC_CVT_L_D = FOP(37, FMT_D), 9651 OPC_CMP_F_D = FOP(48, FMT_D), 9652 OPC_CMP_UN_D = FOP(49, FMT_D), 9653 OPC_CMP_EQ_D = FOP(50, FMT_D), 9654 OPC_CMP_UEQ_D = FOP(51, FMT_D), 9655 OPC_CMP_OLT_D = FOP(52, FMT_D), 9656 OPC_CMP_ULT_D = FOP(53, FMT_D), 9657 OPC_CMP_OLE_D = FOP(54, FMT_D), 9658 OPC_CMP_ULE_D = FOP(55, FMT_D), 9659 OPC_CMP_SF_D = FOP(56, FMT_D), 9660 OPC_CMP_NGLE_D = FOP(57, FMT_D), 9661 OPC_CMP_SEQ_D = FOP(58, FMT_D), 9662 OPC_CMP_NGL_D = FOP(59, FMT_D), 9663 OPC_CMP_LT_D = FOP(60, FMT_D), 9664 OPC_CMP_NGE_D = FOP(61, FMT_D), 9665 OPC_CMP_LE_D = FOP(62, FMT_D), 9666 OPC_CMP_NGT_D = FOP(63, FMT_D), 9667 9668 OPC_CVT_S_W = FOP(32, FMT_W), 9669 OPC_CVT_D_W = FOP(33, FMT_W), 9670 OPC_CVT_S_L = FOP(32, FMT_L), 9671 OPC_CVT_D_L = FOP(33, FMT_L), 9672 OPC_CVT_PS_PW = FOP(38, FMT_W), 9673 9674 OPC_ADD_PS = FOP(0, FMT_PS), 9675 OPC_SUB_PS = FOP(1, FMT_PS), 9676 OPC_MUL_PS = FOP(2, FMT_PS), 9677 OPC_DIV_PS = FOP(3, FMT_PS), 9678 OPC_ABS_PS = FOP(5, FMT_PS), 9679 OPC_MOV_PS = FOP(6, FMT_PS), 9680 OPC_NEG_PS = FOP(7, FMT_PS), 9681 OPC_MOVCF_PS = FOP(17, FMT_PS), 9682 OPC_MOVZ_PS = FOP(18, FMT_PS), 9683 OPC_MOVN_PS = FOP(19, FMT_PS), 9684 OPC_ADDR_PS = FOP(24, FMT_PS), 9685 OPC_MULR_PS = FOP(26, FMT_PS), 9686 OPC_RECIP2_PS = FOP(28, FMT_PS), 9687 OPC_RECIP1_PS = FOP(29, FMT_PS), 9688 OPC_RSQRT1_PS = FOP(30, FMT_PS), 9689 OPC_RSQRT2_PS = FOP(31, FMT_PS), 9690 9691 OPC_CVT_S_PU = FOP(32, FMT_PS), 9692 OPC_CVT_PW_PS = FOP(36, FMT_PS), 9693 OPC_CVT_S_PL = FOP(40, FMT_PS), 9694 OPC_PLL_PS = FOP(44, FMT_PS), 9695 OPC_PLU_PS = FOP(45, FMT_PS), 9696 OPC_PUL_PS = FOP(46, FMT_PS), 9697 OPC_PUU_PS = FOP(47, FMT_PS), 9698 OPC_CMP_F_PS = FOP(48, FMT_PS), 9699 OPC_CMP_UN_PS = FOP(49, FMT_PS), 9700 OPC_CMP_EQ_PS = FOP(50, FMT_PS), 9701 OPC_CMP_UEQ_PS = FOP(51, FMT_PS), 9702 OPC_CMP_OLT_PS = FOP(52, FMT_PS), 9703 OPC_CMP_ULT_PS = FOP(53, FMT_PS), 9704 OPC_CMP_OLE_PS = FOP(54, FMT_PS), 9705 OPC_CMP_ULE_PS = FOP(55, FMT_PS), 9706 OPC_CMP_SF_PS = FOP(56, FMT_PS), 9707 OPC_CMP_NGLE_PS = FOP(57, FMT_PS), 9708 OPC_CMP_SEQ_PS = FOP(58, FMT_PS), 9709 OPC_CMP_NGL_PS = FOP(59, FMT_PS), 9710 OPC_CMP_LT_PS = FOP(60, FMT_PS), 9711 OPC_CMP_NGE_PS = FOP(61, FMT_PS), 9712 OPC_CMP_LE_PS = FOP(62, FMT_PS), 9713 OPC_CMP_NGT_PS = FOP(63, FMT_PS), 9714 }; 9715 9716 enum r6_f_cmp_op { 9717 R6_OPC_CMP_AF_S = FOP(0, FMT_W), 9718 R6_OPC_CMP_UN_S = FOP(1, FMT_W), 9719 R6_OPC_CMP_EQ_S = FOP(2, FMT_W), 9720 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W), 9721 R6_OPC_CMP_LT_S = FOP(4, FMT_W), 9722 R6_OPC_CMP_ULT_S = FOP(5, FMT_W), 9723 R6_OPC_CMP_LE_S = FOP(6, FMT_W), 9724 R6_OPC_CMP_ULE_S = FOP(7, FMT_W), 9725 R6_OPC_CMP_SAF_S = FOP(8, FMT_W), 9726 R6_OPC_CMP_SUN_S = FOP(9, FMT_W), 9727 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W), 9728 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W), 9729 R6_OPC_CMP_SLT_S = FOP(12, FMT_W), 9730 R6_OPC_CMP_SULT_S = FOP(13, FMT_W), 9731 R6_OPC_CMP_SLE_S = FOP(14, FMT_W), 9732 R6_OPC_CMP_SULE_S = FOP(15, FMT_W), 9733 R6_OPC_CMP_OR_S = FOP(17, FMT_W), 9734 R6_OPC_CMP_UNE_S = FOP(18, FMT_W), 9735 R6_OPC_CMP_NE_S = FOP(19, FMT_W), 9736 R6_OPC_CMP_SOR_S = FOP(25, FMT_W), 9737 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W), 9738 R6_OPC_CMP_SNE_S = FOP(27, FMT_W), 9739 9740 R6_OPC_CMP_AF_D = FOP(0, FMT_L), 9741 R6_OPC_CMP_UN_D = FOP(1, FMT_L), 9742 R6_OPC_CMP_EQ_D = FOP(2, FMT_L), 9743 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L), 9744 R6_OPC_CMP_LT_D = FOP(4, FMT_L), 9745 R6_OPC_CMP_ULT_D = FOP(5, FMT_L), 9746 R6_OPC_CMP_LE_D = FOP(6, FMT_L), 9747 R6_OPC_CMP_ULE_D = FOP(7, FMT_L), 9748 R6_OPC_CMP_SAF_D = FOP(8, FMT_L), 9749 R6_OPC_CMP_SUN_D = FOP(9, FMT_L), 9750 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L), 9751 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L), 9752 R6_OPC_CMP_SLT_D = FOP(12, FMT_L), 9753 R6_OPC_CMP_SULT_D = FOP(13, FMT_L), 9754 R6_OPC_CMP_SLE_D = FOP(14, FMT_L), 9755 R6_OPC_CMP_SULE_D = FOP(15, FMT_L), 9756 R6_OPC_CMP_OR_D = FOP(17, FMT_L), 9757 R6_OPC_CMP_UNE_D = FOP(18, FMT_L), 9758 R6_OPC_CMP_NE_D = FOP(19, FMT_L), 9759 R6_OPC_CMP_SOR_D = FOP(25, FMT_L), 9760 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L), 9761 R6_OPC_CMP_SNE_D = FOP(27, FMT_L), 9762 }; 9763 9764 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) 9765 { 9766 TCGv t0 = tcg_temp_new(); 9767 9768 switch (opc) { 9769 case OPC_MFC1: 9770 { 9771 TCGv_i32 fp0 = tcg_temp_new_i32(); 9772 9773 gen_load_fpr32(ctx, fp0, fs); 9774 tcg_gen_ext_i32_tl(t0, fp0); 9775 tcg_temp_free_i32(fp0); 9776 } 9777 gen_store_gpr(t0, rt); 9778 break; 9779 case OPC_MTC1: 9780 gen_load_gpr(t0, rt); 9781 { 9782 TCGv_i32 fp0 = tcg_temp_new_i32(); 9783 9784 tcg_gen_trunc_tl_i32(fp0, t0); 9785 gen_store_fpr32(ctx, fp0, fs); 9786 tcg_temp_free_i32(fp0); 9787 } 9788 break; 9789 case OPC_CFC1: 9790 gen_helper_1e0i(cfc1, t0, fs); 9791 gen_store_gpr(t0, rt); 9792 break; 9793 case OPC_CTC1: 9794 gen_load_gpr(t0, rt); 9795 save_cpu_state(ctx, 0); 9796 { 9797 TCGv_i32 fs_tmp = tcg_const_i32(fs); 9798 9799 gen_helper_0e2i(ctc1, t0, fs_tmp, rt); 9800 tcg_temp_free_i32(fs_tmp); 9801 } 9802 /* Stop translation as we may have changed hflags */ 9803 ctx->base.is_jmp = DISAS_STOP; 9804 break; 9805 #if defined(TARGET_MIPS64) 9806 case OPC_DMFC1: 9807 gen_load_fpr64(ctx, t0, fs); 9808 gen_store_gpr(t0, rt); 9809 break; 9810 case OPC_DMTC1: 9811 gen_load_gpr(t0, rt); 9812 gen_store_fpr64(ctx, t0, fs); 9813 break; 9814 #endif 9815 case OPC_MFHC1: 9816 { 9817 TCGv_i32 fp0 = tcg_temp_new_i32(); 9818 9819 gen_load_fpr32h(ctx, fp0, fs); 9820 tcg_gen_ext_i32_tl(t0, fp0); 9821 tcg_temp_free_i32(fp0); 9822 } 9823 gen_store_gpr(t0, rt); 9824 break; 9825 case OPC_MTHC1: 9826 gen_load_gpr(t0, rt); 9827 { 9828 TCGv_i32 fp0 = tcg_temp_new_i32(); 9829 9830 tcg_gen_trunc_tl_i32(fp0, t0); 9831 gen_store_fpr32h(ctx, fp0, fs); 9832 tcg_temp_free_i32(fp0); 9833 } 9834 break; 9835 default: 9836 MIPS_INVAL("cp1 move"); 9837 gen_reserved_instruction(ctx); 9838 goto out; 9839 } 9840 9841 out: 9842 tcg_temp_free(t0); 9843 } 9844 9845 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf) 9846 { 9847 TCGLabel *l1; 9848 TCGCond cond; 9849 TCGv_i32 t0; 9850 9851 if (rd == 0) { 9852 /* Treat as NOP. */ 9853 return; 9854 } 9855 9856 if (tf) { 9857 cond = TCG_COND_EQ; 9858 } else { 9859 cond = TCG_COND_NE; 9860 } 9861 9862 l1 = gen_new_label(); 9863 t0 = tcg_temp_new_i32(); 9864 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9865 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9866 tcg_temp_free_i32(t0); 9867 gen_load_gpr(cpu_gpr[rd], rs); 9868 gen_set_label(l1); 9869 } 9870 9871 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, 9872 int tf) 9873 { 9874 int cond; 9875 TCGv_i32 t0 = tcg_temp_new_i32(); 9876 TCGLabel *l1 = gen_new_label(); 9877 9878 if (tf) { 9879 cond = TCG_COND_EQ; 9880 } else { 9881 cond = TCG_COND_NE; 9882 } 9883 9884 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9885 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9886 gen_load_fpr32(ctx, t0, fs); 9887 gen_store_fpr32(ctx, t0, fd); 9888 gen_set_label(l1); 9889 tcg_temp_free_i32(t0); 9890 } 9891 9892 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, 9893 int tf) 9894 { 9895 int cond; 9896 TCGv_i32 t0 = tcg_temp_new_i32(); 9897 TCGv_i64 fp0; 9898 TCGLabel *l1 = gen_new_label(); 9899 9900 if (tf) { 9901 cond = TCG_COND_EQ; 9902 } else { 9903 cond = TCG_COND_NE; 9904 } 9905 9906 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9907 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9908 tcg_temp_free_i32(t0); 9909 fp0 = tcg_temp_new_i64(); 9910 gen_load_fpr64(ctx, fp0, fs); 9911 gen_store_fpr64(ctx, fp0, fd); 9912 tcg_temp_free_i64(fp0); 9913 gen_set_label(l1); 9914 } 9915 9916 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, 9917 int cc, int tf) 9918 { 9919 int cond; 9920 TCGv_i32 t0 = tcg_temp_new_i32(); 9921 TCGLabel *l1 = gen_new_label(); 9922 TCGLabel *l2 = gen_new_label(); 9923 9924 if (tf) { 9925 cond = TCG_COND_EQ; 9926 } else { 9927 cond = TCG_COND_NE; 9928 } 9929 9930 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); 9931 tcg_gen_brcondi_i32(cond, t0, 0, l1); 9932 gen_load_fpr32(ctx, t0, fs); 9933 gen_store_fpr32(ctx, t0, fd); 9934 gen_set_label(l1); 9935 9936 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1)); 9937 tcg_gen_brcondi_i32(cond, t0, 0, l2); 9938 gen_load_fpr32h(ctx, t0, fs); 9939 gen_store_fpr32h(ctx, t0, fd); 9940 tcg_temp_free_i32(t0); 9941 gen_set_label(l2); 9942 } 9943 9944 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9945 int fs) 9946 { 9947 TCGv_i32 t1 = tcg_const_i32(0); 9948 TCGv_i32 fp0 = tcg_temp_new_i32(); 9949 TCGv_i32 fp1 = tcg_temp_new_i32(); 9950 TCGv_i32 fp2 = tcg_temp_new_i32(); 9951 gen_load_fpr32(ctx, fp0, fd); 9952 gen_load_fpr32(ctx, fp1, ft); 9953 gen_load_fpr32(ctx, fp2, fs); 9954 9955 switch (op1) { 9956 case OPC_SEL_S: 9957 tcg_gen_andi_i32(fp0, fp0, 1); 9958 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9959 break; 9960 case OPC_SELEQZ_S: 9961 tcg_gen_andi_i32(fp1, fp1, 1); 9962 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 9963 break; 9964 case OPC_SELNEZ_S: 9965 tcg_gen_andi_i32(fp1, fp1, 1); 9966 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 9967 break; 9968 default: 9969 MIPS_INVAL("gen_sel_s"); 9970 gen_reserved_instruction(ctx); 9971 break; 9972 } 9973 9974 gen_store_fpr32(ctx, fp0, fd); 9975 tcg_temp_free_i32(fp2); 9976 tcg_temp_free_i32(fp1); 9977 tcg_temp_free_i32(fp0); 9978 tcg_temp_free_i32(t1); 9979 } 9980 9981 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft, 9982 int fs) 9983 { 9984 TCGv_i64 t1 = tcg_const_i64(0); 9985 TCGv_i64 fp0 = tcg_temp_new_i64(); 9986 TCGv_i64 fp1 = tcg_temp_new_i64(); 9987 TCGv_i64 fp2 = tcg_temp_new_i64(); 9988 gen_load_fpr64(ctx, fp0, fd); 9989 gen_load_fpr64(ctx, fp1, ft); 9990 gen_load_fpr64(ctx, fp2, fs); 9991 9992 switch (op1) { 9993 case OPC_SEL_D: 9994 tcg_gen_andi_i64(fp0, fp0, 1); 9995 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2); 9996 break; 9997 case OPC_SELEQZ_D: 9998 tcg_gen_andi_i64(fp1, fp1, 1); 9999 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1); 10000 break; 10001 case OPC_SELNEZ_D: 10002 tcg_gen_andi_i64(fp1, fp1, 1); 10003 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1); 10004 break; 10005 default: 10006 MIPS_INVAL("gen_sel_d"); 10007 gen_reserved_instruction(ctx); 10008 break; 10009 } 10010 10011 gen_store_fpr64(ctx, fp0, fd); 10012 tcg_temp_free_i64(fp2); 10013 tcg_temp_free_i64(fp1); 10014 tcg_temp_free_i64(fp0); 10015 tcg_temp_free_i64(t1); 10016 } 10017 10018 static void gen_farith(DisasContext *ctx, enum fopcode op1, 10019 int ft, int fs, int fd, int cc) 10020 { 10021 uint32_t func = ctx->opcode & 0x3f; 10022 switch (op1) { 10023 case OPC_ADD_S: 10024 { 10025 TCGv_i32 fp0 = tcg_temp_new_i32(); 10026 TCGv_i32 fp1 = tcg_temp_new_i32(); 10027 10028 gen_load_fpr32(ctx, fp0, fs); 10029 gen_load_fpr32(ctx, fp1, ft); 10030 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1); 10031 tcg_temp_free_i32(fp1); 10032 gen_store_fpr32(ctx, fp0, fd); 10033 tcg_temp_free_i32(fp0); 10034 } 10035 break; 10036 case OPC_SUB_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_sub_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_MUL_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_mul_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_DIV_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_div_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_SQRT_S: 10076 { 10077 TCGv_i32 fp0 = tcg_temp_new_i32(); 10078 10079 gen_load_fpr32(ctx, fp0, fs); 10080 gen_helper_float_sqrt_s(fp0, cpu_env, fp0); 10081 gen_store_fpr32(ctx, fp0, fd); 10082 tcg_temp_free_i32(fp0); 10083 } 10084 break; 10085 case OPC_ABS_S: 10086 { 10087 TCGv_i32 fp0 = tcg_temp_new_i32(); 10088 10089 gen_load_fpr32(ctx, fp0, fs); 10090 if (ctx->abs2008) { 10091 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL); 10092 } else { 10093 gen_helper_float_abs_s(fp0, fp0); 10094 } 10095 gen_store_fpr32(ctx, fp0, fd); 10096 tcg_temp_free_i32(fp0); 10097 } 10098 break; 10099 case OPC_MOV_S: 10100 { 10101 TCGv_i32 fp0 = tcg_temp_new_i32(); 10102 10103 gen_load_fpr32(ctx, fp0, fs); 10104 gen_store_fpr32(ctx, fp0, fd); 10105 tcg_temp_free_i32(fp0); 10106 } 10107 break; 10108 case OPC_NEG_S: 10109 { 10110 TCGv_i32 fp0 = tcg_temp_new_i32(); 10111 10112 gen_load_fpr32(ctx, fp0, fs); 10113 if (ctx->abs2008) { 10114 tcg_gen_xori_i32(fp0, fp0, 1UL << 31); 10115 } else { 10116 gen_helper_float_chs_s(fp0, fp0); 10117 } 10118 gen_store_fpr32(ctx, fp0, fd); 10119 tcg_temp_free_i32(fp0); 10120 } 10121 break; 10122 case OPC_ROUND_L_S: 10123 check_cp1_64bitmode(ctx); 10124 { 10125 TCGv_i32 fp32 = tcg_temp_new_i32(); 10126 TCGv_i64 fp64 = tcg_temp_new_i64(); 10127 10128 gen_load_fpr32(ctx, fp32, fs); 10129 if (ctx->nan2008) { 10130 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32); 10131 } else { 10132 gen_helper_float_round_l_s(fp64, cpu_env, fp32); 10133 } 10134 tcg_temp_free_i32(fp32); 10135 gen_store_fpr64(ctx, fp64, fd); 10136 tcg_temp_free_i64(fp64); 10137 } 10138 break; 10139 case OPC_TRUNC_L_S: 10140 check_cp1_64bitmode(ctx); 10141 { 10142 TCGv_i32 fp32 = tcg_temp_new_i32(); 10143 TCGv_i64 fp64 = tcg_temp_new_i64(); 10144 10145 gen_load_fpr32(ctx, fp32, fs); 10146 if (ctx->nan2008) { 10147 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32); 10148 } else { 10149 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32); 10150 } 10151 tcg_temp_free_i32(fp32); 10152 gen_store_fpr64(ctx, fp64, fd); 10153 tcg_temp_free_i64(fp64); 10154 } 10155 break; 10156 case OPC_CEIL_L_S: 10157 check_cp1_64bitmode(ctx); 10158 { 10159 TCGv_i32 fp32 = tcg_temp_new_i32(); 10160 TCGv_i64 fp64 = tcg_temp_new_i64(); 10161 10162 gen_load_fpr32(ctx, fp32, fs); 10163 if (ctx->nan2008) { 10164 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32); 10165 } else { 10166 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32); 10167 } 10168 tcg_temp_free_i32(fp32); 10169 gen_store_fpr64(ctx, fp64, fd); 10170 tcg_temp_free_i64(fp64); 10171 } 10172 break; 10173 case OPC_FLOOR_L_S: 10174 check_cp1_64bitmode(ctx); 10175 { 10176 TCGv_i32 fp32 = tcg_temp_new_i32(); 10177 TCGv_i64 fp64 = tcg_temp_new_i64(); 10178 10179 gen_load_fpr32(ctx, fp32, fs); 10180 if (ctx->nan2008) { 10181 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32); 10182 } else { 10183 gen_helper_float_floor_l_s(fp64, cpu_env, fp32); 10184 } 10185 tcg_temp_free_i32(fp32); 10186 gen_store_fpr64(ctx, fp64, fd); 10187 tcg_temp_free_i64(fp64); 10188 } 10189 break; 10190 case OPC_ROUND_W_S: 10191 { 10192 TCGv_i32 fp0 = tcg_temp_new_i32(); 10193 10194 gen_load_fpr32(ctx, fp0, fs); 10195 if (ctx->nan2008) { 10196 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0); 10197 } else { 10198 gen_helper_float_round_w_s(fp0, cpu_env, fp0); 10199 } 10200 gen_store_fpr32(ctx, fp0, fd); 10201 tcg_temp_free_i32(fp0); 10202 } 10203 break; 10204 case OPC_TRUNC_W_S: 10205 { 10206 TCGv_i32 fp0 = tcg_temp_new_i32(); 10207 10208 gen_load_fpr32(ctx, fp0, fs); 10209 if (ctx->nan2008) { 10210 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0); 10211 } else { 10212 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0); 10213 } 10214 gen_store_fpr32(ctx, fp0, fd); 10215 tcg_temp_free_i32(fp0); 10216 } 10217 break; 10218 case OPC_CEIL_W_S: 10219 { 10220 TCGv_i32 fp0 = tcg_temp_new_i32(); 10221 10222 gen_load_fpr32(ctx, fp0, fs); 10223 if (ctx->nan2008) { 10224 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0); 10225 } else { 10226 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0); 10227 } 10228 gen_store_fpr32(ctx, fp0, fd); 10229 tcg_temp_free_i32(fp0); 10230 } 10231 break; 10232 case OPC_FLOOR_W_S: 10233 { 10234 TCGv_i32 fp0 = tcg_temp_new_i32(); 10235 10236 gen_load_fpr32(ctx, fp0, fs); 10237 if (ctx->nan2008) { 10238 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0); 10239 } else { 10240 gen_helper_float_floor_w_s(fp0, cpu_env, fp0); 10241 } 10242 gen_store_fpr32(ctx, fp0, fd); 10243 tcg_temp_free_i32(fp0); 10244 } 10245 break; 10246 case OPC_SEL_S: 10247 check_insn(ctx, ISA_MIPS_R6); 10248 gen_sel_s(ctx, op1, fd, ft, fs); 10249 break; 10250 case OPC_SELEQZ_S: 10251 check_insn(ctx, ISA_MIPS_R6); 10252 gen_sel_s(ctx, op1, fd, ft, fs); 10253 break; 10254 case OPC_SELNEZ_S: 10255 check_insn(ctx, ISA_MIPS_R6); 10256 gen_sel_s(ctx, op1, fd, ft, fs); 10257 break; 10258 case OPC_MOVCF_S: 10259 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10260 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10261 break; 10262 case OPC_MOVZ_S: 10263 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10264 { 10265 TCGLabel *l1 = gen_new_label(); 10266 TCGv_i32 fp0; 10267 10268 if (ft != 0) { 10269 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10270 } 10271 fp0 = tcg_temp_new_i32(); 10272 gen_load_fpr32(ctx, fp0, fs); 10273 gen_store_fpr32(ctx, fp0, fd); 10274 tcg_temp_free_i32(fp0); 10275 gen_set_label(l1); 10276 } 10277 break; 10278 case OPC_MOVN_S: 10279 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10280 { 10281 TCGLabel *l1 = gen_new_label(); 10282 TCGv_i32 fp0; 10283 10284 if (ft != 0) { 10285 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10286 fp0 = tcg_temp_new_i32(); 10287 gen_load_fpr32(ctx, fp0, fs); 10288 gen_store_fpr32(ctx, fp0, fd); 10289 tcg_temp_free_i32(fp0); 10290 gen_set_label(l1); 10291 } 10292 } 10293 break; 10294 case OPC_RECIP_S: 10295 { 10296 TCGv_i32 fp0 = tcg_temp_new_i32(); 10297 10298 gen_load_fpr32(ctx, fp0, fs); 10299 gen_helper_float_recip_s(fp0, cpu_env, fp0); 10300 gen_store_fpr32(ctx, fp0, fd); 10301 tcg_temp_free_i32(fp0); 10302 } 10303 break; 10304 case OPC_RSQRT_S: 10305 { 10306 TCGv_i32 fp0 = tcg_temp_new_i32(); 10307 10308 gen_load_fpr32(ctx, fp0, fs); 10309 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0); 10310 gen_store_fpr32(ctx, fp0, fd); 10311 tcg_temp_free_i32(fp0); 10312 } 10313 break; 10314 case OPC_MADDF_S: 10315 check_insn(ctx, ISA_MIPS_R6); 10316 { 10317 TCGv_i32 fp0 = tcg_temp_new_i32(); 10318 TCGv_i32 fp1 = tcg_temp_new_i32(); 10319 TCGv_i32 fp2 = tcg_temp_new_i32(); 10320 gen_load_fpr32(ctx, fp0, fs); 10321 gen_load_fpr32(ctx, fp1, ft); 10322 gen_load_fpr32(ctx, fp2, fd); 10323 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2); 10324 gen_store_fpr32(ctx, fp2, fd); 10325 tcg_temp_free_i32(fp2); 10326 tcg_temp_free_i32(fp1); 10327 tcg_temp_free_i32(fp0); 10328 } 10329 break; 10330 case OPC_MSUBF_S: 10331 check_insn(ctx, ISA_MIPS_R6); 10332 { 10333 TCGv_i32 fp0 = tcg_temp_new_i32(); 10334 TCGv_i32 fp1 = tcg_temp_new_i32(); 10335 TCGv_i32 fp2 = tcg_temp_new_i32(); 10336 gen_load_fpr32(ctx, fp0, fs); 10337 gen_load_fpr32(ctx, fp1, ft); 10338 gen_load_fpr32(ctx, fp2, fd); 10339 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2); 10340 gen_store_fpr32(ctx, fp2, fd); 10341 tcg_temp_free_i32(fp2); 10342 tcg_temp_free_i32(fp1); 10343 tcg_temp_free_i32(fp0); 10344 } 10345 break; 10346 case OPC_RINT_S: 10347 check_insn(ctx, ISA_MIPS_R6); 10348 { 10349 TCGv_i32 fp0 = tcg_temp_new_i32(); 10350 gen_load_fpr32(ctx, fp0, fs); 10351 gen_helper_float_rint_s(fp0, cpu_env, fp0); 10352 gen_store_fpr32(ctx, fp0, fd); 10353 tcg_temp_free_i32(fp0); 10354 } 10355 break; 10356 case OPC_CLASS_S: 10357 check_insn(ctx, ISA_MIPS_R6); 10358 { 10359 TCGv_i32 fp0 = tcg_temp_new_i32(); 10360 gen_load_fpr32(ctx, fp0, fs); 10361 gen_helper_float_class_s(fp0, cpu_env, fp0); 10362 gen_store_fpr32(ctx, fp0, fd); 10363 tcg_temp_free_i32(fp0); 10364 } 10365 break; 10366 case OPC_MIN_S: /* OPC_RECIP2_S */ 10367 if (ctx->insn_flags & ISA_MIPS_R6) { 10368 /* OPC_MIN_S */ 10369 TCGv_i32 fp0 = tcg_temp_new_i32(); 10370 TCGv_i32 fp1 = tcg_temp_new_i32(); 10371 TCGv_i32 fp2 = tcg_temp_new_i32(); 10372 gen_load_fpr32(ctx, fp0, fs); 10373 gen_load_fpr32(ctx, fp1, ft); 10374 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1); 10375 gen_store_fpr32(ctx, fp2, fd); 10376 tcg_temp_free_i32(fp2); 10377 tcg_temp_free_i32(fp1); 10378 tcg_temp_free_i32(fp0); 10379 } else { 10380 /* OPC_RECIP2_S */ 10381 check_cp1_64bitmode(ctx); 10382 { 10383 TCGv_i32 fp0 = tcg_temp_new_i32(); 10384 TCGv_i32 fp1 = tcg_temp_new_i32(); 10385 10386 gen_load_fpr32(ctx, fp0, fs); 10387 gen_load_fpr32(ctx, fp1, ft); 10388 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1); 10389 tcg_temp_free_i32(fp1); 10390 gen_store_fpr32(ctx, fp0, fd); 10391 tcg_temp_free_i32(fp0); 10392 } 10393 } 10394 break; 10395 case OPC_MINA_S: /* OPC_RECIP1_S */ 10396 if (ctx->insn_flags & ISA_MIPS_R6) { 10397 /* OPC_MINA_S */ 10398 TCGv_i32 fp0 = tcg_temp_new_i32(); 10399 TCGv_i32 fp1 = tcg_temp_new_i32(); 10400 TCGv_i32 fp2 = tcg_temp_new_i32(); 10401 gen_load_fpr32(ctx, fp0, fs); 10402 gen_load_fpr32(ctx, fp1, ft); 10403 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1); 10404 gen_store_fpr32(ctx, fp2, fd); 10405 tcg_temp_free_i32(fp2); 10406 tcg_temp_free_i32(fp1); 10407 tcg_temp_free_i32(fp0); 10408 } else { 10409 /* OPC_RECIP1_S */ 10410 check_cp1_64bitmode(ctx); 10411 { 10412 TCGv_i32 fp0 = tcg_temp_new_i32(); 10413 10414 gen_load_fpr32(ctx, fp0, fs); 10415 gen_helper_float_recip1_s(fp0, cpu_env, fp0); 10416 gen_store_fpr32(ctx, fp0, fd); 10417 tcg_temp_free_i32(fp0); 10418 } 10419 } 10420 break; 10421 case OPC_MAX_S: /* OPC_RSQRT1_S */ 10422 if (ctx->insn_flags & ISA_MIPS_R6) { 10423 /* OPC_MAX_S */ 10424 TCGv_i32 fp0 = tcg_temp_new_i32(); 10425 TCGv_i32 fp1 = tcg_temp_new_i32(); 10426 gen_load_fpr32(ctx, fp0, fs); 10427 gen_load_fpr32(ctx, fp1, ft); 10428 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1); 10429 gen_store_fpr32(ctx, fp1, fd); 10430 tcg_temp_free_i32(fp1); 10431 tcg_temp_free_i32(fp0); 10432 } else { 10433 /* OPC_RSQRT1_S */ 10434 check_cp1_64bitmode(ctx); 10435 { 10436 TCGv_i32 fp0 = tcg_temp_new_i32(); 10437 10438 gen_load_fpr32(ctx, fp0, fs); 10439 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0); 10440 gen_store_fpr32(ctx, fp0, fd); 10441 tcg_temp_free_i32(fp0); 10442 } 10443 } 10444 break; 10445 case OPC_MAXA_S: /* OPC_RSQRT2_S */ 10446 if (ctx->insn_flags & ISA_MIPS_R6) { 10447 /* OPC_MAXA_S */ 10448 TCGv_i32 fp0 = tcg_temp_new_i32(); 10449 TCGv_i32 fp1 = tcg_temp_new_i32(); 10450 gen_load_fpr32(ctx, fp0, fs); 10451 gen_load_fpr32(ctx, fp1, ft); 10452 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1); 10453 gen_store_fpr32(ctx, fp1, fd); 10454 tcg_temp_free_i32(fp1); 10455 tcg_temp_free_i32(fp0); 10456 } else { 10457 /* OPC_RSQRT2_S */ 10458 check_cp1_64bitmode(ctx); 10459 { 10460 TCGv_i32 fp0 = tcg_temp_new_i32(); 10461 TCGv_i32 fp1 = tcg_temp_new_i32(); 10462 10463 gen_load_fpr32(ctx, fp0, fs); 10464 gen_load_fpr32(ctx, fp1, ft); 10465 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1); 10466 tcg_temp_free_i32(fp1); 10467 gen_store_fpr32(ctx, fp0, fd); 10468 tcg_temp_free_i32(fp0); 10469 } 10470 } 10471 break; 10472 case OPC_CVT_D_S: 10473 check_cp1_registers(ctx, fd); 10474 { 10475 TCGv_i32 fp32 = tcg_temp_new_i32(); 10476 TCGv_i64 fp64 = tcg_temp_new_i64(); 10477 10478 gen_load_fpr32(ctx, fp32, fs); 10479 gen_helper_float_cvtd_s(fp64, cpu_env, fp32); 10480 tcg_temp_free_i32(fp32); 10481 gen_store_fpr64(ctx, fp64, fd); 10482 tcg_temp_free_i64(fp64); 10483 } 10484 break; 10485 case OPC_CVT_W_S: 10486 { 10487 TCGv_i32 fp0 = tcg_temp_new_i32(); 10488 10489 gen_load_fpr32(ctx, fp0, fs); 10490 if (ctx->nan2008) { 10491 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0); 10492 } else { 10493 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0); 10494 } 10495 gen_store_fpr32(ctx, fp0, fd); 10496 tcg_temp_free_i32(fp0); 10497 } 10498 break; 10499 case OPC_CVT_L_S: 10500 check_cp1_64bitmode(ctx); 10501 { 10502 TCGv_i32 fp32 = tcg_temp_new_i32(); 10503 TCGv_i64 fp64 = tcg_temp_new_i64(); 10504 10505 gen_load_fpr32(ctx, fp32, fs); 10506 if (ctx->nan2008) { 10507 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32); 10508 } else { 10509 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32); 10510 } 10511 tcg_temp_free_i32(fp32); 10512 gen_store_fpr64(ctx, fp64, fd); 10513 tcg_temp_free_i64(fp64); 10514 } 10515 break; 10516 case OPC_CVT_PS_S: 10517 check_ps(ctx); 10518 { 10519 TCGv_i64 fp64 = tcg_temp_new_i64(); 10520 TCGv_i32 fp32_0 = tcg_temp_new_i32(); 10521 TCGv_i32 fp32_1 = tcg_temp_new_i32(); 10522 10523 gen_load_fpr32(ctx, fp32_0, fs); 10524 gen_load_fpr32(ctx, fp32_1, ft); 10525 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); 10526 tcg_temp_free_i32(fp32_1); 10527 tcg_temp_free_i32(fp32_0); 10528 gen_store_fpr64(ctx, fp64, fd); 10529 tcg_temp_free_i64(fp64); 10530 } 10531 break; 10532 case OPC_CMP_F_S: 10533 case OPC_CMP_UN_S: 10534 case OPC_CMP_EQ_S: 10535 case OPC_CMP_UEQ_S: 10536 case OPC_CMP_OLT_S: 10537 case OPC_CMP_ULT_S: 10538 case OPC_CMP_OLE_S: 10539 case OPC_CMP_ULE_S: 10540 case OPC_CMP_SF_S: 10541 case OPC_CMP_NGLE_S: 10542 case OPC_CMP_SEQ_S: 10543 case OPC_CMP_NGL_S: 10544 case OPC_CMP_LT_S: 10545 case OPC_CMP_NGE_S: 10546 case OPC_CMP_LE_S: 10547 case OPC_CMP_NGT_S: 10548 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10549 if (ctx->opcode & (1 << 6)) { 10550 gen_cmpabs_s(ctx, func - 48, ft, fs, cc); 10551 } else { 10552 gen_cmp_s(ctx, func - 48, ft, fs, cc); 10553 } 10554 break; 10555 case OPC_ADD_D: 10556 check_cp1_registers(ctx, fs | ft | fd); 10557 { 10558 TCGv_i64 fp0 = tcg_temp_new_i64(); 10559 TCGv_i64 fp1 = tcg_temp_new_i64(); 10560 10561 gen_load_fpr64(ctx, fp0, fs); 10562 gen_load_fpr64(ctx, fp1, ft); 10563 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1); 10564 tcg_temp_free_i64(fp1); 10565 gen_store_fpr64(ctx, fp0, fd); 10566 tcg_temp_free_i64(fp0); 10567 } 10568 break; 10569 case OPC_SUB_D: 10570 check_cp1_registers(ctx, fs | ft | fd); 10571 { 10572 TCGv_i64 fp0 = tcg_temp_new_i64(); 10573 TCGv_i64 fp1 = tcg_temp_new_i64(); 10574 10575 gen_load_fpr64(ctx, fp0, fs); 10576 gen_load_fpr64(ctx, fp1, ft); 10577 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1); 10578 tcg_temp_free_i64(fp1); 10579 gen_store_fpr64(ctx, fp0, fd); 10580 tcg_temp_free_i64(fp0); 10581 } 10582 break; 10583 case OPC_MUL_D: 10584 check_cp1_registers(ctx, fs | ft | fd); 10585 { 10586 TCGv_i64 fp0 = tcg_temp_new_i64(); 10587 TCGv_i64 fp1 = tcg_temp_new_i64(); 10588 10589 gen_load_fpr64(ctx, fp0, fs); 10590 gen_load_fpr64(ctx, fp1, ft); 10591 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1); 10592 tcg_temp_free_i64(fp1); 10593 gen_store_fpr64(ctx, fp0, fd); 10594 tcg_temp_free_i64(fp0); 10595 } 10596 break; 10597 case OPC_DIV_D: 10598 check_cp1_registers(ctx, fs | ft | fd); 10599 { 10600 TCGv_i64 fp0 = tcg_temp_new_i64(); 10601 TCGv_i64 fp1 = tcg_temp_new_i64(); 10602 10603 gen_load_fpr64(ctx, fp0, fs); 10604 gen_load_fpr64(ctx, fp1, ft); 10605 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1); 10606 tcg_temp_free_i64(fp1); 10607 gen_store_fpr64(ctx, fp0, fd); 10608 tcg_temp_free_i64(fp0); 10609 } 10610 break; 10611 case OPC_SQRT_D: 10612 check_cp1_registers(ctx, fs | fd); 10613 { 10614 TCGv_i64 fp0 = tcg_temp_new_i64(); 10615 10616 gen_load_fpr64(ctx, fp0, fs); 10617 gen_helper_float_sqrt_d(fp0, cpu_env, fp0); 10618 gen_store_fpr64(ctx, fp0, fd); 10619 tcg_temp_free_i64(fp0); 10620 } 10621 break; 10622 case OPC_ABS_D: 10623 check_cp1_registers(ctx, fs | fd); 10624 { 10625 TCGv_i64 fp0 = tcg_temp_new_i64(); 10626 10627 gen_load_fpr64(ctx, fp0, fs); 10628 if (ctx->abs2008) { 10629 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL); 10630 } else { 10631 gen_helper_float_abs_d(fp0, fp0); 10632 } 10633 gen_store_fpr64(ctx, fp0, fd); 10634 tcg_temp_free_i64(fp0); 10635 } 10636 break; 10637 case OPC_MOV_D: 10638 check_cp1_registers(ctx, fs | fd); 10639 { 10640 TCGv_i64 fp0 = tcg_temp_new_i64(); 10641 10642 gen_load_fpr64(ctx, fp0, fs); 10643 gen_store_fpr64(ctx, fp0, fd); 10644 tcg_temp_free_i64(fp0); 10645 } 10646 break; 10647 case OPC_NEG_D: 10648 check_cp1_registers(ctx, fs | fd); 10649 { 10650 TCGv_i64 fp0 = tcg_temp_new_i64(); 10651 10652 gen_load_fpr64(ctx, fp0, fs); 10653 if (ctx->abs2008) { 10654 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63); 10655 } else { 10656 gen_helper_float_chs_d(fp0, fp0); 10657 } 10658 gen_store_fpr64(ctx, fp0, fd); 10659 tcg_temp_free_i64(fp0); 10660 } 10661 break; 10662 case OPC_ROUND_L_D: 10663 check_cp1_64bitmode(ctx); 10664 { 10665 TCGv_i64 fp0 = tcg_temp_new_i64(); 10666 10667 gen_load_fpr64(ctx, fp0, fs); 10668 if (ctx->nan2008) { 10669 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0); 10670 } else { 10671 gen_helper_float_round_l_d(fp0, cpu_env, fp0); 10672 } 10673 gen_store_fpr64(ctx, fp0, fd); 10674 tcg_temp_free_i64(fp0); 10675 } 10676 break; 10677 case OPC_TRUNC_L_D: 10678 check_cp1_64bitmode(ctx); 10679 { 10680 TCGv_i64 fp0 = tcg_temp_new_i64(); 10681 10682 gen_load_fpr64(ctx, fp0, fs); 10683 if (ctx->nan2008) { 10684 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0); 10685 } else { 10686 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0); 10687 } 10688 gen_store_fpr64(ctx, fp0, fd); 10689 tcg_temp_free_i64(fp0); 10690 } 10691 break; 10692 case OPC_CEIL_L_D: 10693 check_cp1_64bitmode(ctx); 10694 { 10695 TCGv_i64 fp0 = tcg_temp_new_i64(); 10696 10697 gen_load_fpr64(ctx, fp0, fs); 10698 if (ctx->nan2008) { 10699 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0); 10700 } else { 10701 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0); 10702 } 10703 gen_store_fpr64(ctx, fp0, fd); 10704 tcg_temp_free_i64(fp0); 10705 } 10706 break; 10707 case OPC_FLOOR_L_D: 10708 check_cp1_64bitmode(ctx); 10709 { 10710 TCGv_i64 fp0 = tcg_temp_new_i64(); 10711 10712 gen_load_fpr64(ctx, fp0, fs); 10713 if (ctx->nan2008) { 10714 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0); 10715 } else { 10716 gen_helper_float_floor_l_d(fp0, cpu_env, fp0); 10717 } 10718 gen_store_fpr64(ctx, fp0, fd); 10719 tcg_temp_free_i64(fp0); 10720 } 10721 break; 10722 case OPC_ROUND_W_D: 10723 check_cp1_registers(ctx, fs); 10724 { 10725 TCGv_i32 fp32 = tcg_temp_new_i32(); 10726 TCGv_i64 fp64 = tcg_temp_new_i64(); 10727 10728 gen_load_fpr64(ctx, fp64, fs); 10729 if (ctx->nan2008) { 10730 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64); 10731 } else { 10732 gen_helper_float_round_w_d(fp32, cpu_env, fp64); 10733 } 10734 tcg_temp_free_i64(fp64); 10735 gen_store_fpr32(ctx, fp32, fd); 10736 tcg_temp_free_i32(fp32); 10737 } 10738 break; 10739 case OPC_TRUNC_W_D: 10740 check_cp1_registers(ctx, fs); 10741 { 10742 TCGv_i32 fp32 = tcg_temp_new_i32(); 10743 TCGv_i64 fp64 = tcg_temp_new_i64(); 10744 10745 gen_load_fpr64(ctx, fp64, fs); 10746 if (ctx->nan2008) { 10747 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64); 10748 } else { 10749 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64); 10750 } 10751 tcg_temp_free_i64(fp64); 10752 gen_store_fpr32(ctx, fp32, fd); 10753 tcg_temp_free_i32(fp32); 10754 } 10755 break; 10756 case OPC_CEIL_W_D: 10757 check_cp1_registers(ctx, fs); 10758 { 10759 TCGv_i32 fp32 = tcg_temp_new_i32(); 10760 TCGv_i64 fp64 = tcg_temp_new_i64(); 10761 10762 gen_load_fpr64(ctx, fp64, fs); 10763 if (ctx->nan2008) { 10764 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64); 10765 } else { 10766 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64); 10767 } 10768 tcg_temp_free_i64(fp64); 10769 gen_store_fpr32(ctx, fp32, fd); 10770 tcg_temp_free_i32(fp32); 10771 } 10772 break; 10773 case OPC_FLOOR_W_D: 10774 check_cp1_registers(ctx, fs); 10775 { 10776 TCGv_i32 fp32 = tcg_temp_new_i32(); 10777 TCGv_i64 fp64 = tcg_temp_new_i64(); 10778 10779 gen_load_fpr64(ctx, fp64, fs); 10780 if (ctx->nan2008) { 10781 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64); 10782 } else { 10783 gen_helper_float_floor_w_d(fp32, cpu_env, fp64); 10784 } 10785 tcg_temp_free_i64(fp64); 10786 gen_store_fpr32(ctx, fp32, fd); 10787 tcg_temp_free_i32(fp32); 10788 } 10789 break; 10790 case OPC_SEL_D: 10791 check_insn(ctx, ISA_MIPS_R6); 10792 gen_sel_d(ctx, op1, fd, ft, fs); 10793 break; 10794 case OPC_SELEQZ_D: 10795 check_insn(ctx, ISA_MIPS_R6); 10796 gen_sel_d(ctx, op1, fd, ft, fs); 10797 break; 10798 case OPC_SELNEZ_D: 10799 check_insn(ctx, ISA_MIPS_R6); 10800 gen_sel_d(ctx, op1, fd, ft, fs); 10801 break; 10802 case OPC_MOVCF_D: 10803 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10804 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 10805 break; 10806 case OPC_MOVZ_D: 10807 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10808 { 10809 TCGLabel *l1 = gen_new_label(); 10810 TCGv_i64 fp0; 10811 10812 if (ft != 0) { 10813 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 10814 } 10815 fp0 = tcg_temp_new_i64(); 10816 gen_load_fpr64(ctx, fp0, fs); 10817 gen_store_fpr64(ctx, fp0, fd); 10818 tcg_temp_free_i64(fp0); 10819 gen_set_label(l1); 10820 } 10821 break; 10822 case OPC_MOVN_D: 10823 check_insn_opc_removed(ctx, ISA_MIPS_R6); 10824 { 10825 TCGLabel *l1 = gen_new_label(); 10826 TCGv_i64 fp0; 10827 10828 if (ft != 0) { 10829 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 10830 fp0 = tcg_temp_new_i64(); 10831 gen_load_fpr64(ctx, fp0, fs); 10832 gen_store_fpr64(ctx, fp0, fd); 10833 tcg_temp_free_i64(fp0); 10834 gen_set_label(l1); 10835 } 10836 } 10837 break; 10838 case OPC_RECIP_D: 10839 check_cp1_registers(ctx, fs | fd); 10840 { 10841 TCGv_i64 fp0 = tcg_temp_new_i64(); 10842 10843 gen_load_fpr64(ctx, fp0, fs); 10844 gen_helper_float_recip_d(fp0, cpu_env, fp0); 10845 gen_store_fpr64(ctx, fp0, fd); 10846 tcg_temp_free_i64(fp0); 10847 } 10848 break; 10849 case OPC_RSQRT_D: 10850 check_cp1_registers(ctx, fs | fd); 10851 { 10852 TCGv_i64 fp0 = tcg_temp_new_i64(); 10853 10854 gen_load_fpr64(ctx, fp0, fs); 10855 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0); 10856 gen_store_fpr64(ctx, fp0, fd); 10857 tcg_temp_free_i64(fp0); 10858 } 10859 break; 10860 case OPC_MADDF_D: 10861 check_insn(ctx, ISA_MIPS_R6); 10862 { 10863 TCGv_i64 fp0 = tcg_temp_new_i64(); 10864 TCGv_i64 fp1 = tcg_temp_new_i64(); 10865 TCGv_i64 fp2 = tcg_temp_new_i64(); 10866 gen_load_fpr64(ctx, fp0, fs); 10867 gen_load_fpr64(ctx, fp1, ft); 10868 gen_load_fpr64(ctx, fp2, fd); 10869 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2); 10870 gen_store_fpr64(ctx, fp2, fd); 10871 tcg_temp_free_i64(fp2); 10872 tcg_temp_free_i64(fp1); 10873 tcg_temp_free_i64(fp0); 10874 } 10875 break; 10876 case OPC_MSUBF_D: 10877 check_insn(ctx, ISA_MIPS_R6); 10878 { 10879 TCGv_i64 fp0 = tcg_temp_new_i64(); 10880 TCGv_i64 fp1 = tcg_temp_new_i64(); 10881 TCGv_i64 fp2 = tcg_temp_new_i64(); 10882 gen_load_fpr64(ctx, fp0, fs); 10883 gen_load_fpr64(ctx, fp1, ft); 10884 gen_load_fpr64(ctx, fp2, fd); 10885 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2); 10886 gen_store_fpr64(ctx, fp2, fd); 10887 tcg_temp_free_i64(fp2); 10888 tcg_temp_free_i64(fp1); 10889 tcg_temp_free_i64(fp0); 10890 } 10891 break; 10892 case OPC_RINT_D: 10893 check_insn(ctx, ISA_MIPS_R6); 10894 { 10895 TCGv_i64 fp0 = tcg_temp_new_i64(); 10896 gen_load_fpr64(ctx, fp0, fs); 10897 gen_helper_float_rint_d(fp0, cpu_env, fp0); 10898 gen_store_fpr64(ctx, fp0, fd); 10899 tcg_temp_free_i64(fp0); 10900 } 10901 break; 10902 case OPC_CLASS_D: 10903 check_insn(ctx, ISA_MIPS_R6); 10904 { 10905 TCGv_i64 fp0 = tcg_temp_new_i64(); 10906 gen_load_fpr64(ctx, fp0, fs); 10907 gen_helper_float_class_d(fp0, cpu_env, fp0); 10908 gen_store_fpr64(ctx, fp0, fd); 10909 tcg_temp_free_i64(fp0); 10910 } 10911 break; 10912 case OPC_MIN_D: /* OPC_RECIP2_D */ 10913 if (ctx->insn_flags & ISA_MIPS_R6) { 10914 /* OPC_MIN_D */ 10915 TCGv_i64 fp0 = tcg_temp_new_i64(); 10916 TCGv_i64 fp1 = tcg_temp_new_i64(); 10917 gen_load_fpr64(ctx, fp0, fs); 10918 gen_load_fpr64(ctx, fp1, ft); 10919 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1); 10920 gen_store_fpr64(ctx, fp1, fd); 10921 tcg_temp_free_i64(fp1); 10922 tcg_temp_free_i64(fp0); 10923 } else { 10924 /* OPC_RECIP2_D */ 10925 check_cp1_64bitmode(ctx); 10926 { 10927 TCGv_i64 fp0 = tcg_temp_new_i64(); 10928 TCGv_i64 fp1 = tcg_temp_new_i64(); 10929 10930 gen_load_fpr64(ctx, fp0, fs); 10931 gen_load_fpr64(ctx, fp1, ft); 10932 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1); 10933 tcg_temp_free_i64(fp1); 10934 gen_store_fpr64(ctx, fp0, fd); 10935 tcg_temp_free_i64(fp0); 10936 } 10937 } 10938 break; 10939 case OPC_MINA_D: /* OPC_RECIP1_D */ 10940 if (ctx->insn_flags & ISA_MIPS_R6) { 10941 /* OPC_MINA_D */ 10942 TCGv_i64 fp0 = tcg_temp_new_i64(); 10943 TCGv_i64 fp1 = tcg_temp_new_i64(); 10944 gen_load_fpr64(ctx, fp0, fs); 10945 gen_load_fpr64(ctx, fp1, ft); 10946 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1); 10947 gen_store_fpr64(ctx, fp1, fd); 10948 tcg_temp_free_i64(fp1); 10949 tcg_temp_free_i64(fp0); 10950 } else { 10951 /* OPC_RECIP1_D */ 10952 check_cp1_64bitmode(ctx); 10953 { 10954 TCGv_i64 fp0 = tcg_temp_new_i64(); 10955 10956 gen_load_fpr64(ctx, fp0, fs); 10957 gen_helper_float_recip1_d(fp0, cpu_env, fp0); 10958 gen_store_fpr64(ctx, fp0, fd); 10959 tcg_temp_free_i64(fp0); 10960 } 10961 } 10962 break; 10963 case OPC_MAX_D: /* OPC_RSQRT1_D */ 10964 if (ctx->insn_flags & ISA_MIPS_R6) { 10965 /* OPC_MAX_D */ 10966 TCGv_i64 fp0 = tcg_temp_new_i64(); 10967 TCGv_i64 fp1 = tcg_temp_new_i64(); 10968 gen_load_fpr64(ctx, fp0, fs); 10969 gen_load_fpr64(ctx, fp1, ft); 10970 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1); 10971 gen_store_fpr64(ctx, fp1, fd); 10972 tcg_temp_free_i64(fp1); 10973 tcg_temp_free_i64(fp0); 10974 } else { 10975 /* OPC_RSQRT1_D */ 10976 check_cp1_64bitmode(ctx); 10977 { 10978 TCGv_i64 fp0 = tcg_temp_new_i64(); 10979 10980 gen_load_fpr64(ctx, fp0, fs); 10981 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0); 10982 gen_store_fpr64(ctx, fp0, fd); 10983 tcg_temp_free_i64(fp0); 10984 } 10985 } 10986 break; 10987 case OPC_MAXA_D: /* OPC_RSQRT2_D */ 10988 if (ctx->insn_flags & ISA_MIPS_R6) { 10989 /* OPC_MAXA_D */ 10990 TCGv_i64 fp0 = tcg_temp_new_i64(); 10991 TCGv_i64 fp1 = tcg_temp_new_i64(); 10992 gen_load_fpr64(ctx, fp0, fs); 10993 gen_load_fpr64(ctx, fp1, ft); 10994 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1); 10995 gen_store_fpr64(ctx, fp1, fd); 10996 tcg_temp_free_i64(fp1); 10997 tcg_temp_free_i64(fp0); 10998 } else { 10999 /* OPC_RSQRT2_D */ 11000 check_cp1_64bitmode(ctx); 11001 { 11002 TCGv_i64 fp0 = tcg_temp_new_i64(); 11003 TCGv_i64 fp1 = tcg_temp_new_i64(); 11004 11005 gen_load_fpr64(ctx, fp0, fs); 11006 gen_load_fpr64(ctx, fp1, ft); 11007 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1); 11008 tcg_temp_free_i64(fp1); 11009 gen_store_fpr64(ctx, fp0, fd); 11010 tcg_temp_free_i64(fp0); 11011 } 11012 } 11013 break; 11014 case OPC_CMP_F_D: 11015 case OPC_CMP_UN_D: 11016 case OPC_CMP_EQ_D: 11017 case OPC_CMP_UEQ_D: 11018 case OPC_CMP_OLT_D: 11019 case OPC_CMP_ULT_D: 11020 case OPC_CMP_OLE_D: 11021 case OPC_CMP_ULE_D: 11022 case OPC_CMP_SF_D: 11023 case OPC_CMP_NGLE_D: 11024 case OPC_CMP_SEQ_D: 11025 case OPC_CMP_NGL_D: 11026 case OPC_CMP_LT_D: 11027 case OPC_CMP_NGE_D: 11028 case OPC_CMP_LE_D: 11029 case OPC_CMP_NGT_D: 11030 check_insn_opc_removed(ctx, ISA_MIPS_R6); 11031 if (ctx->opcode & (1 << 6)) { 11032 gen_cmpabs_d(ctx, func - 48, ft, fs, cc); 11033 } else { 11034 gen_cmp_d(ctx, func - 48, ft, fs, cc); 11035 } 11036 break; 11037 case OPC_CVT_S_D: 11038 check_cp1_registers(ctx, fs); 11039 { 11040 TCGv_i32 fp32 = tcg_temp_new_i32(); 11041 TCGv_i64 fp64 = tcg_temp_new_i64(); 11042 11043 gen_load_fpr64(ctx, fp64, fs); 11044 gen_helper_float_cvts_d(fp32, cpu_env, fp64); 11045 tcg_temp_free_i64(fp64); 11046 gen_store_fpr32(ctx, fp32, fd); 11047 tcg_temp_free_i32(fp32); 11048 } 11049 break; 11050 case OPC_CVT_W_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 if (ctx->nan2008) { 11058 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64); 11059 } else { 11060 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64); 11061 } 11062 tcg_temp_free_i64(fp64); 11063 gen_store_fpr32(ctx, fp32, fd); 11064 tcg_temp_free_i32(fp32); 11065 } 11066 break; 11067 case OPC_CVT_L_D: 11068 check_cp1_64bitmode(ctx); 11069 { 11070 TCGv_i64 fp0 = tcg_temp_new_i64(); 11071 11072 gen_load_fpr64(ctx, fp0, fs); 11073 if (ctx->nan2008) { 11074 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0); 11075 } else { 11076 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0); 11077 } 11078 gen_store_fpr64(ctx, fp0, fd); 11079 tcg_temp_free_i64(fp0); 11080 } 11081 break; 11082 case OPC_CVT_S_W: 11083 { 11084 TCGv_i32 fp0 = tcg_temp_new_i32(); 11085 11086 gen_load_fpr32(ctx, fp0, fs); 11087 gen_helper_float_cvts_w(fp0, cpu_env, fp0); 11088 gen_store_fpr32(ctx, fp0, fd); 11089 tcg_temp_free_i32(fp0); 11090 } 11091 break; 11092 case OPC_CVT_D_W: 11093 check_cp1_registers(ctx, fd); 11094 { 11095 TCGv_i32 fp32 = tcg_temp_new_i32(); 11096 TCGv_i64 fp64 = tcg_temp_new_i64(); 11097 11098 gen_load_fpr32(ctx, fp32, fs); 11099 gen_helper_float_cvtd_w(fp64, cpu_env, fp32); 11100 tcg_temp_free_i32(fp32); 11101 gen_store_fpr64(ctx, fp64, fd); 11102 tcg_temp_free_i64(fp64); 11103 } 11104 break; 11105 case OPC_CVT_S_L: 11106 check_cp1_64bitmode(ctx); 11107 { 11108 TCGv_i32 fp32 = tcg_temp_new_i32(); 11109 TCGv_i64 fp64 = tcg_temp_new_i64(); 11110 11111 gen_load_fpr64(ctx, fp64, fs); 11112 gen_helper_float_cvts_l(fp32, cpu_env, fp64); 11113 tcg_temp_free_i64(fp64); 11114 gen_store_fpr32(ctx, fp32, fd); 11115 tcg_temp_free_i32(fp32); 11116 } 11117 break; 11118 case OPC_CVT_D_L: 11119 check_cp1_64bitmode(ctx); 11120 { 11121 TCGv_i64 fp0 = tcg_temp_new_i64(); 11122 11123 gen_load_fpr64(ctx, fp0, fs); 11124 gen_helper_float_cvtd_l(fp0, cpu_env, fp0); 11125 gen_store_fpr64(ctx, fp0, fd); 11126 tcg_temp_free_i64(fp0); 11127 } 11128 break; 11129 case OPC_CVT_PS_PW: 11130 check_ps(ctx); 11131 { 11132 TCGv_i64 fp0 = tcg_temp_new_i64(); 11133 11134 gen_load_fpr64(ctx, fp0, fs); 11135 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0); 11136 gen_store_fpr64(ctx, fp0, fd); 11137 tcg_temp_free_i64(fp0); 11138 } 11139 break; 11140 case OPC_ADD_PS: 11141 check_ps(ctx); 11142 { 11143 TCGv_i64 fp0 = tcg_temp_new_i64(); 11144 TCGv_i64 fp1 = tcg_temp_new_i64(); 11145 11146 gen_load_fpr64(ctx, fp0, fs); 11147 gen_load_fpr64(ctx, fp1, ft); 11148 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1); 11149 tcg_temp_free_i64(fp1); 11150 gen_store_fpr64(ctx, fp0, fd); 11151 tcg_temp_free_i64(fp0); 11152 } 11153 break; 11154 case OPC_SUB_PS: 11155 check_ps(ctx); 11156 { 11157 TCGv_i64 fp0 = tcg_temp_new_i64(); 11158 TCGv_i64 fp1 = tcg_temp_new_i64(); 11159 11160 gen_load_fpr64(ctx, fp0, fs); 11161 gen_load_fpr64(ctx, fp1, ft); 11162 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1); 11163 tcg_temp_free_i64(fp1); 11164 gen_store_fpr64(ctx, fp0, fd); 11165 tcg_temp_free_i64(fp0); 11166 } 11167 break; 11168 case OPC_MUL_PS: 11169 check_ps(ctx); 11170 { 11171 TCGv_i64 fp0 = tcg_temp_new_i64(); 11172 TCGv_i64 fp1 = tcg_temp_new_i64(); 11173 11174 gen_load_fpr64(ctx, fp0, fs); 11175 gen_load_fpr64(ctx, fp1, ft); 11176 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1); 11177 tcg_temp_free_i64(fp1); 11178 gen_store_fpr64(ctx, fp0, fd); 11179 tcg_temp_free_i64(fp0); 11180 } 11181 break; 11182 case OPC_ABS_PS: 11183 check_ps(ctx); 11184 { 11185 TCGv_i64 fp0 = tcg_temp_new_i64(); 11186 11187 gen_load_fpr64(ctx, fp0, fs); 11188 gen_helper_float_abs_ps(fp0, fp0); 11189 gen_store_fpr64(ctx, fp0, fd); 11190 tcg_temp_free_i64(fp0); 11191 } 11192 break; 11193 case OPC_MOV_PS: 11194 check_ps(ctx); 11195 { 11196 TCGv_i64 fp0 = tcg_temp_new_i64(); 11197 11198 gen_load_fpr64(ctx, fp0, fs); 11199 gen_store_fpr64(ctx, fp0, fd); 11200 tcg_temp_free_i64(fp0); 11201 } 11202 break; 11203 case OPC_NEG_PS: 11204 check_ps(ctx); 11205 { 11206 TCGv_i64 fp0 = tcg_temp_new_i64(); 11207 11208 gen_load_fpr64(ctx, fp0, fs); 11209 gen_helper_float_chs_ps(fp0, fp0); 11210 gen_store_fpr64(ctx, fp0, fd); 11211 tcg_temp_free_i64(fp0); 11212 } 11213 break; 11214 case OPC_MOVCF_PS: 11215 check_ps(ctx); 11216 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1); 11217 break; 11218 case OPC_MOVZ_PS: 11219 check_ps(ctx); 11220 { 11221 TCGLabel *l1 = gen_new_label(); 11222 TCGv_i64 fp0; 11223 11224 if (ft != 0) { 11225 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); 11226 } 11227 fp0 = tcg_temp_new_i64(); 11228 gen_load_fpr64(ctx, fp0, fs); 11229 gen_store_fpr64(ctx, fp0, fd); 11230 tcg_temp_free_i64(fp0); 11231 gen_set_label(l1); 11232 } 11233 break; 11234 case OPC_MOVN_PS: 11235 check_ps(ctx); 11236 { 11237 TCGLabel *l1 = gen_new_label(); 11238 TCGv_i64 fp0; 11239 11240 if (ft != 0) { 11241 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); 11242 fp0 = tcg_temp_new_i64(); 11243 gen_load_fpr64(ctx, fp0, fs); 11244 gen_store_fpr64(ctx, fp0, fd); 11245 tcg_temp_free_i64(fp0); 11246 gen_set_label(l1); 11247 } 11248 } 11249 break; 11250 case OPC_ADDR_PS: 11251 check_ps(ctx); 11252 { 11253 TCGv_i64 fp0 = tcg_temp_new_i64(); 11254 TCGv_i64 fp1 = tcg_temp_new_i64(); 11255 11256 gen_load_fpr64(ctx, fp0, ft); 11257 gen_load_fpr64(ctx, fp1, fs); 11258 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1); 11259 tcg_temp_free_i64(fp1); 11260 gen_store_fpr64(ctx, fp0, fd); 11261 tcg_temp_free_i64(fp0); 11262 } 11263 break; 11264 case OPC_MULR_PS: 11265 check_ps(ctx); 11266 { 11267 TCGv_i64 fp0 = tcg_temp_new_i64(); 11268 TCGv_i64 fp1 = tcg_temp_new_i64(); 11269 11270 gen_load_fpr64(ctx, fp0, ft); 11271 gen_load_fpr64(ctx, fp1, fs); 11272 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1); 11273 tcg_temp_free_i64(fp1); 11274 gen_store_fpr64(ctx, fp0, fd); 11275 tcg_temp_free_i64(fp0); 11276 } 11277 break; 11278 case OPC_RECIP2_PS: 11279 check_ps(ctx); 11280 { 11281 TCGv_i64 fp0 = tcg_temp_new_i64(); 11282 TCGv_i64 fp1 = tcg_temp_new_i64(); 11283 11284 gen_load_fpr64(ctx, fp0, fs); 11285 gen_load_fpr64(ctx, fp1, ft); 11286 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1); 11287 tcg_temp_free_i64(fp1); 11288 gen_store_fpr64(ctx, fp0, fd); 11289 tcg_temp_free_i64(fp0); 11290 } 11291 break; 11292 case OPC_RECIP1_PS: 11293 check_ps(ctx); 11294 { 11295 TCGv_i64 fp0 = tcg_temp_new_i64(); 11296 11297 gen_load_fpr64(ctx, fp0, fs); 11298 gen_helper_float_recip1_ps(fp0, cpu_env, fp0); 11299 gen_store_fpr64(ctx, fp0, fd); 11300 tcg_temp_free_i64(fp0); 11301 } 11302 break; 11303 case OPC_RSQRT1_PS: 11304 check_ps(ctx); 11305 { 11306 TCGv_i64 fp0 = tcg_temp_new_i64(); 11307 11308 gen_load_fpr64(ctx, fp0, fs); 11309 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0); 11310 gen_store_fpr64(ctx, fp0, fd); 11311 tcg_temp_free_i64(fp0); 11312 } 11313 break; 11314 case OPC_RSQRT2_PS: 11315 check_ps(ctx); 11316 { 11317 TCGv_i64 fp0 = tcg_temp_new_i64(); 11318 TCGv_i64 fp1 = tcg_temp_new_i64(); 11319 11320 gen_load_fpr64(ctx, fp0, fs); 11321 gen_load_fpr64(ctx, fp1, ft); 11322 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1); 11323 tcg_temp_free_i64(fp1); 11324 gen_store_fpr64(ctx, fp0, fd); 11325 tcg_temp_free_i64(fp0); 11326 } 11327 break; 11328 case OPC_CVT_S_PU: 11329 check_cp1_64bitmode(ctx); 11330 { 11331 TCGv_i32 fp0 = tcg_temp_new_i32(); 11332 11333 gen_load_fpr32h(ctx, fp0, fs); 11334 gen_helper_float_cvts_pu(fp0, cpu_env, fp0); 11335 gen_store_fpr32(ctx, fp0, fd); 11336 tcg_temp_free_i32(fp0); 11337 } 11338 break; 11339 case OPC_CVT_PW_PS: 11340 check_ps(ctx); 11341 { 11342 TCGv_i64 fp0 = tcg_temp_new_i64(); 11343 11344 gen_load_fpr64(ctx, fp0, fs); 11345 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0); 11346 gen_store_fpr64(ctx, fp0, fd); 11347 tcg_temp_free_i64(fp0); 11348 } 11349 break; 11350 case OPC_CVT_S_PL: 11351 check_cp1_64bitmode(ctx); 11352 { 11353 TCGv_i32 fp0 = tcg_temp_new_i32(); 11354 11355 gen_load_fpr32(ctx, fp0, fs); 11356 gen_helper_float_cvts_pl(fp0, cpu_env, fp0); 11357 gen_store_fpr32(ctx, fp0, fd); 11358 tcg_temp_free_i32(fp0); 11359 } 11360 break; 11361 case OPC_PLL_PS: 11362 check_ps(ctx); 11363 { 11364 TCGv_i32 fp0 = tcg_temp_new_i32(); 11365 TCGv_i32 fp1 = tcg_temp_new_i32(); 11366 11367 gen_load_fpr32(ctx, fp0, fs); 11368 gen_load_fpr32(ctx, fp1, ft); 11369 gen_store_fpr32h(ctx, fp0, fd); 11370 gen_store_fpr32(ctx, fp1, fd); 11371 tcg_temp_free_i32(fp0); 11372 tcg_temp_free_i32(fp1); 11373 } 11374 break; 11375 case OPC_PLU_PS: 11376 check_ps(ctx); 11377 { 11378 TCGv_i32 fp0 = tcg_temp_new_i32(); 11379 TCGv_i32 fp1 = tcg_temp_new_i32(); 11380 11381 gen_load_fpr32(ctx, fp0, fs); 11382 gen_load_fpr32h(ctx, fp1, ft); 11383 gen_store_fpr32(ctx, fp1, fd); 11384 gen_store_fpr32h(ctx, fp0, fd); 11385 tcg_temp_free_i32(fp0); 11386 tcg_temp_free_i32(fp1); 11387 } 11388 break; 11389 case OPC_PUL_PS: 11390 check_ps(ctx); 11391 { 11392 TCGv_i32 fp0 = tcg_temp_new_i32(); 11393 TCGv_i32 fp1 = tcg_temp_new_i32(); 11394 11395 gen_load_fpr32h(ctx, fp0, fs); 11396 gen_load_fpr32(ctx, fp1, ft); 11397 gen_store_fpr32(ctx, fp1, fd); 11398 gen_store_fpr32h(ctx, fp0, fd); 11399 tcg_temp_free_i32(fp0); 11400 tcg_temp_free_i32(fp1); 11401 } 11402 break; 11403 case OPC_PUU_PS: 11404 check_ps(ctx); 11405 { 11406 TCGv_i32 fp0 = tcg_temp_new_i32(); 11407 TCGv_i32 fp1 = tcg_temp_new_i32(); 11408 11409 gen_load_fpr32h(ctx, fp0, fs); 11410 gen_load_fpr32h(ctx, fp1, ft); 11411 gen_store_fpr32(ctx, fp1, fd); 11412 gen_store_fpr32h(ctx, fp0, fd); 11413 tcg_temp_free_i32(fp0); 11414 tcg_temp_free_i32(fp1); 11415 } 11416 break; 11417 case OPC_CMP_F_PS: 11418 case OPC_CMP_UN_PS: 11419 case OPC_CMP_EQ_PS: 11420 case OPC_CMP_UEQ_PS: 11421 case OPC_CMP_OLT_PS: 11422 case OPC_CMP_ULT_PS: 11423 case OPC_CMP_OLE_PS: 11424 case OPC_CMP_ULE_PS: 11425 case OPC_CMP_SF_PS: 11426 case OPC_CMP_NGLE_PS: 11427 case OPC_CMP_SEQ_PS: 11428 case OPC_CMP_NGL_PS: 11429 case OPC_CMP_LT_PS: 11430 case OPC_CMP_NGE_PS: 11431 case OPC_CMP_LE_PS: 11432 case OPC_CMP_NGT_PS: 11433 if (ctx->opcode & (1 << 6)) { 11434 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc); 11435 } else { 11436 gen_cmp_ps(ctx, func - 48, ft, fs, cc); 11437 } 11438 break; 11439 default: 11440 MIPS_INVAL("farith"); 11441 gen_reserved_instruction(ctx); 11442 return; 11443 } 11444 } 11445 11446 /* Coprocessor 3 (FPU) */ 11447 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, 11448 int fd, int fs, int base, int index) 11449 { 11450 TCGv t0 = tcg_temp_new(); 11451 11452 if (base == 0) { 11453 gen_load_gpr(t0, index); 11454 } else if (index == 0) { 11455 gen_load_gpr(t0, base); 11456 } else { 11457 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); 11458 } 11459 /* 11460 * Don't do NOP if destination is zero: we must perform the actual 11461 * memory access. 11462 */ 11463 switch (opc) { 11464 case OPC_LWXC1: 11465 check_cop1x(ctx); 11466 { 11467 TCGv_i32 fp0 = tcg_temp_new_i32(); 11468 11469 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); 11470 tcg_gen_trunc_tl_i32(fp0, t0); 11471 gen_store_fpr32(ctx, fp0, fd); 11472 tcg_temp_free_i32(fp0); 11473 } 11474 break; 11475 case OPC_LDXC1: 11476 check_cop1x(ctx); 11477 check_cp1_registers(ctx, fd); 11478 { 11479 TCGv_i64 fp0 = tcg_temp_new_i64(); 11480 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11481 gen_store_fpr64(ctx, fp0, fd); 11482 tcg_temp_free_i64(fp0); 11483 } 11484 break; 11485 case OPC_LUXC1: 11486 check_cp1_64bitmode(ctx); 11487 tcg_gen_andi_tl(t0, t0, ~0x7); 11488 { 11489 TCGv_i64 fp0 = tcg_temp_new_i64(); 11490 11491 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11492 gen_store_fpr64(ctx, fp0, fd); 11493 tcg_temp_free_i64(fp0); 11494 } 11495 break; 11496 case OPC_SWXC1: 11497 check_cop1x(ctx); 11498 { 11499 TCGv_i32 fp0 = tcg_temp_new_i32(); 11500 gen_load_fpr32(ctx, fp0, fs); 11501 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL); 11502 tcg_temp_free_i32(fp0); 11503 } 11504 break; 11505 case OPC_SDXC1: 11506 check_cop1x(ctx); 11507 check_cp1_registers(ctx, fs); 11508 { 11509 TCGv_i64 fp0 = tcg_temp_new_i64(); 11510 gen_load_fpr64(ctx, fp0, fs); 11511 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11512 tcg_temp_free_i64(fp0); 11513 } 11514 break; 11515 case OPC_SUXC1: 11516 check_cp1_64bitmode(ctx); 11517 tcg_gen_andi_tl(t0, t0, ~0x7); 11518 { 11519 TCGv_i64 fp0 = tcg_temp_new_i64(); 11520 gen_load_fpr64(ctx, fp0, fs); 11521 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ); 11522 tcg_temp_free_i64(fp0); 11523 } 11524 break; 11525 } 11526 tcg_temp_free(t0); 11527 } 11528 11529 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, 11530 int fd, int fr, int fs, int ft) 11531 { 11532 switch (opc) { 11533 case OPC_ALNV_PS: 11534 check_ps(ctx); 11535 { 11536 TCGv t0 = tcg_temp_local_new(); 11537 TCGv_i32 fp = tcg_temp_new_i32(); 11538 TCGv_i32 fph = tcg_temp_new_i32(); 11539 TCGLabel *l1 = gen_new_label(); 11540 TCGLabel *l2 = gen_new_label(); 11541 11542 gen_load_gpr(t0, fr); 11543 tcg_gen_andi_tl(t0, t0, 0x7); 11544 11545 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); 11546 gen_load_fpr32(ctx, fp, fs); 11547 gen_load_fpr32h(ctx, fph, fs); 11548 gen_store_fpr32(ctx, fp, fd); 11549 gen_store_fpr32h(ctx, fph, fd); 11550 tcg_gen_br(l2); 11551 gen_set_label(l1); 11552 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); 11553 tcg_temp_free(t0); 11554 #ifdef TARGET_WORDS_BIGENDIAN 11555 gen_load_fpr32(ctx, fp, fs); 11556 gen_load_fpr32h(ctx, fph, ft); 11557 gen_store_fpr32h(ctx, fp, fd); 11558 gen_store_fpr32(ctx, fph, fd); 11559 #else 11560 gen_load_fpr32h(ctx, fph, fs); 11561 gen_load_fpr32(ctx, fp, ft); 11562 gen_store_fpr32(ctx, fph, fd); 11563 gen_store_fpr32h(ctx, fp, fd); 11564 #endif 11565 gen_set_label(l2); 11566 tcg_temp_free_i32(fp); 11567 tcg_temp_free_i32(fph); 11568 } 11569 break; 11570 case OPC_MADD_S: 11571 check_cop1x(ctx); 11572 { 11573 TCGv_i32 fp0 = tcg_temp_new_i32(); 11574 TCGv_i32 fp1 = tcg_temp_new_i32(); 11575 TCGv_i32 fp2 = tcg_temp_new_i32(); 11576 11577 gen_load_fpr32(ctx, fp0, fs); 11578 gen_load_fpr32(ctx, fp1, ft); 11579 gen_load_fpr32(ctx, fp2, fr); 11580 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2); 11581 tcg_temp_free_i32(fp0); 11582 tcg_temp_free_i32(fp1); 11583 gen_store_fpr32(ctx, fp2, fd); 11584 tcg_temp_free_i32(fp2); 11585 } 11586 break; 11587 case OPC_MADD_D: 11588 check_cop1x(ctx); 11589 check_cp1_registers(ctx, fd | fs | ft | fr); 11590 { 11591 TCGv_i64 fp0 = tcg_temp_new_i64(); 11592 TCGv_i64 fp1 = tcg_temp_new_i64(); 11593 TCGv_i64 fp2 = tcg_temp_new_i64(); 11594 11595 gen_load_fpr64(ctx, fp0, fs); 11596 gen_load_fpr64(ctx, fp1, ft); 11597 gen_load_fpr64(ctx, fp2, fr); 11598 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2); 11599 tcg_temp_free_i64(fp0); 11600 tcg_temp_free_i64(fp1); 11601 gen_store_fpr64(ctx, fp2, fd); 11602 tcg_temp_free_i64(fp2); 11603 } 11604 break; 11605 case OPC_MADD_PS: 11606 check_ps(ctx); 11607 { 11608 TCGv_i64 fp0 = tcg_temp_new_i64(); 11609 TCGv_i64 fp1 = tcg_temp_new_i64(); 11610 TCGv_i64 fp2 = tcg_temp_new_i64(); 11611 11612 gen_load_fpr64(ctx, fp0, fs); 11613 gen_load_fpr64(ctx, fp1, ft); 11614 gen_load_fpr64(ctx, fp2, fr); 11615 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2); 11616 tcg_temp_free_i64(fp0); 11617 tcg_temp_free_i64(fp1); 11618 gen_store_fpr64(ctx, fp2, fd); 11619 tcg_temp_free_i64(fp2); 11620 } 11621 break; 11622 case OPC_MSUB_S: 11623 check_cop1x(ctx); 11624 { 11625 TCGv_i32 fp0 = tcg_temp_new_i32(); 11626 TCGv_i32 fp1 = tcg_temp_new_i32(); 11627 TCGv_i32 fp2 = tcg_temp_new_i32(); 11628 11629 gen_load_fpr32(ctx, fp0, fs); 11630 gen_load_fpr32(ctx, fp1, ft); 11631 gen_load_fpr32(ctx, fp2, fr); 11632 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2); 11633 tcg_temp_free_i32(fp0); 11634 tcg_temp_free_i32(fp1); 11635 gen_store_fpr32(ctx, fp2, fd); 11636 tcg_temp_free_i32(fp2); 11637 } 11638 break; 11639 case OPC_MSUB_D: 11640 check_cop1x(ctx); 11641 check_cp1_registers(ctx, fd | fs | ft | fr); 11642 { 11643 TCGv_i64 fp0 = tcg_temp_new_i64(); 11644 TCGv_i64 fp1 = tcg_temp_new_i64(); 11645 TCGv_i64 fp2 = tcg_temp_new_i64(); 11646 11647 gen_load_fpr64(ctx, fp0, fs); 11648 gen_load_fpr64(ctx, fp1, ft); 11649 gen_load_fpr64(ctx, fp2, fr); 11650 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2); 11651 tcg_temp_free_i64(fp0); 11652 tcg_temp_free_i64(fp1); 11653 gen_store_fpr64(ctx, fp2, fd); 11654 tcg_temp_free_i64(fp2); 11655 } 11656 break; 11657 case OPC_MSUB_PS: 11658 check_ps(ctx); 11659 { 11660 TCGv_i64 fp0 = tcg_temp_new_i64(); 11661 TCGv_i64 fp1 = tcg_temp_new_i64(); 11662 TCGv_i64 fp2 = tcg_temp_new_i64(); 11663 11664 gen_load_fpr64(ctx, fp0, fs); 11665 gen_load_fpr64(ctx, fp1, ft); 11666 gen_load_fpr64(ctx, fp2, fr); 11667 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2); 11668 tcg_temp_free_i64(fp0); 11669 tcg_temp_free_i64(fp1); 11670 gen_store_fpr64(ctx, fp2, fd); 11671 tcg_temp_free_i64(fp2); 11672 } 11673 break; 11674 case OPC_NMADD_S: 11675 check_cop1x(ctx); 11676 { 11677 TCGv_i32 fp0 = tcg_temp_new_i32(); 11678 TCGv_i32 fp1 = tcg_temp_new_i32(); 11679 TCGv_i32 fp2 = tcg_temp_new_i32(); 11680 11681 gen_load_fpr32(ctx, fp0, fs); 11682 gen_load_fpr32(ctx, fp1, ft); 11683 gen_load_fpr32(ctx, fp2, fr); 11684 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2); 11685 tcg_temp_free_i32(fp0); 11686 tcg_temp_free_i32(fp1); 11687 gen_store_fpr32(ctx, fp2, fd); 11688 tcg_temp_free_i32(fp2); 11689 } 11690 break; 11691 case OPC_NMADD_D: 11692 check_cop1x(ctx); 11693 check_cp1_registers(ctx, fd | fs | ft | fr); 11694 { 11695 TCGv_i64 fp0 = tcg_temp_new_i64(); 11696 TCGv_i64 fp1 = tcg_temp_new_i64(); 11697 TCGv_i64 fp2 = tcg_temp_new_i64(); 11698 11699 gen_load_fpr64(ctx, fp0, fs); 11700 gen_load_fpr64(ctx, fp1, ft); 11701 gen_load_fpr64(ctx, fp2, fr); 11702 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2); 11703 tcg_temp_free_i64(fp0); 11704 tcg_temp_free_i64(fp1); 11705 gen_store_fpr64(ctx, fp2, fd); 11706 tcg_temp_free_i64(fp2); 11707 } 11708 break; 11709 case OPC_NMADD_PS: 11710 check_ps(ctx); 11711 { 11712 TCGv_i64 fp0 = tcg_temp_new_i64(); 11713 TCGv_i64 fp1 = tcg_temp_new_i64(); 11714 TCGv_i64 fp2 = tcg_temp_new_i64(); 11715 11716 gen_load_fpr64(ctx, fp0, fs); 11717 gen_load_fpr64(ctx, fp1, ft); 11718 gen_load_fpr64(ctx, fp2, fr); 11719 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2); 11720 tcg_temp_free_i64(fp0); 11721 tcg_temp_free_i64(fp1); 11722 gen_store_fpr64(ctx, fp2, fd); 11723 tcg_temp_free_i64(fp2); 11724 } 11725 break; 11726 case OPC_NMSUB_S: 11727 check_cop1x(ctx); 11728 { 11729 TCGv_i32 fp0 = tcg_temp_new_i32(); 11730 TCGv_i32 fp1 = tcg_temp_new_i32(); 11731 TCGv_i32 fp2 = tcg_temp_new_i32(); 11732 11733 gen_load_fpr32(ctx, fp0, fs); 11734 gen_load_fpr32(ctx, fp1, ft); 11735 gen_load_fpr32(ctx, fp2, fr); 11736 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2); 11737 tcg_temp_free_i32(fp0); 11738 tcg_temp_free_i32(fp1); 11739 gen_store_fpr32(ctx, fp2, fd); 11740 tcg_temp_free_i32(fp2); 11741 } 11742 break; 11743 case OPC_NMSUB_D: 11744 check_cop1x(ctx); 11745 check_cp1_registers(ctx, fd | fs | ft | fr); 11746 { 11747 TCGv_i64 fp0 = tcg_temp_new_i64(); 11748 TCGv_i64 fp1 = tcg_temp_new_i64(); 11749 TCGv_i64 fp2 = tcg_temp_new_i64(); 11750 11751 gen_load_fpr64(ctx, fp0, fs); 11752 gen_load_fpr64(ctx, fp1, ft); 11753 gen_load_fpr64(ctx, fp2, fr); 11754 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2); 11755 tcg_temp_free_i64(fp0); 11756 tcg_temp_free_i64(fp1); 11757 gen_store_fpr64(ctx, fp2, fd); 11758 tcg_temp_free_i64(fp2); 11759 } 11760 break; 11761 case OPC_NMSUB_PS: 11762 check_ps(ctx); 11763 { 11764 TCGv_i64 fp0 = tcg_temp_new_i64(); 11765 TCGv_i64 fp1 = tcg_temp_new_i64(); 11766 TCGv_i64 fp2 = tcg_temp_new_i64(); 11767 11768 gen_load_fpr64(ctx, fp0, fs); 11769 gen_load_fpr64(ctx, fp1, ft); 11770 gen_load_fpr64(ctx, fp2, fr); 11771 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2); 11772 tcg_temp_free_i64(fp0); 11773 tcg_temp_free_i64(fp1); 11774 gen_store_fpr64(ctx, fp2, fd); 11775 tcg_temp_free_i64(fp2); 11776 } 11777 break; 11778 default: 11779 MIPS_INVAL("flt3_arith"); 11780 gen_reserved_instruction(ctx); 11781 return; 11782 } 11783 } 11784 11785 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel) 11786 { 11787 TCGv t0; 11788 11789 #if !defined(CONFIG_USER_ONLY) 11790 /* 11791 * The Linux kernel will emulate rdhwr if it's not supported natively. 11792 * Therefore only check the ISA in system mode. 11793 */ 11794 check_insn(ctx, ISA_MIPS_R2); 11795 #endif 11796 t0 = tcg_temp_new(); 11797 11798 switch (rd) { 11799 case 0: 11800 gen_helper_rdhwr_cpunum(t0, cpu_env); 11801 gen_store_gpr(t0, rt); 11802 break; 11803 case 1: 11804 gen_helper_rdhwr_synci_step(t0, cpu_env); 11805 gen_store_gpr(t0, rt); 11806 break; 11807 case 2: 11808 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 11809 gen_io_start(); 11810 } 11811 gen_helper_rdhwr_cc(t0, cpu_env); 11812 gen_store_gpr(t0, rt); 11813 /* 11814 * Break the TB to be able to take timer interrupts immediately 11815 * after reading count. DISAS_STOP isn't sufficient, we need to ensure 11816 * we break completely out of translated code. 11817 */ 11818 gen_save_pc(ctx->base.pc_next + 4); 11819 ctx->base.is_jmp = DISAS_EXIT; 11820 break; 11821 case 3: 11822 gen_helper_rdhwr_ccres(t0, cpu_env); 11823 gen_store_gpr(t0, rt); 11824 break; 11825 case 4: 11826 check_insn(ctx, ISA_MIPS_R6); 11827 if (sel != 0) { 11828 /* 11829 * Performance counter registers are not implemented other than 11830 * control register 0. 11831 */ 11832 generate_exception(ctx, EXCP_RI); 11833 } 11834 gen_helper_rdhwr_performance(t0, cpu_env); 11835 gen_store_gpr(t0, rt); 11836 break; 11837 case 5: 11838 check_insn(ctx, ISA_MIPS_R6); 11839 gen_helper_rdhwr_xnp(t0, cpu_env); 11840 gen_store_gpr(t0, rt); 11841 break; 11842 case 29: 11843 #if defined(CONFIG_USER_ONLY) 11844 tcg_gen_ld_tl(t0, cpu_env, 11845 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 11846 gen_store_gpr(t0, rt); 11847 break; 11848 #else 11849 if ((ctx->hflags & MIPS_HFLAG_CP0) || 11850 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) { 11851 tcg_gen_ld_tl(t0, cpu_env, 11852 offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); 11853 gen_store_gpr(t0, rt); 11854 } else { 11855 gen_reserved_instruction(ctx); 11856 } 11857 break; 11858 #endif 11859 default: /* Invalid */ 11860 MIPS_INVAL("rdhwr"); 11861 gen_reserved_instruction(ctx); 11862 break; 11863 } 11864 tcg_temp_free(t0); 11865 } 11866 11867 static inline void clear_branch_hflags(DisasContext *ctx) 11868 { 11869 ctx->hflags &= ~MIPS_HFLAG_BMASK; 11870 if (ctx->base.is_jmp == DISAS_NEXT) { 11871 save_cpu_state(ctx, 0); 11872 } else { 11873 /* 11874 * It is not safe to save ctx->hflags as hflags may be changed 11875 * in execution time by the instruction in delay / forbidden slot. 11876 */ 11877 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK); 11878 } 11879 } 11880 11881 static void gen_branch(DisasContext *ctx, int insn_bytes) 11882 { 11883 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11884 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK; 11885 /* Branches completion */ 11886 clear_branch_hflags(ctx); 11887 ctx->base.is_jmp = DISAS_NORETURN; 11888 /* FIXME: Need to clear can_do_io. */ 11889 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) { 11890 case MIPS_HFLAG_FBNSLOT: 11891 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes); 11892 break; 11893 case MIPS_HFLAG_B: 11894 /* unconditional branch */ 11895 if (proc_hflags & MIPS_HFLAG_BX) { 11896 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16); 11897 } 11898 gen_goto_tb(ctx, 0, ctx->btarget); 11899 break; 11900 case MIPS_HFLAG_BL: 11901 /* blikely taken case */ 11902 gen_goto_tb(ctx, 0, ctx->btarget); 11903 break; 11904 case MIPS_HFLAG_BC: 11905 /* Conditional branch */ 11906 { 11907 TCGLabel *l1 = gen_new_label(); 11908 11909 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 11910 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); 11911 gen_set_label(l1); 11912 gen_goto_tb(ctx, 0, ctx->btarget); 11913 } 11914 break; 11915 case MIPS_HFLAG_BR: 11916 /* unconditional branch to register */ 11917 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) { 11918 TCGv t0 = tcg_temp_new(); 11919 TCGv_i32 t1 = tcg_temp_new_i32(); 11920 11921 tcg_gen_andi_tl(t0, btarget, 0x1); 11922 tcg_gen_trunc_tl_i32(t1, t0); 11923 tcg_temp_free(t0); 11924 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16); 11925 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT); 11926 tcg_gen_or_i32(hflags, hflags, t1); 11927 tcg_temp_free_i32(t1); 11928 11929 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1); 11930 } else { 11931 tcg_gen_mov_tl(cpu_PC, btarget); 11932 } 11933 if (ctx->base.singlestep_enabled) { 11934 save_cpu_state(ctx, 0); 11935 gen_helper_raise_exception_debug(cpu_env); 11936 } 11937 tcg_gen_lookup_and_goto_ptr(); 11938 break; 11939 default: 11940 LOG_DISAS("unknown branch 0x%x\n", proc_hflags); 11941 gen_reserved_instruction(ctx); 11942 } 11943 } 11944 } 11945 11946 /* Compact Branches */ 11947 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc, 11948 int rs, int rt, int32_t offset) 11949 { 11950 int bcond_compute = 0; 11951 TCGv t0 = tcg_temp_new(); 11952 TCGv t1 = tcg_temp_new(); 11953 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0; 11954 11955 if (ctx->hflags & MIPS_HFLAG_BMASK) { 11956 #ifdef MIPS_DEBUG_DISAS 11957 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx 11958 "\n", ctx->base.pc_next); 11959 #endif 11960 gen_reserved_instruction(ctx); 11961 goto out; 11962 } 11963 11964 /* Load needed operands and calculate btarget */ 11965 switch (opc) { 11966 /* compact branch */ 11967 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 11968 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 11969 gen_load_gpr(t0, rs); 11970 gen_load_gpr(t1, rt); 11971 bcond_compute = 1; 11972 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11973 if (rs <= rt && rs == 0) { 11974 /* OPC_BEQZALC, OPC_BNEZALC */ 11975 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11976 } 11977 break; 11978 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 11979 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 11980 gen_load_gpr(t0, rs); 11981 gen_load_gpr(t1, rt); 11982 bcond_compute = 1; 11983 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11984 break; 11985 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 11986 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 11987 if (rs == 0 || rs == rt) { 11988 /* OPC_BLEZALC, OPC_BGEZALC */ 11989 /* OPC_BGTZALC, OPC_BLTZALC */ 11990 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 11991 } 11992 gen_load_gpr(t0, rs); 11993 gen_load_gpr(t1, rt); 11994 bcond_compute = 1; 11995 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 11996 break; 11997 case OPC_BC: 11998 case OPC_BALC: 11999 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 12000 break; 12001 case OPC_BEQZC: 12002 case OPC_BNEZC: 12003 if (rs != 0) { 12004 /* OPC_BEQZC, OPC_BNEZC */ 12005 gen_load_gpr(t0, rs); 12006 bcond_compute = 1; 12007 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 12008 } else { 12009 /* OPC_JIC, OPC_JIALC */ 12010 TCGv tbase = tcg_temp_new(); 12011 TCGv toffset = tcg_temp_new(); 12012 12013 gen_load_gpr(tbase, rt); 12014 tcg_gen_movi_tl(toffset, offset); 12015 gen_op_addr_add(ctx, btarget, tbase, toffset); 12016 tcg_temp_free(tbase); 12017 tcg_temp_free(toffset); 12018 } 12019 break; 12020 default: 12021 MIPS_INVAL("Compact branch/jump"); 12022 gen_reserved_instruction(ctx); 12023 goto out; 12024 } 12025 12026 if (bcond_compute == 0) { 12027 /* Unconditional compact branch */ 12028 switch (opc) { 12029 case OPC_JIALC: 12030 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 12031 /* Fallthrough */ 12032 case OPC_JIC: 12033 ctx->hflags |= MIPS_HFLAG_BR; 12034 break; 12035 case OPC_BALC: 12036 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit); 12037 /* Fallthrough */ 12038 case OPC_BC: 12039 ctx->hflags |= MIPS_HFLAG_B; 12040 break; 12041 default: 12042 MIPS_INVAL("Compact branch/jump"); 12043 gen_reserved_instruction(ctx); 12044 goto out; 12045 } 12046 12047 /* Generating branch here as compact branches don't have delay slot */ 12048 gen_branch(ctx, 4); 12049 } else { 12050 /* Conditional compact branch */ 12051 TCGLabel *fs = gen_new_label(); 12052 save_cpu_state(ctx, 0); 12053 12054 switch (opc) { 12055 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */ 12056 if (rs == 0 && rt != 0) { 12057 /* OPC_BLEZALC */ 12058 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 12059 } else if (rs != 0 && rt != 0 && rs == rt) { 12060 /* OPC_BGEZALC */ 12061 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 12062 } else { 12063 /* OPC_BGEUC */ 12064 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 12065 } 12066 break; 12067 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */ 12068 if (rs == 0 && rt != 0) { 12069 /* OPC_BGTZALC */ 12070 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 12071 } else if (rs != 0 && rt != 0 && rs == rt) { 12072 /* OPC_BLTZALC */ 12073 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 12074 } else { 12075 /* OPC_BLTUC */ 12076 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 12077 } 12078 break; 12079 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */ 12080 if (rs == 0 && rt != 0) { 12081 /* OPC_BLEZC */ 12082 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 12083 } else if (rs != 0 && rt != 0 && rs == rt) { 12084 /* OPC_BGEZC */ 12085 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 12086 } else { 12087 /* OPC_BGEC */ 12088 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 12089 } 12090 break; 12091 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */ 12092 if (rs == 0 && rt != 0) { 12093 /* OPC_BGTZC */ 12094 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 12095 } else if (rs != 0 && rt != 0 && rs == rt) { 12096 /* OPC_BLTZC */ 12097 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 12098 } else { 12099 /* OPC_BLTC */ 12100 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 12101 } 12102 break; 12103 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */ 12104 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 12105 if (rs >= rt) { 12106 /* OPC_BOVC, OPC_BNVC */ 12107 TCGv t2 = tcg_temp_new(); 12108 TCGv t3 = tcg_temp_new(); 12109 TCGv t4 = tcg_temp_new(); 12110 TCGv input_overflow = tcg_temp_new(); 12111 12112 gen_load_gpr(t0, rs); 12113 gen_load_gpr(t1, rt); 12114 tcg_gen_ext32s_tl(t2, t0); 12115 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0); 12116 tcg_gen_ext32s_tl(t3, t1); 12117 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1); 12118 tcg_gen_or_tl(input_overflow, input_overflow, t4); 12119 12120 tcg_gen_add_tl(t4, t2, t3); 12121 tcg_gen_ext32s_tl(t4, t4); 12122 tcg_gen_xor_tl(t2, t2, t3); 12123 tcg_gen_xor_tl(t3, t4, t3); 12124 tcg_gen_andc_tl(t2, t3, t2); 12125 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0); 12126 tcg_gen_or_tl(t4, t4, input_overflow); 12127 if (opc == OPC_BOVC) { 12128 /* OPC_BOVC */ 12129 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs); 12130 } else { 12131 /* OPC_BNVC */ 12132 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs); 12133 } 12134 tcg_temp_free(input_overflow); 12135 tcg_temp_free(t4); 12136 tcg_temp_free(t3); 12137 tcg_temp_free(t2); 12138 } else if (rs < rt && rs == 0) { 12139 /* OPC_BEQZALC, OPC_BNEZALC */ 12140 if (opc == OPC_BEQZALC) { 12141 /* OPC_BEQZALC */ 12142 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs); 12143 } else { 12144 /* OPC_BNEZALC */ 12145 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs); 12146 } 12147 } else { 12148 /* OPC_BEQC, OPC_BNEC */ 12149 if (opc == OPC_BEQC) { 12150 /* OPC_BEQC */ 12151 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs); 12152 } else { 12153 /* OPC_BNEC */ 12154 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs); 12155 } 12156 } 12157 break; 12158 case OPC_BEQZC: 12159 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 12160 break; 12161 case OPC_BNEZC: 12162 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs); 12163 break; 12164 default: 12165 MIPS_INVAL("Compact conditional branch/jump"); 12166 gen_reserved_instruction(ctx); 12167 goto out; 12168 } 12169 12170 /* Generating branch here as compact branches don't have delay slot */ 12171 gen_goto_tb(ctx, 1, ctx->btarget); 12172 gen_set_label(fs); 12173 12174 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 12175 } 12176 12177 out: 12178 tcg_temp_free(t0); 12179 tcg_temp_free(t1); 12180 } 12181 12182 void gen_addiupc(DisasContext *ctx, int rx, int imm, 12183 int is_64_bit, int extended) 12184 { 12185 TCGv t0; 12186 12187 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) { 12188 gen_reserved_instruction(ctx); 12189 return; 12190 } 12191 12192 t0 = tcg_temp_new(); 12193 12194 tcg_gen_movi_tl(t0, pc_relative_pc(ctx)); 12195 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm); 12196 if (!is_64_bit) { 12197 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); 12198 } 12199 12200 tcg_temp_free(t0); 12201 } 12202 12203 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, 12204 int16_t offset) 12205 { 12206 TCGv_i32 t0 = tcg_const_i32(op); 12207 TCGv t1 = tcg_temp_new(); 12208 gen_base_offset_addr(ctx, t1, base, offset); 12209 gen_helper_cache(cpu_env, t1, t0); 12210 tcg_temp_free(t1); 12211 tcg_temp_free_i32(t0); 12212 } 12213 12214 static inline bool is_uhi(int sdbbp_code) 12215 { 12216 #ifdef CONFIG_USER_ONLY 12217 return false; 12218 #else 12219 return semihosting_enabled() && sdbbp_code == 1; 12220 #endif 12221 } 12222 12223 #ifdef CONFIG_USER_ONLY 12224 /* The above should dead-code away any calls to this..*/ 12225 static inline void gen_helper_do_semihosting(void *env) 12226 { 12227 g_assert_not_reached(); 12228 } 12229 #endif 12230 12231 void gen_ldxs(DisasContext *ctx, int base, int index, int rd) 12232 { 12233 TCGv t0 = tcg_temp_new(); 12234 TCGv t1 = tcg_temp_new(); 12235 12236 gen_load_gpr(t0, base); 12237 12238 if (index != 0) { 12239 gen_load_gpr(t1, index); 12240 tcg_gen_shli_tl(t1, t1, 2); 12241 gen_op_addr_add(ctx, t0, t1, t0); 12242 } 12243 12244 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); 12245 gen_store_gpr(t1, rd); 12246 12247 tcg_temp_free(t0); 12248 tcg_temp_free(t1); 12249 } 12250 12251 static void gen_sync(int stype) 12252 { 12253 TCGBar tcg_mo = TCG_BAR_SC; 12254 12255 switch (stype) { 12256 case 0x4: /* SYNC_WMB */ 12257 tcg_mo |= TCG_MO_ST_ST; 12258 break; 12259 case 0x10: /* SYNC_MB */ 12260 tcg_mo |= TCG_MO_ALL; 12261 break; 12262 case 0x11: /* SYNC_ACQUIRE */ 12263 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; 12264 break; 12265 case 0x12: /* SYNC_RELEASE */ 12266 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; 12267 break; 12268 case 0x13: /* SYNC_RMB */ 12269 tcg_mo |= TCG_MO_LD_LD; 12270 break; 12271 default: 12272 tcg_mo |= TCG_MO_ALL; 12273 break; 12274 } 12275 12276 tcg_gen_mb(tcg_mo); 12277 } 12278 12279 /* ISA extensions (ASEs) */ 12280 12281 /* MIPS16 extension to MIPS32 */ 12282 #include "mips16e_translate.c.inc" 12283 12284 /* microMIPS extension to MIPS32/MIPS64 */ 12285 12286 /* 12287 * Values for microMIPS fmt field. Variable-width, depending on which 12288 * formats the instruction supports. 12289 */ 12290 enum { 12291 FMT_SD_S = 0, 12292 FMT_SD_D = 1, 12293 12294 FMT_SDPS_S = 0, 12295 FMT_SDPS_D = 1, 12296 FMT_SDPS_PS = 2, 12297 12298 FMT_SWL_S = 0, 12299 FMT_SWL_W = 1, 12300 FMT_SWL_L = 2, 12301 12302 FMT_DWL_D = 0, 12303 FMT_DWL_W = 1, 12304 FMT_DWL_L = 2 12305 }; 12306 12307 #include "micromips_translate.c.inc" 12308 12309 #include "nanomips_translate.c.inc" 12310 12311 /* MIPSDSP functions. */ 12312 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc, 12313 int rd, int base, int offset) 12314 { 12315 TCGv t0; 12316 12317 check_dsp(ctx); 12318 t0 = tcg_temp_new(); 12319 12320 if (base == 0) { 12321 gen_load_gpr(t0, offset); 12322 } else if (offset == 0) { 12323 gen_load_gpr(t0, base); 12324 } else { 12325 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]); 12326 } 12327 12328 switch (opc) { 12329 case OPC_LBUX: 12330 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB); 12331 gen_store_gpr(t0, rd); 12332 break; 12333 case OPC_LHX: 12334 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW); 12335 gen_store_gpr(t0, rd); 12336 break; 12337 case OPC_LWX: 12338 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); 12339 gen_store_gpr(t0, rd); 12340 break; 12341 #if defined(TARGET_MIPS64) 12342 case OPC_LDX: 12343 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); 12344 gen_store_gpr(t0, rd); 12345 break; 12346 #endif 12347 } 12348 tcg_temp_free(t0); 12349 } 12350 12351 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2, 12352 int ret, int v1, int v2) 12353 { 12354 TCGv v1_t; 12355 TCGv v2_t; 12356 12357 if (ret == 0) { 12358 /* Treat as NOP. */ 12359 return; 12360 } 12361 12362 v1_t = tcg_temp_new(); 12363 v2_t = tcg_temp_new(); 12364 12365 gen_load_gpr(v1_t, v1); 12366 gen_load_gpr(v2_t, v2); 12367 12368 switch (op1) { 12369 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */ 12370 case OPC_MULT_G_2E: 12371 check_dsp_r2(ctx); 12372 switch (op2) { 12373 case OPC_ADDUH_QB: 12374 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t); 12375 break; 12376 case OPC_ADDUH_R_QB: 12377 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t); 12378 break; 12379 case OPC_ADDQH_PH: 12380 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t); 12381 break; 12382 case OPC_ADDQH_R_PH: 12383 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 12384 break; 12385 case OPC_ADDQH_W: 12386 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t); 12387 break; 12388 case OPC_ADDQH_R_W: 12389 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t); 12390 break; 12391 case OPC_SUBUH_QB: 12392 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t); 12393 break; 12394 case OPC_SUBUH_R_QB: 12395 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t); 12396 break; 12397 case OPC_SUBQH_PH: 12398 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t); 12399 break; 12400 case OPC_SUBQH_R_PH: 12401 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t); 12402 break; 12403 case OPC_SUBQH_W: 12404 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t); 12405 break; 12406 case OPC_SUBQH_R_W: 12407 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t); 12408 break; 12409 } 12410 break; 12411 case OPC_ABSQ_S_PH_DSP: 12412 switch (op2) { 12413 case OPC_ABSQ_S_QB: 12414 check_dsp_r2(ctx); 12415 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env); 12416 break; 12417 case OPC_ABSQ_S_PH: 12418 check_dsp(ctx); 12419 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env); 12420 break; 12421 case OPC_ABSQ_S_W: 12422 check_dsp(ctx); 12423 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env); 12424 break; 12425 case OPC_PRECEQ_W_PHL: 12426 check_dsp(ctx); 12427 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000); 12428 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12429 break; 12430 case OPC_PRECEQ_W_PHR: 12431 check_dsp(ctx); 12432 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF); 12433 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16); 12434 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 12435 break; 12436 case OPC_PRECEQU_PH_QBL: 12437 check_dsp(ctx); 12438 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t); 12439 break; 12440 case OPC_PRECEQU_PH_QBR: 12441 check_dsp(ctx); 12442 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t); 12443 break; 12444 case OPC_PRECEQU_PH_QBLA: 12445 check_dsp(ctx); 12446 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t); 12447 break; 12448 case OPC_PRECEQU_PH_QBRA: 12449 check_dsp(ctx); 12450 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t); 12451 break; 12452 case OPC_PRECEU_PH_QBL: 12453 check_dsp(ctx); 12454 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t); 12455 break; 12456 case OPC_PRECEU_PH_QBR: 12457 check_dsp(ctx); 12458 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t); 12459 break; 12460 case OPC_PRECEU_PH_QBLA: 12461 check_dsp(ctx); 12462 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t); 12463 break; 12464 case OPC_PRECEU_PH_QBRA: 12465 check_dsp(ctx); 12466 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t); 12467 break; 12468 } 12469 break; 12470 case OPC_ADDU_QB_DSP: 12471 switch (op2) { 12472 case OPC_ADDQ_PH: 12473 check_dsp(ctx); 12474 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12475 break; 12476 case OPC_ADDQ_S_PH: 12477 check_dsp(ctx); 12478 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12479 break; 12480 case OPC_ADDQ_S_W: 12481 check_dsp(ctx); 12482 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12483 break; 12484 case OPC_ADDU_QB: 12485 check_dsp(ctx); 12486 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12487 break; 12488 case OPC_ADDU_S_QB: 12489 check_dsp(ctx); 12490 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12491 break; 12492 case OPC_ADDU_PH: 12493 check_dsp_r2(ctx); 12494 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12495 break; 12496 case OPC_ADDU_S_PH: 12497 check_dsp_r2(ctx); 12498 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12499 break; 12500 case OPC_SUBQ_PH: 12501 check_dsp(ctx); 12502 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12503 break; 12504 case OPC_SUBQ_S_PH: 12505 check_dsp(ctx); 12506 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12507 break; 12508 case OPC_SUBQ_S_W: 12509 check_dsp(ctx); 12510 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12511 break; 12512 case OPC_SUBU_QB: 12513 check_dsp(ctx); 12514 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12515 break; 12516 case OPC_SUBU_S_QB: 12517 check_dsp(ctx); 12518 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12519 break; 12520 case OPC_SUBU_PH: 12521 check_dsp_r2(ctx); 12522 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12523 break; 12524 case OPC_SUBU_S_PH: 12525 check_dsp_r2(ctx); 12526 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12527 break; 12528 case OPC_ADDSC: 12529 check_dsp(ctx); 12530 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12531 break; 12532 case OPC_ADDWC: 12533 check_dsp(ctx); 12534 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12535 break; 12536 case OPC_MODSUB: 12537 check_dsp(ctx); 12538 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t); 12539 break; 12540 case OPC_RADDU_W_QB: 12541 check_dsp(ctx); 12542 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t); 12543 break; 12544 } 12545 break; 12546 case OPC_CMPU_EQ_QB_DSP: 12547 switch (op2) { 12548 case OPC_PRECR_QB_PH: 12549 check_dsp_r2(ctx); 12550 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t); 12551 break; 12552 case OPC_PRECRQ_QB_PH: 12553 check_dsp(ctx); 12554 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t); 12555 break; 12556 case OPC_PRECR_SRA_PH_W: 12557 check_dsp_r2(ctx); 12558 { 12559 TCGv_i32 sa_t = tcg_const_i32(v2); 12560 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t, 12561 cpu_gpr[ret]); 12562 tcg_temp_free_i32(sa_t); 12563 break; 12564 } 12565 case OPC_PRECR_SRA_R_PH_W: 12566 check_dsp_r2(ctx); 12567 { 12568 TCGv_i32 sa_t = tcg_const_i32(v2); 12569 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t, 12570 cpu_gpr[ret]); 12571 tcg_temp_free_i32(sa_t); 12572 break; 12573 } 12574 case OPC_PRECRQ_PH_W: 12575 check_dsp(ctx); 12576 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t); 12577 break; 12578 case OPC_PRECRQ_RS_PH_W: 12579 check_dsp(ctx); 12580 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12581 break; 12582 case OPC_PRECRQU_S_QB_PH: 12583 check_dsp(ctx); 12584 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12585 break; 12586 } 12587 break; 12588 #ifdef TARGET_MIPS64 12589 case OPC_ABSQ_S_QH_DSP: 12590 switch (op2) { 12591 case OPC_PRECEQ_L_PWL: 12592 check_dsp(ctx); 12593 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull); 12594 break; 12595 case OPC_PRECEQ_L_PWR: 12596 check_dsp(ctx); 12597 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32); 12598 break; 12599 case OPC_PRECEQ_PW_QHL: 12600 check_dsp(ctx); 12601 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t); 12602 break; 12603 case OPC_PRECEQ_PW_QHR: 12604 check_dsp(ctx); 12605 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t); 12606 break; 12607 case OPC_PRECEQ_PW_QHLA: 12608 check_dsp(ctx); 12609 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t); 12610 break; 12611 case OPC_PRECEQ_PW_QHRA: 12612 check_dsp(ctx); 12613 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t); 12614 break; 12615 case OPC_PRECEQU_QH_OBL: 12616 check_dsp(ctx); 12617 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t); 12618 break; 12619 case OPC_PRECEQU_QH_OBR: 12620 check_dsp(ctx); 12621 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t); 12622 break; 12623 case OPC_PRECEQU_QH_OBLA: 12624 check_dsp(ctx); 12625 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t); 12626 break; 12627 case OPC_PRECEQU_QH_OBRA: 12628 check_dsp(ctx); 12629 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t); 12630 break; 12631 case OPC_PRECEU_QH_OBL: 12632 check_dsp(ctx); 12633 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t); 12634 break; 12635 case OPC_PRECEU_QH_OBR: 12636 check_dsp(ctx); 12637 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t); 12638 break; 12639 case OPC_PRECEU_QH_OBLA: 12640 check_dsp(ctx); 12641 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t); 12642 break; 12643 case OPC_PRECEU_QH_OBRA: 12644 check_dsp(ctx); 12645 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t); 12646 break; 12647 case OPC_ABSQ_S_OB: 12648 check_dsp_r2(ctx); 12649 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env); 12650 break; 12651 case OPC_ABSQ_S_PW: 12652 check_dsp(ctx); 12653 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env); 12654 break; 12655 case OPC_ABSQ_S_QH: 12656 check_dsp(ctx); 12657 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env); 12658 break; 12659 } 12660 break; 12661 case OPC_ADDU_OB_DSP: 12662 switch (op2) { 12663 case OPC_RADDU_L_OB: 12664 check_dsp(ctx); 12665 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t); 12666 break; 12667 case OPC_SUBQ_PW: 12668 check_dsp(ctx); 12669 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12670 break; 12671 case OPC_SUBQ_S_PW: 12672 check_dsp(ctx); 12673 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12674 break; 12675 case OPC_SUBQ_QH: 12676 check_dsp(ctx); 12677 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12678 break; 12679 case OPC_SUBQ_S_QH: 12680 check_dsp(ctx); 12681 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12682 break; 12683 case OPC_SUBU_OB: 12684 check_dsp(ctx); 12685 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12686 break; 12687 case OPC_SUBU_S_OB: 12688 check_dsp(ctx); 12689 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12690 break; 12691 case OPC_SUBU_QH: 12692 check_dsp_r2(ctx); 12693 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12694 break; 12695 case OPC_SUBU_S_QH: 12696 check_dsp_r2(ctx); 12697 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12698 break; 12699 case OPC_SUBUH_OB: 12700 check_dsp_r2(ctx); 12701 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t); 12702 break; 12703 case OPC_SUBUH_R_OB: 12704 check_dsp_r2(ctx); 12705 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t); 12706 break; 12707 case OPC_ADDQ_PW: 12708 check_dsp(ctx); 12709 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12710 break; 12711 case OPC_ADDQ_S_PW: 12712 check_dsp(ctx); 12713 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12714 break; 12715 case OPC_ADDQ_QH: 12716 check_dsp(ctx); 12717 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12718 break; 12719 case OPC_ADDQ_S_QH: 12720 check_dsp(ctx); 12721 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12722 break; 12723 case OPC_ADDU_OB: 12724 check_dsp(ctx); 12725 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12726 break; 12727 case OPC_ADDU_S_OB: 12728 check_dsp(ctx); 12729 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12730 break; 12731 case OPC_ADDU_QH: 12732 check_dsp_r2(ctx); 12733 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12734 break; 12735 case OPC_ADDU_S_QH: 12736 check_dsp_r2(ctx); 12737 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12738 break; 12739 case OPC_ADDUH_OB: 12740 check_dsp_r2(ctx); 12741 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t); 12742 break; 12743 case OPC_ADDUH_R_OB: 12744 check_dsp_r2(ctx); 12745 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t); 12746 break; 12747 } 12748 break; 12749 case OPC_CMPU_EQ_OB_DSP: 12750 switch (op2) { 12751 case OPC_PRECR_OB_QH: 12752 check_dsp_r2(ctx); 12753 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t); 12754 break; 12755 case OPC_PRECR_SRA_QH_PW: 12756 check_dsp_r2(ctx); 12757 { 12758 TCGv_i32 ret_t = tcg_const_i32(ret); 12759 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t); 12760 tcg_temp_free_i32(ret_t); 12761 break; 12762 } 12763 case OPC_PRECR_SRA_R_QH_PW: 12764 check_dsp_r2(ctx); 12765 { 12766 TCGv_i32 sa_v = tcg_const_i32(ret); 12767 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v); 12768 tcg_temp_free_i32(sa_v); 12769 break; 12770 } 12771 case OPC_PRECRQ_OB_QH: 12772 check_dsp(ctx); 12773 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t); 12774 break; 12775 case OPC_PRECRQ_PW_L: 12776 check_dsp(ctx); 12777 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t); 12778 break; 12779 case OPC_PRECRQ_QH_PW: 12780 check_dsp(ctx); 12781 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t); 12782 break; 12783 case OPC_PRECRQ_RS_QH_PW: 12784 check_dsp(ctx); 12785 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12786 break; 12787 case OPC_PRECRQU_S_OB_QH: 12788 check_dsp(ctx); 12789 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12790 break; 12791 } 12792 break; 12793 #endif 12794 } 12795 12796 tcg_temp_free(v1_t); 12797 tcg_temp_free(v2_t); 12798 } 12799 12800 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc, 12801 int ret, int v1, int v2) 12802 { 12803 uint32_t op2; 12804 TCGv t0; 12805 TCGv v1_t; 12806 TCGv v2_t; 12807 12808 if (ret == 0) { 12809 /* Treat as NOP. */ 12810 return; 12811 } 12812 12813 t0 = tcg_temp_new(); 12814 v1_t = tcg_temp_new(); 12815 v2_t = tcg_temp_new(); 12816 12817 tcg_gen_movi_tl(t0, v1); 12818 gen_load_gpr(v1_t, v1); 12819 gen_load_gpr(v2_t, v2); 12820 12821 switch (opc) { 12822 case OPC_SHLL_QB_DSP: 12823 { 12824 op2 = MASK_SHLL_QB(ctx->opcode); 12825 switch (op2) { 12826 case OPC_SHLL_QB: 12827 check_dsp(ctx); 12828 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env); 12829 break; 12830 case OPC_SHLLV_QB: 12831 check_dsp(ctx); 12832 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12833 break; 12834 case OPC_SHLL_PH: 12835 check_dsp(ctx); 12836 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env); 12837 break; 12838 case OPC_SHLLV_PH: 12839 check_dsp(ctx); 12840 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12841 break; 12842 case OPC_SHLL_S_PH: 12843 check_dsp(ctx); 12844 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env); 12845 break; 12846 case OPC_SHLLV_S_PH: 12847 check_dsp(ctx); 12848 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12849 break; 12850 case OPC_SHLL_S_W: 12851 check_dsp(ctx); 12852 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env); 12853 break; 12854 case OPC_SHLLV_S_W: 12855 check_dsp(ctx); 12856 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 12857 break; 12858 case OPC_SHRL_QB: 12859 check_dsp(ctx); 12860 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t); 12861 break; 12862 case OPC_SHRLV_QB: 12863 check_dsp(ctx); 12864 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t); 12865 break; 12866 case OPC_SHRL_PH: 12867 check_dsp_r2(ctx); 12868 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t); 12869 break; 12870 case OPC_SHRLV_PH: 12871 check_dsp_r2(ctx); 12872 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t); 12873 break; 12874 case OPC_SHRA_QB: 12875 check_dsp_r2(ctx); 12876 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t); 12877 break; 12878 case OPC_SHRA_R_QB: 12879 check_dsp_r2(ctx); 12880 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t); 12881 break; 12882 case OPC_SHRAV_QB: 12883 check_dsp_r2(ctx); 12884 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t); 12885 break; 12886 case OPC_SHRAV_R_QB: 12887 check_dsp_r2(ctx); 12888 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t); 12889 break; 12890 case OPC_SHRA_PH: 12891 check_dsp(ctx); 12892 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t); 12893 break; 12894 case OPC_SHRA_R_PH: 12895 check_dsp(ctx); 12896 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t); 12897 break; 12898 case OPC_SHRAV_PH: 12899 check_dsp(ctx); 12900 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t); 12901 break; 12902 case OPC_SHRAV_R_PH: 12903 check_dsp(ctx); 12904 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t); 12905 break; 12906 case OPC_SHRA_R_W: 12907 check_dsp(ctx); 12908 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t); 12909 break; 12910 case OPC_SHRAV_R_W: 12911 check_dsp(ctx); 12912 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t); 12913 break; 12914 default: /* Invalid */ 12915 MIPS_INVAL("MASK SHLL.QB"); 12916 gen_reserved_instruction(ctx); 12917 break; 12918 } 12919 break; 12920 } 12921 #ifdef TARGET_MIPS64 12922 case OPC_SHLL_OB_DSP: 12923 op2 = MASK_SHLL_OB(ctx->opcode); 12924 switch (op2) { 12925 case OPC_SHLL_PW: 12926 check_dsp(ctx); 12927 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env); 12928 break; 12929 case OPC_SHLLV_PW: 12930 check_dsp(ctx); 12931 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12932 break; 12933 case OPC_SHLL_S_PW: 12934 check_dsp(ctx); 12935 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env); 12936 break; 12937 case OPC_SHLLV_S_PW: 12938 check_dsp(ctx); 12939 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12940 break; 12941 case OPC_SHLL_OB: 12942 check_dsp(ctx); 12943 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env); 12944 break; 12945 case OPC_SHLLV_OB: 12946 check_dsp(ctx); 12947 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12948 break; 12949 case OPC_SHLL_QH: 12950 check_dsp(ctx); 12951 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env); 12952 break; 12953 case OPC_SHLLV_QH: 12954 check_dsp(ctx); 12955 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12956 break; 12957 case OPC_SHLL_S_QH: 12958 check_dsp(ctx); 12959 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env); 12960 break; 12961 case OPC_SHLLV_S_QH: 12962 check_dsp(ctx); 12963 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env); 12964 break; 12965 case OPC_SHRA_OB: 12966 check_dsp_r2(ctx); 12967 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0); 12968 break; 12969 case OPC_SHRAV_OB: 12970 check_dsp_r2(ctx); 12971 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t); 12972 break; 12973 case OPC_SHRA_R_OB: 12974 check_dsp_r2(ctx); 12975 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0); 12976 break; 12977 case OPC_SHRAV_R_OB: 12978 check_dsp_r2(ctx); 12979 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t); 12980 break; 12981 case OPC_SHRA_PW: 12982 check_dsp(ctx); 12983 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0); 12984 break; 12985 case OPC_SHRAV_PW: 12986 check_dsp(ctx); 12987 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t); 12988 break; 12989 case OPC_SHRA_R_PW: 12990 check_dsp(ctx); 12991 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0); 12992 break; 12993 case OPC_SHRAV_R_PW: 12994 check_dsp(ctx); 12995 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t); 12996 break; 12997 case OPC_SHRA_QH: 12998 check_dsp(ctx); 12999 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0); 13000 break; 13001 case OPC_SHRAV_QH: 13002 check_dsp(ctx); 13003 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t); 13004 break; 13005 case OPC_SHRA_R_QH: 13006 check_dsp(ctx); 13007 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0); 13008 break; 13009 case OPC_SHRAV_R_QH: 13010 check_dsp(ctx); 13011 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t); 13012 break; 13013 case OPC_SHRL_OB: 13014 check_dsp(ctx); 13015 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0); 13016 break; 13017 case OPC_SHRLV_OB: 13018 check_dsp(ctx); 13019 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t); 13020 break; 13021 case OPC_SHRL_QH: 13022 check_dsp_r2(ctx); 13023 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0); 13024 break; 13025 case OPC_SHRLV_QH: 13026 check_dsp_r2(ctx); 13027 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t); 13028 break; 13029 default: /* Invalid */ 13030 MIPS_INVAL("MASK SHLL.OB"); 13031 gen_reserved_instruction(ctx); 13032 break; 13033 } 13034 break; 13035 #endif 13036 } 13037 13038 tcg_temp_free(t0); 13039 tcg_temp_free(v1_t); 13040 tcg_temp_free(v2_t); 13041 } 13042 13043 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2, 13044 int ret, int v1, int v2, int check_ret) 13045 { 13046 TCGv_i32 t0; 13047 TCGv v1_t; 13048 TCGv v2_t; 13049 13050 if ((ret == 0) && (check_ret == 1)) { 13051 /* Treat as NOP. */ 13052 return; 13053 } 13054 13055 t0 = tcg_temp_new_i32(); 13056 v1_t = tcg_temp_new(); 13057 v2_t = tcg_temp_new(); 13058 13059 tcg_gen_movi_i32(t0, ret); 13060 gen_load_gpr(v1_t, v1); 13061 gen_load_gpr(v2_t, v2); 13062 13063 switch (op1) { 13064 /* 13065 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 13066 * the same mask and op1. 13067 */ 13068 case OPC_MULT_G_2E: 13069 check_dsp_r2(ctx); 13070 switch (op2) { 13071 case OPC_MUL_PH: 13072 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13073 break; 13074 case OPC_MUL_S_PH: 13075 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13076 break; 13077 case OPC_MULQ_S_W: 13078 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13079 break; 13080 case OPC_MULQ_RS_W: 13081 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13082 break; 13083 } 13084 break; 13085 case OPC_DPA_W_PH_DSP: 13086 switch (op2) { 13087 case OPC_DPAU_H_QBL: 13088 check_dsp(ctx); 13089 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env); 13090 break; 13091 case OPC_DPAU_H_QBR: 13092 check_dsp(ctx); 13093 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env); 13094 break; 13095 case OPC_DPSU_H_QBL: 13096 check_dsp(ctx); 13097 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env); 13098 break; 13099 case OPC_DPSU_H_QBR: 13100 check_dsp(ctx); 13101 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env); 13102 break; 13103 case OPC_DPA_W_PH: 13104 check_dsp_r2(ctx); 13105 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env); 13106 break; 13107 case OPC_DPAX_W_PH: 13108 check_dsp_r2(ctx); 13109 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env); 13110 break; 13111 case OPC_DPAQ_S_W_PH: 13112 check_dsp(ctx); 13113 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env); 13114 break; 13115 case OPC_DPAQX_S_W_PH: 13116 check_dsp_r2(ctx); 13117 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env); 13118 break; 13119 case OPC_DPAQX_SA_W_PH: 13120 check_dsp_r2(ctx); 13121 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); 13122 break; 13123 case OPC_DPS_W_PH: 13124 check_dsp_r2(ctx); 13125 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env); 13126 break; 13127 case OPC_DPSX_W_PH: 13128 check_dsp_r2(ctx); 13129 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env); 13130 break; 13131 case OPC_DPSQ_S_W_PH: 13132 check_dsp(ctx); 13133 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env); 13134 break; 13135 case OPC_DPSQX_S_W_PH: 13136 check_dsp_r2(ctx); 13137 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env); 13138 break; 13139 case OPC_DPSQX_SA_W_PH: 13140 check_dsp_r2(ctx); 13141 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env); 13142 break; 13143 case OPC_MULSAQ_S_W_PH: 13144 check_dsp(ctx); 13145 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env); 13146 break; 13147 case OPC_DPAQ_SA_L_W: 13148 check_dsp(ctx); 13149 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env); 13150 break; 13151 case OPC_DPSQ_SA_L_W: 13152 check_dsp(ctx); 13153 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env); 13154 break; 13155 case OPC_MAQ_S_W_PHL: 13156 check_dsp(ctx); 13157 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env); 13158 break; 13159 case OPC_MAQ_S_W_PHR: 13160 check_dsp(ctx); 13161 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env); 13162 break; 13163 case OPC_MAQ_SA_W_PHL: 13164 check_dsp(ctx); 13165 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env); 13166 break; 13167 case OPC_MAQ_SA_W_PHR: 13168 check_dsp(ctx); 13169 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env); 13170 break; 13171 case OPC_MULSA_W_PH: 13172 check_dsp_r2(ctx); 13173 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env); 13174 break; 13175 } 13176 break; 13177 #ifdef TARGET_MIPS64 13178 case OPC_DPAQ_W_QH_DSP: 13179 { 13180 int ac = ret & 0x03; 13181 tcg_gen_movi_i32(t0, ac); 13182 13183 switch (op2) { 13184 case OPC_DMADD: 13185 check_dsp(ctx); 13186 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env); 13187 break; 13188 case OPC_DMADDU: 13189 check_dsp(ctx); 13190 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env); 13191 break; 13192 case OPC_DMSUB: 13193 check_dsp(ctx); 13194 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env); 13195 break; 13196 case OPC_DMSUBU: 13197 check_dsp(ctx); 13198 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env); 13199 break; 13200 case OPC_DPA_W_QH: 13201 check_dsp_r2(ctx); 13202 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env); 13203 break; 13204 case OPC_DPAQ_S_W_QH: 13205 check_dsp(ctx); 13206 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13207 break; 13208 case OPC_DPAQ_SA_L_PW: 13209 check_dsp(ctx); 13210 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env); 13211 break; 13212 case OPC_DPAU_H_OBL: 13213 check_dsp(ctx); 13214 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env); 13215 break; 13216 case OPC_DPAU_H_OBR: 13217 check_dsp(ctx); 13218 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env); 13219 break; 13220 case OPC_DPS_W_QH: 13221 check_dsp_r2(ctx); 13222 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env); 13223 break; 13224 case OPC_DPSQ_S_W_QH: 13225 check_dsp(ctx); 13226 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13227 break; 13228 case OPC_DPSQ_SA_L_PW: 13229 check_dsp(ctx); 13230 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env); 13231 break; 13232 case OPC_DPSU_H_OBL: 13233 check_dsp(ctx); 13234 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env); 13235 break; 13236 case OPC_DPSU_H_OBR: 13237 check_dsp(ctx); 13238 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env); 13239 break; 13240 case OPC_MAQ_S_L_PWL: 13241 check_dsp(ctx); 13242 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env); 13243 break; 13244 case OPC_MAQ_S_L_PWR: 13245 check_dsp(ctx); 13246 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env); 13247 break; 13248 case OPC_MAQ_S_W_QHLL: 13249 check_dsp(ctx); 13250 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env); 13251 break; 13252 case OPC_MAQ_SA_W_QHLL: 13253 check_dsp(ctx); 13254 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env); 13255 break; 13256 case OPC_MAQ_S_W_QHLR: 13257 check_dsp(ctx); 13258 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env); 13259 break; 13260 case OPC_MAQ_SA_W_QHLR: 13261 check_dsp(ctx); 13262 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env); 13263 break; 13264 case OPC_MAQ_S_W_QHRL: 13265 check_dsp(ctx); 13266 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env); 13267 break; 13268 case OPC_MAQ_SA_W_QHRL: 13269 check_dsp(ctx); 13270 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env); 13271 break; 13272 case OPC_MAQ_S_W_QHRR: 13273 check_dsp(ctx); 13274 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env); 13275 break; 13276 case OPC_MAQ_SA_W_QHRR: 13277 check_dsp(ctx); 13278 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env); 13279 break; 13280 case OPC_MULSAQ_S_L_PW: 13281 check_dsp(ctx); 13282 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env); 13283 break; 13284 case OPC_MULSAQ_S_W_QH: 13285 check_dsp(ctx); 13286 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env); 13287 break; 13288 } 13289 } 13290 break; 13291 #endif 13292 case OPC_ADDU_QB_DSP: 13293 switch (op2) { 13294 case OPC_MULEU_S_PH_QBL: 13295 check_dsp(ctx); 13296 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13297 break; 13298 case OPC_MULEU_S_PH_QBR: 13299 check_dsp(ctx); 13300 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13301 break; 13302 case OPC_MULQ_RS_PH: 13303 check_dsp(ctx); 13304 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13305 break; 13306 case OPC_MULEQ_S_W_PHL: 13307 check_dsp(ctx); 13308 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13309 break; 13310 case OPC_MULEQ_S_W_PHR: 13311 check_dsp(ctx); 13312 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13313 break; 13314 case OPC_MULQ_S_PH: 13315 check_dsp_r2(ctx); 13316 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13317 break; 13318 } 13319 break; 13320 #ifdef TARGET_MIPS64 13321 case OPC_ADDU_OB_DSP: 13322 switch (op2) { 13323 case OPC_MULEQ_S_PW_QHL: 13324 check_dsp(ctx); 13325 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13326 break; 13327 case OPC_MULEQ_S_PW_QHR: 13328 check_dsp(ctx); 13329 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13330 break; 13331 case OPC_MULEU_S_QH_OBL: 13332 check_dsp(ctx); 13333 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13334 break; 13335 case OPC_MULEU_S_QH_OBR: 13336 check_dsp(ctx); 13337 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13338 break; 13339 case OPC_MULQ_RS_QH: 13340 check_dsp(ctx); 13341 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13342 break; 13343 } 13344 break; 13345 #endif 13346 } 13347 13348 tcg_temp_free_i32(t0); 13349 tcg_temp_free(v1_t); 13350 tcg_temp_free(v2_t); 13351 } 13352 13353 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 13354 int ret, int val) 13355 { 13356 int16_t imm; 13357 TCGv t0; 13358 TCGv val_t; 13359 13360 if (ret == 0) { 13361 /* Treat as NOP. */ 13362 return; 13363 } 13364 13365 t0 = tcg_temp_new(); 13366 val_t = tcg_temp_new(); 13367 gen_load_gpr(val_t, val); 13368 13369 switch (op1) { 13370 case OPC_ABSQ_S_PH_DSP: 13371 switch (op2) { 13372 case OPC_BITREV: 13373 check_dsp(ctx); 13374 gen_helper_bitrev(cpu_gpr[ret], val_t); 13375 break; 13376 case OPC_REPL_QB: 13377 check_dsp(ctx); 13378 { 13379 target_long result; 13380 imm = (ctx->opcode >> 16) & 0xFF; 13381 result = (uint32_t)imm << 24 | 13382 (uint32_t)imm << 16 | 13383 (uint32_t)imm << 8 | 13384 (uint32_t)imm; 13385 result = (int32_t)result; 13386 tcg_gen_movi_tl(cpu_gpr[ret], result); 13387 } 13388 break; 13389 case OPC_REPLV_QB: 13390 check_dsp(ctx); 13391 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 13392 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 13393 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13394 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13395 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13396 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 13397 break; 13398 case OPC_REPL_PH: 13399 check_dsp(ctx); 13400 { 13401 imm = (ctx->opcode >> 16) & 0x03FF; 13402 imm = (int16_t)(imm << 6) >> 6; 13403 tcg_gen_movi_tl(cpu_gpr[ret], \ 13404 (target_long)((int32_t)imm << 16 | \ 13405 (uint16_t)imm)); 13406 } 13407 break; 13408 case OPC_REPLV_PH: 13409 check_dsp(ctx); 13410 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 13411 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13412 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13413 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 13414 break; 13415 } 13416 break; 13417 #ifdef TARGET_MIPS64 13418 case OPC_ABSQ_S_QH_DSP: 13419 switch (op2) { 13420 case OPC_REPL_OB: 13421 check_dsp(ctx); 13422 { 13423 target_long temp; 13424 13425 imm = (ctx->opcode >> 16) & 0xFF; 13426 temp = ((uint64_t)imm << 8) | (uint64_t)imm; 13427 temp = (temp << 16) | temp; 13428 temp = (temp << 32) | temp; 13429 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13430 break; 13431 } 13432 case OPC_REPL_PW: 13433 check_dsp(ctx); 13434 { 13435 target_long temp; 13436 13437 imm = (ctx->opcode >> 16) & 0x03FF; 13438 imm = (int16_t)(imm << 6) >> 6; 13439 temp = ((target_long)imm << 32) \ 13440 | ((target_long)imm & 0xFFFFFFFF); 13441 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13442 break; 13443 } 13444 case OPC_REPL_QH: 13445 check_dsp(ctx); 13446 { 13447 target_long temp; 13448 13449 imm = (ctx->opcode >> 16) & 0x03FF; 13450 imm = (int16_t)(imm << 6) >> 6; 13451 13452 temp = ((uint64_t)(uint16_t)imm << 48) | 13453 ((uint64_t)(uint16_t)imm << 32) | 13454 ((uint64_t)(uint16_t)imm << 16) | 13455 (uint64_t)(uint16_t)imm; 13456 tcg_gen_movi_tl(cpu_gpr[ret], temp); 13457 break; 13458 } 13459 case OPC_REPLV_OB: 13460 check_dsp(ctx); 13461 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t); 13462 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8); 13463 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13464 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13465 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13466 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13467 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13468 break; 13469 case OPC_REPLV_PW: 13470 check_dsp(ctx); 13471 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t); 13472 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13473 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13474 break; 13475 case OPC_REPLV_QH: 13476 check_dsp(ctx); 13477 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t); 13478 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16); 13479 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13480 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32); 13481 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 13482 break; 13483 } 13484 break; 13485 #endif 13486 } 13487 tcg_temp_free(t0); 13488 tcg_temp_free(val_t); 13489 } 13490 13491 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx, 13492 uint32_t op1, uint32_t op2, 13493 int ret, int v1, int v2, int check_ret) 13494 { 13495 TCGv t1; 13496 TCGv v1_t; 13497 TCGv v2_t; 13498 13499 if ((ret == 0) && (check_ret == 1)) { 13500 /* Treat as NOP. */ 13501 return; 13502 } 13503 13504 t1 = tcg_temp_new(); 13505 v1_t = tcg_temp_new(); 13506 v2_t = tcg_temp_new(); 13507 13508 gen_load_gpr(v1_t, v1); 13509 gen_load_gpr(v2_t, v2); 13510 13511 switch (op1) { 13512 case OPC_CMPU_EQ_QB_DSP: 13513 switch (op2) { 13514 case OPC_CMPU_EQ_QB: 13515 check_dsp(ctx); 13516 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); 13517 break; 13518 case OPC_CMPU_LT_QB: 13519 check_dsp(ctx); 13520 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); 13521 break; 13522 case OPC_CMPU_LE_QB: 13523 check_dsp(ctx); 13524 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); 13525 break; 13526 case OPC_CMPGU_EQ_QB: 13527 check_dsp(ctx); 13528 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t); 13529 break; 13530 case OPC_CMPGU_LT_QB: 13531 check_dsp(ctx); 13532 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t); 13533 break; 13534 case OPC_CMPGU_LE_QB: 13535 check_dsp(ctx); 13536 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t); 13537 break; 13538 case OPC_CMPGDU_EQ_QB: 13539 check_dsp_r2(ctx); 13540 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t); 13541 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13542 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13543 tcg_gen_shli_tl(t1, t1, 24); 13544 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13545 break; 13546 case OPC_CMPGDU_LT_QB: 13547 check_dsp_r2(ctx); 13548 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t); 13549 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13550 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13551 tcg_gen_shli_tl(t1, t1, 24); 13552 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13553 break; 13554 case OPC_CMPGDU_LE_QB: 13555 check_dsp_r2(ctx); 13556 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t); 13557 tcg_gen_mov_tl(cpu_gpr[ret], t1); 13558 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF); 13559 tcg_gen_shli_tl(t1, t1, 24); 13560 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1); 13561 break; 13562 case OPC_CMP_EQ_PH: 13563 check_dsp(ctx); 13564 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); 13565 break; 13566 case OPC_CMP_LT_PH: 13567 check_dsp(ctx); 13568 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); 13569 break; 13570 case OPC_CMP_LE_PH: 13571 check_dsp(ctx); 13572 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); 13573 break; 13574 case OPC_PICK_QB: 13575 check_dsp(ctx); 13576 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13577 break; 13578 case OPC_PICK_PH: 13579 check_dsp(ctx); 13580 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13581 break; 13582 case OPC_PACKRL_PH: 13583 check_dsp(ctx); 13584 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t); 13585 break; 13586 } 13587 break; 13588 #ifdef TARGET_MIPS64 13589 case OPC_CMPU_EQ_OB_DSP: 13590 switch (op2) { 13591 case OPC_CMP_EQ_PW: 13592 check_dsp(ctx); 13593 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env); 13594 break; 13595 case OPC_CMP_LT_PW: 13596 check_dsp(ctx); 13597 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env); 13598 break; 13599 case OPC_CMP_LE_PW: 13600 check_dsp(ctx); 13601 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env); 13602 break; 13603 case OPC_CMP_EQ_QH: 13604 check_dsp(ctx); 13605 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env); 13606 break; 13607 case OPC_CMP_LT_QH: 13608 check_dsp(ctx); 13609 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env); 13610 break; 13611 case OPC_CMP_LE_QH: 13612 check_dsp(ctx); 13613 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env); 13614 break; 13615 case OPC_CMPGDU_EQ_OB: 13616 check_dsp_r2(ctx); 13617 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13618 break; 13619 case OPC_CMPGDU_LT_OB: 13620 check_dsp_r2(ctx); 13621 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13622 break; 13623 case OPC_CMPGDU_LE_OB: 13624 check_dsp_r2(ctx); 13625 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13626 break; 13627 case OPC_CMPGU_EQ_OB: 13628 check_dsp(ctx); 13629 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t); 13630 break; 13631 case OPC_CMPGU_LT_OB: 13632 check_dsp(ctx); 13633 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t); 13634 break; 13635 case OPC_CMPGU_LE_OB: 13636 check_dsp(ctx); 13637 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t); 13638 break; 13639 case OPC_CMPU_EQ_OB: 13640 check_dsp(ctx); 13641 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env); 13642 break; 13643 case OPC_CMPU_LT_OB: 13644 check_dsp(ctx); 13645 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env); 13646 break; 13647 case OPC_CMPU_LE_OB: 13648 check_dsp(ctx); 13649 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env); 13650 break; 13651 case OPC_PACKRL_PW: 13652 check_dsp(ctx); 13653 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t); 13654 break; 13655 case OPC_PICK_OB: 13656 check_dsp(ctx); 13657 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13658 break; 13659 case OPC_PICK_PW: 13660 check_dsp(ctx); 13661 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13662 break; 13663 case OPC_PICK_QH: 13664 check_dsp(ctx); 13665 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env); 13666 break; 13667 } 13668 break; 13669 #endif 13670 } 13671 13672 tcg_temp_free(t1); 13673 tcg_temp_free(v1_t); 13674 tcg_temp_free(v2_t); 13675 } 13676 13677 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx, 13678 uint32_t op1, int rt, int rs, int sa) 13679 { 13680 TCGv t0; 13681 13682 check_dsp_r2(ctx); 13683 13684 if (rt == 0) { 13685 /* Treat as NOP. */ 13686 return; 13687 } 13688 13689 t0 = tcg_temp_new(); 13690 gen_load_gpr(t0, rs); 13691 13692 switch (op1) { 13693 case OPC_APPEND_DSP: 13694 switch (MASK_APPEND(ctx->opcode)) { 13695 case OPC_APPEND: 13696 if (sa != 0) { 13697 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa); 13698 } 13699 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13700 break; 13701 case OPC_PREPEND: 13702 if (sa != 0) { 13703 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]); 13704 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 13705 tcg_gen_shli_tl(t0, t0, 32 - sa); 13706 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13707 } 13708 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13709 break; 13710 case OPC_BALIGN: 13711 sa &= 3; 13712 if (sa != 0 && sa != 2) { 13713 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 13714 tcg_gen_ext32u_tl(t0, t0); 13715 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa)); 13716 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13717 } 13718 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 13719 break; 13720 default: /* Invalid */ 13721 MIPS_INVAL("MASK APPEND"); 13722 gen_reserved_instruction(ctx); 13723 break; 13724 } 13725 break; 13726 #ifdef TARGET_MIPS64 13727 case OPC_DAPPEND_DSP: 13728 switch (MASK_DAPPEND(ctx->opcode)) { 13729 case OPC_DAPPEND: 13730 if (sa != 0) { 13731 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa); 13732 } 13733 break; 13734 case OPC_PREPENDD: 13735 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa); 13736 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa)); 13737 tcg_gen_or_tl(cpu_gpr[rt], t0, t0); 13738 break; 13739 case OPC_PREPENDW: 13740 if (sa != 0) { 13741 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa); 13742 tcg_gen_shli_tl(t0, t0, 64 - sa); 13743 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13744 } 13745 break; 13746 case OPC_DBALIGN: 13747 sa &= 7; 13748 if (sa != 0 && sa != 2 && sa != 4) { 13749 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa); 13750 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa)); 13751 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0); 13752 } 13753 break; 13754 default: /* Invalid */ 13755 MIPS_INVAL("MASK DAPPEND"); 13756 gen_reserved_instruction(ctx); 13757 break; 13758 } 13759 break; 13760 #endif 13761 } 13762 tcg_temp_free(t0); 13763 } 13764 13765 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, 13766 int ret, int v1, int v2, int check_ret) 13767 13768 { 13769 TCGv t0; 13770 TCGv t1; 13771 TCGv v1_t; 13772 TCGv v2_t; 13773 int16_t imm; 13774 13775 if ((ret == 0) && (check_ret == 1)) { 13776 /* Treat as NOP. */ 13777 return; 13778 } 13779 13780 t0 = tcg_temp_new(); 13781 t1 = tcg_temp_new(); 13782 v1_t = tcg_temp_new(); 13783 v2_t = tcg_temp_new(); 13784 13785 gen_load_gpr(v1_t, v1); 13786 gen_load_gpr(v2_t, v2); 13787 13788 switch (op1) { 13789 case OPC_EXTR_W_DSP: 13790 check_dsp(ctx); 13791 switch (op2) { 13792 case OPC_EXTR_W: 13793 tcg_gen_movi_tl(t0, v2); 13794 tcg_gen_movi_tl(t1, v1); 13795 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env); 13796 break; 13797 case OPC_EXTR_R_W: 13798 tcg_gen_movi_tl(t0, v2); 13799 tcg_gen_movi_tl(t1, v1); 13800 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env); 13801 break; 13802 case OPC_EXTR_RS_W: 13803 tcg_gen_movi_tl(t0, v2); 13804 tcg_gen_movi_tl(t1, v1); 13805 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); 13806 break; 13807 case OPC_EXTR_S_H: 13808 tcg_gen_movi_tl(t0, v2); 13809 tcg_gen_movi_tl(t1, v1); 13810 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13811 break; 13812 case OPC_EXTRV_S_H: 13813 tcg_gen_movi_tl(t0, v2); 13814 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env); 13815 break; 13816 case OPC_EXTRV_W: 13817 tcg_gen_movi_tl(t0, v2); 13818 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13819 break; 13820 case OPC_EXTRV_R_W: 13821 tcg_gen_movi_tl(t0, v2); 13822 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13823 break; 13824 case OPC_EXTRV_RS_W: 13825 tcg_gen_movi_tl(t0, v2); 13826 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13827 break; 13828 case OPC_EXTP: 13829 tcg_gen_movi_tl(t0, v2); 13830 tcg_gen_movi_tl(t1, v1); 13831 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env); 13832 break; 13833 case OPC_EXTPV: 13834 tcg_gen_movi_tl(t0, v2); 13835 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env); 13836 break; 13837 case OPC_EXTPDP: 13838 tcg_gen_movi_tl(t0, v2); 13839 tcg_gen_movi_tl(t1, v1); 13840 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env); 13841 break; 13842 case OPC_EXTPDPV: 13843 tcg_gen_movi_tl(t0, v2); 13844 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env); 13845 break; 13846 case OPC_SHILO: 13847 imm = (ctx->opcode >> 20) & 0x3F; 13848 tcg_gen_movi_tl(t0, ret); 13849 tcg_gen_movi_tl(t1, imm); 13850 gen_helper_shilo(t0, t1, cpu_env); 13851 break; 13852 case OPC_SHILOV: 13853 tcg_gen_movi_tl(t0, ret); 13854 gen_helper_shilo(t0, v1_t, cpu_env); 13855 break; 13856 case OPC_MTHLIP: 13857 tcg_gen_movi_tl(t0, ret); 13858 gen_helper_mthlip(t0, v1_t, cpu_env); 13859 break; 13860 case OPC_WRDSP: 13861 imm = (ctx->opcode >> 11) & 0x3FF; 13862 tcg_gen_movi_tl(t0, imm); 13863 gen_helper_wrdsp(v1_t, t0, cpu_env); 13864 break; 13865 case OPC_RDDSP: 13866 imm = (ctx->opcode >> 16) & 0x03FF; 13867 tcg_gen_movi_tl(t0, imm); 13868 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env); 13869 break; 13870 } 13871 break; 13872 #ifdef TARGET_MIPS64 13873 case OPC_DEXTR_W_DSP: 13874 check_dsp(ctx); 13875 switch (op2) { 13876 case OPC_DMTHLIP: 13877 tcg_gen_movi_tl(t0, ret); 13878 gen_helper_dmthlip(v1_t, t0, cpu_env); 13879 break; 13880 case OPC_DSHILO: 13881 { 13882 int shift = (ctx->opcode >> 19) & 0x7F; 13883 int ac = (ctx->opcode >> 11) & 0x03; 13884 tcg_gen_movi_tl(t0, shift); 13885 tcg_gen_movi_tl(t1, ac); 13886 gen_helper_dshilo(t0, t1, cpu_env); 13887 break; 13888 } 13889 case OPC_DSHILOV: 13890 { 13891 int ac = (ctx->opcode >> 11) & 0x03; 13892 tcg_gen_movi_tl(t0, ac); 13893 gen_helper_dshilo(v1_t, t0, cpu_env); 13894 break; 13895 } 13896 case OPC_DEXTP: 13897 tcg_gen_movi_tl(t0, v2); 13898 tcg_gen_movi_tl(t1, v1); 13899 13900 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env); 13901 break; 13902 case OPC_DEXTPV: 13903 tcg_gen_movi_tl(t0, v2); 13904 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env); 13905 break; 13906 case OPC_DEXTPDP: 13907 tcg_gen_movi_tl(t0, v2); 13908 tcg_gen_movi_tl(t1, v1); 13909 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env); 13910 break; 13911 case OPC_DEXTPDPV: 13912 tcg_gen_movi_tl(t0, v2); 13913 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env); 13914 break; 13915 case OPC_DEXTR_L: 13916 tcg_gen_movi_tl(t0, v2); 13917 tcg_gen_movi_tl(t1, v1); 13918 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env); 13919 break; 13920 case OPC_DEXTR_R_L: 13921 tcg_gen_movi_tl(t0, v2); 13922 tcg_gen_movi_tl(t1, v1); 13923 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env); 13924 break; 13925 case OPC_DEXTR_RS_L: 13926 tcg_gen_movi_tl(t0, v2); 13927 tcg_gen_movi_tl(t1, v1); 13928 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env); 13929 break; 13930 case OPC_DEXTR_W: 13931 tcg_gen_movi_tl(t0, v2); 13932 tcg_gen_movi_tl(t1, v1); 13933 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env); 13934 break; 13935 case OPC_DEXTR_R_W: 13936 tcg_gen_movi_tl(t0, v2); 13937 tcg_gen_movi_tl(t1, v1); 13938 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env); 13939 break; 13940 case OPC_DEXTR_RS_W: 13941 tcg_gen_movi_tl(t0, v2); 13942 tcg_gen_movi_tl(t1, v1); 13943 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env); 13944 break; 13945 case OPC_DEXTR_S_H: 13946 tcg_gen_movi_tl(t0, v2); 13947 tcg_gen_movi_tl(t1, v1); 13948 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13949 break; 13950 case OPC_DEXTRV_S_H: 13951 tcg_gen_movi_tl(t0, v2); 13952 tcg_gen_movi_tl(t1, v1); 13953 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env); 13954 break; 13955 case OPC_DEXTRV_L: 13956 tcg_gen_movi_tl(t0, v2); 13957 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13958 break; 13959 case OPC_DEXTRV_R_L: 13960 tcg_gen_movi_tl(t0, v2); 13961 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13962 break; 13963 case OPC_DEXTRV_RS_L: 13964 tcg_gen_movi_tl(t0, v2); 13965 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env); 13966 break; 13967 case OPC_DEXTRV_W: 13968 tcg_gen_movi_tl(t0, v2); 13969 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13970 break; 13971 case OPC_DEXTRV_R_W: 13972 tcg_gen_movi_tl(t0, v2); 13973 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13974 break; 13975 case OPC_DEXTRV_RS_W: 13976 tcg_gen_movi_tl(t0, v2); 13977 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env); 13978 break; 13979 } 13980 break; 13981 #endif 13982 } 13983 13984 tcg_temp_free(t0); 13985 tcg_temp_free(t1); 13986 tcg_temp_free(v1_t); 13987 tcg_temp_free(v2_t); 13988 } 13989 13990 /* End MIPSDSP functions. */ 13991 13992 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) 13993 { 13994 int rs, rt, rd, sa; 13995 uint32_t op1, op2; 13996 13997 rs = (ctx->opcode >> 21) & 0x1f; 13998 rt = (ctx->opcode >> 16) & 0x1f; 13999 rd = (ctx->opcode >> 11) & 0x1f; 14000 sa = (ctx->opcode >> 6) & 0x1f; 14001 14002 op1 = MASK_SPECIAL(ctx->opcode); 14003 switch (op1) { 14004 case OPC_MULT: 14005 case OPC_MULTU: 14006 case OPC_DIV: 14007 case OPC_DIVU: 14008 op2 = MASK_R6_MULDIV(ctx->opcode); 14009 switch (op2) { 14010 case R6_OPC_MUL: 14011 case R6_OPC_MUH: 14012 case R6_OPC_MULU: 14013 case R6_OPC_MUHU: 14014 case R6_OPC_DIV: 14015 case R6_OPC_MOD: 14016 case R6_OPC_DIVU: 14017 case R6_OPC_MODU: 14018 gen_r6_muldiv(ctx, op2, rd, rs, rt); 14019 break; 14020 default: 14021 MIPS_INVAL("special_r6 muldiv"); 14022 gen_reserved_instruction(ctx); 14023 break; 14024 } 14025 break; 14026 case OPC_SELEQZ: 14027 case OPC_SELNEZ: 14028 gen_cond_move(ctx, op1, rd, rs, rt); 14029 break; 14030 case R6_OPC_CLO: 14031 case R6_OPC_CLZ: 14032 if (rt == 0 && sa == 1) { 14033 /* 14034 * Major opcode and function field is shared with preR6 MFHI/MTHI. 14035 * We need additionally to check other fields. 14036 */ 14037 gen_cl(ctx, op1, rd, rs); 14038 } else { 14039 gen_reserved_instruction(ctx); 14040 } 14041 break; 14042 case R6_OPC_SDBBP: 14043 if (is_uhi(extract32(ctx->opcode, 6, 20))) { 14044 gen_helper_do_semihosting(cpu_env); 14045 } else { 14046 if (ctx->hflags & MIPS_HFLAG_SBRI) { 14047 gen_reserved_instruction(ctx); 14048 } else { 14049 generate_exception_end(ctx, EXCP_DBp); 14050 } 14051 } 14052 break; 14053 #if defined(TARGET_MIPS64) 14054 case R6_OPC_DCLO: 14055 case R6_OPC_DCLZ: 14056 if (rt == 0 && sa == 1) { 14057 /* 14058 * Major opcode and function field is shared with preR6 MFHI/MTHI. 14059 * We need additionally to check other fields. 14060 */ 14061 check_mips_64(ctx); 14062 gen_cl(ctx, op1, rd, rs); 14063 } else { 14064 gen_reserved_instruction(ctx); 14065 } 14066 break; 14067 case OPC_DMULT: 14068 case OPC_DMULTU: 14069 case OPC_DDIV: 14070 case OPC_DDIVU: 14071 14072 op2 = MASK_R6_MULDIV(ctx->opcode); 14073 switch (op2) { 14074 case R6_OPC_DMUL: 14075 case R6_OPC_DMUH: 14076 case R6_OPC_DMULU: 14077 case R6_OPC_DMUHU: 14078 case R6_OPC_DDIV: 14079 case R6_OPC_DMOD: 14080 case R6_OPC_DDIVU: 14081 case R6_OPC_DMODU: 14082 check_mips_64(ctx); 14083 gen_r6_muldiv(ctx, op2, rd, rs, rt); 14084 break; 14085 default: 14086 MIPS_INVAL("special_r6 muldiv"); 14087 gen_reserved_instruction(ctx); 14088 break; 14089 } 14090 break; 14091 #endif 14092 default: /* Invalid */ 14093 MIPS_INVAL("special_r6"); 14094 gen_reserved_instruction(ctx); 14095 break; 14096 } 14097 } 14098 14099 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) 14100 { 14101 int rs = extract32(ctx->opcode, 21, 5); 14102 int rt = extract32(ctx->opcode, 16, 5); 14103 int rd = extract32(ctx->opcode, 11, 5); 14104 uint32_t op1 = MASK_SPECIAL(ctx->opcode); 14105 14106 switch (op1) { 14107 case OPC_MOVN: /* Conditional move */ 14108 case OPC_MOVZ: 14109 gen_cond_move(ctx, op1, rd, rs, rt); 14110 break; 14111 case OPC_MFHI: /* Move from HI/LO */ 14112 case OPC_MFLO: 14113 gen_HILO(ctx, op1, 0, rd); 14114 break; 14115 case OPC_MTHI: 14116 case OPC_MTLO: /* Move to HI/LO */ 14117 gen_HILO(ctx, op1, 0, rs); 14118 break; 14119 case OPC_MULT: 14120 case OPC_MULTU: 14121 gen_mul_txx9(ctx, op1, rd, rs, rt); 14122 break; 14123 case OPC_DIV: 14124 case OPC_DIVU: 14125 gen_muldiv(ctx, op1, 0, rs, rt); 14126 break; 14127 #if defined(TARGET_MIPS64) 14128 case OPC_DMULT: 14129 case OPC_DMULTU: 14130 case OPC_DDIV: 14131 case OPC_DDIVU: 14132 check_insn_opc_user_only(ctx, INSN_R5900); 14133 gen_muldiv(ctx, op1, 0, rs, rt); 14134 break; 14135 #endif 14136 case OPC_JR: 14137 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); 14138 break; 14139 default: /* Invalid */ 14140 MIPS_INVAL("special_tx79"); 14141 gen_reserved_instruction(ctx); 14142 break; 14143 } 14144 } 14145 14146 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) 14147 { 14148 int rs, rt, rd, sa; 14149 uint32_t op1; 14150 14151 rs = (ctx->opcode >> 21) & 0x1f; 14152 rt = (ctx->opcode >> 16) & 0x1f; 14153 rd = (ctx->opcode >> 11) & 0x1f; 14154 sa = (ctx->opcode >> 6) & 0x1f; 14155 14156 op1 = MASK_SPECIAL(ctx->opcode); 14157 switch (op1) { 14158 case OPC_MOVN: /* Conditional move */ 14159 case OPC_MOVZ: 14160 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | 14161 INSN_LOONGSON2E | INSN_LOONGSON2F); 14162 gen_cond_move(ctx, op1, rd, rs, rt); 14163 break; 14164 case OPC_MFHI: /* Move from HI/LO */ 14165 case OPC_MFLO: 14166 gen_HILO(ctx, op1, rs & 3, rd); 14167 break; 14168 case OPC_MTHI: 14169 case OPC_MTLO: /* Move to HI/LO */ 14170 gen_HILO(ctx, op1, rd & 3, rs); 14171 break; 14172 case OPC_MOVCI: 14173 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 14174 if (env->CP0_Config1 & (1 << CP0C1_FP)) { 14175 check_cp1_enabled(ctx); 14176 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, 14177 (ctx->opcode >> 16) & 1); 14178 } else { 14179 generate_exception_err(ctx, EXCP_CpU, 1); 14180 } 14181 break; 14182 case OPC_MULT: 14183 case OPC_MULTU: 14184 if (sa) { 14185 check_insn(ctx, INSN_VR54XX); 14186 op1 = MASK_MUL_VR54XX(ctx->opcode); 14187 gen_mul_vr54xx(ctx, op1, rd, rs, rt); 14188 } else { 14189 gen_muldiv(ctx, op1, rd & 3, rs, rt); 14190 } 14191 break; 14192 case OPC_DIV: 14193 case OPC_DIVU: 14194 gen_muldiv(ctx, op1, 0, rs, rt); 14195 break; 14196 #if defined(TARGET_MIPS64) 14197 case OPC_DMULT: 14198 case OPC_DMULTU: 14199 case OPC_DDIV: 14200 case OPC_DDIVU: 14201 check_insn(ctx, ISA_MIPS3); 14202 check_mips_64(ctx); 14203 gen_muldiv(ctx, op1, 0, rs, rt); 14204 break; 14205 #endif 14206 case OPC_JR: 14207 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 14208 break; 14209 case OPC_SPIM: 14210 #ifdef MIPS_STRICT_STANDARD 14211 MIPS_INVAL("SPIM"); 14212 gen_reserved_instruction(ctx); 14213 #else 14214 /* Implemented as RI exception for now. */ 14215 MIPS_INVAL("spim (unofficial)"); 14216 gen_reserved_instruction(ctx); 14217 #endif 14218 break; 14219 default: /* Invalid */ 14220 MIPS_INVAL("special_legacy"); 14221 gen_reserved_instruction(ctx); 14222 break; 14223 } 14224 } 14225 14226 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) 14227 { 14228 int rs, rt, rd, sa; 14229 uint32_t op1; 14230 14231 rs = (ctx->opcode >> 21) & 0x1f; 14232 rt = (ctx->opcode >> 16) & 0x1f; 14233 rd = (ctx->opcode >> 11) & 0x1f; 14234 sa = (ctx->opcode >> 6) & 0x1f; 14235 14236 op1 = MASK_SPECIAL(ctx->opcode); 14237 switch (op1) { 14238 case OPC_SLL: /* Shift with immediate */ 14239 if (sa == 5 && rd == 0 && 14240 rs == 0 && rt == 0) { /* PAUSE */ 14241 if ((ctx->insn_flags & ISA_MIPS_R6) && 14242 (ctx->hflags & MIPS_HFLAG_BMASK)) { 14243 gen_reserved_instruction(ctx); 14244 break; 14245 } 14246 } 14247 /* Fallthrough */ 14248 case OPC_SRA: 14249 gen_shift_imm(ctx, op1, rd, rt, sa); 14250 break; 14251 case OPC_SRL: 14252 switch ((ctx->opcode >> 21) & 0x1f) { 14253 case 1: 14254 /* rotr is decoded as srl on non-R2 CPUs */ 14255 if (ctx->insn_flags & ISA_MIPS_R2) { 14256 op1 = OPC_ROTR; 14257 } 14258 /* Fallthrough */ 14259 case 0: 14260 gen_shift_imm(ctx, op1, rd, rt, sa); 14261 break; 14262 default: 14263 gen_reserved_instruction(ctx); 14264 break; 14265 } 14266 break; 14267 case OPC_ADD: 14268 case OPC_ADDU: 14269 case OPC_SUB: 14270 case OPC_SUBU: 14271 gen_arith(ctx, op1, rd, rs, rt); 14272 break; 14273 case OPC_SLLV: /* Shifts */ 14274 case OPC_SRAV: 14275 gen_shift(ctx, op1, rd, rs, rt); 14276 break; 14277 case OPC_SRLV: 14278 switch ((ctx->opcode >> 6) & 0x1f) { 14279 case 1: 14280 /* rotrv is decoded as srlv on non-R2 CPUs */ 14281 if (ctx->insn_flags & ISA_MIPS_R2) { 14282 op1 = OPC_ROTRV; 14283 } 14284 /* Fallthrough */ 14285 case 0: 14286 gen_shift(ctx, op1, rd, rs, rt); 14287 break; 14288 default: 14289 gen_reserved_instruction(ctx); 14290 break; 14291 } 14292 break; 14293 case OPC_SLT: /* Set on less than */ 14294 case OPC_SLTU: 14295 gen_slt(ctx, op1, rd, rs, rt); 14296 break; 14297 case OPC_AND: /* Logic*/ 14298 case OPC_OR: 14299 case OPC_NOR: 14300 case OPC_XOR: 14301 gen_logic(ctx, op1, rd, rs, rt); 14302 break; 14303 case OPC_JALR: 14304 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); 14305 break; 14306 case OPC_TGE: /* Traps */ 14307 case OPC_TGEU: 14308 case OPC_TLT: 14309 case OPC_TLTU: 14310 case OPC_TEQ: 14311 case OPC_TNE: 14312 check_insn(ctx, ISA_MIPS2); 14313 gen_trap(ctx, op1, rs, rt, -1); 14314 break; 14315 case OPC_PMON: 14316 /* Pmon entry point, also R4010 selsl */ 14317 #ifdef MIPS_STRICT_STANDARD 14318 MIPS_INVAL("PMON / selsl"); 14319 gen_reserved_instruction(ctx); 14320 #else 14321 gen_helper_0e0i(pmon, sa); 14322 #endif 14323 break; 14324 case OPC_SYSCALL: 14325 generate_exception_end(ctx, EXCP_SYSCALL); 14326 break; 14327 case OPC_BREAK: 14328 generate_exception_end(ctx, EXCP_BREAK); 14329 break; 14330 case OPC_SYNC: 14331 check_insn(ctx, ISA_MIPS2); 14332 gen_sync(extract32(ctx->opcode, 6, 5)); 14333 break; 14334 14335 #if defined(TARGET_MIPS64) 14336 /* MIPS64 specific opcodes */ 14337 case OPC_DSLL: 14338 case OPC_DSRA: 14339 case OPC_DSLL32: 14340 case OPC_DSRA32: 14341 check_insn(ctx, ISA_MIPS3); 14342 check_mips_64(ctx); 14343 gen_shift_imm(ctx, op1, rd, rt, sa); 14344 break; 14345 case OPC_DSRL: 14346 switch ((ctx->opcode >> 21) & 0x1f) { 14347 case 1: 14348 /* drotr is decoded as dsrl on non-R2 CPUs */ 14349 if (ctx->insn_flags & ISA_MIPS_R2) { 14350 op1 = OPC_DROTR; 14351 } 14352 /* Fallthrough */ 14353 case 0: 14354 check_insn(ctx, ISA_MIPS3); 14355 check_mips_64(ctx); 14356 gen_shift_imm(ctx, op1, rd, rt, sa); 14357 break; 14358 default: 14359 gen_reserved_instruction(ctx); 14360 break; 14361 } 14362 break; 14363 case OPC_DSRL32: 14364 switch ((ctx->opcode >> 21) & 0x1f) { 14365 case 1: 14366 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */ 14367 if (ctx->insn_flags & ISA_MIPS_R2) { 14368 op1 = OPC_DROTR32; 14369 } 14370 /* Fallthrough */ 14371 case 0: 14372 check_insn(ctx, ISA_MIPS3); 14373 check_mips_64(ctx); 14374 gen_shift_imm(ctx, op1, rd, rt, sa); 14375 break; 14376 default: 14377 gen_reserved_instruction(ctx); 14378 break; 14379 } 14380 break; 14381 case OPC_DADD: 14382 case OPC_DADDU: 14383 case OPC_DSUB: 14384 case OPC_DSUBU: 14385 check_insn(ctx, ISA_MIPS3); 14386 check_mips_64(ctx); 14387 gen_arith(ctx, op1, rd, rs, rt); 14388 break; 14389 case OPC_DSLLV: 14390 case OPC_DSRAV: 14391 check_insn(ctx, ISA_MIPS3); 14392 check_mips_64(ctx); 14393 gen_shift(ctx, op1, rd, rs, rt); 14394 break; 14395 case OPC_DSRLV: 14396 switch ((ctx->opcode >> 6) & 0x1f) { 14397 case 1: 14398 /* drotrv is decoded as dsrlv on non-R2 CPUs */ 14399 if (ctx->insn_flags & ISA_MIPS_R2) { 14400 op1 = OPC_DROTRV; 14401 } 14402 /* Fallthrough */ 14403 case 0: 14404 check_insn(ctx, ISA_MIPS3); 14405 check_mips_64(ctx); 14406 gen_shift(ctx, op1, rd, rs, rt); 14407 break; 14408 default: 14409 gen_reserved_instruction(ctx); 14410 break; 14411 } 14412 break; 14413 #endif 14414 default: 14415 if (ctx->insn_flags & ISA_MIPS_R6) { 14416 decode_opc_special_r6(env, ctx); 14417 } else if (ctx->insn_flags & INSN_R5900) { 14418 decode_opc_special_tx79(env, ctx); 14419 } else { 14420 decode_opc_special_legacy(env, ctx); 14421 } 14422 } 14423 } 14424 14425 14426 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) 14427 { 14428 int rs, rt, rd; 14429 uint32_t op1; 14430 14431 rs = (ctx->opcode >> 21) & 0x1f; 14432 rt = (ctx->opcode >> 16) & 0x1f; 14433 rd = (ctx->opcode >> 11) & 0x1f; 14434 14435 op1 = MASK_SPECIAL2(ctx->opcode); 14436 switch (op1) { 14437 case OPC_MADD: /* Multiply and add/sub */ 14438 case OPC_MADDU: 14439 case OPC_MSUB: 14440 case OPC_MSUBU: 14441 check_insn(ctx, ISA_MIPS_R1); 14442 gen_muldiv(ctx, op1, rd & 3, rs, rt); 14443 break; 14444 case OPC_MUL: 14445 gen_arith(ctx, op1, rd, rs, rt); 14446 break; 14447 case OPC_DIV_G_2F: 14448 case OPC_DIVU_G_2F: 14449 case OPC_MULT_G_2F: 14450 case OPC_MULTU_G_2F: 14451 case OPC_MOD_G_2F: 14452 case OPC_MODU_G_2F: 14453 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 14454 gen_loongson_integer(ctx, op1, rd, rs, rt); 14455 break; 14456 case OPC_CLO: 14457 case OPC_CLZ: 14458 check_insn(ctx, ISA_MIPS_R1); 14459 gen_cl(ctx, op1, rd, rs); 14460 break; 14461 case OPC_SDBBP: 14462 if (is_uhi(extract32(ctx->opcode, 6, 20))) { 14463 gen_helper_do_semihosting(cpu_env); 14464 } else { 14465 /* 14466 * XXX: not clear which exception should be raised 14467 * when in debug mode... 14468 */ 14469 check_insn(ctx, ISA_MIPS_R1); 14470 generate_exception_end(ctx, EXCP_DBp); 14471 } 14472 break; 14473 #if defined(TARGET_MIPS64) 14474 case OPC_DCLO: 14475 case OPC_DCLZ: 14476 check_insn(ctx, ISA_MIPS_R1); 14477 check_mips_64(ctx); 14478 gen_cl(ctx, op1, rd, rs); 14479 break; 14480 case OPC_DMULT_G_2F: 14481 case OPC_DMULTU_G_2F: 14482 case OPC_DDIV_G_2F: 14483 case OPC_DDIVU_G_2F: 14484 case OPC_DMOD_G_2F: 14485 case OPC_DMODU_G_2F: 14486 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT); 14487 gen_loongson_integer(ctx, op1, rd, rs, rt); 14488 break; 14489 #endif 14490 default: /* Invalid */ 14491 MIPS_INVAL("special2_legacy"); 14492 gen_reserved_instruction(ctx); 14493 break; 14494 } 14495 } 14496 14497 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) 14498 { 14499 int rs, rt, rd, sa; 14500 uint32_t op1, op2; 14501 int16_t imm; 14502 14503 rs = (ctx->opcode >> 21) & 0x1f; 14504 rt = (ctx->opcode >> 16) & 0x1f; 14505 rd = (ctx->opcode >> 11) & 0x1f; 14506 sa = (ctx->opcode >> 6) & 0x1f; 14507 imm = (int16_t)ctx->opcode >> 7; 14508 14509 op1 = MASK_SPECIAL3(ctx->opcode); 14510 switch (op1) { 14511 case R6_OPC_PREF: 14512 if (rt >= 24) { 14513 /* hint codes 24-31 are reserved and signal RI */ 14514 gen_reserved_instruction(ctx); 14515 } 14516 /* Treat as NOP. */ 14517 break; 14518 case R6_OPC_CACHE: 14519 check_cp0_enabled(ctx); 14520 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 14521 gen_cache_operation(ctx, rt, rs, imm); 14522 } 14523 break; 14524 case R6_OPC_SC: 14525 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); 14526 break; 14527 case R6_OPC_LL: 14528 gen_ld(ctx, op1, rt, rs, imm); 14529 break; 14530 case OPC_BSHFL: 14531 { 14532 if (rd == 0) { 14533 /* Treat as NOP. */ 14534 break; 14535 } 14536 op2 = MASK_BSHFL(ctx->opcode); 14537 switch (op2) { 14538 case OPC_ALIGN: 14539 case OPC_ALIGN_1: 14540 case OPC_ALIGN_2: 14541 case OPC_ALIGN_3: 14542 gen_align(ctx, 32, rd, rs, rt, sa & 3); 14543 break; 14544 case OPC_BITSWAP: 14545 gen_bitswap(ctx, op2, rd, rt); 14546 break; 14547 } 14548 } 14549 break; 14550 #ifndef CONFIG_USER_ONLY 14551 case OPC_GINV: 14552 if (unlikely(ctx->gi <= 1)) { 14553 gen_reserved_instruction(ctx); 14554 } 14555 check_cp0_enabled(ctx); 14556 switch ((ctx->opcode >> 6) & 3) { 14557 case 0: /* GINVI */ 14558 /* Treat as NOP. */ 14559 break; 14560 case 2: /* GINVT */ 14561 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); 14562 break; 14563 default: 14564 gen_reserved_instruction(ctx); 14565 break; 14566 } 14567 break; 14568 #endif 14569 #if defined(TARGET_MIPS64) 14570 case R6_OPC_SCD: 14571 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false); 14572 break; 14573 case R6_OPC_LLD: 14574 gen_ld(ctx, op1, rt, rs, imm); 14575 break; 14576 case OPC_DBSHFL: 14577 check_mips_64(ctx); 14578 { 14579 if (rd == 0) { 14580 /* Treat as NOP. */ 14581 break; 14582 } 14583 op2 = MASK_DBSHFL(ctx->opcode); 14584 switch (op2) { 14585 case OPC_DALIGN: 14586 case OPC_DALIGN_1: 14587 case OPC_DALIGN_2: 14588 case OPC_DALIGN_3: 14589 case OPC_DALIGN_4: 14590 case OPC_DALIGN_5: 14591 case OPC_DALIGN_6: 14592 case OPC_DALIGN_7: 14593 gen_align(ctx, 64, rd, rs, rt, sa & 7); 14594 break; 14595 case OPC_DBITSWAP: 14596 gen_bitswap(ctx, op2, rd, rt); 14597 break; 14598 } 14599 14600 } 14601 break; 14602 #endif 14603 default: /* Invalid */ 14604 MIPS_INVAL("special3_r6"); 14605 gen_reserved_instruction(ctx); 14606 break; 14607 } 14608 } 14609 14610 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) 14611 { 14612 int rs, rt, rd; 14613 uint32_t op1, op2; 14614 14615 rs = (ctx->opcode >> 21) & 0x1f; 14616 rt = (ctx->opcode >> 16) & 0x1f; 14617 rd = (ctx->opcode >> 11) & 0x1f; 14618 14619 op1 = MASK_SPECIAL3(ctx->opcode); 14620 switch (op1) { 14621 case OPC_DIV_G_2E: 14622 case OPC_DIVU_G_2E: 14623 case OPC_MOD_G_2E: 14624 case OPC_MODU_G_2E: 14625 case OPC_MULT_G_2E: 14626 case OPC_MULTU_G_2E: 14627 /* 14628 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have 14629 * the same mask and op1. 14630 */ 14631 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) { 14632 op2 = MASK_ADDUH_QB(ctx->opcode); 14633 switch (op2) { 14634 case OPC_ADDUH_QB: 14635 case OPC_ADDUH_R_QB: 14636 case OPC_ADDQH_PH: 14637 case OPC_ADDQH_R_PH: 14638 case OPC_ADDQH_W: 14639 case OPC_ADDQH_R_W: 14640 case OPC_SUBUH_QB: 14641 case OPC_SUBUH_R_QB: 14642 case OPC_SUBQH_PH: 14643 case OPC_SUBQH_R_PH: 14644 case OPC_SUBQH_W: 14645 case OPC_SUBQH_R_W: 14646 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14647 break; 14648 case OPC_MUL_PH: 14649 case OPC_MUL_S_PH: 14650 case OPC_MULQ_S_W: 14651 case OPC_MULQ_RS_W: 14652 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14653 break; 14654 default: 14655 MIPS_INVAL("MASK ADDUH.QB"); 14656 gen_reserved_instruction(ctx); 14657 break; 14658 } 14659 } else if (ctx->insn_flags & INSN_LOONGSON2E) { 14660 gen_loongson_integer(ctx, op1, rd, rs, rt); 14661 } else { 14662 gen_reserved_instruction(ctx); 14663 } 14664 break; 14665 case OPC_LX_DSP: 14666 op2 = MASK_LX(ctx->opcode); 14667 switch (op2) { 14668 #if defined(TARGET_MIPS64) 14669 case OPC_LDX: 14670 #endif 14671 case OPC_LBUX: 14672 case OPC_LHX: 14673 case OPC_LWX: 14674 gen_mipsdsp_ld(ctx, op2, rd, rs, rt); 14675 break; 14676 default: /* Invalid */ 14677 MIPS_INVAL("MASK LX"); 14678 gen_reserved_instruction(ctx); 14679 break; 14680 } 14681 break; 14682 case OPC_ABSQ_S_PH_DSP: 14683 op2 = MASK_ABSQ_S_PH(ctx->opcode); 14684 switch (op2) { 14685 case OPC_ABSQ_S_QB: 14686 case OPC_ABSQ_S_PH: 14687 case OPC_ABSQ_S_W: 14688 case OPC_PRECEQ_W_PHL: 14689 case OPC_PRECEQ_W_PHR: 14690 case OPC_PRECEQU_PH_QBL: 14691 case OPC_PRECEQU_PH_QBR: 14692 case OPC_PRECEQU_PH_QBLA: 14693 case OPC_PRECEQU_PH_QBRA: 14694 case OPC_PRECEU_PH_QBL: 14695 case OPC_PRECEU_PH_QBR: 14696 case OPC_PRECEU_PH_QBLA: 14697 case OPC_PRECEU_PH_QBRA: 14698 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14699 break; 14700 case OPC_BITREV: 14701 case OPC_REPL_QB: 14702 case OPC_REPLV_QB: 14703 case OPC_REPL_PH: 14704 case OPC_REPLV_PH: 14705 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 14706 break; 14707 default: 14708 MIPS_INVAL("MASK ABSQ_S.PH"); 14709 gen_reserved_instruction(ctx); 14710 break; 14711 } 14712 break; 14713 case OPC_ADDU_QB_DSP: 14714 op2 = MASK_ADDU_QB(ctx->opcode); 14715 switch (op2) { 14716 case OPC_ADDQ_PH: 14717 case OPC_ADDQ_S_PH: 14718 case OPC_ADDQ_S_W: 14719 case OPC_ADDU_QB: 14720 case OPC_ADDU_S_QB: 14721 case OPC_ADDU_PH: 14722 case OPC_ADDU_S_PH: 14723 case OPC_SUBQ_PH: 14724 case OPC_SUBQ_S_PH: 14725 case OPC_SUBQ_S_W: 14726 case OPC_SUBU_QB: 14727 case OPC_SUBU_S_QB: 14728 case OPC_SUBU_PH: 14729 case OPC_SUBU_S_PH: 14730 case OPC_ADDSC: 14731 case OPC_ADDWC: 14732 case OPC_MODSUB: 14733 case OPC_RADDU_W_QB: 14734 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14735 break; 14736 case OPC_MULEU_S_PH_QBL: 14737 case OPC_MULEU_S_PH_QBR: 14738 case OPC_MULQ_RS_PH: 14739 case OPC_MULEQ_S_W_PHL: 14740 case OPC_MULEQ_S_W_PHR: 14741 case OPC_MULQ_S_PH: 14742 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14743 break; 14744 default: /* Invalid */ 14745 MIPS_INVAL("MASK ADDU.QB"); 14746 gen_reserved_instruction(ctx); 14747 break; 14748 14749 } 14750 break; 14751 case OPC_CMPU_EQ_QB_DSP: 14752 op2 = MASK_CMPU_EQ_QB(ctx->opcode); 14753 switch (op2) { 14754 case OPC_PRECR_SRA_PH_W: 14755 case OPC_PRECR_SRA_R_PH_W: 14756 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 14757 break; 14758 case OPC_PRECR_QB_PH: 14759 case OPC_PRECRQ_QB_PH: 14760 case OPC_PRECRQ_PH_W: 14761 case OPC_PRECRQ_RS_PH_W: 14762 case OPC_PRECRQU_S_QB_PH: 14763 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14764 break; 14765 case OPC_CMPU_EQ_QB: 14766 case OPC_CMPU_LT_QB: 14767 case OPC_CMPU_LE_QB: 14768 case OPC_CMP_EQ_PH: 14769 case OPC_CMP_LT_PH: 14770 case OPC_CMP_LE_PH: 14771 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 14772 break; 14773 case OPC_CMPGU_EQ_QB: 14774 case OPC_CMPGU_LT_QB: 14775 case OPC_CMPGU_LE_QB: 14776 case OPC_CMPGDU_EQ_QB: 14777 case OPC_CMPGDU_LT_QB: 14778 case OPC_CMPGDU_LE_QB: 14779 case OPC_PICK_QB: 14780 case OPC_PICK_PH: 14781 case OPC_PACKRL_PH: 14782 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 14783 break; 14784 default: /* Invalid */ 14785 MIPS_INVAL("MASK CMPU.EQ.QB"); 14786 gen_reserved_instruction(ctx); 14787 break; 14788 } 14789 break; 14790 case OPC_SHLL_QB_DSP: 14791 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 14792 break; 14793 case OPC_DPA_W_PH_DSP: 14794 op2 = MASK_DPA_W_PH(ctx->opcode); 14795 switch (op2) { 14796 case OPC_DPAU_H_QBL: 14797 case OPC_DPAU_H_QBR: 14798 case OPC_DPSU_H_QBL: 14799 case OPC_DPSU_H_QBR: 14800 case OPC_DPA_W_PH: 14801 case OPC_DPAX_W_PH: 14802 case OPC_DPAQ_S_W_PH: 14803 case OPC_DPAQX_S_W_PH: 14804 case OPC_DPAQX_SA_W_PH: 14805 case OPC_DPS_W_PH: 14806 case OPC_DPSX_W_PH: 14807 case OPC_DPSQ_S_W_PH: 14808 case OPC_DPSQX_S_W_PH: 14809 case OPC_DPSQX_SA_W_PH: 14810 case OPC_MULSAQ_S_W_PH: 14811 case OPC_DPAQ_SA_L_W: 14812 case OPC_DPSQ_SA_L_W: 14813 case OPC_MAQ_S_W_PHL: 14814 case OPC_MAQ_S_W_PHR: 14815 case OPC_MAQ_SA_W_PHL: 14816 case OPC_MAQ_SA_W_PHR: 14817 case OPC_MULSA_W_PH: 14818 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 14819 break; 14820 default: /* Invalid */ 14821 MIPS_INVAL("MASK DPAW.PH"); 14822 gen_reserved_instruction(ctx); 14823 break; 14824 } 14825 break; 14826 case OPC_INSV_DSP: 14827 op2 = MASK_INSV(ctx->opcode); 14828 switch (op2) { 14829 case OPC_INSV: 14830 check_dsp(ctx); 14831 { 14832 TCGv t0, t1; 14833 14834 if (rt == 0) { 14835 break; 14836 } 14837 14838 t0 = tcg_temp_new(); 14839 t1 = tcg_temp_new(); 14840 14841 gen_load_gpr(t0, rt); 14842 gen_load_gpr(t1, rs); 14843 14844 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0); 14845 14846 tcg_temp_free(t0); 14847 tcg_temp_free(t1); 14848 break; 14849 } 14850 default: /* Invalid */ 14851 MIPS_INVAL("MASK INSV"); 14852 gen_reserved_instruction(ctx); 14853 break; 14854 } 14855 break; 14856 case OPC_APPEND_DSP: 14857 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 14858 break; 14859 case OPC_EXTR_W_DSP: 14860 op2 = MASK_EXTR_W(ctx->opcode); 14861 switch (op2) { 14862 case OPC_EXTR_W: 14863 case OPC_EXTR_R_W: 14864 case OPC_EXTR_RS_W: 14865 case OPC_EXTR_S_H: 14866 case OPC_EXTRV_S_H: 14867 case OPC_EXTRV_W: 14868 case OPC_EXTRV_R_W: 14869 case OPC_EXTRV_RS_W: 14870 case OPC_EXTP: 14871 case OPC_EXTPV: 14872 case OPC_EXTPDP: 14873 case OPC_EXTPDPV: 14874 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 14875 break; 14876 case OPC_RDDSP: 14877 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1); 14878 break; 14879 case OPC_SHILO: 14880 case OPC_SHILOV: 14881 case OPC_MTHLIP: 14882 case OPC_WRDSP: 14883 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 14884 break; 14885 default: /* Invalid */ 14886 MIPS_INVAL("MASK EXTR.W"); 14887 gen_reserved_instruction(ctx); 14888 break; 14889 } 14890 break; 14891 #if defined(TARGET_MIPS64) 14892 case OPC_DDIV_G_2E: 14893 case OPC_DDIVU_G_2E: 14894 case OPC_DMULT_G_2E: 14895 case OPC_DMULTU_G_2E: 14896 case OPC_DMOD_G_2E: 14897 case OPC_DMODU_G_2E: 14898 check_insn(ctx, INSN_LOONGSON2E); 14899 gen_loongson_integer(ctx, op1, rd, rs, rt); 14900 break; 14901 case OPC_ABSQ_S_QH_DSP: 14902 op2 = MASK_ABSQ_S_QH(ctx->opcode); 14903 switch (op2) { 14904 case OPC_PRECEQ_L_PWL: 14905 case OPC_PRECEQ_L_PWR: 14906 case OPC_PRECEQ_PW_QHL: 14907 case OPC_PRECEQ_PW_QHR: 14908 case OPC_PRECEQ_PW_QHLA: 14909 case OPC_PRECEQ_PW_QHRA: 14910 case OPC_PRECEQU_QH_OBL: 14911 case OPC_PRECEQU_QH_OBR: 14912 case OPC_PRECEQU_QH_OBLA: 14913 case OPC_PRECEQU_QH_OBRA: 14914 case OPC_PRECEU_QH_OBL: 14915 case OPC_PRECEU_QH_OBR: 14916 case OPC_PRECEU_QH_OBLA: 14917 case OPC_PRECEU_QH_OBRA: 14918 case OPC_ABSQ_S_OB: 14919 case OPC_ABSQ_S_PW: 14920 case OPC_ABSQ_S_QH: 14921 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14922 break; 14923 case OPC_REPL_OB: 14924 case OPC_REPL_PW: 14925 case OPC_REPL_QH: 14926 case OPC_REPLV_OB: 14927 case OPC_REPLV_PW: 14928 case OPC_REPLV_QH: 14929 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt); 14930 break; 14931 default: /* Invalid */ 14932 MIPS_INVAL("MASK ABSQ_S.QH"); 14933 gen_reserved_instruction(ctx); 14934 break; 14935 } 14936 break; 14937 case OPC_ADDU_OB_DSP: 14938 op2 = MASK_ADDU_OB(ctx->opcode); 14939 switch (op2) { 14940 case OPC_RADDU_L_OB: 14941 case OPC_SUBQ_PW: 14942 case OPC_SUBQ_S_PW: 14943 case OPC_SUBQ_QH: 14944 case OPC_SUBQ_S_QH: 14945 case OPC_SUBU_OB: 14946 case OPC_SUBU_S_OB: 14947 case OPC_SUBU_QH: 14948 case OPC_SUBU_S_QH: 14949 case OPC_SUBUH_OB: 14950 case OPC_SUBUH_R_OB: 14951 case OPC_ADDQ_PW: 14952 case OPC_ADDQ_S_PW: 14953 case OPC_ADDQ_QH: 14954 case OPC_ADDQ_S_QH: 14955 case OPC_ADDU_OB: 14956 case OPC_ADDU_S_OB: 14957 case OPC_ADDU_QH: 14958 case OPC_ADDU_S_QH: 14959 case OPC_ADDUH_OB: 14960 case OPC_ADDUH_R_OB: 14961 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14962 break; 14963 case OPC_MULEQ_S_PW_QHL: 14964 case OPC_MULEQ_S_PW_QHR: 14965 case OPC_MULEU_S_QH_OBL: 14966 case OPC_MULEU_S_QH_OBR: 14967 case OPC_MULQ_RS_QH: 14968 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1); 14969 break; 14970 default: /* Invalid */ 14971 MIPS_INVAL("MASK ADDU.OB"); 14972 gen_reserved_instruction(ctx); 14973 break; 14974 } 14975 break; 14976 case OPC_CMPU_EQ_OB_DSP: 14977 op2 = MASK_CMPU_EQ_OB(ctx->opcode); 14978 switch (op2) { 14979 case OPC_PRECR_SRA_QH_PW: 14980 case OPC_PRECR_SRA_R_QH_PW: 14981 /* Return value is rt. */ 14982 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd); 14983 break; 14984 case OPC_PRECR_OB_QH: 14985 case OPC_PRECRQ_OB_QH: 14986 case OPC_PRECRQ_PW_L: 14987 case OPC_PRECRQ_QH_PW: 14988 case OPC_PRECRQ_RS_QH_PW: 14989 case OPC_PRECRQU_S_OB_QH: 14990 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt); 14991 break; 14992 case OPC_CMPU_EQ_OB: 14993 case OPC_CMPU_LT_OB: 14994 case OPC_CMPU_LE_OB: 14995 case OPC_CMP_EQ_QH: 14996 case OPC_CMP_LT_QH: 14997 case OPC_CMP_LE_QH: 14998 case OPC_CMP_EQ_PW: 14999 case OPC_CMP_LT_PW: 15000 case OPC_CMP_LE_PW: 15001 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0); 15002 break; 15003 case OPC_CMPGDU_EQ_OB: 15004 case OPC_CMPGDU_LT_OB: 15005 case OPC_CMPGDU_LE_OB: 15006 case OPC_CMPGU_EQ_OB: 15007 case OPC_CMPGU_LT_OB: 15008 case OPC_CMPGU_LE_OB: 15009 case OPC_PACKRL_PW: 15010 case OPC_PICK_OB: 15011 case OPC_PICK_PW: 15012 case OPC_PICK_QH: 15013 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1); 15014 break; 15015 default: /* Invalid */ 15016 MIPS_INVAL("MASK CMPU_EQ.OB"); 15017 gen_reserved_instruction(ctx); 15018 break; 15019 } 15020 break; 15021 case OPC_DAPPEND_DSP: 15022 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd); 15023 break; 15024 case OPC_DEXTR_W_DSP: 15025 op2 = MASK_DEXTR_W(ctx->opcode); 15026 switch (op2) { 15027 case OPC_DEXTP: 15028 case OPC_DEXTPDP: 15029 case OPC_DEXTPDPV: 15030 case OPC_DEXTPV: 15031 case OPC_DEXTR_L: 15032 case OPC_DEXTR_R_L: 15033 case OPC_DEXTR_RS_L: 15034 case OPC_DEXTR_W: 15035 case OPC_DEXTR_R_W: 15036 case OPC_DEXTR_RS_W: 15037 case OPC_DEXTR_S_H: 15038 case OPC_DEXTRV_L: 15039 case OPC_DEXTRV_R_L: 15040 case OPC_DEXTRV_RS_L: 15041 case OPC_DEXTRV_S_H: 15042 case OPC_DEXTRV_W: 15043 case OPC_DEXTRV_R_W: 15044 case OPC_DEXTRV_RS_W: 15045 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1); 15046 break; 15047 case OPC_DMTHLIP: 15048 case OPC_DSHILO: 15049 case OPC_DSHILOV: 15050 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0); 15051 break; 15052 default: /* Invalid */ 15053 MIPS_INVAL("MASK EXTR.W"); 15054 gen_reserved_instruction(ctx); 15055 break; 15056 } 15057 break; 15058 case OPC_DPAQ_W_QH_DSP: 15059 op2 = MASK_DPAQ_W_QH(ctx->opcode); 15060 switch (op2) { 15061 case OPC_DPAU_H_OBL: 15062 case OPC_DPAU_H_OBR: 15063 case OPC_DPSU_H_OBL: 15064 case OPC_DPSU_H_OBR: 15065 case OPC_DPA_W_QH: 15066 case OPC_DPAQ_S_W_QH: 15067 case OPC_DPS_W_QH: 15068 case OPC_DPSQ_S_W_QH: 15069 case OPC_MULSAQ_S_W_QH: 15070 case OPC_DPAQ_SA_L_PW: 15071 case OPC_DPSQ_SA_L_PW: 15072 case OPC_MULSAQ_S_L_PW: 15073 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 15074 break; 15075 case OPC_MAQ_S_W_QHLL: 15076 case OPC_MAQ_S_W_QHLR: 15077 case OPC_MAQ_S_W_QHRL: 15078 case OPC_MAQ_S_W_QHRR: 15079 case OPC_MAQ_SA_W_QHLL: 15080 case OPC_MAQ_SA_W_QHLR: 15081 case OPC_MAQ_SA_W_QHRL: 15082 case OPC_MAQ_SA_W_QHRR: 15083 case OPC_MAQ_S_L_PWL: 15084 case OPC_MAQ_S_L_PWR: 15085 case OPC_DMADD: 15086 case OPC_DMADDU: 15087 case OPC_DMSUB: 15088 case OPC_DMSUBU: 15089 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0); 15090 break; 15091 default: /* Invalid */ 15092 MIPS_INVAL("MASK DPAQ.W.QH"); 15093 gen_reserved_instruction(ctx); 15094 break; 15095 } 15096 break; 15097 case OPC_DINSV_DSP: 15098 op2 = MASK_INSV(ctx->opcode); 15099 switch (op2) { 15100 case OPC_DINSV: 15101 { 15102 TCGv t0, t1; 15103 15104 check_dsp(ctx); 15105 15106 if (rt == 0) { 15107 break; 15108 } 15109 15110 t0 = tcg_temp_new(); 15111 t1 = tcg_temp_new(); 15112 15113 gen_load_gpr(t0, rt); 15114 gen_load_gpr(t1, rs); 15115 15116 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0); 15117 15118 tcg_temp_free(t0); 15119 tcg_temp_free(t1); 15120 break; 15121 } 15122 default: /* Invalid */ 15123 MIPS_INVAL("MASK DINSV"); 15124 gen_reserved_instruction(ctx); 15125 break; 15126 } 15127 break; 15128 case OPC_SHLL_OB_DSP: 15129 gen_mipsdsp_shift(ctx, op1, rd, rs, rt); 15130 break; 15131 #endif 15132 default: /* Invalid */ 15133 MIPS_INVAL("special3_legacy"); 15134 gen_reserved_instruction(ctx); 15135 break; 15136 } 15137 } 15138 15139 15140 #if defined(TARGET_MIPS64) 15141 15142 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) 15143 { 15144 uint32_t opc = MASK_MMI(ctx->opcode); 15145 int rs = extract32(ctx->opcode, 21, 5); 15146 int rt = extract32(ctx->opcode, 16, 5); 15147 int rd = extract32(ctx->opcode, 11, 5); 15148 15149 switch (opc) { 15150 case MMI_OPC_MULT1: 15151 case MMI_OPC_MULTU1: 15152 case MMI_OPC_MADD: 15153 case MMI_OPC_MADDU: 15154 case MMI_OPC_MADD1: 15155 case MMI_OPC_MADDU1: 15156 gen_mul_txx9(ctx, opc, rd, rs, rt); 15157 break; 15158 case MMI_OPC_DIV1: 15159 case MMI_OPC_DIVU1: 15160 gen_div1_tx79(ctx, opc, rs, rt); 15161 break; 15162 default: 15163 MIPS_INVAL("TX79 MMI class"); 15164 gen_reserved_instruction(ctx); 15165 break; 15166 } 15167 } 15168 15169 static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx) 15170 { 15171 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_LQ */ 15172 } 15173 15174 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset) 15175 { 15176 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */ 15177 } 15178 15179 /* 15180 * The TX79-specific instruction Store Quadword 15181 * 15182 * +--------+-------+-------+------------------------+ 15183 * | 011111 | base | rt | offset | SQ 15184 * +--------+-------+-------+------------------------+ 15185 * 6 5 5 16 15186 * 15187 * has the same opcode as the Read Hardware Register instruction 15188 * 15189 * +--------+-------+-------+-------+-------+--------+ 15190 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR 15191 * +--------+-------+-------+-------+-------+--------+ 15192 * 6 5 5 5 5 6 15193 * 15194 * that is required, trapped and emulated by the Linux kernel. However, all 15195 * RDHWR encodings yield address error exceptions on the TX79 since the SQ 15196 * offset is odd. Therefore all valid SQ instructions can execute normally. 15197 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish 15198 * between SQ and RDHWR, as the Linux kernel does. 15199 */ 15200 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx) 15201 { 15202 int base = extract32(ctx->opcode, 21, 5); 15203 int rt = extract32(ctx->opcode, 16, 5); 15204 int offset = extract32(ctx->opcode, 0, 16); 15205 15206 #ifdef CONFIG_USER_ONLY 15207 uint32_t op1 = MASK_SPECIAL3(ctx->opcode); 15208 uint32_t op2 = extract32(ctx->opcode, 6, 5); 15209 15210 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) { 15211 int rd = extract32(ctx->opcode, 11, 5); 15212 15213 gen_rdhwr(ctx, rt, rd, 0); 15214 return; 15215 } 15216 #endif 15217 15218 gen_mmi_sq(ctx, base, rt, offset); 15219 } 15220 15221 #endif 15222 15223 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) 15224 { 15225 int rs, rt, rd, sa; 15226 uint32_t op1, op2; 15227 int16_t imm; 15228 15229 rs = (ctx->opcode >> 21) & 0x1f; 15230 rt = (ctx->opcode >> 16) & 0x1f; 15231 rd = (ctx->opcode >> 11) & 0x1f; 15232 sa = (ctx->opcode >> 6) & 0x1f; 15233 imm = sextract32(ctx->opcode, 7, 9); 15234 15235 op1 = MASK_SPECIAL3(ctx->opcode); 15236 15237 /* 15238 * EVA loads and stores overlap Loongson 2E instructions decoded by 15239 * decode_opc_special3_legacy(), so be careful to allow their decoding when 15240 * EVA is absent. 15241 */ 15242 if (ctx->eva) { 15243 switch (op1) { 15244 case OPC_LWLE: 15245 case OPC_LWRE: 15246 case OPC_LBUE: 15247 case OPC_LHUE: 15248 case OPC_LBE: 15249 case OPC_LHE: 15250 case OPC_LLE: 15251 case OPC_LWE: 15252 check_cp0_enabled(ctx); 15253 gen_ld(ctx, op1, rt, rs, imm); 15254 return; 15255 case OPC_SWLE: 15256 case OPC_SWRE: 15257 case OPC_SBE: 15258 case OPC_SHE: 15259 case OPC_SWE: 15260 check_cp0_enabled(ctx); 15261 gen_st(ctx, op1, rt, rs, imm); 15262 return; 15263 case OPC_SCE: 15264 check_cp0_enabled(ctx); 15265 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true); 15266 return; 15267 case OPC_CACHEE: 15268 check_eva(ctx); 15269 check_cp0_enabled(ctx); 15270 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 15271 gen_cache_operation(ctx, rt, rs, imm); 15272 } 15273 return; 15274 case OPC_PREFE: 15275 check_cp0_enabled(ctx); 15276 /* Treat as NOP. */ 15277 return; 15278 } 15279 } 15280 15281 switch (op1) { 15282 case OPC_EXT: 15283 case OPC_INS: 15284 check_insn(ctx, ISA_MIPS_R2); 15285 gen_bitops(ctx, op1, rt, rs, sa, rd); 15286 break; 15287 case OPC_BSHFL: 15288 op2 = MASK_BSHFL(ctx->opcode); 15289 switch (op2) { 15290 case OPC_ALIGN: 15291 case OPC_ALIGN_1: 15292 case OPC_ALIGN_2: 15293 case OPC_ALIGN_3: 15294 case OPC_BITSWAP: 15295 check_insn(ctx, ISA_MIPS_R6); 15296 decode_opc_special3_r6(env, ctx); 15297 break; 15298 default: 15299 check_insn(ctx, ISA_MIPS_R2); 15300 gen_bshfl(ctx, op2, rt, rd); 15301 break; 15302 } 15303 break; 15304 #if defined(TARGET_MIPS64) 15305 case OPC_DEXTM: 15306 case OPC_DEXTU: 15307 case OPC_DEXT: 15308 case OPC_DINSM: 15309 case OPC_DINSU: 15310 case OPC_DINS: 15311 check_insn(ctx, ISA_MIPS_R2); 15312 check_mips_64(ctx); 15313 gen_bitops(ctx, op1, rt, rs, sa, rd); 15314 break; 15315 case OPC_DBSHFL: 15316 op2 = MASK_DBSHFL(ctx->opcode); 15317 switch (op2) { 15318 case OPC_DALIGN: 15319 case OPC_DALIGN_1: 15320 case OPC_DALIGN_2: 15321 case OPC_DALIGN_3: 15322 case OPC_DALIGN_4: 15323 case OPC_DALIGN_5: 15324 case OPC_DALIGN_6: 15325 case OPC_DALIGN_7: 15326 case OPC_DBITSWAP: 15327 check_insn(ctx, ISA_MIPS_R6); 15328 decode_opc_special3_r6(env, ctx); 15329 break; 15330 default: 15331 check_insn(ctx, ISA_MIPS_R2); 15332 check_mips_64(ctx); 15333 op2 = MASK_DBSHFL(ctx->opcode); 15334 gen_bshfl(ctx, op2, rt, rd); 15335 break; 15336 } 15337 break; 15338 #endif 15339 case OPC_RDHWR: 15340 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3)); 15341 break; 15342 case OPC_FORK: 15343 check_mt(ctx); 15344 { 15345 TCGv t0 = tcg_temp_new(); 15346 TCGv t1 = tcg_temp_new(); 15347 15348 gen_load_gpr(t0, rt); 15349 gen_load_gpr(t1, rs); 15350 gen_helper_fork(t0, t1); 15351 tcg_temp_free(t0); 15352 tcg_temp_free(t1); 15353 } 15354 break; 15355 case OPC_YIELD: 15356 check_mt(ctx); 15357 { 15358 TCGv t0 = tcg_temp_new(); 15359 15360 gen_load_gpr(t0, rs); 15361 gen_helper_yield(t0, cpu_env, t0); 15362 gen_store_gpr(t0, rd); 15363 tcg_temp_free(t0); 15364 } 15365 break; 15366 default: 15367 if (ctx->insn_flags & ISA_MIPS_R6) { 15368 decode_opc_special3_r6(env, ctx); 15369 } else { 15370 decode_opc_special3_legacy(env, ctx); 15371 } 15372 } 15373 } 15374 15375 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) 15376 { 15377 int32_t offset; 15378 int rs, rt, rd, sa; 15379 uint32_t op, op1; 15380 int16_t imm; 15381 15382 op = MASK_OP_MAJOR(ctx->opcode); 15383 rs = (ctx->opcode >> 21) & 0x1f; 15384 rt = (ctx->opcode >> 16) & 0x1f; 15385 rd = (ctx->opcode >> 11) & 0x1f; 15386 sa = (ctx->opcode >> 6) & 0x1f; 15387 imm = (int16_t)ctx->opcode; 15388 switch (op) { 15389 case OPC_SPECIAL: 15390 decode_opc_special(env, ctx); 15391 break; 15392 case OPC_SPECIAL2: 15393 #if defined(TARGET_MIPS64) 15394 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) { 15395 decode_mmi(env, ctx); 15396 break; 15397 } 15398 #endif 15399 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) { 15400 if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) { 15401 gen_arith(ctx, OPC_MUL, rd, rs, rt); 15402 } else { 15403 decode_ase_mxu(ctx, ctx->opcode); 15404 } 15405 break; 15406 } 15407 decode_opc_special2_legacy(env, ctx); 15408 break; 15409 case OPC_SPECIAL3: 15410 #if defined(TARGET_MIPS64) 15411 if (ctx->insn_flags & INSN_R5900) { 15412 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */ 15413 } else { 15414 decode_opc_special3(env, ctx); 15415 } 15416 #else 15417 decode_opc_special3(env, ctx); 15418 #endif 15419 break; 15420 case OPC_REGIMM: 15421 op1 = MASK_REGIMM(ctx->opcode); 15422 switch (op1) { 15423 case OPC_BLTZL: /* REGIMM branches */ 15424 case OPC_BGEZL: 15425 case OPC_BLTZALL: 15426 case OPC_BGEZALL: 15427 check_insn(ctx, ISA_MIPS2); 15428 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15429 /* Fallthrough */ 15430 case OPC_BLTZ: 15431 case OPC_BGEZ: 15432 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 15433 break; 15434 case OPC_BLTZAL: 15435 case OPC_BGEZAL: 15436 if (ctx->insn_flags & ISA_MIPS_R6) { 15437 if (rs == 0) { 15438 /* OPC_NAL, OPC_BAL */ 15439 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4); 15440 } else { 15441 gen_reserved_instruction(ctx); 15442 } 15443 } else { 15444 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4); 15445 } 15446 break; 15447 case OPC_TGEI: /* REGIMM traps */ 15448 case OPC_TGEIU: 15449 case OPC_TLTI: 15450 case OPC_TLTIU: 15451 case OPC_TEQI: 15452 15453 case OPC_TNEI: 15454 check_insn(ctx, ISA_MIPS2); 15455 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15456 gen_trap(ctx, op1, rs, -1, imm); 15457 break; 15458 case OPC_SIGRIE: 15459 check_insn(ctx, ISA_MIPS_R6); 15460 gen_reserved_instruction(ctx); 15461 break; 15462 case OPC_SYNCI: 15463 check_insn(ctx, ISA_MIPS_R2); 15464 /* 15465 * Break the TB to be able to sync copied instructions 15466 * immediately. 15467 */ 15468 ctx->base.is_jmp = DISAS_STOP; 15469 break; 15470 case OPC_BPOSGE32: /* MIPS DSP branch */ 15471 #if defined(TARGET_MIPS64) 15472 case OPC_BPOSGE64: 15473 #endif 15474 check_dsp(ctx); 15475 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4); 15476 break; 15477 #if defined(TARGET_MIPS64) 15478 case OPC_DAHI: 15479 check_insn(ctx, ISA_MIPS_R6); 15480 check_mips_64(ctx); 15481 if (rs != 0) { 15482 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32); 15483 } 15484 break; 15485 case OPC_DATI: 15486 check_insn(ctx, ISA_MIPS_R6); 15487 check_mips_64(ctx); 15488 if (rs != 0) { 15489 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48); 15490 } 15491 break; 15492 #endif 15493 default: /* Invalid */ 15494 MIPS_INVAL("regimm"); 15495 gen_reserved_instruction(ctx); 15496 break; 15497 } 15498 break; 15499 case OPC_CP0: 15500 check_cp0_enabled(ctx); 15501 op1 = MASK_CP0(ctx->opcode); 15502 switch (op1) { 15503 case OPC_MFC0: 15504 case OPC_MTC0: 15505 case OPC_MFTR: 15506 case OPC_MTTR: 15507 case OPC_MFHC0: 15508 case OPC_MTHC0: 15509 #if defined(TARGET_MIPS64) 15510 case OPC_DMFC0: 15511 case OPC_DMTC0: 15512 #endif 15513 #ifndef CONFIG_USER_ONLY 15514 gen_cp0(env, ctx, op1, rt, rd); 15515 #endif /* !CONFIG_USER_ONLY */ 15516 break; 15517 case OPC_C0: 15518 case OPC_C0_1: 15519 case OPC_C0_2: 15520 case OPC_C0_3: 15521 case OPC_C0_4: 15522 case OPC_C0_5: 15523 case OPC_C0_6: 15524 case OPC_C0_7: 15525 case OPC_C0_8: 15526 case OPC_C0_9: 15527 case OPC_C0_A: 15528 case OPC_C0_B: 15529 case OPC_C0_C: 15530 case OPC_C0_D: 15531 case OPC_C0_E: 15532 case OPC_C0_F: 15533 #ifndef CONFIG_USER_ONLY 15534 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); 15535 #endif /* !CONFIG_USER_ONLY */ 15536 break; 15537 case OPC_MFMC0: 15538 #ifndef CONFIG_USER_ONLY 15539 { 15540 uint32_t op2; 15541 TCGv t0 = tcg_temp_new(); 15542 15543 op2 = MASK_MFMC0(ctx->opcode); 15544 switch (op2) { 15545 case OPC_DMT: 15546 check_cp0_mt(ctx); 15547 gen_helper_dmt(t0); 15548 gen_store_gpr(t0, rt); 15549 break; 15550 case OPC_EMT: 15551 check_cp0_mt(ctx); 15552 gen_helper_emt(t0); 15553 gen_store_gpr(t0, rt); 15554 break; 15555 case OPC_DVPE: 15556 check_cp0_mt(ctx); 15557 gen_helper_dvpe(t0, cpu_env); 15558 gen_store_gpr(t0, rt); 15559 break; 15560 case OPC_EVPE: 15561 check_cp0_mt(ctx); 15562 gen_helper_evpe(t0, cpu_env); 15563 gen_store_gpr(t0, rt); 15564 break; 15565 case OPC_DVP: 15566 check_insn(ctx, ISA_MIPS_R6); 15567 if (ctx->vp) { 15568 gen_helper_dvp(t0, cpu_env); 15569 gen_store_gpr(t0, rt); 15570 } 15571 break; 15572 case OPC_EVP: 15573 check_insn(ctx, ISA_MIPS_R6); 15574 if (ctx->vp) { 15575 gen_helper_evp(t0, cpu_env); 15576 gen_store_gpr(t0, rt); 15577 } 15578 break; 15579 case OPC_DI: 15580 check_insn(ctx, ISA_MIPS_R2); 15581 save_cpu_state(ctx, 1); 15582 gen_helper_di(t0, cpu_env); 15583 gen_store_gpr(t0, rt); 15584 /* 15585 * Stop translation as we may have switched 15586 * the execution mode. 15587 */ 15588 ctx->base.is_jmp = DISAS_STOP; 15589 break; 15590 case OPC_EI: 15591 check_insn(ctx, ISA_MIPS_R2); 15592 save_cpu_state(ctx, 1); 15593 gen_helper_ei(t0, cpu_env); 15594 gen_store_gpr(t0, rt); 15595 /* 15596 * DISAS_STOP isn't sufficient, we need to ensure we break 15597 * out of translated code to check for pending interrupts. 15598 */ 15599 gen_save_pc(ctx->base.pc_next + 4); 15600 ctx->base.is_jmp = DISAS_EXIT; 15601 break; 15602 default: /* Invalid */ 15603 MIPS_INVAL("mfmc0"); 15604 gen_reserved_instruction(ctx); 15605 break; 15606 } 15607 tcg_temp_free(t0); 15608 } 15609 #endif /* !CONFIG_USER_ONLY */ 15610 break; 15611 case OPC_RDPGPR: 15612 check_insn(ctx, ISA_MIPS_R2); 15613 gen_load_srsgpr(rt, rd); 15614 break; 15615 case OPC_WRPGPR: 15616 check_insn(ctx, ISA_MIPS_R2); 15617 gen_store_srsgpr(rt, rd); 15618 break; 15619 default: 15620 MIPS_INVAL("cp0"); 15621 gen_reserved_instruction(ctx); 15622 break; 15623 } 15624 break; 15625 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */ 15626 if (ctx->insn_flags & ISA_MIPS_R6) { 15627 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */ 15628 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15629 } else { 15630 /* OPC_ADDI */ 15631 /* Arithmetic with immediate opcode */ 15632 gen_arith_imm(ctx, op, rt, rs, imm); 15633 } 15634 break; 15635 case OPC_ADDIU: 15636 gen_arith_imm(ctx, op, rt, rs, imm); 15637 break; 15638 case OPC_SLTI: /* Set on less than with immediate opcode */ 15639 case OPC_SLTIU: 15640 gen_slt_imm(ctx, op, rt, rs, imm); 15641 break; 15642 case OPC_ANDI: /* Arithmetic with immediate opcode */ 15643 case OPC_LUI: /* OPC_AUI */ 15644 case OPC_ORI: 15645 case OPC_XORI: 15646 gen_logic_imm(ctx, op, rt, rs, imm); 15647 break; 15648 case OPC_J: /* Jump */ 15649 case OPC_JAL: 15650 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 15651 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 15652 break; 15653 /* Branch */ 15654 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */ 15655 if (ctx->insn_flags & ISA_MIPS_R6) { 15656 if (rt == 0) { 15657 gen_reserved_instruction(ctx); 15658 break; 15659 } 15660 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */ 15661 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15662 } else { 15663 /* OPC_BLEZL */ 15664 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15665 } 15666 break; 15667 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */ 15668 if (ctx->insn_flags & ISA_MIPS_R6) { 15669 if (rt == 0) { 15670 gen_reserved_instruction(ctx); 15671 break; 15672 } 15673 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */ 15674 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15675 } else { 15676 /* OPC_BGTZL */ 15677 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15678 } 15679 break; 15680 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */ 15681 if (rt == 0) { 15682 /* OPC_BLEZ */ 15683 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15684 } else { 15685 check_insn(ctx, ISA_MIPS_R6); 15686 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */ 15687 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15688 } 15689 break; 15690 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */ 15691 if (rt == 0) { 15692 /* OPC_BGTZ */ 15693 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15694 } else { 15695 check_insn(ctx, ISA_MIPS_R6); 15696 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */ 15697 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 15698 } 15699 break; 15700 case OPC_BEQL: 15701 case OPC_BNEL: 15702 check_insn(ctx, ISA_MIPS2); 15703 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15704 /* Fallthrough */ 15705 case OPC_BEQ: 15706 case OPC_BNE: 15707 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4); 15708 break; 15709 case OPC_LL: /* Load and stores */ 15710 check_insn(ctx, ISA_MIPS2); 15711 if (ctx->insn_flags & INSN_R5900) { 15712 check_insn_opc_user_only(ctx, INSN_R5900); 15713 } 15714 /* Fallthrough */ 15715 case OPC_LWL: 15716 case OPC_LWR: 15717 case OPC_LB: 15718 case OPC_LH: 15719 case OPC_LW: 15720 case OPC_LWPC: 15721 case OPC_LBU: 15722 case OPC_LHU: 15723 gen_ld(ctx, op, rt, rs, imm); 15724 break; 15725 case OPC_SWL: 15726 case OPC_SWR: 15727 case OPC_SB: 15728 case OPC_SH: 15729 case OPC_SW: 15730 gen_st(ctx, op, rt, rs, imm); 15731 break; 15732 case OPC_SC: 15733 check_insn(ctx, ISA_MIPS2); 15734 if (ctx->insn_flags & INSN_R5900) { 15735 check_insn_opc_user_only(ctx, INSN_R5900); 15736 } 15737 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false); 15738 break; 15739 case OPC_CACHE: 15740 check_cp0_enabled(ctx); 15741 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1); 15742 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 15743 gen_cache_operation(ctx, rt, rs, imm); 15744 } 15745 /* Treat as NOP. */ 15746 break; 15747 case OPC_PREF: 15748 if (ctx->insn_flags & INSN_R5900) { 15749 /* Treat as NOP. */ 15750 } else { 15751 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); 15752 /* Treat as NOP. */ 15753 } 15754 break; 15755 15756 /* Floating point (COP1). */ 15757 case OPC_LWC1: 15758 case OPC_LDC1: 15759 case OPC_SWC1: 15760 case OPC_SDC1: 15761 gen_cop1_ldst(ctx, op, rt, rs, imm); 15762 break; 15763 15764 case OPC_CP1: 15765 op1 = MASK_CP1(ctx->opcode); 15766 15767 switch (op1) { 15768 case OPC_MFHC1: 15769 case OPC_MTHC1: 15770 check_cp1_enabled(ctx); 15771 check_insn(ctx, ISA_MIPS_R2); 15772 /* fall through */ 15773 case OPC_MFC1: 15774 case OPC_CFC1: 15775 case OPC_MTC1: 15776 case OPC_CTC1: 15777 check_cp1_enabled(ctx); 15778 gen_cp1(ctx, op1, rt, rd); 15779 break; 15780 #if defined(TARGET_MIPS64) 15781 case OPC_DMFC1: 15782 case OPC_DMTC1: 15783 check_cp1_enabled(ctx); 15784 check_insn(ctx, ISA_MIPS3); 15785 check_mips_64(ctx); 15786 gen_cp1(ctx, op1, rt, rd); 15787 break; 15788 #endif 15789 case OPC_BC1EQZ: /* OPC_BC1ANY2 */ 15790 check_cp1_enabled(ctx); 15791 if (ctx->insn_flags & ISA_MIPS_R6) { 15792 /* OPC_BC1EQZ */ 15793 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 15794 rt, imm << 2, 4); 15795 } else { 15796 /* OPC_BC1ANY2 */ 15797 check_cop1x(ctx); 15798 check_insn(ctx, ASE_MIPS3D); 15799 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 15800 (rt >> 2) & 0x7, imm << 2); 15801 } 15802 break; 15803 case OPC_BC1NEZ: 15804 check_cp1_enabled(ctx); 15805 check_insn(ctx, ISA_MIPS_R6); 15806 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode), 15807 rt, imm << 2, 4); 15808 break; 15809 case OPC_BC1ANY4: 15810 check_cp1_enabled(ctx); 15811 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15812 check_cop1x(ctx); 15813 check_insn(ctx, ASE_MIPS3D); 15814 /* fall through */ 15815 case OPC_BC1: 15816 check_cp1_enabled(ctx); 15817 check_insn_opc_removed(ctx, ISA_MIPS_R6); 15818 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode), 15819 (rt >> 2) & 0x7, imm << 2); 15820 break; 15821 case OPC_PS_FMT: 15822 check_ps(ctx); 15823 /* fall through */ 15824 case OPC_S_FMT: 15825 case OPC_D_FMT: 15826 check_cp1_enabled(ctx); 15827 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 15828 (imm >> 8) & 0x7); 15829 break; 15830 case OPC_W_FMT: 15831 case OPC_L_FMT: 15832 { 15833 int r6_op = ctx->opcode & FOP(0x3f, 0x1f); 15834 check_cp1_enabled(ctx); 15835 if (ctx->insn_flags & ISA_MIPS_R6) { 15836 switch (r6_op) { 15837 case R6_OPC_CMP_AF_S: 15838 case R6_OPC_CMP_UN_S: 15839 case R6_OPC_CMP_EQ_S: 15840 case R6_OPC_CMP_UEQ_S: 15841 case R6_OPC_CMP_LT_S: 15842 case R6_OPC_CMP_ULT_S: 15843 case R6_OPC_CMP_LE_S: 15844 case R6_OPC_CMP_ULE_S: 15845 case R6_OPC_CMP_SAF_S: 15846 case R6_OPC_CMP_SUN_S: 15847 case R6_OPC_CMP_SEQ_S: 15848 case R6_OPC_CMP_SEUQ_S: 15849 case R6_OPC_CMP_SLT_S: 15850 case R6_OPC_CMP_SULT_S: 15851 case R6_OPC_CMP_SLE_S: 15852 case R6_OPC_CMP_SULE_S: 15853 case R6_OPC_CMP_OR_S: 15854 case R6_OPC_CMP_UNE_S: 15855 case R6_OPC_CMP_NE_S: 15856 case R6_OPC_CMP_SOR_S: 15857 case R6_OPC_CMP_SUNE_S: 15858 case R6_OPC_CMP_SNE_S: 15859 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa); 15860 break; 15861 case R6_OPC_CMP_AF_D: 15862 case R6_OPC_CMP_UN_D: 15863 case R6_OPC_CMP_EQ_D: 15864 case R6_OPC_CMP_UEQ_D: 15865 case R6_OPC_CMP_LT_D: 15866 case R6_OPC_CMP_ULT_D: 15867 case R6_OPC_CMP_LE_D: 15868 case R6_OPC_CMP_ULE_D: 15869 case R6_OPC_CMP_SAF_D: 15870 case R6_OPC_CMP_SUN_D: 15871 case R6_OPC_CMP_SEQ_D: 15872 case R6_OPC_CMP_SEUQ_D: 15873 case R6_OPC_CMP_SLT_D: 15874 case R6_OPC_CMP_SULT_D: 15875 case R6_OPC_CMP_SLE_D: 15876 case R6_OPC_CMP_SULE_D: 15877 case R6_OPC_CMP_OR_D: 15878 case R6_OPC_CMP_UNE_D: 15879 case R6_OPC_CMP_NE_D: 15880 case R6_OPC_CMP_SOR_D: 15881 case R6_OPC_CMP_SUNE_D: 15882 case R6_OPC_CMP_SNE_D: 15883 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa); 15884 break; 15885 default: 15886 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), 15887 rt, rd, sa, (imm >> 8) & 0x7); 15888 15889 break; 15890 } 15891 } else { 15892 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa, 15893 (imm >> 8) & 0x7); 15894 } 15895 break; 15896 } 15897 default: 15898 MIPS_INVAL("cp1"); 15899 gen_reserved_instruction(ctx); 15900 break; 15901 } 15902 break; 15903 15904 /* Compact branches [R6] and COP2 [non-R6] */ 15905 case OPC_BC: /* OPC_LWC2 */ 15906 case OPC_BALC: /* OPC_SWC2 */ 15907 if (ctx->insn_flags & ISA_MIPS_R6) { 15908 /* OPC_BC, OPC_BALC */ 15909 gen_compute_compact_branch(ctx, op, 0, 0, 15910 sextract32(ctx->opcode << 2, 0, 28)); 15911 } else if (ctx->insn_flags & ASE_LEXT) { 15912 gen_loongson_lswc2(ctx, rt, rs, rd); 15913 } else { 15914 /* OPC_LWC2, OPC_SWC2 */ 15915 /* COP2: Not implemented. */ 15916 generate_exception_err(ctx, EXCP_CpU, 2); 15917 } 15918 break; 15919 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */ 15920 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */ 15921 if (ctx->insn_flags & ISA_MIPS_R6) { 15922 if (rs != 0) { 15923 /* OPC_BEQZC, OPC_BNEZC */ 15924 gen_compute_compact_branch(ctx, op, rs, 0, 15925 sextract32(ctx->opcode << 2, 0, 23)); 15926 } else { 15927 /* OPC_JIC, OPC_JIALC */ 15928 gen_compute_compact_branch(ctx, op, 0, rt, imm); 15929 } 15930 } else if (ctx->insn_flags & ASE_LEXT) { 15931 gen_loongson_lsdc2(ctx, rt, rs, rd); 15932 } else { 15933 /* OPC_LWC2, OPC_SWC2 */ 15934 /* COP2: Not implemented. */ 15935 generate_exception_err(ctx, EXCP_CpU, 2); 15936 } 15937 break; 15938 case OPC_CP2: 15939 check_insn(ctx, ASE_LMMI); 15940 /* Note that these instructions use different fields. */ 15941 gen_loongson_multimedia(ctx, sa, rd, rt); 15942 break; 15943 15944 case OPC_CP3: 15945 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 15946 check_cp1_enabled(ctx); 15947 op1 = MASK_CP3(ctx->opcode); 15948 switch (op1) { 15949 case OPC_LUXC1: 15950 case OPC_SUXC1: 15951 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 15952 /* Fallthrough */ 15953 case OPC_LWXC1: 15954 case OPC_LDXC1: 15955 case OPC_SWXC1: 15956 case OPC_SDXC1: 15957 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15958 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); 15959 break; 15960 case OPC_PREFX: 15961 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15962 /* Treat as NOP. */ 15963 break; 15964 case OPC_ALNV_PS: 15965 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2); 15966 /* Fallthrough */ 15967 case OPC_MADD_S: 15968 case OPC_MADD_D: 15969 case OPC_MADD_PS: 15970 case OPC_MSUB_S: 15971 case OPC_MSUB_D: 15972 case OPC_MSUB_PS: 15973 case OPC_NMADD_S: 15974 case OPC_NMADD_D: 15975 case OPC_NMADD_PS: 15976 case OPC_NMSUB_S: 15977 case OPC_NMSUB_D: 15978 case OPC_NMSUB_PS: 15979 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2); 15980 gen_flt3_arith(ctx, op1, sa, rs, rd, rt); 15981 break; 15982 default: 15983 MIPS_INVAL("cp3"); 15984 gen_reserved_instruction(ctx); 15985 break; 15986 } 15987 } else { 15988 generate_exception_err(ctx, EXCP_CpU, 1); 15989 } 15990 break; 15991 15992 #if defined(TARGET_MIPS64) 15993 /* MIPS64 opcodes */ 15994 case OPC_LLD: 15995 if (ctx->insn_flags & INSN_R5900) { 15996 check_insn_opc_user_only(ctx, INSN_R5900); 15997 } 15998 /* fall through */ 15999 case OPC_LDL: 16000 case OPC_LDR: 16001 case OPC_LWU: 16002 case OPC_LD: 16003 check_insn(ctx, ISA_MIPS3); 16004 check_mips_64(ctx); 16005 gen_ld(ctx, op, rt, rs, imm); 16006 break; 16007 case OPC_SDL: 16008 case OPC_SDR: 16009 case OPC_SD: 16010 check_insn(ctx, ISA_MIPS3); 16011 check_mips_64(ctx); 16012 gen_st(ctx, op, rt, rs, imm); 16013 break; 16014 case OPC_SCD: 16015 check_insn(ctx, ISA_MIPS3); 16016 if (ctx->insn_flags & INSN_R5900) { 16017 check_insn_opc_user_only(ctx, INSN_R5900); 16018 } 16019 check_mips_64(ctx); 16020 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false); 16021 break; 16022 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */ 16023 if (ctx->insn_flags & ISA_MIPS_R6) { 16024 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */ 16025 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 16026 } else { 16027 /* OPC_DADDI */ 16028 check_insn(ctx, ISA_MIPS3); 16029 check_mips_64(ctx); 16030 gen_arith_imm(ctx, op, rt, rs, imm); 16031 } 16032 break; 16033 case OPC_DADDIU: 16034 check_insn(ctx, ISA_MIPS3); 16035 check_mips_64(ctx); 16036 gen_arith_imm(ctx, op, rt, rs, imm); 16037 break; 16038 #else 16039 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */ 16040 if (ctx->insn_flags & ISA_MIPS_R6) { 16041 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2); 16042 } else { 16043 MIPS_INVAL("major opcode"); 16044 gen_reserved_instruction(ctx); 16045 } 16046 break; 16047 #endif 16048 case OPC_DAUI: /* OPC_JALX */ 16049 if (ctx->insn_flags & ISA_MIPS_R6) { 16050 #if defined(TARGET_MIPS64) 16051 /* OPC_DAUI */ 16052 check_mips_64(ctx); 16053 if (rs == 0) { 16054 generate_exception(ctx, EXCP_RI); 16055 } else if (rt != 0) { 16056 TCGv t0 = tcg_temp_new(); 16057 gen_load_gpr(t0, rs); 16058 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16); 16059 tcg_temp_free(t0); 16060 } 16061 #else 16062 gen_reserved_instruction(ctx); 16063 MIPS_INVAL("major opcode"); 16064 #endif 16065 } else { 16066 /* OPC_JALX */ 16067 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS); 16068 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; 16069 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4); 16070 } 16071 break; 16072 case OPC_MDMX: /* MMI_OPC_LQ */ 16073 if (ctx->insn_flags & INSN_R5900) { 16074 #if defined(TARGET_MIPS64) 16075 gen_mmi_lq(env, ctx); 16076 #endif 16077 } else { 16078 /* MDMX: Not implemented. */ 16079 } 16080 break; 16081 case OPC_PCREL: 16082 check_insn(ctx, ISA_MIPS_R6); 16083 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs); 16084 break; 16085 default: /* Invalid */ 16086 MIPS_INVAL("major opcode"); 16087 return false; 16088 } 16089 return true; 16090 } 16091 16092 static void decode_opc(CPUMIPSState *env, DisasContext *ctx) 16093 { 16094 /* make sure instructions are on a word boundary */ 16095 if (ctx->base.pc_next & 0x3) { 16096 env->CP0_BadVAddr = ctx->base.pc_next; 16097 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); 16098 return; 16099 } 16100 16101 /* Handle blikely not taken case */ 16102 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { 16103 TCGLabel *l1 = gen_new_label(); 16104 16105 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); 16106 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); 16107 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); 16108 gen_set_label(l1); 16109 } 16110 16111 /* Transition to the auto-generated decoder. */ 16112 16113 /* ISA extensions */ 16114 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) { 16115 return; 16116 } 16117 16118 /* ISA (from latest to oldest) */ 16119 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) { 16120 return; 16121 } 16122 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { 16123 return; 16124 } 16125 16126 if (decode_opc_legacy(env, ctx)) { 16127 return; 16128 } 16129 16130 gen_reserved_instruction(ctx); 16131 } 16132 16133 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 16134 { 16135 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16136 CPUMIPSState *env = cs->env_ptr; 16137 16138 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; 16139 ctx->saved_pc = -1; 16140 ctx->insn_flags = env->insn_flags; 16141 ctx->CP0_Config1 = env->CP0_Config1; 16142 ctx->CP0_Config2 = env->CP0_Config2; 16143 ctx->CP0_Config3 = env->CP0_Config3; 16144 ctx->CP0_Config5 = env->CP0_Config5; 16145 ctx->btarget = 0; 16146 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff; 16147 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1; 16148 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3; 16149 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1; 16150 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1; 16151 ctx->PAMask = env->PAMask; 16152 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1; 16153 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1; 16154 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1; 16155 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift; 16156 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1; 16157 /* Restore delay slot state from the tb context. */ 16158 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ 16159 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1; 16160 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || 16161 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); 16162 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1; 16163 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; 16164 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; 16165 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; 16166 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1; 16167 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3; 16168 restore_cpu_state(env, ctx); 16169 #ifdef CONFIG_USER_ONLY 16170 ctx->mem_idx = MIPS_HFLAG_UM; 16171 #else 16172 ctx->mem_idx = hflags_mmu_index(ctx->hflags); 16173 #endif 16174 ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 | 16175 INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN; 16176 16177 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, 16178 ctx->hflags); 16179 } 16180 16181 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) 16182 { 16183 } 16184 16185 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 16186 { 16187 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16188 16189 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK, 16190 ctx->btarget); 16191 } 16192 16193 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, 16194 const CPUBreakpoint *bp) 16195 { 16196 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16197 16198 save_cpu_state(ctx, 1); 16199 ctx->base.is_jmp = DISAS_NORETURN; 16200 gen_helper_raise_exception_debug(cpu_env); 16201 /* 16202 * The address covered by the breakpoint must be included in 16203 * [tb->pc, tb->pc + tb->size) in order to for it to be 16204 * properly cleared -- thus we increment the PC here so that 16205 * the logic setting tb->size below does the right thing. 16206 */ 16207 ctx->base.pc_next += 4; 16208 return true; 16209 } 16210 16211 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 16212 { 16213 CPUMIPSState *env = cs->env_ptr; 16214 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16215 int insn_bytes; 16216 int is_slot; 16217 16218 is_slot = ctx->hflags & MIPS_HFLAG_BMASK; 16219 if (ctx->insn_flags & ISA_NANOMIPS32) { 16220 ctx->opcode = translator_lduw(env, ctx->base.pc_next); 16221 insn_bytes = decode_isa_nanomips(env, ctx); 16222 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) { 16223 ctx->opcode = translator_ldl(env, ctx->base.pc_next); 16224 insn_bytes = 4; 16225 decode_opc(env, ctx); 16226 } else if (ctx->insn_flags & ASE_MICROMIPS) { 16227 ctx->opcode = translator_lduw(env, ctx->base.pc_next); 16228 insn_bytes = decode_isa_micromips(env, ctx); 16229 } else if (ctx->insn_flags & ASE_MIPS16) { 16230 ctx->opcode = translator_lduw(env, ctx->base.pc_next); 16231 insn_bytes = decode_ase_mips16e(env, ctx); 16232 } else { 16233 gen_reserved_instruction(ctx); 16234 g_assert(ctx->base.is_jmp == DISAS_NORETURN); 16235 return; 16236 } 16237 16238 if (ctx->hflags & MIPS_HFLAG_BMASK) { 16239 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 | 16240 MIPS_HFLAG_FBNSLOT))) { 16241 /* 16242 * Force to generate branch as there is neither delay nor 16243 * forbidden slot. 16244 */ 16245 is_slot = 1; 16246 } 16247 if ((ctx->hflags & MIPS_HFLAG_M16) && 16248 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) { 16249 /* 16250 * Force to generate branch as microMIPS R6 doesn't restrict 16251 * branches in the forbidden slot. 16252 */ 16253 is_slot = 1; 16254 } 16255 } 16256 if (is_slot) { 16257 gen_branch(ctx, insn_bytes); 16258 } 16259 ctx->base.pc_next += insn_bytes; 16260 16261 if (ctx->base.is_jmp != DISAS_NEXT) { 16262 return; 16263 } 16264 /* 16265 * Execute a branch and its delay slot as a single instruction. 16266 * This is what GDB expects and is consistent with what the 16267 * hardware does (e.g. if a delay slot instruction faults, the 16268 * reported PC is the PC of the branch). 16269 */ 16270 if (ctx->base.singlestep_enabled && 16271 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) { 16272 ctx->base.is_jmp = DISAS_TOO_MANY; 16273 } 16274 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) { 16275 ctx->base.is_jmp = DISAS_TOO_MANY; 16276 } 16277 } 16278 16279 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 16280 { 16281 DisasContext *ctx = container_of(dcbase, DisasContext, base); 16282 16283 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) { 16284 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT); 16285 gen_helper_raise_exception_debug(cpu_env); 16286 } else { 16287 switch (ctx->base.is_jmp) { 16288 case DISAS_STOP: 16289 gen_save_pc(ctx->base.pc_next); 16290 tcg_gen_lookup_and_goto_ptr(); 16291 break; 16292 case DISAS_NEXT: 16293 case DISAS_TOO_MANY: 16294 save_cpu_state(ctx, 0); 16295 gen_goto_tb(ctx, 0, ctx->base.pc_next); 16296 break; 16297 case DISAS_EXIT: 16298 tcg_gen_exit_tb(NULL, 0); 16299 break; 16300 case DISAS_NORETURN: 16301 break; 16302 default: 16303 g_assert_not_reached(); 16304 } 16305 } 16306 } 16307 16308 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs) 16309 { 16310 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); 16311 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size); 16312 } 16313 16314 static const TranslatorOps mips_tr_ops = { 16315 .init_disas_context = mips_tr_init_disas_context, 16316 .tb_start = mips_tr_tb_start, 16317 .insn_start = mips_tr_insn_start, 16318 .breakpoint_check = mips_tr_breakpoint_check, 16319 .translate_insn = mips_tr_translate_insn, 16320 .tb_stop = mips_tr_tb_stop, 16321 .disas_log = mips_tr_disas_log, 16322 }; 16323 16324 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) 16325 { 16326 DisasContext ctx; 16327 16328 translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns); 16329 } 16330 16331 void mips_tcg_init(void) 16332 { 16333 int i; 16334 16335 cpu_gpr[0] = NULL; 16336 for (i = 1; i < 32; i++) 16337 cpu_gpr[i] = tcg_global_mem_new(cpu_env, 16338 offsetof(CPUMIPSState, 16339 active_tc.gpr[i]), 16340 regnames[i]); 16341 #if defined(TARGET_MIPS64) 16342 cpu_gpr_hi[0] = NULL; 16343 16344 for (unsigned i = 1; i < 32; i++) { 16345 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]); 16346 16347 cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env, 16348 offsetof(CPUMIPSState, 16349 active_tc.gpr_hi[i]), 16350 rname); 16351 } 16352 #endif /* !TARGET_MIPS64 */ 16353 for (i = 0; i < 32; i++) { 16354 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]); 16355 16356 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); 16357 } 16358 msa_translate_init(); 16359 cpu_PC = tcg_global_mem_new(cpu_env, 16360 offsetof(CPUMIPSState, active_tc.PC), "PC"); 16361 for (i = 0; i < MIPS_DSP_ACC; i++) { 16362 cpu_HI[i] = tcg_global_mem_new(cpu_env, 16363 offsetof(CPUMIPSState, active_tc.HI[i]), 16364 regnames_HI[i]); 16365 cpu_LO[i] = tcg_global_mem_new(cpu_env, 16366 offsetof(CPUMIPSState, active_tc.LO[i]), 16367 regnames_LO[i]); 16368 } 16369 cpu_dspctrl = tcg_global_mem_new(cpu_env, 16370 offsetof(CPUMIPSState, 16371 active_tc.DSPControl), 16372 "DSPControl"); 16373 bcond = tcg_global_mem_new(cpu_env, 16374 offsetof(CPUMIPSState, bcond), "bcond"); 16375 btarget = tcg_global_mem_new(cpu_env, 16376 offsetof(CPUMIPSState, btarget), "btarget"); 16377 hflags = tcg_global_mem_new_i32(cpu_env, 16378 offsetof(CPUMIPSState, hflags), "hflags"); 16379 16380 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env, 16381 offsetof(CPUMIPSState, active_fpu.fcr0), 16382 "fcr0"); 16383 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env, 16384 offsetof(CPUMIPSState, active_fpu.fcr31), 16385 "fcr31"); 16386 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr), 16387 "lladdr"); 16388 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval), 16389 "llval"); 16390 16391 if (TARGET_LONG_BITS == 32) { 16392 mxu_translate_init(); 16393 } 16394 } 16395 16396 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, 16397 target_ulong *data) 16398 { 16399 env->active_tc.PC = data[0]; 16400 env->hflags &= ~MIPS_HFLAG_BMASK; 16401 env->hflags |= data[1]; 16402 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) { 16403 case MIPS_HFLAG_BR: 16404 break; 16405 case MIPS_HFLAG_BC: 16406 case MIPS_HFLAG_BL: 16407 case MIPS_HFLAG_B: 16408 env->btarget = data[2]; 16409 break; 16410 } 16411 } 16412